1 /*
2 * file user.c - communication interface for users
3 *
4 * $Id: user.c,v 1.14 2006/03/28 11:41:19 fzago Exp $
5 *
6 * Program XBLAST
7 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8 * Added by Koen De Raedt for central support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published
12 * by the Free Software Foundation; either version 2; or (at your option)
13 * any later version
14 *
15 * This program is distributed in the hope that it will be entertaining,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
18 * Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25 #include "xblast.h"
26
27 /*
28 * local macros
29 */
30 #define TIME_POLL_QUERY 5
31
32 #define PID_NONE -1001
33 #define PID_INVALID -3
34
35 /*
36 * local variables
37 */
38 static XBComm *comm = NULL;
39 static int PID = PID_NONE;
40 static int received = 0;
41
42 /**********************
43 * connect/disconnect *
44 **********************/
45
46 /*
47 * try to connect to server
48 */
49 XBBool
User_Connect(CFGCentralSetup * cfg)50 User_Connect (CFGCentralSetup * cfg)
51 {
52 int j;
53 char tmp[16];
54 /* create communication */
55 assert (comm == NULL);
56 comm = X2C_CreateComm (cfg);
57 if (NULL == comm) {
58 Dbg_User ("failed to establish tcp connection to central\n");
59 return XBFalse;
60 }
61 Dbg_User ("successfully established tcp to central\n");
62 /* init data */
63 PID = PID_NONE;
64 received = 0;
65 /* is that needed ? */
66 j = sprintf (tmp, "tmpPlayer");
67 tmp[j + 1] = 0;
68 Network_SetPlayer (0, 0, GUI_StringToAtom (tmp));
69 return XBTrue;
70 } /* User_Connect */
71
72 /*
73 * disconnect from server by shutting down
74 */
75 void
User_Disconnect(void)76 User_Disconnect (void)
77 {
78 if (comm != NULL) {
79 Dbg_User ("disconnecting from central\n");
80 CommDelete (comm);
81 }
82 else {
83 Dbg_User ("already disconnected from central\n");
84 }
85 } /* User_Disconnect */
86
87 /*
88 * handle stream events
89 */
90 XBBool
User_EventToCentral(const XBEventToCentral ev)91 User_EventToCentral (const XBEventToCentral ev)
92 {
93 switch (ev) {
94 case XBE2C_IORead:
95 Dbg_User ("read error to central, shutdown!\n");
96 Network_QueueEvent (XBNW_Error, CENTRAL_READ_ERR);
97 return XBTrue;
98 case XBE2C_IOWrite:
99 Dbg_User ("write error to central, shutdown!\n");
100 Network_QueueEvent (XBNW_Error, CENTRAL_WRITE_ERR);
101 return XBTrue;
102 case XBE2C_InvalidCot:
103 Dbg_User ("invalid telegram CoT from central, shutdown!\n");
104 Network_QueueEvent (XBNW_Error, CENTRAL_COT_INVALID);
105 return XBTrue;
106 case XBE2C_InvalidID:
107 Dbg_User ("invalid telegram id central, ignoring!\n");
108 return XBTrue;
109 case XBE2C_UnexpectedEOF:
110 Dbg_User ("unexpected eof to central, shutdown!\n");
111 Network_QueueEvent (XBNW_Error, CENTRAL_DISCONNECT);
112 return XBTrue;
113 case XBE2C_StreamWaiting:
114 Dbg_User ("all queued data sent to central\n");
115 return XBFalse;
116 case XBE2C_StreamBusy:
117 /* Dbg_User("data waits to be sent to central\n"); */
118 return XBFalse;
119 case XBE2C_StreamClosed:
120 Dbg_User ("connection to central has been removed\n");
121 comm = NULL;
122 return XBFalse;
123 default:
124 Dbg_User ("unknown event on stream, ignoring\n");
125 return XBFalse;
126 }
127 } /* User_EventToCentral */
128
129 /****************
130 * receive data *
131 ****************/
132
133 /*
134 * receive player config from server
135 */
136 void
User_ReceivePlayerConfig(const char * data)137 User_ReceivePlayerConfig (const char *data)
138 {
139 XBAtom atom, atomID;
140 CFGPlayerEx tmpPlayer;
141 int i;
142 atom = Network_ReceivePlayerConfig (CT_Central, 0, 0, data);
143 /* if atom is valid, data is complete */
144 if (ATOM_INVALID != atom) {
145 Dbg_User ("Got player from central\n");
146 RetrievePlayerEx (CT_Central, atom, &tmpPlayer);
147 i = tmpPlayer.id.PID;
148 if (i >= 0) {
149 /* store player under valid pid */
150 received++;
151 atomID = GUI_IntToAtom (i);
152 StorePlayerEx (CT_Central, atomID, &tmpPlayer);
153 }
154 /* remove the received database */
155 DeletePlayerConfig (CT_Central, atom);
156 }
157 } /* User_ReceivePlayerConfig */
158
159 /*
160 * received last player
161 */
162 void
User_NoMorePlayers(void)163 User_NoMorePlayers (void)
164 {
165 Dbg_User ("received %u players\n", received);
166 User_SendDisconnect ();
167 Network_QueueEvent (XBNW_Disconnected, CENTRAL_FINISHED);
168 } /* User_NoMorePlayers */
169
170 /*
171 * receive player pid from server
172 */
173 void
User_ReceivePlayerPID(const char * data)174 User_ReceivePlayerPID (const char *data)
175 {
176 if (!sscanf (data, "%i", &PID)) {
177 PID = PID_INVALID;
178 }
179 } /* User_ReceivePlayerPID */
180
181 #ifdef unused
182 /*
183 * central has disconnected
184 */
185 static void
User_ReceiveDisconnect(unsigned id)186 User_ReceiveDisconnect (unsigned id)
187 {
188 Network_QueueEvent (XBNW_Disconnected, CENTRAL_DISCONNECT);
189 } /* User_ReceiveDisconnect */
190 #endif
191
192 /******************
193 * get local data *
194 ******************/
195
196 /*
197 * return if connection is up
198 */
199 XBBool
User_Connected(void)200 User_Connected (void)
201 {
202 return (comm != NULL);
203 } /* User_Connected */
204
205 /*
206 * return PID
207 */
208 int
User_GetPID(void)209 User_GetPID (void)
210 {
211 return PID;
212 } /* User_GetPID */
213
214 /*
215 * return number of players received
216 */
217 int
User_Received(void)218 User_Received (void)
219 {
220 return received;
221 } /* User_Received */
222
223 /**************
224 * queue data *
225 **************/
226
227 /*
228 * send disconnect sequence, will shutdown after send
229 */
230 void
User_SendDisconnect(void)231 User_SendDisconnect (void)
232 {
233 if (comm != NULL) {
234 Dbg_User ("queueing disconnect sequence to central\n");
235 X2C_SendDisconnect (comm);
236
237 }
238 else {
239 Dbg_User ("already disconnected from central\n");
240 }
241 } /* User_SendDisconnect */
242
243 /*
244 * queue registration data
245 */
246 void
User_SendRegisterPlayer(XBAtom atom)247 User_SendRegisterPlayer (XBAtom atom)
248 {
249 PID = PID_NONE;
250 X2C_SendPlayerConfig (comm, atom);
251 } /* Use_SendRegisterPlayer */
252
253 /*
254 * unregister player
255 */
256 void
User_SendUnregisterPlayer(XBAtom atom)257 User_SendUnregisterPlayer (XBAtom atom)
258 {
259 } /* User_SendUnregisterPlayer */
260
261 /*
262 * queue request for scores
263 */
264 void
User_RequestUpdate(void)265 User_RequestUpdate (void)
266 {
267 received = 0;
268 RemoveAllPlayers (CT_Central);
269 X2C_QueryPlayerConfig (comm);
270 Dbg_User ("queueing update request, old rankings deleted\n");
271 } /* User_RequestUpdate */
272
273 /*
274 * queue current score
275 */
276 void
User_SendGameStat(int numPlayers,BMPlayer * playerStat,int * pa)277 User_SendGameStat (int numPlayers, BMPlayer * playerStat, int *pa)
278 {
279 int PID[MAX_PLAYER];
280 int Score[MAX_PLAYER];
281 BMPlayer *ps, *ps2;
282 int i, j, t = 0, k;
283
284 if (numPlayers > 0) {
285 for (i = 0, j = 0, ps = playerStat; i < numPlayers; ps++, i++) {
286 if (pa[i]) {
287 PID[j] = ps->PID;
288 Score[j] = 0;
289 for (k = 0, ps2 = playerStat; k < numPlayers; ps2++, k++) {
290 if ((ps->team == ps2->team) && (ps2->lives > 0)) {
291 Score[j] = 1;
292 }
293 }
294 t += Score[j];
295 j++;
296 }
297 }
298 if (t == 0) {
299 for (i = 0; i < j; i++) {
300 Score[i] = 1;
301 }
302 }
303 }
304 else {
305 j = -numPlayers;
306 for (i = 0, ps = playerStat; i < j; ps++, i++) {
307 PID[i] = ps->PID;
308 Score[i] = ps->lives;
309 }
310 }
311
312 X2C_SendGameStat (comm, j, PID, Score);
313 } /* User_SendGameStat */
314
315 /*
316 * end of file user.c
317 */
318