22 |
22 |
23 #include "netconn_internal.h" |
23 #include "netconn_internal.h" |
24 #include "netprotocol.h" |
24 #include "netprotocol.h" |
25 #include "../util/logging.h" |
25 #include "../util/logging.h" |
26 #include "../util/util.h" |
26 #include "../util/util.h" |
27 #include "../model/roomlist.h" |
|
28 #include "../md5/md5.h" |
27 #include "../md5/md5.h" |
29 #include "../base64/base64.h" |
28 #include "../base64/base64.h" |
30 #include "../model/mapcfg.h" |
29 #include "../model/mapcfg.h" |
31 |
30 |
32 #include <stdlib.h> |
31 #include <stdlib.h> |
44 newConn->dataDirPath = flib_strdupnull(dataDirPath); |
43 newConn->dataDirPath = flib_strdupnull(dataDirPath); |
45 |
44 |
46 newConn->netconnState = NETCONN_STATE_CONNECTING; |
45 newConn->netconnState = NETCONN_STATE_CONNECTING; |
47 newConn->isAdmin = false; |
46 newConn->isAdmin = false; |
48 newConn->metaCfg = flib_metascheme_retain(metacfg); |
47 newConn->metaCfg = flib_metascheme_retain(metacfg); |
49 newConn->roomList.roomCount = 0; |
|
50 newConn->roomList.rooms = NULL; |
|
51 |
48 |
52 newConn->isChief = false; |
49 newConn->isChief = false; |
53 newConn->map = flib_map_create_named("", "NoSuchMap"); |
50 newConn->map = flib_map_create_named("", "NoSuchMap"); |
54 newConn->pendingTeamlist.teamCount = 0; |
51 newConn->pendingTeamlist.teamCount = 0; |
55 newConn->pendingTeamlist.teams = NULL; |
52 newConn->pendingTeamlist.teams = NULL; |
86 flib_netbase_destroy(conn->netBase); |
83 flib_netbase_destroy(conn->netBase); |
87 free(conn->playerName); |
84 free(conn->playerName); |
88 free(conn->dataDirPath); |
85 free(conn->dataDirPath); |
89 |
86 |
90 flib_metascheme_release(conn->metaCfg); |
87 flib_metascheme_release(conn->metaCfg); |
91 flib_roomlist_clear(&conn->roomList); |
|
92 |
88 |
93 flib_map_release(conn->map); |
89 flib_map_release(conn->map); |
94 flib_teamlist_clear(&conn->pendingTeamlist); |
90 flib_teamlist_clear(&conn->pendingTeamlist); |
95 flib_teamlist_clear(&conn->teamlist); |
91 flib_teamlist_clear(&conn->teamlist); |
96 flib_scheme_release(conn->scheme); |
92 flib_scheme_release(conn->scheme); |
100 free(conn); |
96 free(conn); |
101 } |
97 } |
102 } |
98 } |
103 } |
99 } |
104 |
100 |
105 const flib_roomlist *flib_netconn_get_roomlist(flib_netconn *conn) { |
|
106 if(!log_badargs_if(conn==NULL)) { |
|
107 return &conn->roomList; |
|
108 } |
|
109 return NULL; |
|
110 } |
|
111 |
|
112 bool flib_netconn_is_chief(flib_netconn *conn) { |
101 bool flib_netconn_is_chief(flib_netconn *conn) { |
113 if(!log_badargs_if(conn==NULL) && flib_netconn_is_in_room_context(conn)) { |
102 if(!log_badargs_if(conn==NULL) && flib_netconn_is_in_room_context(conn)) { |
114 return conn->isChief; |
103 return conn->isChief; |
115 } |
104 } |
116 return false; |
105 return false; |
|
106 } |
|
107 |
|
108 const char *flib_netconn_get_playername(flib_netconn *conn) { |
|
109 if(!log_badargs_if(conn==NULL)) { |
|
110 return conn->playerName; |
|
111 } |
|
112 return NULL; |
117 } |
113 } |
118 |
114 |
119 void netconn_leaveRoom(flib_netconn *conn) { |
115 void netconn_leaveRoom(flib_netconn *conn) { |
120 conn->netconnState = NETCONN_STATE_LOBBY; |
116 conn->netconnState = NETCONN_STATE_LOBBY; |
121 conn->isChief = false; |
117 conn->isChief = false; |
267 } |
263 } |
268 } else if(!strcmp(cmd, "ROOMS")) { |
264 } else if(!strcmp(cmd, "ROOMS")) { |
269 if(netmsg->partCount % 8 != 1) { |
265 if(netmsg->partCount % 8 != 1) { |
270 flib_log_w("Net: Malformed ROOMS message"); |
266 flib_log_w("Net: Malformed ROOMS message"); |
271 } else { |
267 } else { |
272 flib_roomlist_clear(&conn->roomList); |
268 int roomCount = netmsg->partCount/8; |
273 for(int i=1; i<netmsg->partCount; i+=8) { |
269 flib_room **rooms = flib_room_array_from_netmsg(netmsg->parts+1, roomCount); |
274 if(flib_roomlist_add(&conn->roomList, netmsg->parts+i)) { |
270 if(rooms) { |
275 flib_log_e("Error adding room to list in ROOMS message"); |
271 conn->onRoomlistCb(conn->onRoomlistCtx, (const flib_room**)rooms, roomCount); |
|
272 for(int i=0; i<roomCount; i++) { |
|
273 flib_room_destroy(rooms[i]); |
276 } |
274 } |
277 } |
275 free(rooms); |
278 if(conn->netconnState == NETCONN_STATE_CONNECTING) { |
|
279 // We delay the "connected" callback until now to ensure the room list is avaliable. |
|
280 conn->onConnectedCb(conn->onConnectedCtx); |
|
281 conn->netconnState = NETCONN_STATE_LOBBY; |
|
282 } |
276 } |
283 } |
277 } |
284 } else if (!strcmp(cmd, "SERVER_MESSAGE")) { |
278 } else if (!strcmp(cmd, "SERVER_MESSAGE")) { |
285 if(netmsg->partCount < 2) { |
279 if(netmsg->partCount < 2) { |
286 flib_log_w("Net: Empty SERVERMESSAGE message"); |
280 flib_log_w("Net: Empty SERVERMESSAGE message"); |
375 flib_log_w("Net: Bad JOINED message"); |
369 flib_log_w("Net: Bad JOINED message"); |
376 } else { |
370 } else { |
377 for(int i = 1; i < netmsg->partCount; ++i) |
371 for(int i = 1; i < netmsg->partCount; ++i) |
378 { |
372 { |
379 bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); |
373 bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); |
380 if (isMe) { |
374 if (isMe && conn->netconnState == NETCONN_STATE_CONNECTING) { |
381 if(flib_netbase_sendf(conn->netBase, "%s\n\n", "LIST")) { |
375 conn->onConnectedCb(conn->onConnectedCtx); |
382 // If sending this fails, the protocol breaks (we'd be waiting infinitely for the room list) |
376 conn->netconnState = NETCONN_STATE_LOBBY; |
383 flib_netbase_sendf(net, "%s\n%s\n\n", "QUIT", "Client error"); |
|
384 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
|
385 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Failed to send a critical message."); |
|
386 exit = true; |
|
387 } |
|
388 } |
377 } |
389 conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]); |
378 conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]); |
390 } |
379 } |
391 } |
380 } |
392 } else if(!strcmp(cmd, "LEFT")) { |
381 } else if(!strcmp(cmd, "LEFT")) { |
396 conn->onRoomLeaveCb(conn->onRoomLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); |
385 conn->onRoomLeaveCb(conn->onRoomLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); |
397 } |
386 } |
398 } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) { |
387 } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) { |
399 const char *subcmd = netmsg->parts[1]; |
388 const char *subcmd = netmsg->parts[1]; |
400 if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) { |
389 if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) { |
401 if(flib_roomlist_add(&conn->roomList, netmsg->parts+2)) { |
390 flib_room *room = flib_room_from_netmsg(netmsg->parts+2); |
402 flib_log_e("Error adding new room to list"); |
391 if(room) { |
403 } else { |
392 conn->onRoomAddCb(conn->onRoomAddCtx, room); |
404 conn->onRoomAddCb(conn->onRoomAddCtx, conn->roomList.rooms[0]); |
|
405 } |
393 } |
|
394 flib_room_destroy(room); |
406 } else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) { |
395 } else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) { |
407 char *newName = netmsg->parts[4]; |
396 flib_room *room = flib_room_from_netmsg(netmsg->parts+3); |
408 if(flib_roomlist_update(&conn->roomList, netmsg->parts[2], netmsg->parts+3)) { |
397 if(room) { |
409 flib_log_e("Error updating room in list"); |
398 conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], room); |
410 } else { |
|
411 conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], flib_roomlist_find(&conn->roomList, newName)); |
|
412 } |
399 } |
|
400 flib_room_destroy(room); |
413 } else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) { |
401 } else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) { |
414 if(flib_roomlist_delete(&conn->roomList, netmsg->parts[2])) { |
402 conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); |
415 flib_log_e("Error deleting room from list"); |
|
416 } else { |
|
417 conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); |
|
418 } |
|
419 } else { |
403 } else { |
420 flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd); |
404 flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd); |
421 } |
405 } |
422 } else if(!strcmp(cmd, "LOBBY:LEFT")) { |
406 } else if(!strcmp(cmd, "LOBBY:LEFT")) { |
423 if(netmsg->partCount < 2) { |
407 if(netmsg->partCount < 2) { |