16 * You should have received a copy of the GNU General Public License |
16 * You should have received a copy of the GNU General Public License |
17 * along with this program; if not, write to the Free Software |
17 * along with this program; if not, write to the Free Software |
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
19 */ |
19 */ |
20 |
20 |
21 #include "netconn.h" |
21 // TODO: Check the state transitions. Document with a diagram or something |
22 #include "netbase.h" |
22 |
|
23 #include "netconn_internal.h" |
23 #include "netprotocol.h" |
24 #include "netprotocol.h" |
24 #include "../util/logging.h" |
25 #include "../util/logging.h" |
25 #include "../util/util.h" |
26 #include "../util/util.h" |
26 #include "../model/roomlist.h" |
27 #include "../model/roomlist.h" |
27 #include "../md5/md5.h" |
28 #include "../md5/md5.h" |
28 |
29 #include "../base64/base64.h" |
29 #include <stdbool.h> |
30 |
30 #include <stdlib.h> |
31 #include <stdlib.h> |
31 #include <string.h> |
32 #include <string.h> |
32 #include <errno.h> |
33 #include <errno.h> |
33 #include <ctype.h> |
34 #include <ctype.h> |
34 |
|
35 struct _flib_netconn { |
|
36 flib_netbase *netBase; |
|
37 char *playerName; |
|
38 flib_cfg_meta *metaCfg; |
|
39 flib_roomlist *roomList; |
|
40 |
|
41 int netconnState; // One of the NETCONN_STATE constants |
|
42 |
|
43 bool isAdmin; // Player is server administrator |
|
44 bool isChief; // Player can modify the current room |
|
45 |
|
46 |
|
47 void (*onMessageCb)(void *context, int msgtype, const char *msg); |
|
48 void *onMessageCtx; |
|
49 |
|
50 void (*onConnectedCb)(void *context); |
|
51 void *onConnectedCtx; |
|
52 |
|
53 void (*onDisconnectedCb)(void *context, int reason, const char *message); |
|
54 void *onDisconnectedCtx; |
|
55 |
|
56 void (*onRoomAddCb)(void *context, const flib_roomlist_room *room); |
|
57 void *onRoomAddCtx; |
|
58 |
|
59 void (*onRoomDeleteCb)(void *context, const char *name); |
|
60 void *onRoomDeleteCtx; |
|
61 |
|
62 void (*onRoomUpdateCb)(void *context, const char *oldName, const flib_roomlist_room *room); |
|
63 void *onRoomUpdateCtx; |
|
64 |
|
65 void (*onChatCb)(void *context, const char *nick, const char *msg); |
|
66 void *onChatCtx; |
|
67 |
|
68 void (*onLobbyJoinCb)(void *context, const char *nick); |
|
69 void *onLobbyJoinCtx; |
|
70 |
|
71 void (*onLobbyLeaveCb)(void *context, const char *nick, const char *partMessage); |
|
72 void *onLobbyLeaveCtx; |
|
73 |
|
74 void (*onRoomJoinCb)(void *context, const char *nick); |
|
75 void *onRoomJoinCtx; |
|
76 |
|
77 void (*onRoomLeaveCb)(void *context, const char *nick, const char *partMessage); |
|
78 void *onRoomLeaveCtx; |
|
79 |
|
80 void (*onNickTakenCb)(void *context, const char *nick); |
|
81 void *onNickTakenCtx; |
|
82 |
|
83 void (*onNickAcceptCb)(void *context, const char *nick); |
|
84 void *onNickAcceptCtx; |
|
85 |
|
86 void (*onPasswordRequestCb)(void *context, const char *nick); |
|
87 void *onPasswordRequestCtx; |
|
88 |
|
89 void (*onRoomChiefStatusCb)(void *context, bool isChief); |
|
90 void *onRoomChiefStatusCtx; |
|
91 |
|
92 void (*onReadyStateCb)(void *context, const char *nick, bool ready); |
|
93 void *onReadyStateCtx; |
|
94 |
|
95 void (*onEnterRoomCb)(void *context, bool chief); |
|
96 void *onEnterRoomCtx; |
|
97 |
|
98 void (*onLeaveRoomCb)(void *context, int reason, const char *message); |
|
99 void *onLeaveRoomCtx; |
|
100 |
|
101 void (*onTeamAddCb)(void *context, flib_team *team); |
|
102 void *onTeamAddCtx; |
|
103 |
|
104 bool running; |
|
105 bool destroyRequested; |
|
106 }; |
|
107 |
35 |
108 static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { |
36 static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { |
109 flib_log_i("Net: [%i] %s", msgtype, msg); |
37 flib_log_i("Net: [%i] %s", msgtype, msg); |
110 } |
38 } |
111 |
39 |
113 static void defaultCallback_bool(void *context, bool isChief) {} |
41 static void defaultCallback_bool(void *context, bool isChief) {} |
114 static void defaultCallback_str(void *context, const char *str) {} |
42 static void defaultCallback_str(void *context, const char *str) {} |
115 static void defaultCallback_int_str(void *context, int i, const char *str) {} |
43 static void defaultCallback_int_str(void *context, int i, const char *str) {} |
116 static void defaultCallback_str_str(void *context, const char *str1, const char *str2) {} |
44 static void defaultCallback_str_str(void *context, const char *str1, const char *str2) {} |
117 static void defaultCallback_str_bool(void *context, const char *str, bool b) {} |
45 static void defaultCallback_str_bool(void *context, const char *str, bool b) {} |
|
46 static void defaultCallback_str_int(void *context, const char *str, int i) {} |
118 |
47 |
119 static void defaultCallback_onRoomAdd(void *context, const flib_roomlist_room *room) {} |
48 static void defaultCallback_onRoomAdd(void *context, const flib_roomlist_room *room) {} |
120 static void defaultCallback_onRoomUpdate(void *context, const char *oldName, const flib_roomlist_room *room) {} |
49 static void defaultCallback_onRoomUpdate(void *context, const char *oldName, const flib_roomlist_room *room) {} |
121 static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { |
50 static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { |
122 flib_log_i("%s: %s", nick, msg); |
51 flib_log_i("%s: %s", nick, msg); |
147 static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { |
76 static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { |
148 flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); |
77 flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); |
149 } |
78 } |
150 |
79 |
151 static void defaultCallback_onTeamAdd(void *context, flib_team *team) {} |
80 static void defaultCallback_onTeamAdd(void *context, flib_team *team) {} |
|
81 static void defaultCallback_onTeamColorChanged(void *context, const char *teamName, uint32_t color) {} |
|
82 static void defaultCallback_onCfgScheme(void *context, flib_cfg *scheme) {} |
|
83 static void defaultCallback_onMapChanged(void *context, const flib_map *map, int changetype) {} |
|
84 static void defaultCallback_onWeaponsetChanged(void *context, flib_weaponset *weaponset) {} |
152 |
85 |
153 static void clearCallbacks(flib_netconn *conn) { |
86 static void clearCallbacks(flib_netconn *conn) { |
154 flib_netconn_onMessage(conn, NULL, NULL); |
87 flib_netconn_onMessage(conn, NULL, NULL); |
155 flib_netconn_onConnected(conn, NULL, NULL); |
88 flib_netconn_onConnected(conn, NULL, NULL); |
156 flib_netconn_onDisconnected(conn, NULL, NULL); |
89 flib_netconn_onDisconnected(conn, NULL, NULL); |
161 flib_netconn_onLobbyJoin(conn, NULL, NULL); |
94 flib_netconn_onLobbyJoin(conn, NULL, NULL); |
162 flib_netconn_onLobbyLeave(conn, NULL, NULL); |
95 flib_netconn_onLobbyLeave(conn, NULL, NULL); |
163 flib_netconn_onRoomJoin(conn, NULL, NULL); |
96 flib_netconn_onRoomJoin(conn, NULL, NULL); |
164 flib_netconn_onRoomLeave(conn, NULL, NULL); |
97 flib_netconn_onRoomLeave(conn, NULL, NULL); |
165 flib_netconn_onNickTaken(conn, NULL, NULL); |
98 flib_netconn_onNickTaken(conn, NULL, NULL); |
166 flib_netconn_onNickAccept(conn, NULL, NULL); |
|
167 flib_netconn_onPasswordRequest(conn, NULL, NULL); |
99 flib_netconn_onPasswordRequest(conn, NULL, NULL); |
168 flib_netconn_onRoomChiefStatus(conn, NULL, NULL); |
100 flib_netconn_onRoomChiefStatus(conn, NULL, NULL); |
169 flib_netconn_onReadyStateCb(conn, NULL, NULL); |
101 flib_netconn_onReadyState(conn, NULL, NULL); |
170 flib_netconn_onEnterRoomCb(conn, NULL, NULL); |
102 flib_netconn_onEnterRoom(conn, NULL, NULL); |
171 flib_netconn_onTeamAddCb(conn, NULL, NULL); |
103 flib_netconn_onLeaveRoom(conn, NULL, NULL); |
|
104 flib_netconn_onTeamAdd(conn, NULL, NULL); |
|
105 flib_netconn_onTeamDelete(conn, NULL, NULL); |
|
106 flib_netconn_onRunGame(conn, NULL, NULL); |
|
107 flib_netconn_onTeamAccepted(conn, NULL, NULL); |
|
108 flib_netconn_onHogCountChanged(conn, NULL, NULL); |
|
109 flib_netconn_onTeamColorChanged(conn, NULL, NULL); |
|
110 flib_netconn_onEngineMessage(conn, NULL, NULL); |
|
111 flib_netconn_onCfgScheme(conn, NULL, NULL); |
|
112 flib_netconn_onMapChanged(conn, NULL, NULL); |
|
113 flib_netconn_onScriptChanged(conn, NULL, NULL); |
|
114 flib_netconn_onWeaponsetChanged(conn, NULL, NULL); |
|
115 flib_netconn_onAdminAccess(conn, NULL, NULL); |
|
116 flib_netconn_onServerVar(conn, NULL, NULL); |
172 } |
117 } |
173 |
118 |
174 flib_netconn *flib_netconn_create(const char *playerName, flib_cfg_meta *metacfg, const char *host, uint16_t port) { |
119 flib_netconn *flib_netconn_create(const char *playerName, flib_cfg_meta *metacfg, const char *host, uint16_t port) { |
175 flib_netconn *result = NULL; |
120 flib_netconn *result = NULL; |
176 if(!playerName || !metacfg || !host) { |
121 if(!playerName || !metacfg || !host) { |
232 bool result = false; |
179 bool result = false; |
233 if(!conn) { |
180 if(!conn) { |
234 flib_log_e("null parameter in flib_netconn_is_chief"); |
181 flib_log_e("null parameter in flib_netconn_is_chief"); |
235 } else if(conn->netconnState == NETCONN_STATE_ROOM || conn->netconnState == NETCONN_STATE_INGAME) { |
182 } else if(conn->netconnState == NETCONN_STATE_ROOM || conn->netconnState == NETCONN_STATE_INGAME) { |
236 result = conn->isChief; |
183 result = conn->isChief; |
237 } |
|
238 return result; |
|
239 } |
|
240 |
|
241 int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) { |
|
242 int result = -1; |
|
243 if(!conn) { |
|
244 flib_log_e("null parameter in flib_netconn_send_quit"); |
|
245 } else { |
|
246 result = flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "QUIT", quitmsg ? quitmsg : "User quit"); |
|
247 } |
|
248 return result; |
|
249 } |
|
250 |
|
251 int flib_netconn_send_chat(flib_netconn *conn, const char *chat) { |
|
252 int result = -1; |
|
253 if(!conn || !chat) { |
|
254 flib_log_e("null parameter in flib_netconn_send_chat"); |
|
255 } else { |
|
256 result = flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "CHAT", chat); |
|
257 } |
|
258 return result; |
|
259 } |
|
260 |
|
261 int flib_netconn_send_nick(flib_netconn *conn, const char *nick) { |
|
262 int result = -1; |
|
263 if(!conn || !nick) { |
|
264 flib_log_e("null parameter in flib_netconn_send_nick"); |
|
265 } else { |
|
266 char *tmpName = flib_strdupnull(nick); |
|
267 if(tmpName) { |
|
268 if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) { |
|
269 free(conn->playerName); |
|
270 conn->playerName = tmpName; |
|
271 tmpName = NULL; |
|
272 result = 0; |
|
273 } |
|
274 } |
|
275 free(tmpName); |
|
276 } |
|
277 return result; |
|
278 } |
|
279 |
|
280 int flib_netconn_send_password(flib_netconn *conn, const char *latin1Passwd) { |
|
281 int result = -1; |
|
282 if(!conn || !latin1Passwd) { |
|
283 flib_log_e("null parameter in flib_netconn_send_password"); |
|
284 } else { |
|
285 md5_state_t md5state; |
|
286 uint8_t md5bytes[16]; |
|
287 char md5hex[33]; |
|
288 md5_init(&md5state); |
|
289 md5_append(&md5state, (unsigned char*)latin1Passwd, strlen(latin1Passwd)); |
|
290 md5_finish(&md5state, md5bytes); |
|
291 for(int i=0;i<sizeof(md5bytes); i++) { |
|
292 // Needs to be lowercase - server checks case sensitive |
|
293 snprintf(md5hex+i*2, 3, "%02x", (unsigned)md5bytes[i]); |
|
294 } |
|
295 result = flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "PASSWORD", md5hex); |
|
296 } |
184 } |
297 return result; |
185 return result; |
298 } |
186 } |
299 |
187 |
300 /* |
188 /* |
440 conn->onRoomChiefStatusCb = callback ? callback : &defaultCallback_bool; |
319 conn->onRoomChiefStatusCb = callback ? callback : &defaultCallback_bool; |
441 conn->onRoomChiefStatusCtx = context; |
320 conn->onRoomChiefStatusCtx = context; |
442 } |
321 } |
443 } |
322 } |
444 |
323 |
445 void flib_netconn_onReadyStateCb(flib_netconn *conn, void (*callback)(void *context, const char *nick, bool ready), void* context) { |
324 void flib_netconn_onReadyState(flib_netconn *conn, void (*callback)(void *context, const char *nick, bool ready), void* context) { |
446 if(!conn) { |
325 if(!conn) { |
447 flib_log_e("null parameter in flib_netconn_onReadyStateCb"); |
326 flib_log_e("null parameter in flib_netconn_onReadyState"); |
448 } else { |
327 } else { |
449 conn->onReadyStateCb = callback ? callback : &defaultCallback_str_bool; |
328 conn->onReadyStateCb = callback ? callback : &defaultCallback_str_bool; |
450 conn->onReadyStateCtx = context; |
329 conn->onReadyStateCtx = context; |
451 } |
330 } |
452 } |
331 } |
453 |
332 |
454 void flib_netconn_onEnterRoomCb(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context) { |
333 void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context) { |
455 if(!conn) { |
334 if(!conn) { |
456 flib_log_e("null parameter in flib_netconn_onEnterRoomCb"); |
335 flib_log_e("null parameter in flib_netconn_onEnterRoom"); |
457 } else { |
336 } else { |
458 conn->onEnterRoomCb = callback ? callback : &defaultCallback_bool; |
337 conn->onEnterRoomCb = callback ? callback : &defaultCallback_bool; |
459 conn->onEnterRoomCtx = context; |
338 conn->onEnterRoomCtx = context; |
460 } |
339 } |
461 } |
340 } |
462 |
341 |
463 void flib_netconn_onLeaveRoomCb(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context) { |
342 void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context) { |
464 if(!conn) { |
343 if(!conn) { |
465 flib_log_e("null parameter in flib_netconn_onLeaveRoomCb"); |
344 flib_log_e("null parameter in flib_netconn_onLeaveRoom"); |
466 } else { |
345 } else { |
467 conn->onLeaveRoomCb = callback ? callback : &defaultCallback_int_str; |
346 conn->onLeaveRoomCb = callback ? callback : &defaultCallback_int_str; |
468 conn->onLeaveRoomCtx = context; |
347 conn->onLeaveRoomCtx = context; |
469 } |
348 } |
470 } |
349 } |
471 |
350 |
472 void flib_netconn_onTeamAddCb(flib_netconn *conn, void (*callback)(void *context, flib_team *team), void *context) { |
351 void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, flib_team *team), void *context) { |
473 if(!conn) { |
352 if(!conn) { |
474 flib_log_e("null parameter in flib_netconn_onTeamAddCb"); |
353 flib_log_e("null parameter in flib_netconn_onTeamAdd"); |
475 } else { |
354 } else { |
476 conn->onTeamAddCb = callback ? callback : &defaultCallback_onTeamAdd; |
355 conn->onTeamAddCb = callback ? callback : &defaultCallback_onTeamAdd; |
477 conn->onTeamAddCtx = context; |
356 conn->onTeamAddCtx = context; |
|
357 } |
|
358 } |
|
359 |
|
360 void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), void *context) { |
|
361 if(!conn) { |
|
362 flib_log_e("null parameter in flib_netconn_onTeamDelete"); |
|
363 } else { |
|
364 conn->onTeamDeleteCb = callback ? callback : &defaultCallback_str; |
|
365 conn->onTeamDeleteCtx = context; |
|
366 } |
|
367 } |
|
368 |
|
369 void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context) { |
|
370 if(!conn) { |
|
371 flib_log_e("null parameter in flib_netconn_onRunGame"); |
|
372 } else { |
|
373 conn->onRunGameCb = callback ? callback : &defaultCallback_void; |
|
374 conn->onRunGameCtx = context; |
|
375 } |
|
376 } |
|
377 |
|
378 void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *teamName), void *context) { |
|
379 if(!conn) { |
|
380 flib_log_e("null parameter in flib_netconn_onTeamAccepted"); |
|
381 } else { |
|
382 conn->onTeamAcceptedCb = callback ? callback : &defaultCallback_str; |
|
383 conn->onTeamAcceptedCtx = context; |
|
384 } |
|
385 } |
|
386 |
|
387 void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context) { |
|
388 if(!conn) { |
|
389 flib_log_e("null parameter in flib_netconn_onHogCountChanged"); |
|
390 } else { |
|
391 conn->onHogCountChangedCb = callback ? callback : &defaultCallback_str_int; |
|
392 conn->onHogCountChangedCtx = context; |
|
393 } |
|
394 } |
|
395 |
|
396 void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, uint32_t colorARGB), void *context) { |
|
397 if(!conn) { |
|
398 flib_log_e("null parameter in flib_netconn_onTeamColorChanged"); |
|
399 } else { |
|
400 conn->onTeamColorChangedCb = callback ? callback : &defaultCallback_onTeamColorChanged; |
|
401 conn->onTeamColorChangedCtx = context; |
|
402 } |
|
403 } |
|
404 |
|
405 void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const char *message, int size), void *context) { |
|
406 if(!conn) { |
|
407 flib_log_e("null parameter in flib_netconn_onEngineMessage"); |
|
408 } else { |
|
409 conn->onEngineMessageCb = callback ? callback : &defaultCallback_str_int; |
|
410 conn->onEngineMessageCtx = context; |
|
411 } |
|
412 } |
|
413 |
|
414 void flib_netconn_onCfgScheme(flib_netconn *conn, void (*callback)(void *context, flib_cfg *scheme), void *context) { |
|
415 if(!conn) { |
|
416 flib_log_e("null parameter in flib_netconn_onCfgScheme"); |
|
417 } else { |
|
418 conn->onCfgSchemeCb = callback ? callback : &defaultCallback_onCfgScheme; |
|
419 conn->onCfgSchemeCtx = context; |
|
420 } |
|
421 } |
|
422 |
|
423 void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context) { |
|
424 if(!conn) { |
|
425 flib_log_e("null parameter in flib_netconn_onMapChanged"); |
|
426 } else { |
|
427 conn->onMapChangedCb = callback ? callback : &defaultCallback_onMapChanged; |
|
428 conn->onMapChangedCtx = context; |
|
429 } |
|
430 } |
|
431 |
|
432 void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context) { |
|
433 if(!conn) { |
|
434 flib_log_e("null parameter in flib_netconn_onScriptChanged"); |
|
435 } else { |
|
436 conn->onScriptChangedCb = callback ? callback : &defaultCallback_str; |
|
437 conn->onScriptChangedCtx = context; |
|
438 } |
|
439 } |
|
440 |
|
441 void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, flib_weaponset *weaponset), void *context) { |
|
442 if(!conn) { |
|
443 flib_log_e("null parameter in flib_netconn_onWeaponsetChanged"); |
|
444 } else { |
|
445 conn->onWeaponsetChangedCb = callback ? callback : &defaultCallback_onWeaponsetChanged; |
|
446 conn->onWeaponsetChangedCtx = context; |
|
447 } |
|
448 } |
|
449 |
|
450 void flib_netconn_onAdminAccess(flib_netconn *conn, void (*callback)(void *context), void *context) { |
|
451 if(!conn) { |
|
452 flib_log_e("null parameter in flib_netconn_onAdminAccess"); |
|
453 } else { |
|
454 conn->onAdminAccessCb = callback ? callback : &defaultCallback_void; |
|
455 conn->onAdminAccessCtx = context; |
|
456 } |
|
457 } |
|
458 |
|
459 void flib_netconn_onServerVar(flib_netconn *conn, void (*callback)(void *context, const char *name, const char *value), void *context) { |
|
460 if(!conn) { |
|
461 flib_log_e("null parameter in flib_netconn_onServerVar"); |
|
462 } else { |
|
463 conn->onServerVarCb = callback ? callback : &defaultCallback_str_str; |
|
464 conn->onServerVarCtx = context; |
|
465 } |
|
466 } |
|
467 |
|
468 void leaveRoom(flib_netconn *conn) { |
|
469 conn->netconnState = NETCONN_STATE_LOBBY; |
|
470 conn->isChief = false; |
|
471 flib_map *map = flib_map_create_named("", "NoSuchMap"); |
|
472 if(map) { |
|
473 flib_map_release(conn->map); |
|
474 conn->map = map; |
|
475 } else { |
|
476 flib_log_e("Error resetting netconn.map"); |
478 } |
477 } |
479 } |
478 } |
480 |
479 |
481 static void flib_netconn_wrappedtick(flib_netconn *conn) { |
480 static void flib_netconn_wrappedtick(flib_netconn *conn) { |
482 flib_netmsg *netmsg; |
481 flib_netmsg *netmsg; |
629 if(!team) { |
613 if(!team) { |
630 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
614 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
631 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Internal error"); |
615 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Internal error"); |
632 exit = true; |
616 exit = true; |
633 } else { |
617 } else { |
|
618 team->remoteDriven = true; |
634 conn->onTeamAddCb(conn->onTeamAddCtx, team); |
619 conn->onTeamAddCb(conn->onTeamAddCtx, team); |
635 } |
620 } |
|
621 flib_team_release(team); |
636 } |
622 } |
637 } else if (!strcmp(cmd, "REMOVE_TEAM")) { |
623 } else if (!strcmp(cmd, "REMOVE_TEAM")) { |
638 if(netmsg->partCount != 2) { |
624 if(netmsg->partCount != 2) { |
639 flib_log_w("Net: Bad REMOVETEAM message"); |
625 flib_log_w("Net: Bad REMOVETEAM message"); |
640 } else { |
626 } else { |
641 // TODO |
627 conn->onTeamDeleteCb(conn->onTeamDeleteCtx, netmsg->parts[1]); |
642 // emit RemoveNetTeam(HWTeam(lst[1])); |
|
643 } |
628 } |
644 } else if(!strcmp(cmd, "ROOMABANDONED")) { |
629 } else if(!strcmp(cmd, "ROOMABANDONED")) { |
645 conn->netconnState = NETCONN_STATE_LOBBY; |
630 leaveRoom(conn); |
646 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_ABANDONED, "Room destroyed"); |
631 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_ABANDONED, "Room destroyed"); |
647 } else if(!strcmp(cmd, "KICKED")) { |
632 } else if(!strcmp(cmd, "KICKED")) { |
648 conn->netconnState = NETCONN_STATE_LOBBY; |
633 leaveRoom(conn); |
649 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_KICKED, "You got kicked"); |
634 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_KICKED, "You got kicked"); |
650 } else if(!strcmp(cmd, "JOINED")) { |
635 } else if(!strcmp(cmd, "JOINED")) { |
651 if(netmsg->partCount < 2) { |
636 if(netmsg->partCount < 2) { |
652 flib_log_w("Net: Bad JOINED message"); |
637 flib_log_w("Net: Bad JOINED message"); |
653 } else { |
638 } else { |
738 } |
722 } |
739 } else if (!strcmp(cmd, "TEAM_ACCEPTED")) { |
723 } else if (!strcmp(cmd, "TEAM_ACCEPTED")) { |
740 if (netmsg->partCount != 2) { |
724 if (netmsg->partCount != 2) { |
741 flib_log_w("Net: Bad TEAM_ACCEPTED message"); |
725 flib_log_w("Net: Bad TEAM_ACCEPTED message"); |
742 } else { |
726 } else { |
743 // TODO |
727 conn->onTeamAcceptedCb(conn->onTeamAcceptedCtx, netmsg->parts[1]); |
744 // emit TeamAccepted(lst[1]); |
|
745 } |
728 } |
746 } else if (!strcmp(cmd, "CFG")) { |
729 } else if (!strcmp(cmd, "CFG")) { |
747 if(netmsg->partCount < 3) { |
730 if(netmsg->partCount < 3) { |
748 flib_log_w("Net: Bad CFG message"); |
731 flib_log_w("Net: Bad CFG message"); |
749 } else { |
732 } else { |
750 // TODO |
733 const char *subcmd = netmsg->parts[1]; |
751 // QStringList tmp = lst; |
734 if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == conn->metaCfg->modCount + conn->metaCfg->settingCount + 3) { |
752 // tmp.removeFirst(); |
735 flib_cfg *cfg = flib_netmsg_to_cfg(conn->metaCfg, netmsg->parts+2); |
753 // tmp.removeFirst(); |
736 if(cfg) { |
754 // if (lst[1] == "SCHEME") |
737 conn->onCfgSchemeCb(conn->onCfgSchemeCtx, cfg); |
755 // emit netSchemeConfig(tmp); |
738 } else { |
756 // else |
739 flib_log_e("Error processing CFG SCHEME message"); |
757 // emit paramChanged(lst[1], tmp); |
740 } |
|
741 flib_cfg_release(cfg); |
|
742 } else if(!strcmp(subcmd, "FULLMAPCONFIG") && netmsg->partCount == 7) { |
|
743 flib_map *map = flib_netmsg_to_map(netmsg->parts+2); |
|
744 if(map) { |
|
745 flib_map_release(conn->map); |
|
746 conn->map = map; |
|
747 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_FULL); |
|
748 } else { |
|
749 flib_log_e("Error processing CFG FULLMAPCONFIG message"); |
|
750 } |
|
751 } else if(!strcmp(subcmd, "MAP") && netmsg->partCount == 3) { |
|
752 char *mapname = flib_strdupnull(netmsg->parts[2]); |
|
753 if(mapname) { |
|
754 free(conn->map->name); |
|
755 conn->map->name = mapname; |
|
756 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAP); |
|
757 } else { |
|
758 flib_log_e("Error processing CFG MAP message"); |
|
759 } |
|
760 } else if(!strcmp(subcmd, "THEME") && netmsg->partCount == 3) { |
|
761 char *themename = flib_strdupnull(netmsg->parts[2]); |
|
762 if(themename) { |
|
763 free(conn->map->theme); |
|
764 conn->map->theme = themename; |
|
765 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_THEME); |
|
766 } else { |
|
767 flib_log_e("Error processing CFG THEME message"); |
|
768 } |
|
769 } else if(!strcmp(subcmd, "SEED") && netmsg->partCount == 3) { |
|
770 char *seed = flib_strdupnull(netmsg->parts[2]); |
|
771 if(seed) { |
|
772 free(conn->map->seed); |
|
773 conn->map->seed = seed; |
|
774 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_SEED); |
|
775 } else { |
|
776 flib_log_e("Error processing CFG SEED message"); |
|
777 } |
|
778 } else if(!strcmp(subcmd, "TEMPLATE") && netmsg->partCount == 3) { |
|
779 conn->map->templateFilter = atoi(netmsg->parts[2]); |
|
780 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_TEMPLATE); |
|
781 } else if(!strcmp(subcmd, "MAPGEN") && netmsg->partCount == 3) { |
|
782 conn->map->mapgen = atoi(netmsg->parts[2]); |
|
783 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAPGEN); |
|
784 } else if(!strcmp(subcmd, "MAZE_SIZE") && netmsg->partCount == 3) { |
|
785 conn->map->mazeSize = atoi(netmsg->parts[2]); |
|
786 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAZE_SIZE); |
|
787 } else if(!strcmp(subcmd, "DRAWNMAP") && netmsg->partCount == 3) { |
|
788 size_t drawnMapSize = 0; |
|
789 uint8_t *drawnMapData = flib_netmsg_to_drawnmapdata(&drawnMapSize, netmsg->parts[2]); |
|
790 if(drawnMapData) { |
|
791 free(conn->map->drawData); |
|
792 conn->map->drawData = drawnMapData; |
|
793 conn->map->drawDataSize = drawnMapSize; |
|
794 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_DRAWNMAP); |
|
795 } else { |
|
796 flib_log_e("Error processing CFG DRAWNMAP message"); |
|
797 } |
|
798 } else if(!strcmp(subcmd, "SCRIPT") && netmsg->partCount == 3) { |
|
799 conn->onScriptChangedCb(conn->onScriptChangedCtx, netmsg->parts[2]); |
|
800 } else if(!strcmp(subcmd, "AMMO") && netmsg->partCount == 4) { |
|
801 flib_weaponset *weapons = flib_weaponset_from_ammostring(netmsg->parts[2], netmsg->parts[3]); |
|
802 if(weapons) { |
|
803 conn->onWeaponsetChangedCb(conn->onWeaponsetChangedCtx, weapons); |
|
804 } else { |
|
805 flib_log_e("Error processing CFG AMMO message"); |
|
806 } |
|
807 flib_weaponset_release(weapons); |
|
808 } else { |
|
809 flib_log_w("Net: Unknown or malformed CFG subcommand: %s", subcmd); |
|
810 } |
758 } |
811 } |
759 } else if (!strcmp(cmd, "HH_NUM")) { |
812 } else if (!strcmp(cmd, "HH_NUM")) { |
760 if (netmsg->partCount != 3) { |
813 if (netmsg->partCount != 3) { |
761 flib_log_w("Net: Bad TEAM_ACCEPTED message"); |
814 flib_log_w("Net: Bad HH_NUM message"); |
762 } else { |
815 } else { |
763 // TODO |
816 int hogs = atoi(netmsg->parts[2]); |
764 // HWTeam tmptm(lst[1]); |
817 if(hogs<=0 || hogs>HEDGEHOGS_PER_TEAM) { |
765 // tmptm.setNumHedgehogs(lst[2].toUInt()); |
818 flib_log_w("Net: Bad HH_NUM message: %s hogs", netmsg->parts[2]); |
766 // emit hhnumChanged(tmptm); |
819 } else { |
|
820 conn->onHogCountChangedCb(conn->onHogCountChangedCtx, netmsg->parts[1], hogs); |
|
821 } |
767 } |
822 } |
768 } else if (!strcmp(cmd, "TEAM_COLOR")) { |
823 } else if (!strcmp(cmd, "TEAM_COLOR")) { |
769 if (netmsg->partCount != 3) { |
824 if (netmsg->partCount != 3) { |
770 flib_log_w("Net: Bad TEAM_COLOR message"); |
825 flib_log_w("Net: Bad TEAM_COLOR message"); |
771 } else { |
826 } else { |
772 // TODO |
827 long color; |
773 // HWTeam tmptm(lst[1]); |
828 if(sscanf(netmsg->parts[2], "#%lx", &color)) { |
774 // tmptm.setColor(lst[2].toInt()); |
829 conn->onTeamColorChangedCb(conn->onTeamColorChangedCtx, netmsg->parts[1], (uint32_t)color); |
775 // emit teamColorChanged(tmptm); |
830 } else { |
|
831 flib_log_w("Net: Bad TEAM_COLOR message: Color %s", netmsg->parts[2]); |
|
832 } |
776 } |
833 } |
777 } else if (!strcmp(cmd, "EM")) { |
834 } else if (!strcmp(cmd, "EM")) { |
778 if(netmsg->partCount < 2) { |
835 if(netmsg->partCount < 2) { |
779 flib_log_w("Net: Bad EM message"); |
836 flib_log_w("Net: Bad EM message"); |
780 } else { |
837 } else { |
781 // TODO |
838 for(int i = 1; i < netmsg->partCount; ++i) { |
782 // for(int i = 1; i < netmsg->partCount; ++i) { |
839 char *out = NULL; |
783 // QByteArray em = QByteArray::fromBase64(lst[i].toAscii()); |
840 size_t outlen; |
784 // emit FromNet(em); |
841 bool ok = base64_decode_alloc(netmsg->parts[i], strlen(netmsg->parts[i]), &out, &outlen); |
785 // } |
842 if(ok && outlen) { |
|
843 conn->onEngineMessageCb(conn->onEngineMessageCtx, out, outlen); |
|
844 } else { |
|
845 flib_log_e("Net: Malformed engine message: %s", netmsg->parts[i]); |
|
846 } |
|
847 free(out); |
|
848 } |
786 } |
849 } |
787 } else if (!strcmp(cmd, "BYE")) { |
850 } else if (!strcmp(cmd, "BYE")) { |
788 if (netmsg->partCount < 2) { |
851 if (netmsg->partCount < 2) { |
789 flib_log_w("Net: Bad BYE message"); |
852 flib_log_w("Net: Bad BYE message"); |
790 } else { |
853 } else { |