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