23 #include "../util/util.h" |
23 #include "../util/util.h" |
24 #include "../util/buffer.h" |
24 #include "../util/buffer.h" |
25 #include "../md5/md5.h" |
25 #include "../md5/md5.h" |
26 #include "../base64/base64.h" |
26 #include "../base64/base64.h" |
27 |
27 |
|
28 #include <zlib.h> |
|
29 |
28 #include <stdlib.h> |
30 #include <stdlib.h> |
29 #include <string.h> |
31 #include <string.h> |
30 #include <zlib.h> |
32 #include <limits.h> |
31 |
33 |
32 // cmdname is always given as literal from functions in this file, so it is never null. |
34 // cmdname is always given as literal from functions in this file, so it is never null. |
33 static int sendVoid(flib_netconn *conn, const char *cmdname) { |
35 static int sendVoid(flib_netconn *conn, const char *cmdname) { |
34 if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { |
36 if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { |
35 return -1; |
37 return -1; |
37 return flib_netbase_sendf(conn->netBase, "%s\n\n", cmdname); |
39 return flib_netbase_sendf(conn->netBase, "%s\n\n", cmdname); |
38 } |
40 } |
39 |
41 |
40 // Testing for !*str prevents sending 0-length parameters (they trip up the protocol) |
42 // Testing for !*str prevents sending 0-length parameters (they trip up the protocol) |
41 static int sendStr(flib_netconn *conn, const char *cmdname, const char *str) { |
43 static int sendStr(flib_netconn *conn, const char *cmdname, const char *str) { |
42 if(log_e_if(!conn || !str || !*str, "Invalid parameter sending %s command", cmdname)) { |
44 if(log_e_if(!conn || flib_strempty(str), "Invalid parameter sending %s command", cmdname)) { |
43 return -1; |
45 return -1; |
44 } |
46 } |
45 return flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", cmdname, str); |
47 return flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", cmdname, str); |
46 } |
48 } |
47 |
49 |
55 int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) { |
57 int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) { |
56 return sendStr(conn, "QUIT", (quitmsg && *quitmsg) ? quitmsg : "User quit"); |
58 return sendStr(conn, "QUIT", (quitmsg && *quitmsg) ? quitmsg : "User quit"); |
57 } |
59 } |
58 |
60 |
59 int flib_netconn_send_chat(flib_netconn *conn, const char *chat) { |
61 int flib_netconn_send_chat(flib_netconn *conn, const char *chat) { |
60 if(chat && *chat) { |
62 if(!flib_strempty(chat)) { |
61 return sendStr(conn, "CHAT", chat); |
63 return sendStr(conn, "CHAT", chat); |
62 } |
64 } |
63 return 0; |
65 return 0; |
64 } |
66 } |
65 |
67 |
66 int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) { |
68 int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) { |
67 if(chat && *chat) { |
69 if(!flib_strempty(chat)) { |
68 return sendStr(conn, "TEAMCHAT", chat); |
70 return sendStr(conn, "TEAMCHAT", chat); |
69 } |
71 } |
70 return 0; |
72 return 0; |
71 } |
73 } |
72 |
74 |
73 int flib_netconn_send_nick(flib_netconn *conn, const char *nick) { |
75 int flib_netconn_send_nick(flib_netconn *conn, const char *nick) { |
74 int result = -1; |
76 int result = -1; |
75 if(!log_badparams_if(!conn || !nick || !*nick)) { |
77 if(!log_badargs_if2(conn==NULL, flib_strempty(nick))) { |
76 char *tmpName = flib_strdupnull(nick); |
78 char *tmpName = flib_strdupnull(nick); |
77 if(tmpName) { |
79 if(tmpName) { |
78 if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) { |
80 if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) { |
79 free(conn->playerName); |
81 free(conn->playerName); |
80 conn->playerName = tmpName; |
82 conn->playerName = tmpName; |
87 return result; |
89 return result; |
88 } |
90 } |
89 |
91 |
90 int flib_netconn_send_password(flib_netconn *conn, const char *passwd) { |
92 int flib_netconn_send_password(flib_netconn *conn, const char *passwd) { |
91 int result = -1; |
93 int result = -1; |
92 if(!log_badparams_if(!conn || !passwd)) { |
94 if(!log_badargs_if2(conn==NULL, passwd==NULL)) { |
93 md5_state_t md5state; |
95 md5_state_t md5state; |
94 uint8_t md5bytes[16]; |
96 uint8_t md5bytes[16]; |
95 char md5hex[33]; |
97 char md5hex[33]; |
96 md5_init(&md5state); |
98 md5_init(&md5state); |
97 md5_append(&md5state, (unsigned char*)passwd, strlen(passwd)); |
99 md5_append(&md5state, (unsigned char*)passwd, strlen(passwd)); |
154 flib_team_release(teamcopy); |
156 flib_team_release(teamcopy); |
155 } |
157 } |
156 |
158 |
157 int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) { |
159 int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) { |
158 int result = -1; |
160 int result = -1; |
159 if(!log_badparams_if(!conn || !team)) { |
161 if(!log_badargs_if2(conn==NULL, team==NULL)) { |
160 bool missingInfo = !team->name || !team->grave || !team->fort || !team->voicepack || !team->flag; |
162 bool missingInfo = flib_strempty(team->name) || flib_strempty(team->grave) || flib_strempty(team->fort) || flib_strempty(team->voicepack) || flib_strempty(team->flag); |
161 for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) { |
163 for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) { |
162 missingInfo |= !team->hogs[i].name || !team->hogs[i].hat; |
164 missingInfo |= flib_strempty(team->hogs[i].name) || flib_strempty(team->hogs[i].hat); |
163 } |
165 } |
164 if(!log_e_if(missingInfo, "Incomplete team definition")) { |
166 if(!log_e_if(missingInfo, "Incomplete team definition")) { |
165 flib_vector *vec = flib_vector_create(); |
167 flib_vector *vec = flib_vector_create(); |
166 if(vec) { |
168 if(vec) { |
167 bool error = false; |
169 bool error = false; |
192 return -1; |
194 return -1; |
193 } |
195 } |
194 |
196 |
195 int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) { |
197 int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) { |
196 int result = -1; |
198 int result = -1; |
197 if(!log_badparams_if(!conn || (!message && size>0))) { |
199 if(!log_badargs_if2(conn==NULL, message==NULL && size>0)) { |
198 char *base64encout = NULL; |
200 char *base64encout = NULL; |
199 base64_encode_alloc((const char*)message, size, &base64encout); |
201 base64_encode_alloc((const char*)message, size, &base64encout); |
200 if(base64encout) { |
202 if(base64encout) { |
201 result = flib_netbase_sendf(conn->netBase, "EM\n%s\n\n", base64encout); |
203 result = flib_netbase_sendf(conn->netBase, "EM\n%s\n\n", base64encout); |
202 } |
204 } |
204 } |
206 } |
205 return result; |
207 return result; |
206 } |
208 } |
207 |
209 |
208 int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) { |
210 int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) { |
209 if(!log_badparams_if(!conn || !teamname || hogcount<1 || hogcount>HEDGEHOGS_PER_TEAM) |
211 if(!log_badargs_if4(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM) |
210 && !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) { |
212 && !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) { |
211 if(conn->isChief) { |
213 if(conn->isChief) { |
212 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
214 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
213 if(team) { |
215 if(team) { |
214 team->hogsInGame = hogcount; |
216 team->hogsInGame = hogcount; |
218 } |
220 } |
219 return -1; |
221 return -1; |
220 } |
222 } |
221 |
223 |
222 int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) { |
224 int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) { |
223 if(!log_badparams_if(!conn || !teamname) |
225 if(!log_badargs_if2(conn==NULL, flib_strempty(teamname)) |
224 && !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) { |
226 && !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) { |
225 if(conn->isChief) { |
227 if(conn->isChief) { |
226 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
228 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
227 if(team) { |
229 if(team) { |
228 team->colorIndex = colorIndex; |
230 team->colorIndex = colorIndex; |
232 } |
234 } |
233 return -1; |
235 return -1; |
234 } |
236 } |
235 |
237 |
236 int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) { |
238 int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) { |
237 if(!log_badparams_if(!conn || !weaponset)) { |
239 if(!log_badargs_if3(conn==NULL, weaponset==NULL, flib_strempty(weaponset->name))) { |
238 char ammostring[WEAPONS_COUNT*4+1]; |
240 char ammostring[WEAPONS_COUNT*4+1]; |
239 strcpy(ammostring, weaponset->loadout); |
241 strcpy(ammostring, weaponset->loadout); |
240 strcat(ammostring, weaponset->crateprob); |
242 strcat(ammostring, weaponset->crateprob); |
241 strcat(ammostring, weaponset->delay); |
243 strcat(ammostring, weaponset->delay); |
242 strcat(ammostring, weaponset->crateammo); |
244 strcat(ammostring, weaponset->crateammo); |
346 return -1; |
348 return -1; |
347 } |
349 } |
348 |
350 |
349 int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) { |
351 int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) { |
350 int result = -1; |
352 int result = -1; |
351 if(!log_badparams_if(!conn || (!drawData && size>0) || size>SIZE_MAX/2)) { |
353 if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2)) { |
352 uLongf zippedSize = compressBound(size); |
354 uLongf zippedSize = compressBound(size); |
353 uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header |
355 uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header |
354 if(zipped) { |
356 if(zipped) { |
355 // Create the QCompress size header (uint32 big endian) |
357 // Create the QCompress size header (uint32 big endian) |
356 zipped[0] = (size>>24) & 0xff; |
358 zipped[0] = (size>>24) & 0xff; |
395 return -1; |
397 return -1; |
396 } |
398 } |
397 |
399 |
398 int flib_netconn_send_scheme(flib_netconn *conn, const flib_cfg *scheme) { |
400 int flib_netconn_send_scheme(flib_netconn *conn, const flib_cfg *scheme) { |
399 int result = -1; |
401 int result = -1; |
400 if(!log_badparams_if(!conn || !scheme)) { |
402 if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name))) { |
401 flib_vector *vec = flib_vector_create(); |
403 flib_vector *vec = flib_vector_create(); |
402 if(vec) { |
404 if(vec) { |
403 bool error = false; |
405 bool error = false; |
404 error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name); |
406 error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name); |
405 for(int i=0; i<scheme->meta->modCount; i++) { |
407 for(int i=0; i<scheme->meta->modCount; i++) { |
463 int flib_netconn_send_clearAccountsCache(flib_netconn *conn) { |
465 int flib_netconn_send_clearAccountsCache(flib_netconn *conn) { |
464 return sendVoid(conn, "CLEAR_ACCOUNTS_CACHE"); |
466 return sendVoid(conn, "CLEAR_ACCOUNTS_CACHE"); |
465 } |
467 } |
466 |
468 |
467 int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) { |
469 int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) { |
468 if(log_badparams_if(!conn || !name || !value)) { |
470 if(log_badargs_if3(conn==NULL, flib_strempty(name), flib_strempty(value))) { |
469 return -1; |
471 return -1; |
470 } |
472 } |
471 return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value); |
473 return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value); |
472 } |
474 } |
473 |
475 |