30 #include <string.h> |
30 #include <string.h> |
31 #include <errno.h> |
31 #include <errno.h> |
32 #include <ctype.h> |
32 #include <ctype.h> |
33 |
33 |
34 flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port) { |
34 flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port) { |
35 flib_netconn *result = NULL; |
35 flib_netconn *result = NULL; |
36 if(!log_badargs_if4(playerName==NULL, host==NULL, port<1, port>65535)) { |
36 if(!log_badargs_if4(playerName==NULL, host==NULL, port<1, port>65535)) { |
37 flib_netconn *newConn = flib_calloc(1, sizeof(flib_netconn)); |
37 flib_netconn *newConn = flib_calloc(1, sizeof(flib_netconn)); |
38 if(newConn) { |
38 if(newConn) { |
39 newConn->netBase = flib_netbase_create(host, port); |
39 newConn->netBase = flib_netbase_create(host, port); |
40 newConn->playerName = flib_strdupnull(playerName); |
40 newConn->playerName = flib_strdupnull(playerName); |
41 newConn->dataDirPath = flib_strdupnull(dataDirPath); |
41 newConn->dataDirPath = flib_strdupnull(dataDirPath); |
42 |
42 |
43 newConn->netconnState = NETCONN_STATE_CONNECTING; |
43 newConn->netconnState = NETCONN_STATE_CONNECTING; |
44 |
44 |
45 newConn->isChief = false; |
45 newConn->isChief = false; |
46 newConn->map = flib_map_create_named("", "NoSuchMap"); |
46 newConn->map = flib_map_create_named("", "NoSuchMap"); |
47 newConn->pendingTeamlist.teamCount = 0; |
47 newConn->pendingTeamlist.teamCount = 0; |
48 newConn->pendingTeamlist.teams = NULL; |
48 newConn->pendingTeamlist.teams = NULL; |
49 newConn->teamlist.teamCount = 0; |
49 newConn->teamlist.teamCount = 0; |
50 newConn->teamlist.teams = NULL; |
50 newConn->teamlist.teams = NULL; |
51 newConn->scheme = NULL; |
51 newConn->scheme = NULL; |
52 newConn->style = NULL; |
52 newConn->style = NULL; |
53 newConn->weaponset = NULL; |
53 newConn->weaponset = NULL; |
54 |
54 |
55 newConn->running = false; |
55 newConn->running = false; |
56 newConn->destroyRequested = false; |
56 newConn->destroyRequested = false; |
57 netconn_clearCallbacks(newConn); |
57 netconn_clearCallbacks(newConn); |
58 if(newConn->netBase && newConn->playerName && newConn->dataDirPath && newConn->map) { |
58 if(newConn->netBase && newConn->playerName && newConn->dataDirPath && newConn->map) { |
59 result = newConn; |
59 result = newConn; |
60 newConn = NULL; |
60 newConn = NULL; |
61 } |
61 } |
62 } |
62 } |
63 flib_netconn_destroy(newConn); |
63 flib_netconn_destroy(newConn); |
64 } |
64 } |
65 return result; |
65 return result; |
66 } |
66 } |
67 |
67 |
68 void flib_netconn_destroy(flib_netconn *conn) { |
68 void flib_netconn_destroy(flib_netconn *conn) { |
69 if(conn) { |
69 if(conn) { |
70 if(conn->running) { |
70 if(conn->running) { |
71 /* |
71 /* |
72 * The function was called from a callback, so the tick function is still running |
72 * The function was called from a callback, so the tick function is still running |
73 * and we delay the actual destruction. We ensure no further callbacks will be |
73 * and we delay the actual destruction. We ensure no further callbacks will be |
74 * sent to prevent surprises. |
74 * sent to prevent surprises. |
75 */ |
75 */ |
76 netconn_clearCallbacks(conn); |
76 netconn_clearCallbacks(conn); |
77 conn->destroyRequested = true; |
77 conn->destroyRequested = true; |
78 } else { |
78 } else { |
79 flib_netbase_destroy(conn->netBase); |
79 flib_netbase_destroy(conn->netBase); |
80 free(conn->playerName); |
80 free(conn->playerName); |
81 free(conn->dataDirPath); |
81 free(conn->dataDirPath); |
82 |
82 |
83 flib_map_destroy(conn->map); |
83 flib_map_destroy(conn->map); |
84 flib_teamlist_clear(&conn->pendingTeamlist); |
84 flib_teamlist_clear(&conn->pendingTeamlist); |
85 flib_teamlist_clear(&conn->teamlist); |
85 flib_teamlist_clear(&conn->teamlist); |
86 flib_scheme_destroy(conn->scheme); |
86 flib_scheme_destroy(conn->scheme); |
87 free(conn->style); |
87 free(conn->style); |
88 flib_weaponset_destroy(conn->weaponset); |
88 flib_weaponset_destroy(conn->weaponset); |
89 |
89 |
90 free(conn); |
90 free(conn); |
91 } |
91 } |
92 } |
92 } |
93 } |
93 } |
94 |
94 |
95 bool flib_netconn_is_chief(flib_netconn *conn) { |
95 bool flib_netconn_is_chief(flib_netconn *conn) { |
96 if(!log_badargs_if(conn==NULL) && conn->netconnState==NETCONN_STATE_ROOM) { |
96 if(!log_badargs_if(conn==NULL) && conn->netconnState==NETCONN_STATE_ROOM) { |
97 return conn->isChief; |
97 return conn->isChief; |
98 } |
98 } |
99 return false; |
99 return false; |
100 } |
100 } |
101 |
101 |
102 const char *flib_netconn_get_playername(flib_netconn *conn) { |
102 const char *flib_netconn_get_playername(flib_netconn *conn) { |
103 if(!log_badargs_if(conn==NULL)) { |
103 if(!log_badargs_if(conn==NULL)) { |
104 return conn->playerName; |
104 return conn->playerName; |
105 } |
105 } |
106 return NULL; |
106 return NULL; |
107 } |
107 } |
108 |
108 |
109 void netconn_leaveRoom(flib_netconn *conn) { |
109 void netconn_leaveRoom(flib_netconn *conn) { |
110 conn->netconnState = NETCONN_STATE_LOBBY; |
110 conn->netconnState = NETCONN_STATE_LOBBY; |
111 conn->isChief = false; |
111 conn->isChief = false; |
112 flib_map_destroy(conn->map); |
112 flib_map_destroy(conn->map); |
113 conn->map = flib_map_create_named("", "NoSuchMap"); |
113 conn->map = flib_map_create_named("", "NoSuchMap"); |
114 flib_teamlist_clear(&conn->pendingTeamlist); |
114 flib_teamlist_clear(&conn->pendingTeamlist); |
115 flib_teamlist_clear(&conn->teamlist); |
115 flib_teamlist_clear(&conn->teamlist); |
116 flib_scheme_destroy(conn->scheme); |
116 flib_scheme_destroy(conn->scheme); |
117 conn->scheme = NULL; |
117 conn->scheme = NULL; |
118 free(conn->style); |
118 free(conn->style); |
119 conn->style = NULL; |
119 conn->style = NULL; |
120 flib_weaponset_destroy(conn->weaponset); |
120 flib_weaponset_destroy(conn->weaponset); |
121 conn->weaponset = NULL; |
121 conn->weaponset = NULL; |
122 } |
122 } |
123 |
123 |
124 void netconn_setMap(flib_netconn *conn, const flib_map *map) { |
124 void netconn_setMap(flib_netconn *conn, const flib_map *map) { |
125 flib_map *copy = flib_map_copy(map); |
125 flib_map *copy = flib_map_copy(map); |
126 if(copy) { |
126 if(copy) { |
127 flib_map_destroy(conn->map); |
127 flib_map_destroy(conn->map); |
128 conn->map = copy; |
128 conn->map = copy; |
129 } |
129 } |
130 } |
130 } |
131 |
131 |
132 void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset) { |
132 void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset) { |
133 flib_weaponset *copy = flib_weaponset_copy(weaponset); |
133 flib_weaponset *copy = flib_weaponset_copy(weaponset); |
134 if(copy) { |
134 if(copy) { |
135 flib_weaponset_destroy(conn->weaponset); |
135 flib_weaponset_destroy(conn->weaponset); |
136 conn->weaponset = copy; |
136 conn->weaponset = copy; |
137 } |
137 } |
138 } |
138 } |
139 |
139 |
140 void netconn_setScript(flib_netconn *conn, const char *script) { |
140 void netconn_setScript(flib_netconn *conn, const char *script) { |
141 char *copy = flib_strdupnull(script); |
141 char *copy = flib_strdupnull(script); |
142 if(copy) { |
142 if(copy) { |
143 free(conn->style); |
143 free(conn->style); |
144 conn->style = copy; |
144 conn->style = copy; |
145 } |
145 } |
146 } |
146 } |
147 |
147 |
148 void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme) { |
148 void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme) { |
149 flib_scheme *copy = flib_scheme_copy(scheme); |
149 flib_scheme *copy = flib_scheme_copy(scheme); |
150 if(copy) { |
150 if(copy) { |
151 flib_scheme_destroy(conn->scheme); |
151 flib_scheme_destroy(conn->scheme); |
152 conn->scheme = copy; |
152 conn->scheme = copy; |
153 } |
153 } |
154 } |
154 } |
155 |
155 |
156 flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn) { |
156 flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn) { |
157 flib_gamesetup *result = NULL; |
157 flib_gamesetup *result = NULL; |
158 if(!log_badargs_if(conn==NULL)) { |
158 if(!log_badargs_if(conn==NULL)) { |
159 if(conn->teamlist.teamCount==0 || !conn->scheme || !conn->weaponset) { |
159 if(conn->teamlist.teamCount==0 || !conn->scheme || !conn->weaponset) { |
160 flib_log_e("Incomplete room state"); |
160 flib_log_e("Incomplete room state"); |
161 } else { |
161 } else { |
162 flib_gamesetup stackSetup = {0}; |
162 flib_gamesetup stackSetup = {0}; |
163 stackSetup.gamescheme = conn->scheme; |
163 stackSetup.gamescheme = conn->scheme; |
164 stackSetup.map = conn->map; |
164 stackSetup.map = conn->map; |
165 stackSetup.style = conn->style; |
165 stackSetup.style = conn->style; |
166 stackSetup.teamlist = &conn->teamlist; |
166 stackSetup.teamlist = &conn->teamlist; |
167 result = flib_gamesetup_copy(&stackSetup); |
167 result = flib_gamesetup_copy(&stackSetup); |
168 if(result) { |
168 if(result) { |
169 bool error = false; |
169 bool error = false; |
170 for(int i=0; i<result->teamlist->teamCount; i++) { |
170 for(int i=0; i<result->teamlist->teamCount; i++) { |
171 if(flib_team_set_weaponset(result->teamlist->teams[i], conn->weaponset)) { |
171 if(flib_team_set_weaponset(result->teamlist->teams[i], conn->weaponset)) { |
172 error = true; |
172 error = true; |
173 } |
173 } |
174 flib_team_set_health(result->teamlist->teams[i], flib_scheme_get_setting(conn->scheme, "health", 100)); |
174 flib_team_set_health(result->teamlist->teams[i], flib_scheme_get_setting(conn->scheme, "health", 100)); |
175 } |
175 } |
176 if(result->map->mapgen == MAPGEN_NAMED && result->map->name) { |
176 if(result->map->mapgen == MAPGEN_NAMED && result->map->name) { |
177 flib_mapcfg mapcfg; |
177 flib_mapcfg mapcfg; |
178 if(!flib_mapcfg_read(conn->dataDirPath, result->map->name, &mapcfg)) { |
178 if(!flib_mapcfg_read(conn->dataDirPath, result->map->name, &mapcfg)) { |
179 free(result->map->theme); |
179 free(result->map->theme); |
180 result->map->theme = flib_strdupnull(mapcfg.theme); |
180 result->map->theme = flib_strdupnull(mapcfg.theme); |
181 if(!result->map->theme) { |
181 if(!result->map->theme) { |
182 error = true; |
182 error = true; |
183 } |
183 } |
184 } else { |
184 } else { |
185 flib_log_e("Unable to read map config for map %s", result->map->name); |
185 flib_log_e("Unable to read map config for map %s", result->map->name); |
186 } |
186 } |
187 } |
187 } |
188 if(error) { |
188 if(error) { |
189 flib_gamesetup_destroy(result); |
189 flib_gamesetup_destroy(result); |
190 result = NULL; |
190 result = NULL; |
191 } |
191 } |
192 } |
192 } |
193 } |
193 } |
194 } |
194 } |
195 return result; |
195 return result; |
196 } |
196 } |
197 |
197 |
198 static void flib_netconn_wrappedtick(flib_netconn *conn) { |
198 static void flib_netconn_wrappedtick(flib_netconn *conn) { |
199 flib_netmsg *netmsg; |
199 flib_netmsg *netmsg; |
200 flib_netbase *net = conn->netBase; |
200 flib_netbase *net = conn->netBase; |
201 bool exit = false; |
201 bool exit = false; |
202 |
202 |
203 while(!exit && !conn->destroyRequested && (netmsg=flib_netbase_recv_message(conn->netBase))) { |
203 while(!exit && !conn->destroyRequested && (netmsg=flib_netbase_recv_message(conn->netBase))) { |
204 if(netmsg->partCount==0) { |
204 if(netmsg->partCount==0) { |
205 flib_log_w("Empty server message"); |
205 flib_log_w("Empty server message"); |
206 continue; |
206 continue; |
207 } |
207 } |
208 |
208 |
209 if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { |
209 if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { |
210 char *buf = flib_join(netmsg->parts, netmsg->partCount, "|"); |
210 char *buf = flib_join(netmsg->parts, netmsg->partCount, "|"); |
211 if(buf) { |
211 if(buf) { |
212 flib_log_d("[Net In]%s", buf); |
212 flib_log_d("[Net In]%s", buf); |
213 } |
213 } |
214 free(buf); |
214 free(buf); |
215 } |
215 } |
216 |
216 |
217 const char *cmd = netmsg->parts[0]; |
217 const char *cmd = netmsg->parts[0]; |
218 |
218 |
219 if (!strcmp(cmd, "NICK") && netmsg->partCount>=2) { |
219 if (!strcmp(cmd, "NICK") && netmsg->partCount>=2) { |
220 if(netmsg->partCount<2) { |
220 if(netmsg->partCount<2) { |
221 flib_log_w("Net: Malformed NICK message"); |
221 flib_log_w("Net: Malformed NICK message"); |
222 } else { |
222 } else { |
223 char *nick = flib_strdupnull(netmsg->parts[1]); |
223 char *nick = flib_strdupnull(netmsg->parts[1]); |
224 if(nick) { |
224 if(nick) { |
225 free(conn->playerName); |
225 free(conn->playerName); |
226 conn->playerName = nick; |
226 conn->playerName = nick; |
227 } else { |
227 } else { |
228 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
228 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
229 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Out of memory"); |
229 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Out of memory"); |
230 exit = true; |
230 exit = true; |
231 } |
231 } |
232 } |
232 } |
233 } else if (!strcmp(cmd, "PROTO")) { |
233 } else if (!strcmp(cmd, "PROTO")) { |
234 // The server just echoes this back apparently |
234 // The server just echoes this back apparently |
235 } else if (!strcmp(cmd, "ERROR")) { |
235 } else if (!strcmp(cmd, "ERROR")) { |
236 if (netmsg->partCount >= 2) { |
236 if (netmsg->partCount >= 2) { |
237 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, netmsg->parts[1]); |
237 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, netmsg->parts[1]); |
238 } else { |
238 } else { |
239 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, "Unknown Error"); |
239 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, "Unknown Error"); |
240 } |
240 } |
241 } else if(!strcmp(cmd, "WARNING")) { |
241 } else if(!strcmp(cmd, "WARNING")) { |
242 if (netmsg->partCount >= 2) { |
242 if (netmsg->partCount >= 2) { |
243 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, netmsg->parts[1]); |
243 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, netmsg->parts[1]); |
244 } else { |
244 } else { |
245 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, "Unknown Warning"); |
245 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, "Unknown Warning"); |
246 } |
246 } |
247 } else if(!strcmp(cmd, "CONNECTED")) { |
247 } else if(!strcmp(cmd, "CONNECTED")) { |
248 if(netmsg->partCount<3 || atol(netmsg->parts[2])<MIN_SERVER_VERSION) { |
248 if(netmsg->partCount<3 || atol(netmsg->parts[2])<MIN_SERVER_VERSION) { |
249 flib_log_w("Net: Server too old"); |
249 flib_log_w("Net: Server too old"); |
250 flib_netbase_sendf(net, "%s\n%s\n\n", "QUIT", "Server too old"); |
250 flib_netbase_sendf(net, "%s\n%s\n\n", "QUIT", "Server too old"); |
251 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
251 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
252 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_SERVER_TOO_OLD, "Server too old"); |
252 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_SERVER_TOO_OLD, "Server too old"); |
253 exit = true; |
253 exit = true; |
254 } else { |
254 } else { |
255 flib_netbase_sendf(net, "%s\n%s\n\n", "NICK", conn->playerName); |
255 flib_netbase_sendf(net, "%s\n%s\n\n", "NICK", conn->playerName); |
256 flib_netbase_sendf(net, "%s\n%i\n\n", "PROTO", (int)PROTOCOL_VERSION); |
256 flib_netbase_sendf(net, "%s\n%i\n\n", "PROTO", (int)PROTOCOL_VERSION); |
257 } |
257 } |
258 } else if(!strcmp(cmd, "PING")) { |
258 } else if(!strcmp(cmd, "PING")) { |
259 if (netmsg->partCount > 1) { |
259 if (netmsg->partCount > 1) { |
260 flib_netbase_sendf(net, "%s\n%s\n\n", "PONG", netmsg->parts[1]); |
260 flib_netbase_sendf(net, "%s\n%s\n\n", "PONG", netmsg->parts[1]); |
261 } else { |
261 } else { |
262 flib_netbase_sendf(net, "%s\n\n", "PONG"); |
262 flib_netbase_sendf(net, "%s\n\n", "PONG"); |
263 } |
263 } |
264 } else if(!strcmp(cmd, "ROOMS")) { |
264 } else if(!strcmp(cmd, "ROOMS")) { |
265 if(netmsg->partCount % 8 != 1) { |
265 if(netmsg->partCount % 8 != 1) { |
266 flib_log_w("Net: Malformed ROOMS message"); |
266 flib_log_w("Net: Malformed ROOMS message"); |
267 } else { |
267 } else { |
268 int roomCount = netmsg->partCount/8; |
268 int roomCount = netmsg->partCount/8; |
269 flib_room **rooms = flib_room_array_from_netmsg(netmsg->parts+1, roomCount); |
269 flib_room **rooms = flib_room_array_from_netmsg(netmsg->parts+1, roomCount); |
270 if(rooms) { |
270 if(rooms) { |
271 conn->onRoomlistCb(conn->onRoomlistCtx, (const flib_room**)rooms, roomCount); |
271 conn->onRoomlistCb(conn->onRoomlistCtx, (const flib_room**)rooms, roomCount); |
272 for(int i=0; i<roomCount; i++) { |
272 for(int i=0; i<roomCount; i++) { |
273 flib_room_destroy(rooms[i]); |
273 flib_room_destroy(rooms[i]); |
274 } |
274 } |
275 free(rooms); |
275 free(rooms); |
276 } |
276 } |
277 } |
277 } |
278 } else if (!strcmp(cmd, "SERVER_MESSAGE")) { |
278 } else if (!strcmp(cmd, "SERVER_MESSAGE")) { |
279 if(netmsg->partCount < 2) { |
279 if(netmsg->partCount < 2) { |
280 flib_log_w("Net: Empty SERVERMESSAGE message"); |
280 flib_log_w("Net: Empty SERVERMESSAGE message"); |
281 } else { |
281 } else { |
282 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_SERVERMESSAGE, netmsg->parts[1]); |
282 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_SERVERMESSAGE, netmsg->parts[1]); |
283 } |
283 } |
284 } else if (!strcmp(cmd, "CHAT")) { |
284 } else if (!strcmp(cmd, "CHAT")) { |
285 if(netmsg->partCount < 3) { |
285 if(netmsg->partCount < 3) { |
286 flib_log_w("Net: Empty CHAT message"); |
286 flib_log_w("Net: Empty CHAT message"); |
287 } else { |
287 } else { |
288 conn->onChatCb(conn->onChatCtx, netmsg->parts[1], netmsg->parts[2]); |
288 conn->onChatCb(conn->onChatCtx, netmsg->parts[1], netmsg->parts[2]); |
289 } |
289 } |
290 } else if (!strcmp(cmd, "INFO")) { |
290 } else if (!strcmp(cmd, "INFO")) { |
291 if(netmsg->partCount < 5) { |
291 if(netmsg->partCount < 5) { |
292 flib_log_w("Net: Malformed INFO message"); |
292 flib_log_w("Net: Malformed INFO message"); |
293 } else { |
293 } else { |
294 char *joined = flib_join(netmsg->parts+1, netmsg->partCount-1, "\n"); |
294 char *joined = flib_join(netmsg->parts+1, netmsg->partCount-1, "\n"); |
295 if(joined) { |
295 if(joined) { |
296 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_PLAYERINFO, joined); |
296 conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_PLAYERINFO, joined); |
297 } |
297 } |
298 free(joined); |
298 free(joined); |
299 } |
299 } |
300 } else if(!strcmp(cmd, "SERVER_VARS")) { |
300 } else if(!strcmp(cmd, "SERVER_VARS")) { |
301 for(int offset=1; offset+2<netmsg->partCount; offset+=2) { |
301 for(int offset=1; offset+2<netmsg->partCount; offset+=2) { |
302 conn->onServerVarCb(conn->onServerVarCtx, netmsg->parts[offset], netmsg->parts[offset+1]); |
302 conn->onServerVarCb(conn->onServerVarCtx, netmsg->parts[offset], netmsg->parts[offset+1]); |
303 } |
303 } |
304 } else if (!strcmp(cmd, "CLIENT_FLAGS")) { |
304 } else if (!strcmp(cmd, "CLIENT_FLAGS")) { |
305 if(netmsg->partCount < 3 || strlen(netmsg->parts[1]) < 2) { |
305 if(netmsg->partCount < 3 || strlen(netmsg->parts[1]) < 2) { |
306 flib_log_w("Net: Malformed CLIENT_FLAGS message"); |
306 flib_log_w("Net: Malformed CLIENT_FLAGS message"); |
307 } else { |
307 } else { |
308 const char *flags = netmsg->parts[1]; |
308 const char *flags = netmsg->parts[1]; |
309 bool setFlag = flags[0] == '+'; |
309 bool setFlag = flags[0] == '+'; |
310 |
310 |
311 for(int j = 2; j < netmsg->partCount; ++j) { |
311 for(int j = 2; j < netmsg->partCount; ++j) { |
312 bool isSelf = !strcmp(conn->playerName, netmsg->parts[j]); |
312 bool isSelf = !strcmp(conn->playerName, netmsg->parts[j]); |
313 if(isSelf && strchr(flags, 'h')) { |
313 if(isSelf && strchr(flags, 'h')) { |
314 conn->isChief = setFlag; |
314 conn->isChief = setFlag; |
315 } |
315 } |
316 conn->onClientFlagsCb(conn->onClientFlagsCtx, netmsg->parts[j], flags+1, setFlag); |
316 conn->onClientFlagsCb(conn->onClientFlagsCtx, netmsg->parts[j], flags+1, setFlag); |
317 } |
317 } |
318 } |
318 } |
319 } else if (!strcmp(cmd, "ADD_TEAM")) { |
319 } else if (!strcmp(cmd, "ADD_TEAM")) { |
320 if(netmsg->partCount != 24 || conn->netconnState!=NETCONN_STATE_ROOM) { |
320 if(netmsg->partCount != 24 || conn->netconnState!=NETCONN_STATE_ROOM) { |
321 flib_log_w("Net: Bad ADD_TEAM message"); |
321 flib_log_w("Net: Bad ADD_TEAM message"); |
322 } else { |
322 } else { |
323 flib_team *team = flib_team_from_netmsg(netmsg->parts+1); |
323 flib_team *team = flib_team_from_netmsg(netmsg->parts+1); |
324 if(!team || flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount)) { |
324 if(!team || flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount)) { |
325 flib_team_destroy(team); |
325 flib_team_destroy(team); |
326 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
326 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
327 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Internal error"); |
327 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Internal error"); |
328 exit = true; |
328 exit = true; |
329 } else { |
329 } else { |
330 conn->onTeamAddCb(conn->onTeamAddCtx, team); |
330 conn->onTeamAddCb(conn->onTeamAddCtx, team); |
331 } |
331 } |
332 } |
332 } |
333 } else if (!strcmp(cmd, "REMOVE_TEAM")) { |
333 } else if (!strcmp(cmd, "REMOVE_TEAM")) { |
334 if(netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { |
334 if(netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { |
335 flib_log_w("Net: Bad REMOVETEAM message"); |
335 flib_log_w("Net: Bad REMOVETEAM message"); |
336 } else { |
336 } else { |
337 flib_teamlist_delete(&conn->teamlist, netmsg->parts[1]); |
337 flib_teamlist_delete(&conn->teamlist, netmsg->parts[1]); |
338 conn->onTeamDeleteCb(conn->onTeamDeleteCtx, netmsg->parts[1]); |
338 conn->onTeamDeleteCb(conn->onTeamDeleteCtx, netmsg->parts[1]); |
339 } |
339 } |
340 } else if(!strcmp(cmd, "ROOMABANDONED")) { |
340 } else if(!strcmp(cmd, "ROOMABANDONED")) { |
341 netconn_leaveRoom(conn); |
341 netconn_leaveRoom(conn); |
342 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_ABANDONED, "Room destroyed"); |
342 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_ABANDONED, "Room destroyed"); |
343 } else if(!strcmp(cmd, "KICKED")) { |
343 } else if(!strcmp(cmd, "KICKED")) { |
344 netconn_leaveRoom(conn); |
344 netconn_leaveRoom(conn); |
345 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_KICKED, "You got kicked"); |
345 conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_KICKED, "You got kicked"); |
346 } else if(!strcmp(cmd, "JOINED")) { |
346 } else if(!strcmp(cmd, "JOINED")) { |
347 if(netmsg->partCount < 2) { |
347 if(netmsg->partCount < 2) { |
348 flib_log_w("Net: Bad JOINED message"); |
348 flib_log_w("Net: Bad JOINED message"); |
349 } else { |
349 } else { |
350 for(int i = 1; i < netmsg->partCount; ++i) |
350 for(int i = 1; i < netmsg->partCount; ++i) |
351 { |
351 { |
352 bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); |
352 bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); |
353 if (isMe) { |
353 if (isMe) { |
354 conn->netconnState = NETCONN_STATE_ROOM; |
354 conn->netconnState = NETCONN_STATE_ROOM; |
355 conn->onEnterRoomCb(conn->onEnterRoomCtx, conn->isChief); |
355 conn->onEnterRoomCb(conn->onEnterRoomCtx, conn->isChief); |
356 } |
356 } |
357 |
357 |
358 conn->onRoomJoinCb(conn->onRoomJoinCtx, netmsg->parts[i]); |
358 conn->onRoomJoinCb(conn->onRoomJoinCtx, netmsg->parts[i]); |
359 } |
359 } |
360 } |
360 } |
361 } else if(!strcmp(cmd, "LOBBY:JOINED")) { |
361 } else if(!strcmp(cmd, "LOBBY:JOINED")) { |
362 if(netmsg->partCount < 2) { |
362 if(netmsg->partCount < 2) { |
363 flib_log_w("Net: Bad JOINED message"); |
363 flib_log_w("Net: Bad JOINED message"); |
364 } else { |
364 } else { |
365 for(int i = 1; i < netmsg->partCount; ++i) |
365 for(int i = 1; i < netmsg->partCount; ++i) |
366 { |
366 { |
367 bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); |
367 bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); |
368 if (isMe && conn->netconnState == NETCONN_STATE_CONNECTING) { |
368 if (isMe && conn->netconnState == NETCONN_STATE_CONNECTING) { |
369 conn->onConnectedCb(conn->onConnectedCtx); |
369 conn->onConnectedCb(conn->onConnectedCtx); |
370 conn->netconnState = NETCONN_STATE_LOBBY; |
370 conn->netconnState = NETCONN_STATE_LOBBY; |
371 } |
371 } |
372 conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]); |
372 conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]); |
373 } |
373 } |
374 } |
374 } |
375 } else if(!strcmp(cmd, "LEFT")) { |
375 } else if(!strcmp(cmd, "LEFT")) { |
376 if(netmsg->partCount < 2) { |
376 if(netmsg->partCount < 2) { |
377 flib_log_w("Net: Bad LEFT message"); |
377 flib_log_w("Net: Bad LEFT message"); |
378 } else { |
378 } else { |
379 conn->onRoomLeaveCb(conn->onRoomLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); |
379 conn->onRoomLeaveCb(conn->onRoomLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); |
380 } |
380 } |
381 } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) { |
381 } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) { |
382 const char *subcmd = netmsg->parts[1]; |
382 const char *subcmd = netmsg->parts[1]; |
383 if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) { |
383 if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) { |
384 flib_room *room = flib_room_from_netmsg(netmsg->parts+2); |
384 flib_room *room = flib_room_from_netmsg(netmsg->parts+2); |
385 if(room) { |
385 if(room) { |
386 conn->onRoomAddCb(conn->onRoomAddCtx, room); |
386 conn->onRoomAddCb(conn->onRoomAddCtx, room); |
387 } |
387 } |
388 flib_room_destroy(room); |
388 flib_room_destroy(room); |
389 } else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) { |
389 } else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) { |
390 flib_room *room = flib_room_from_netmsg(netmsg->parts+3); |
390 flib_room *room = flib_room_from_netmsg(netmsg->parts+3); |
391 if(room) { |
391 if(room) { |
392 conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], room); |
392 conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], room); |
393 } |
393 } |
394 flib_room_destroy(room); |
394 flib_room_destroy(room); |
395 } else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) { |
395 } else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) { |
396 conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); |
396 conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); |
397 } else { |
397 } else { |
398 flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd); |
398 flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd); |
399 } |
399 } |
400 } else if(!strcmp(cmd, "LOBBY:LEFT")) { |
400 } else if(!strcmp(cmd, "LOBBY:LEFT")) { |
401 if(netmsg->partCount < 2) { |
401 if(netmsg->partCount < 2) { |
402 flib_log_w("Net: Bad LOBBY:LEFT message"); |
402 flib_log_w("Net: Bad LOBBY:LEFT message"); |
403 } else { |
403 } else { |
404 conn->onLobbyLeaveCb(conn->onLobbyLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); |
404 conn->onLobbyLeaveCb(conn->onLobbyLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); |
405 } |
405 } |
406 } else if (!strcmp(cmd, "RUN_GAME")) { |
406 } else if (!strcmp(cmd, "RUN_GAME")) { |
407 conn->onRunGameCb(conn->onRunGameCtx); |
407 conn->onRunGameCb(conn->onRunGameCtx); |
408 } else if (!strcmp(cmd, "ASKPASSWORD")) { |
408 } else if (!strcmp(cmd, "ASKPASSWORD")) { |
409 conn->onPasswordRequestCb(conn->onPasswordRequestCtx, conn->playerName); |
409 conn->onPasswordRequestCb(conn->onPasswordRequestCtx, conn->playerName); |
410 } else if (!strcmp(cmd, "NOTICE")) { |
410 } else if (!strcmp(cmd, "NOTICE")) { |
411 if(netmsg->partCount < 2) { |
411 if(netmsg->partCount < 2) { |
412 flib_log_w("Net: Bad NOTICE message"); |
412 flib_log_w("Net: Bad NOTICE message"); |
413 } else { |
413 } else { |
414 errno = 0; |
414 errno = 0; |
415 long n = strtol(netmsg->parts[1], NULL, 10); |
415 long n = strtol(netmsg->parts[1], NULL, 10); |
416 if(errno) { |
416 if(errno) { |
417 flib_log_w("Net: Bad NOTICE message"); |
417 flib_log_w("Net: Bad NOTICE message"); |
418 } else if(n==0) { |
418 } else if(n==0) { |
419 conn->onNickTakenCb(conn->onNickTakenCtx, conn->playerName); |
419 conn->onNickTakenCb(conn->onNickTakenCtx, conn->playerName); |
420 } else { |
420 } else { |
421 flib_log_w("Net: Unknown NOTICE message: %l", n); |
421 flib_log_w("Net: Unknown NOTICE message: %l", n); |
422 } |
422 } |
423 } |
423 } |
424 } else if (!strcmp(cmd, "TEAM_ACCEPTED")) { |
424 } else if (!strcmp(cmd, "TEAM_ACCEPTED")) { |
425 if (netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { |
425 if (netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { |
426 flib_log_w("Net: Bad TEAM_ACCEPTED message"); |
426 flib_log_w("Net: Bad TEAM_ACCEPTED message"); |
427 } else { |
427 } else { |
428 flib_team *team = flib_team_copy(flib_teamlist_find(&conn->pendingTeamlist, netmsg->parts[1])); |
428 flib_team *team = flib_team_copy(flib_teamlist_find(&conn->pendingTeamlist, netmsg->parts[1])); |
429 if(team) { |
429 if(team) { |
430 flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount); |
430 flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount); |
431 flib_teamlist_delete(&conn->pendingTeamlist, netmsg->parts[1]); |
431 flib_teamlist_delete(&conn->pendingTeamlist, netmsg->parts[1]); |
432 } else { |
432 } else { |
433 flib_log_e("Team accepted that was not requested: %s", netmsg->parts[1]); |
433 flib_log_e("Team accepted that was not requested: %s", netmsg->parts[1]); |
434 } |
434 } |
435 conn->onTeamAcceptedCb(conn->onTeamAcceptedCtx, netmsg->parts[1]); |
435 conn->onTeamAcceptedCb(conn->onTeamAcceptedCtx, netmsg->parts[1]); |
436 } |
436 } |
437 } else if (!strcmp(cmd, "CFG")) { |
437 } else if (!strcmp(cmd, "CFG")) { |
438 if(netmsg->partCount < 3 || conn->netconnState!=NETCONN_STATE_ROOM) { |
438 if(netmsg->partCount < 3 || conn->netconnState!=NETCONN_STATE_ROOM) { |
439 flib_log_w("Net: Bad CFG message"); |
439 flib_log_w("Net: Bad CFG message"); |
440 } else { |
440 } else { |
441 const char *subcmd = netmsg->parts[1]; |
441 const char *subcmd = netmsg->parts[1]; |
442 if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == flib_meta.modCount + flib_meta.settingCount + 3) { |
442 if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == flib_meta.modCount + flib_meta.settingCount + 3) { |
443 flib_scheme *cfg = flib_scheme_from_netmsg(netmsg->parts+2); |
443 flib_scheme *cfg = flib_scheme_from_netmsg(netmsg->parts+2); |
444 if(cfg) { |
444 if(cfg) { |
445 flib_scheme_destroy(conn->scheme); |
445 flib_scheme_destroy(conn->scheme); |
446 conn->scheme = cfg; |
446 conn->scheme = cfg; |
447 conn->onSchemeChangedCb(conn->onSchemeChangedCtx, cfg); |
447 conn->onSchemeChangedCb(conn->onSchemeChangedCtx, cfg); |
448 } else { |
448 } else { |
449 flib_log_e("Error processing CFG SCHEME message"); |
449 flib_log_e("Error processing CFG SCHEME message"); |
450 } |
450 } |
451 } else if(!strcmp(subcmd, "FULLMAPCONFIG") && netmsg->partCount == 7) { |
451 } else if(!strcmp(subcmd, "FULLMAPCONFIG") && netmsg->partCount == 7) { |
452 flib_map *map = flib_map_from_netmsg(netmsg->parts+2); |
452 flib_map *map = flib_map_from_netmsg(netmsg->parts+2); |
453 if(map) { |
453 if(map) { |
454 flib_map_destroy(conn->map); |
454 flib_map_destroy(conn->map); |
455 conn->map = map; |
455 conn->map = map; |
456 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_FULL); |
456 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_FULL); |
457 } else { |
457 } else { |
458 flib_log_e("Error processing CFG FULLMAPCONFIG message"); |
458 flib_log_e("Error processing CFG FULLMAPCONFIG message"); |
459 } |
459 } |
460 } else if(!strcmp(subcmd, "MAP") && netmsg->partCount == 3) { |
460 } else if(!strcmp(subcmd, "MAP") && netmsg->partCount == 3) { |
461 char *mapname = flib_strdupnull(netmsg->parts[2]); |
461 char *mapname = flib_strdupnull(netmsg->parts[2]); |
462 if(mapname) { |
462 if(mapname) { |
463 free(conn->map->name); |
463 free(conn->map->name); |
464 conn->map->name = mapname; |
464 conn->map->name = mapname; |
465 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAP); |
465 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAP); |
466 } else { |
466 } else { |
467 flib_log_e("Error processing CFG MAP message"); |
467 flib_log_e("Error processing CFG MAP message"); |
468 } |
468 } |
469 } else if(!strcmp(subcmd, "THEME") && netmsg->partCount == 3) { |
469 } else if(!strcmp(subcmd, "THEME") && netmsg->partCount == 3) { |
470 char *themename = flib_strdupnull(netmsg->parts[2]); |
470 char *themename = flib_strdupnull(netmsg->parts[2]); |
471 if(themename) { |
471 if(themename) { |
472 free(conn->map->theme); |
472 free(conn->map->theme); |
473 conn->map->theme = themename; |
473 conn->map->theme = themename; |
474 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_THEME); |
474 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_THEME); |
475 } else { |
475 } else { |
476 flib_log_e("Error processing CFG THEME message"); |
476 flib_log_e("Error processing CFG THEME message"); |
477 } |
477 } |
478 } else if(!strcmp(subcmd, "SEED") && netmsg->partCount == 3) { |
478 } else if(!strcmp(subcmd, "SEED") && netmsg->partCount == 3) { |
479 char *seed = flib_strdupnull(netmsg->parts[2]); |
479 char *seed = flib_strdupnull(netmsg->parts[2]); |
480 if(seed) { |
480 if(seed) { |
481 free(conn->map->seed); |
481 free(conn->map->seed); |
482 conn->map->seed = seed; |
482 conn->map->seed = seed; |
483 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_SEED); |
483 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_SEED); |
484 } else { |
484 } else { |
485 flib_log_e("Error processing CFG SEED message"); |
485 flib_log_e("Error processing CFG SEED message"); |
486 } |
486 } |
487 } else if(!strcmp(subcmd, "TEMPLATE") && netmsg->partCount == 3) { |
487 } else if(!strcmp(subcmd, "TEMPLATE") && netmsg->partCount == 3) { |
488 conn->map->templateFilter = atoi(netmsg->parts[2]); |
488 conn->map->templateFilter = atoi(netmsg->parts[2]); |
489 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_TEMPLATE); |
489 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_TEMPLATE); |
490 } else if(!strcmp(subcmd, "MAPGEN") && netmsg->partCount == 3) { |
490 } else if(!strcmp(subcmd, "MAPGEN") && netmsg->partCount == 3) { |
491 conn->map->mapgen = atoi(netmsg->parts[2]); |
491 conn->map->mapgen = atoi(netmsg->parts[2]); |
492 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAPGEN); |
492 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAPGEN); |
493 } else if(!strcmp(subcmd, "MAZE_SIZE") && netmsg->partCount == 3) { |
493 } else if(!strcmp(subcmd, "MAZE_SIZE") && netmsg->partCount == 3) { |
494 conn->map->mazeSize = atoi(netmsg->parts[2]); |
494 conn->map->mazeSize = atoi(netmsg->parts[2]); |
495 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAZE_SIZE); |
495 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAZE_SIZE); |
496 } else if(!strcmp(subcmd, "DRAWNMAP") && netmsg->partCount == 3) { |
496 } else if(!strcmp(subcmd, "DRAWNMAP") && netmsg->partCount == 3) { |
497 size_t drawnMapSize = 0; |
497 size_t drawnMapSize = 0; |
498 uint8_t *drawnMapData = NULL; |
498 uint8_t *drawnMapData = NULL; |
499 if(!flib_drawnmapdata_from_netmsg(netmsg->parts[2], &drawnMapData, &drawnMapSize)) { |
499 if(!flib_drawnmapdata_from_netmsg(netmsg->parts[2], &drawnMapData, &drawnMapSize)) { |
500 free(conn->map->drawData); |
500 free(conn->map->drawData); |
501 conn->map->drawData = drawnMapData; |
501 conn->map->drawData = drawnMapData; |
502 conn->map->drawDataSize = drawnMapSize; |
502 conn->map->drawDataSize = drawnMapSize; |
503 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_DRAWNMAP); |
503 conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_DRAWNMAP); |
504 } else { |
504 } else { |
505 flib_log_e("Error processing CFG DRAWNMAP message"); |
505 flib_log_e("Error processing CFG DRAWNMAP message"); |
506 } |
506 } |
507 } else if(!strcmp(subcmd, "SCRIPT") && netmsg->partCount == 3) { |
507 } else if(!strcmp(subcmd, "SCRIPT") && netmsg->partCount == 3) { |
508 netconn_setScript(conn, netmsg->parts[2]); |
508 netconn_setScript(conn, netmsg->parts[2]); |
509 conn->onScriptChangedCb(conn->onScriptChangedCtx, netmsg->parts[2]); |
509 conn->onScriptChangedCb(conn->onScriptChangedCtx, netmsg->parts[2]); |
510 } else if(!strcmp(subcmd, "AMMO") && netmsg->partCount == 4) { |
510 } else if(!strcmp(subcmd, "AMMO") && netmsg->partCount == 4) { |
511 flib_weaponset *weapons = flib_weaponset_from_ammostring(netmsg->parts[2], netmsg->parts[3]); |
511 flib_weaponset *weapons = flib_weaponset_from_ammostring(netmsg->parts[2], netmsg->parts[3]); |
512 if(weapons) { |
512 if(weapons) { |
513 flib_weaponset_destroy(conn->weaponset); |
513 flib_weaponset_destroy(conn->weaponset); |
514 conn->weaponset = weapons; |
514 conn->weaponset = weapons; |
515 conn->onWeaponsetChangedCb(conn->onWeaponsetChangedCtx, weapons); |
515 conn->onWeaponsetChangedCb(conn->onWeaponsetChangedCtx, weapons); |
516 } else { |
516 } else { |
517 flib_log_e("Error processing CFG AMMO message"); |
517 flib_log_e("Error processing CFG AMMO message"); |
518 } |
518 } |
519 } else { |
519 } else { |
520 flib_log_w("Net: Unknown or malformed CFG subcommand: %s", subcmd); |
520 flib_log_w("Net: Unknown or malformed CFG subcommand: %s", subcmd); |
521 } |
521 } |
522 } |
522 } |
523 } else if (!strcmp(cmd, "HH_NUM")) { |
523 } else if (!strcmp(cmd, "HH_NUM")) { |
524 if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { |
524 if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { |
525 flib_log_w("Net: Bad HH_NUM message"); |
525 flib_log_w("Net: Bad HH_NUM message"); |
526 } else { |
526 } else { |
527 int hogs = atoi(netmsg->parts[2]); |
527 int hogs = atoi(netmsg->parts[2]); |
528 if(hogs<=0 || hogs>HEDGEHOGS_PER_TEAM) { |
528 if(hogs<=0 || hogs>HEDGEHOGS_PER_TEAM) { |
529 flib_log_w("Net: Bad HH_NUM message: %s hogs", netmsg->parts[2]); |
529 flib_log_w("Net: Bad HH_NUM message: %s hogs", netmsg->parts[2]); |
530 } else { |
530 } else { |
531 flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]); |
531 flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]); |
532 if(team) { |
532 if(team) { |
533 team->hogsInGame = hogs; |
533 team->hogsInGame = hogs; |
534 } else { |
534 } else { |
535 flib_log_e("HH_NUM message for unknown team %s", netmsg->parts[1]); |
535 flib_log_e("HH_NUM message for unknown team %s", netmsg->parts[1]); |
536 } |
536 } |
537 conn->onHogCountChangedCb(conn->onHogCountChangedCtx, netmsg->parts[1], hogs); |
537 conn->onHogCountChangedCb(conn->onHogCountChangedCtx, netmsg->parts[1], hogs); |
538 } |
538 } |
539 } |
539 } |
540 } else if (!strcmp(cmd, "TEAM_COLOR")) { |
540 } else if (!strcmp(cmd, "TEAM_COLOR")) { |
541 if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { |
541 if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { |
542 flib_log_w("Net: Bad TEAM_COLOR message"); |
542 flib_log_w("Net: Bad TEAM_COLOR message"); |
543 } else { |
543 } else { |
544 long color; |
544 long color; |
545 if(sscanf(netmsg->parts[2], "%lu", &color) && color>=0 && color<flib_teamcolor_count) { |
545 if(sscanf(netmsg->parts[2], "%lu", &color) && color>=0 && color<flib_teamcolor_count) { |
546 flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]); |
546 flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]); |
547 if(team) { |
547 if(team) { |
548 team->colorIndex = color; |
548 team->colorIndex = color; |
549 } else { |
549 } else { |
550 flib_log_e("TEAM_COLOR message for unknown team %s", netmsg->parts[1]); |
550 flib_log_e("TEAM_COLOR message for unknown team %s", netmsg->parts[1]); |
551 } |
551 } |
552 conn->onTeamColorChangedCb(conn->onTeamColorChangedCtx, netmsg->parts[1], color); |
552 conn->onTeamColorChangedCb(conn->onTeamColorChangedCtx, netmsg->parts[1], color); |
553 } else { |
553 } else { |
554 flib_log_w("Net: Bad TEAM_COLOR message: Color %s", netmsg->parts[2]); |
554 flib_log_w("Net: Bad TEAM_COLOR message: Color %s", netmsg->parts[2]); |
555 } |
555 } |
556 } |
556 } |
557 } else if (!strcmp(cmd, "EM")) { |
557 } else if (!strcmp(cmd, "EM")) { |
558 if(netmsg->partCount < 2) { |
558 if(netmsg->partCount < 2) { |
559 flib_log_w("Net: Bad EM message"); |
559 flib_log_w("Net: Bad EM message"); |
560 } else { |
560 } else { |
561 for(int i = 1; i < netmsg->partCount; ++i) { |
561 for(int i = 1; i < netmsg->partCount; ++i) { |
562 char *out = NULL; |
562 char *out = NULL; |
563 size_t outlen; |
563 size_t outlen; |
564 bool ok = base64_decode_alloc(netmsg->parts[i], strlen(netmsg->parts[i]), &out, &outlen); |
564 bool ok = base64_decode_alloc(netmsg->parts[i], strlen(netmsg->parts[i]), &out, &outlen); |
565 if(ok && outlen) { |
565 if(ok && outlen) { |
566 conn->onEngineMessageCb(conn->onEngineMessageCtx, (uint8_t*)out, outlen); |
566 conn->onEngineMessageCb(conn->onEngineMessageCtx, (uint8_t*)out, outlen); |
567 } else { |
567 } else { |
568 flib_log_e("Net: Malformed engine message: %s", netmsg->parts[i]); |
568 flib_log_e("Net: Malformed engine message: %s", netmsg->parts[i]); |
569 } |
569 } |
570 free(out); |
570 free(out); |
571 } |
571 } |
572 } |
572 } |
573 } else if (!strcmp(cmd, "BYE")) { |
573 } else if (!strcmp(cmd, "BYE")) { |
574 if (netmsg->partCount < 2) { |
574 if (netmsg->partCount < 2) { |
575 flib_log_w("Net: Bad BYE message"); |
575 flib_log_w("Net: Bad BYE message"); |
576 } else { |
576 } else { |
577 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
577 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
578 if (!strcmp(netmsg->parts[1], "Authentication failed")) { |
578 if (!strcmp(netmsg->parts[1], "Authentication failed")) { |
579 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_AUTH_FAILED, netmsg->parts[1]); |
579 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_AUTH_FAILED, netmsg->parts[1]); |
580 } else { |
580 } else { |
581 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_NORMAL, netmsg->parts[1]); |
581 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_NORMAL, netmsg->parts[1]); |
582 } |
582 } |
583 exit = true; |
583 exit = true; |
584 } |
584 } |
585 } else if (!strcmp(cmd, "ADMIN_ACCESS")) { |
585 } else if (!strcmp(cmd, "ADMIN_ACCESS")) { |
586 // deprecated |
586 // deprecated |
587 } else if (!strcmp(cmd, "ROOM_CONTROL_ACCESS")) { |
587 } else if (!strcmp(cmd, "ROOM_CONTROL_ACCESS")) { |
588 // deprecated |
588 // deprecated |
589 } else { |
589 } else { |
590 flib_log_w("Unknown server command: %s", cmd); |
590 flib_log_w("Unknown server command: %s", cmd); |
591 } |
591 } |
592 flib_netmsg_destroy(netmsg); |
592 flib_netmsg_destroy(netmsg); |
593 } |
593 } |
594 |
594 |
595 if(!exit && !conn->destroyRequested && !flib_netbase_connected(net)) { |
595 if(!exit && !conn->destroyRequested && !flib_netbase_connected(net)) { |
596 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
596 conn->netconnState = NETCONN_STATE_DISCONNECTED; |
597 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_CONNLOST, "Connection lost"); |
597 conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_CONNLOST, "Connection lost"); |
598 } |
598 } |
599 } |
599 } |
600 |
600 |
601 void flib_netconn_tick(flib_netconn *conn) { |
601 void flib_netconn_tick(flib_netconn *conn) { |
602 if(!log_badargs_if(conn==NULL) |
602 if(!log_badargs_if(conn==NULL) |
603 && !log_w_if(conn->running, "Call to flib_netconn_tick from a callback") |
603 && !log_w_if(conn->running, "Call to flib_netconn_tick from a callback") |
604 && !log_w_if(conn->netconnState == NETCONN_STATE_DISCONNECTED, "We are already done.")) { |
604 && !log_w_if(conn->netconnState == NETCONN_STATE_DISCONNECTED, "We are already done.")) { |
605 conn->running = true; |
605 conn->running = true; |
606 flib_netconn_wrappedtick(conn); |
606 flib_netconn_wrappedtick(conn); |
607 conn->running = false; |
607 conn->running = false; |
608 |
608 |
609 if(conn->destroyRequested) { |
609 if(conn->destroyRequested) { |
610 flib_netconn_destroy(conn); |
610 flib_netconn_destroy(conn); |
611 } |
611 } |
612 } |
612 } |
613 } |
613 } |