project_files/frontlib/net/netconn.c
changeset 7338 1ed603a54ebd
parent 7336 f821f7d727b7
child 7482 d70a5b0d1190
equal deleted inserted replaced
7336:f821f7d727b7 7338:1ed603a54ebd
    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) {