31 #include <string.h> |
31 #include <string.h> |
32 #include <limits.h> |
32 #include <limits.h> |
33 |
33 |
34 // 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. |
35 static int sendVoid(flib_netconn *conn, const char *cmdname) { |
35 static int sendVoid(flib_netconn *conn, const char *cmdname) { |
36 if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { |
36 if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { |
37 return -1; |
37 return -1; |
38 } |
38 } |
39 return flib_netbase_sendf(conn->netBase, "%s\n\n", cmdname); |
39 return flib_netbase_sendf(conn->netBase, "%s\n\n", cmdname); |
40 } |
40 } |
41 |
41 |
42 // 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) |
43 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) { |
44 if(log_e_if(!conn || flib_strempty(str), "Invalid parameter sending %s command", cmdname)) { |
44 if(log_e_if(!conn || flib_strempty(str), "Invalid parameter sending %s command", cmdname)) { |
45 return -1; |
45 return -1; |
46 } |
46 } |
47 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); |
48 } |
48 } |
49 |
49 |
50 static int sendInt(flib_netconn *conn, const char *cmdname, int param) { |
50 static int sendInt(flib_netconn *conn, const char *cmdname, int param) { |
51 if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { |
51 if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { |
52 return -1; |
52 return -1; |
53 } |
53 } |
54 return flib_netbase_sendf(conn->netBase, "%s\n%i\n\n", cmdname, param); |
54 return flib_netbase_sendf(conn->netBase, "%s\n%i\n\n", cmdname, param); |
55 } |
55 } |
56 |
56 |
57 int flib_netconn_send_nick(flib_netconn *conn, const char *nick) { |
57 int flib_netconn_send_nick(flib_netconn *conn, const char *nick) { |
58 int result = -1; |
58 int result = -1; |
59 if(!log_badargs_if2(conn==NULL, flib_strempty(nick))) { |
59 if(!log_badargs_if2(conn==NULL, flib_strempty(nick))) { |
60 char *tmpName = flib_strdupnull(nick); |
60 char *tmpName = flib_strdupnull(nick); |
61 if(tmpName) { |
61 if(tmpName) { |
62 if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) { |
62 if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) { |
63 free(conn->playerName); |
63 free(conn->playerName); |
64 conn->playerName = tmpName; |
64 conn->playerName = tmpName; |
65 tmpName = NULL; |
65 tmpName = NULL; |
66 result = 0; |
66 result = 0; |
67 } |
67 } |
68 } |
68 } |
69 free(tmpName); |
69 free(tmpName); |
70 } |
70 } |
71 return result; |
71 return result; |
72 } |
72 } |
73 |
73 |
74 int flib_netconn_send_password(flib_netconn *conn, const char *passwd) { |
74 int flib_netconn_send_password(flib_netconn *conn, const char *passwd) { |
75 int result = -1; |
75 int result = -1; |
76 if(!log_badargs_if2(conn==NULL, passwd==NULL)) { |
76 if(!log_badargs_if2(conn==NULL, passwd==NULL)) { |
77 md5_state_t md5state; |
77 md5_state_t md5state; |
78 uint8_t md5bytes[16]; |
78 uint8_t md5bytes[16]; |
79 char md5hex[33]; |
79 char md5hex[33]; |
80 md5_init(&md5state); |
80 md5_init(&md5state); |
81 md5_append(&md5state, (unsigned char*)passwd, strlen(passwd)); |
81 md5_append(&md5state, (unsigned char*)passwd, strlen(passwd)); |
82 md5_finish(&md5state, md5bytes); |
82 md5_finish(&md5state, md5bytes); |
83 for(int i=0;i<sizeof(md5bytes); i++) { |
83 for(int i=0;i<sizeof(md5bytes); i++) { |
84 // Needs to be lowercase - server checks case sensitive |
84 // Needs to be lowercase - server checks case sensitive |
85 snprintf(md5hex+i*2, 3, "%02x", (unsigned)md5bytes[i]); |
85 snprintf(md5hex+i*2, 3, "%02x", (unsigned)md5bytes[i]); |
86 } |
86 } |
87 result = flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "PASSWORD", md5hex); |
87 result = flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "PASSWORD", md5hex); |
88 } |
88 } |
89 return result; |
89 return result; |
90 } |
90 } |
91 |
91 |
92 int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) { |
92 int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) { |
93 return sendStr(conn, "QUIT", (quitmsg && *quitmsg) ? quitmsg : "User quit"); |
93 return sendStr(conn, "QUIT", (quitmsg && *quitmsg) ? quitmsg : "User quit"); |
94 } |
94 } |
95 |
95 |
96 int flib_netconn_send_chat(flib_netconn *conn, const char *chat) { |
96 int flib_netconn_send_chat(flib_netconn *conn, const char *chat) { |
97 if(!flib_strempty(chat)) { |
97 if(!flib_strempty(chat)) { |
98 return sendStr(conn, "CHAT", chat); |
98 return sendStr(conn, "CHAT", chat); |
99 } |
99 } |
100 return 0; |
100 return 0; |
101 } |
101 } |
102 |
102 |
103 int flib_netconn_send_kick(flib_netconn *conn, const char *playerName) { |
103 int flib_netconn_send_kick(flib_netconn *conn, const char *playerName) { |
104 return sendStr(conn, "KICK", playerName); |
104 return sendStr(conn, "KICK", playerName); |
105 } |
105 } |
106 |
106 |
107 int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName) { |
107 int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName) { |
108 return sendStr(conn, "INFO", playerName); |
108 return sendStr(conn, "INFO", playerName); |
109 } |
109 } |
110 |
110 |
111 int flib_netconn_send_request_roomlist(flib_netconn *conn) { |
111 int flib_netconn_send_request_roomlist(flib_netconn *conn) { |
112 return sendVoid(conn, "LIST"); |
112 return sendVoid(conn, "LIST"); |
113 } |
113 } |
114 |
114 |
115 int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room) { |
115 int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room) { |
116 if(!sendStr(conn, "JOIN_ROOM", room)) { |
116 if(!sendStr(conn, "JOIN_ROOM", room)) { |
117 conn->isChief = false; |
117 conn->isChief = false; |
118 return 0; |
118 return 0; |
119 } |
119 } |
120 return -1; |
120 return -1; |
121 } |
121 } |
122 |
122 |
123 int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName) { |
123 int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName) { |
124 return sendStr(conn, "FOLLOW", playerName); |
124 return sendStr(conn, "FOLLOW", playerName); |
125 } |
125 } |
126 |
126 |
127 int flib_netconn_send_createRoom(flib_netconn *conn, const char *room) { |
127 int flib_netconn_send_createRoom(flib_netconn *conn, const char *room) { |
128 if(!sendStr(conn, "CREATE_ROOM", room)) { |
128 if(!sendStr(conn, "CREATE_ROOM", room)) { |
129 conn->isChief = true; |
129 conn->isChief = true; |
130 return 0; |
130 return 0; |
131 } |
131 } |
132 return -1; |
132 return -1; |
133 } |
133 } |
134 |
134 |
135 int flib_netconn_send_ban(flib_netconn *conn, const char *playerName) { |
135 int flib_netconn_send_ban(flib_netconn *conn, const char *playerName) { |
136 return sendStr(conn, "BAN", playerName); |
136 return sendStr(conn, "BAN", playerName); |
137 } |
137 } |
138 |
138 |
139 int flib_netconn_send_clearAccountsCache(flib_netconn *conn) { |
139 int flib_netconn_send_clearAccountsCache(flib_netconn *conn) { |
140 return sendVoid(conn, "CLEAR_ACCOUNTS_CACHE"); |
140 return sendVoid(conn, "CLEAR_ACCOUNTS_CACHE"); |
141 } |
141 } |
142 |
142 |
143 int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) { |
143 int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) { |
144 if(log_badargs_if3(conn==NULL, flib_strempty(name), flib_strempty(value))) { |
144 if(log_badargs_if3(conn==NULL, flib_strempty(name), flib_strempty(value))) { |
145 return -1; |
145 return -1; |
146 } |
146 } |
147 return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value); |
147 return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value); |
148 } |
148 } |
149 |
149 |
150 int flib_netconn_send_getServerVars(flib_netconn *conn) { |
150 int flib_netconn_send_getServerVars(flib_netconn *conn) { |
151 return sendVoid(conn, "GET_SERVER_VAR"); |
151 return sendVoid(conn, "GET_SERVER_VAR"); |
152 } |
152 } |
153 int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *str) { |
153 int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *str) { |
154 int result = -1; |
154 int result = -1; |
155 if(conn->netconnState==NETCONN_STATE_ROOM) { |
155 if(conn->netconnState==NETCONN_STATE_ROOM) { |
156 result = (str && *str) ? sendStr(conn, "PART", str) : sendVoid(conn, "PART"); |
156 result = (str && *str) ? sendStr(conn, "PART", str) : sendVoid(conn, "PART"); |
157 if(!result) { |
157 if(!result) { |
158 netconn_leaveRoom(conn); |
158 netconn_leaveRoom(conn); |
159 } |
159 } |
160 } |
160 } |
161 return result; |
161 return result; |
162 } |
162 } |
163 |
163 |
164 int flib_netconn_send_toggleReady(flib_netconn *conn) { |
164 int flib_netconn_send_toggleReady(flib_netconn *conn) { |
165 return sendVoid(conn, "TOGGLE_READY"); |
165 return sendVoid(conn, "TOGGLE_READY"); |
166 } |
166 } |
167 |
167 |
168 static void addTeamToPendingList(flib_netconn *conn, const flib_team *team) { |
168 static void addTeamToPendingList(flib_netconn *conn, const flib_team *team) { |
169 flib_team *teamcopy = flib_team_copy(team); |
169 flib_team *teamcopy = flib_team_copy(team); |
170 if(teamcopy) { |
170 if(teamcopy) { |
171 teamcopy->remoteDriven = false; |
171 teamcopy->remoteDriven = false; |
172 free(teamcopy->ownerName); |
172 free(teamcopy->ownerName); |
173 teamcopy->ownerName = flib_strdupnull(conn->playerName); |
173 teamcopy->ownerName = flib_strdupnull(conn->playerName); |
174 if(teamcopy->ownerName) { |
174 if(teamcopy->ownerName) { |
175 flib_teamlist_delete(&conn->pendingTeamlist, team->name); |
175 flib_teamlist_delete(&conn->pendingTeamlist, team->name); |
176 if(!flib_teamlist_insert(&conn->pendingTeamlist, teamcopy, 0)) { |
176 if(!flib_teamlist_insert(&conn->pendingTeamlist, teamcopy, 0)) { |
177 teamcopy = NULL; |
177 teamcopy = NULL; |
178 } |
178 } |
179 } |
179 } |
180 } |
180 } |
181 flib_team_destroy(teamcopy); |
181 flib_team_destroy(teamcopy); |
182 } |
182 } |
183 |
183 |
184 int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) { |
184 int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) { |
185 int result = -1; |
185 int result = -1; |
186 if(!log_badargs_if2(conn==NULL, team==NULL)) { |
186 if(!log_badargs_if2(conn==NULL, team==NULL)) { |
187 bool missingInfo = flib_strempty(team->name) || flib_strempty(team->grave) || flib_strempty(team->fort) || flib_strempty(team->voicepack) || flib_strempty(team->flag); |
187 bool missingInfo = flib_strempty(team->name) || flib_strempty(team->grave) || flib_strempty(team->fort) || flib_strempty(team->voicepack) || flib_strempty(team->flag); |
188 for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) { |
188 for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) { |
189 missingInfo |= flib_strempty(team->hogs[i].name) || flib_strempty(team->hogs[i].hat); |
189 missingInfo |= flib_strempty(team->hogs[i].name) || flib_strempty(team->hogs[i].hat); |
190 } |
190 } |
191 if(!log_e_if(missingInfo, "Incomplete team definition")) { |
191 if(!log_e_if(missingInfo, "Incomplete team definition")) { |
192 flib_vector *vec = flib_vector_create(); |
192 flib_vector *vec = flib_vector_create(); |
193 if(vec) { |
193 if(vec) { |
194 bool error = false; |
194 bool error = false; |
195 error |= flib_vector_appendf(vec, "ADD_TEAM\n%s\n%i\n%s\n%s\n%s\n%s\n%i\n", team->name, team->colorIndex, team->grave, team->fort, team->voicepack, team->flag, team->hogs[0].difficulty); |
195 error |= flib_vector_appendf(vec, "ADD_TEAM\n%s\n%i\n%s\n%s\n%s\n%s\n%i\n", team->name, team->colorIndex, team->grave, team->fort, team->voicepack, team->flag, team->hogs[0].difficulty); |
196 for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) { |
196 for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) { |
197 error |= flib_vector_appendf(vec, "%s\n%s\n", team->hogs[i].name, team->hogs[i].hat); |
197 error |= flib_vector_appendf(vec, "%s\n%s\n", team->hogs[i].name, team->hogs[i].hat); |
198 } |
198 } |
199 error |= flib_vector_appendf(vec, "\n"); |
199 error |= flib_vector_appendf(vec, "\n"); |
200 if(!error && !flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec))) { |
200 if(!error && !flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec))) { |
201 addTeamToPendingList(conn, team); |
201 addTeamToPendingList(conn, team); |
202 result = 0; |
202 result = 0; |
203 } |
203 } |
204 } |
204 } |
205 flib_vector_destroy(vec); |
205 flib_vector_destroy(vec); |
206 } |
206 } |
207 } |
207 } |
208 return result; |
208 return result; |
209 } |
209 } |
210 |
210 |
211 int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname) { |
211 int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname) { |
212 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
212 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
213 if(team && !team->remoteDriven && !sendStr(conn, "REMOVE_TEAM", teamname)) { |
213 if(team && !team->remoteDriven && !sendStr(conn, "REMOVE_TEAM", teamname)) { |
214 flib_teamlist_delete(&conn->teamlist, teamname); |
214 flib_teamlist_delete(&conn->teamlist, teamname); |
215 return 0; |
215 return 0; |
216 } |
216 } |
217 return -1; |
217 return -1; |
218 } |
218 } |
219 |
219 |
220 int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName) { |
220 int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName) { |
221 return sendStr(conn, "ROOM_NAME", roomName); |
221 return sendStr(conn, "ROOM_NAME", roomName); |
222 } |
222 } |
223 |
223 |
224 int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) { |
224 int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) { |
225 if(!log_badargs_if5(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM, !conn->isChief) |
225 if(!log_badargs_if5(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM, !conn->isChief) |
226 && !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) { |
226 && !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) { |
227 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
227 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
228 if(team) { |
228 if(team) { |
229 team->hogsInGame = hogcount; |
229 team->hogsInGame = hogcount; |
230 } |
230 } |
231 return 0; |
231 return 0; |
232 } |
232 } |
233 return -1; |
233 return -1; |
234 } |
234 } |
235 |
235 |
236 int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) { |
236 int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) { |
237 if(!log_badargs_if3(conn==NULL, flib_strempty(teamname), !conn->isChief) |
237 if(!log_badargs_if3(conn==NULL, flib_strempty(teamname), !conn->isChief) |
238 && !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) { |
238 && !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) { |
239 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
239 flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); |
240 if(team) { |
240 if(team) { |
241 team->colorIndex = colorIndex; |
241 team->colorIndex = colorIndex; |
242 } |
242 } |
243 return 0; |
243 return 0; |
244 } |
244 } |
245 return -1; |
245 return -1; |
246 } |
246 } |
247 |
247 |
248 int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) { |
248 int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) { |
249 if(!log_badargs_if3(conn==NULL, weaponset==NULL, flib_strempty(weaponset->name))) { |
249 if(!log_badargs_if3(conn==NULL, weaponset==NULL, flib_strempty(weaponset->name))) { |
250 char ammostring[WEAPONS_COUNT*4+1]; |
250 char ammostring[WEAPONS_COUNT*4+1]; |
251 strcpy(ammostring, weaponset->loadout); |
251 strcpy(ammostring, weaponset->loadout); |
252 strcat(ammostring, weaponset->crateprob); |
252 strcat(ammostring, weaponset->crateprob); |
253 strcat(ammostring, weaponset->delay); |
253 strcat(ammostring, weaponset->delay); |
254 strcat(ammostring, weaponset->crateammo); |
254 strcat(ammostring, weaponset->crateammo); |
255 if(conn->isChief) { |
255 if(conn->isChief) { |
256 if(!flib_netbase_sendf(conn->netBase, "CFG\nAMMO\n%s\n%s\n\n", weaponset->name, ammostring)) { |
256 if(!flib_netbase_sendf(conn->netBase, "CFG\nAMMO\n%s\n%s\n\n", weaponset->name, ammostring)) { |
257 netconn_setWeaponset(conn, weaponset); |
257 netconn_setWeaponset(conn, weaponset); |
258 return 0; |
258 return 0; |
259 } |
259 } |
260 } |
260 } |
261 } |
261 } |
262 return -1; |
262 return -1; |
263 } |
263 } |
264 |
264 |
265 int flib_netconn_send_map(flib_netconn *conn, const flib_map *map) { |
265 int flib_netconn_send_map(flib_netconn *conn, const flib_map *map) { |
266 if(log_badargs_if2(conn==NULL, map==NULL)) { |
266 if(log_badargs_if2(conn==NULL, map==NULL)) { |
267 return -1; |
267 return -1; |
268 } |
268 } |
269 bool error = false; |
269 bool error = false; |
270 |
270 |
271 if(map->seed) { |
271 if(map->seed) { |
272 error |= flib_netconn_send_mapSeed(conn, map->seed); |
272 error |= flib_netconn_send_mapSeed(conn, map->seed); |
273 } |
273 } |
274 error |= flib_netconn_send_mapTemplate(conn, map->templateFilter); |
274 error |= flib_netconn_send_mapTemplate(conn, map->templateFilter); |
275 if(map->theme) { |
275 if(map->theme) { |
276 error |= flib_netconn_send_mapTheme(conn, map->theme); |
276 error |= flib_netconn_send_mapTheme(conn, map->theme); |
277 } |
277 } |
278 error |= flib_netconn_send_mapGen(conn, map->mapgen); |
278 error |= flib_netconn_send_mapGen(conn, map->mapgen); |
279 error |= flib_netconn_send_mapMazeSize(conn, map->mazeSize); |
279 error |= flib_netconn_send_mapMazeSize(conn, map->mazeSize); |
280 if(map->drawData && map->drawDataSize>0) { |
280 if(map->drawData && map->drawDataSize>0) { |
281 error |= flib_netconn_send_mapDrawdata(conn, map->drawData, map->drawDataSize); |
281 error |= flib_netconn_send_mapDrawdata(conn, map->drawData, map->drawDataSize); |
282 } |
282 } |
283 // Name is sent last, because the QtFrontend uses this to update its preview, and to show/hide |
283 // Name is sent last, because the QtFrontend uses this to update its preview, and to show/hide |
284 // certain fields |
284 // certain fields |
285 if(map->name) { |
285 if(map->name) { |
286 error |= flib_netconn_send_mapName(conn, map->name); |
286 error |= flib_netconn_send_mapName(conn, map->name); |
287 } |
287 } |
288 return error; |
288 return error; |
289 } |
289 } |
290 |
290 |
291 int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName) { |
291 int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName) { |
292 if(log_badargs_if2(conn==NULL, mapName==NULL)) { |
292 if(log_badargs_if2(conn==NULL, mapName==NULL)) { |
293 return -1; |
293 return -1; |
294 } |
294 } |
295 if(conn->isChief) { |
295 if(conn->isChief) { |
296 if(!sendStr(conn, "CFG\nMAP", mapName)) { |
296 if(!sendStr(conn, "CFG\nMAP", mapName)) { |
297 char *copy = flib_strdupnull(mapName); |
297 char *copy = flib_strdupnull(mapName); |
298 if(copy) { |
298 if(copy) { |
299 free(conn->map->name); |
299 free(conn->map->name); |
300 conn->map->name = copy; |
300 conn->map->name = copy; |
301 return 0; |
301 return 0; |
302 } |
302 } |
303 } |
303 } |
304 } |
304 } |
305 return -1; |
305 return -1; |
306 } |
306 } |
307 |
307 |
308 int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen) { |
308 int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen) { |
309 if(log_badargs_if(conn==NULL)) { |
309 if(log_badargs_if(conn==NULL)) { |
310 return -1; |
310 return -1; |
311 } |
311 } |
312 if(conn->isChief) { |
312 if(conn->isChief) { |
313 if(!sendInt(conn, "CFG\nMAPGEN", mapGen)) { |
313 if(!sendInt(conn, "CFG\nMAPGEN", mapGen)) { |
314 conn->map->mapgen = mapGen; |
314 conn->map->mapgen = mapGen; |
315 return 0; |
315 return 0; |
316 } |
316 } |
317 } |
317 } |
318 return -1; |
318 return -1; |
319 } |
319 } |
320 |
320 |
321 int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter) { |
321 int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter) { |
322 if(log_badargs_if(conn==NULL)) { |
322 if(log_badargs_if(conn==NULL)) { |
323 return -1; |
323 return -1; |
324 } |
324 } |
325 if(conn->isChief) { |
325 if(conn->isChief) { |
326 if(!sendInt(conn, "CFG\nTEMPLATE", templateFilter)) { |
326 if(!sendInt(conn, "CFG\nTEMPLATE", templateFilter)) { |
327 conn->map->templateFilter = templateFilter; |
327 conn->map->templateFilter = templateFilter; |
328 return 0; |
328 return 0; |
329 } |
329 } |
330 } |
330 } |
331 return -1; |
331 return -1; |
332 } |
332 } |
333 |
333 |
334 int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize) { |
334 int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize) { |
335 if(log_badargs_if(conn==NULL)) { |
335 if(log_badargs_if(conn==NULL)) { |
336 return -1; |
336 return -1; |
337 } |
337 } |
338 if(conn->isChief) { |
338 if(conn->isChief) { |
339 if(!sendInt(conn, "CFG\nMAZE_SIZE", mazeSize)) { |
339 if(!sendInt(conn, "CFG\nMAZE_SIZE", mazeSize)) { |
340 conn->map->mazeSize = mazeSize; |
340 conn->map->mazeSize = mazeSize; |
341 return 0; |
341 return 0; |
342 } |
342 } |
343 } |
343 } |
344 return -1; |
344 return -1; |
345 } |
345 } |
346 |
346 |
347 int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed) { |
347 int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed) { |
348 if(log_badargs_if2(conn==NULL, seed==NULL)) { |
348 if(log_badargs_if2(conn==NULL, seed==NULL)) { |
349 return -1; |
349 return -1; |
350 } |
350 } |
351 if(conn->isChief) { |
351 if(conn->isChief) { |
352 if(!sendStr(conn, "CFG\nSEED", seed)) { |
352 if(!sendStr(conn, "CFG\nSEED", seed)) { |
353 char *copy = flib_strdupnull(seed); |
353 char *copy = flib_strdupnull(seed); |
354 if(copy) { |
354 if(copy) { |
355 free(conn->map->seed); |
355 free(conn->map->seed); |
356 conn->map->seed = copy; |
356 conn->map->seed = copy; |
357 return 0; |
357 return 0; |
358 } |
358 } |
359 } |
359 } |
360 } |
360 } |
361 return -1; |
361 return -1; |
362 } |
362 } |
363 |
363 |
364 int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme) { |
364 int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme) { |
365 if(log_badargs_if2(conn==NULL, theme==NULL)) { |
365 if(log_badargs_if2(conn==NULL, theme==NULL)) { |
366 return -1; |
366 return -1; |
367 } |
367 } |
368 if(conn->isChief) { |
368 if(conn->isChief) { |
369 if(!sendStr(conn, "CFG\nTHEME", theme)) { |
369 if(!sendStr(conn, "CFG\nTHEME", theme)) { |
370 char *copy = flib_strdupnull(theme); |
370 char *copy = flib_strdupnull(theme); |
371 if(copy) { |
371 if(copy) { |
372 free(conn->map->theme); |
372 free(conn->map->theme); |
373 conn->map->theme = copy; |
373 conn->map->theme = copy; |
374 return 0; |
374 return 0; |
375 } |
375 } |
376 } |
376 } |
377 } |
377 } |
378 return -1; |
378 return -1; |
379 } |
379 } |
380 |
380 |
381 int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) { |
381 int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) { |
382 int result = -1; |
382 int result = -1; |
383 if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2) && conn->isChief) { |
383 if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2) && conn->isChief) { |
384 uLongf zippedSize = compressBound(size); |
384 uLongf zippedSize = compressBound(size); |
385 uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header |
385 uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header |
386 if(zipped) { |
386 if(zipped) { |
387 // Create the QCompress size header (uint32 big endian) |
387 // Create the QCompress size header (uint32 big endian) |
388 zipped[0] = (size>>24) & 0xff; |
388 zipped[0] = (size>>24) & 0xff; |
389 zipped[1] = (size>>16) & 0xff; |
389 zipped[1] = (size>>16) & 0xff; |
390 zipped[2] = (size>>8) & 0xff; |
390 zipped[2] = (size>>8) & 0xff; |
391 zipped[3] = (size) & 0xff; |
391 zipped[3] = (size) & 0xff; |
392 |
392 |
393 if(compress(zipped+4, &zippedSize, drawData, size) != Z_OK) { |
393 if(compress(zipped+4, &zippedSize, drawData, size) != Z_OK) { |
394 flib_log_e("Error compressing drawn map data."); |
394 flib_log_e("Error compressing drawn map data."); |
395 } else { |
395 } else { |
396 char *base64encout = NULL; |
396 char *base64encout = NULL; |
397 base64_encode_alloc((const char*)zipped, zippedSize+4, &base64encout); |
397 base64_encode_alloc((const char*)zipped, zippedSize+4, &base64encout); |
398 if(!base64encout) { |
398 if(!base64encout) { |
399 flib_log_e("Error base64-encoding drawn map data."); |
399 flib_log_e("Error base64-encoding drawn map data."); |
400 } else { |
400 } else { |
401 result = flib_netbase_sendf(conn->netBase, "CFG\nDRAWNMAP\n%s\n\n", base64encout); |
401 result = flib_netbase_sendf(conn->netBase, "CFG\nDRAWNMAP\n%s\n\n", base64encout); |
402 } |
402 } |
403 free(base64encout); |
403 free(base64encout); |
404 } |
404 } |
405 } |
405 } |
406 free(zipped); |
406 free(zipped); |
407 } |
407 } |
408 |
408 |
409 if(!result) { |
409 if(!result) { |
410 uint8_t *copy = flib_bufdupnull(drawData, size); |
410 uint8_t *copy = flib_bufdupnull(drawData, size); |
411 if(copy) { |
411 if(copy) { |
412 free(conn->map->drawData); |
412 free(conn->map->drawData); |
413 conn->map->drawData = copy; |
413 conn->map->drawData = copy; |
414 conn->map->drawDataSize = size; |
414 conn->map->drawDataSize = size; |
415 } |
415 } |
416 } |
416 } |
417 return result; |
417 return result; |
418 } |
418 } |
419 |
419 |
420 int flib_netconn_send_script(flib_netconn *conn, const char *scriptName) { |
420 int flib_netconn_send_script(flib_netconn *conn, const char *scriptName) { |
421 if(log_badargs_if2(conn==NULL, scriptName==NULL)) { |
421 if(log_badargs_if2(conn==NULL, scriptName==NULL)) { |
422 return -1; |
422 return -1; |
423 } |
423 } |
424 if(conn->isChief) { |
424 if(conn->isChief) { |
425 if(!sendStr(conn, "CFG\nSCRIPT", scriptName)) { |
425 if(!sendStr(conn, "CFG\nSCRIPT", scriptName)) { |
426 netconn_setScript(conn, scriptName); |
426 netconn_setScript(conn, scriptName); |
427 return 0; |
427 return 0; |
428 } |
428 } |
429 } |
429 } |
430 return -1; |
430 return -1; |
431 } |
431 } |
432 |
432 |
433 int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme) { |
433 int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme) { |
434 int result = -1; |
434 int result = -1; |
435 if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name)) && conn->isChief) { |
435 if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name)) && conn->isChief) { |
436 flib_vector *vec = flib_vector_create(); |
436 flib_vector *vec = flib_vector_create(); |
437 if(vec) { |
437 if(vec) { |
438 bool error = false; |
438 bool error = false; |
439 error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name); |
439 error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name); |
440 for(int i=0; i<flib_meta.modCount; i++) { |
440 for(int i=0; i<flib_meta.modCount; i++) { |
441 error |= flib_vector_appendf(vec, "%s\n", scheme->mods[i] ? "true" : "false"); |
441 error |= flib_vector_appendf(vec, "%s\n", scheme->mods[i] ? "true" : "false"); |
442 } |
442 } |
443 for(int i=0; i<flib_meta.settingCount; i++) { |
443 for(int i=0; i<flib_meta.settingCount; i++) { |
444 error |= flib_vector_appendf(vec, "%i\n", scheme->settings[i]); |
444 error |= flib_vector_appendf(vec, "%i\n", scheme->settings[i]); |
445 } |
445 } |
446 error |= flib_vector_appendf(vec, "\n"); |
446 error |= flib_vector_appendf(vec, "\n"); |
447 if(!error) { |
447 if(!error) { |
448 result = flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec)); |
448 result = flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec)); |
449 } |
449 } |
450 } |
450 } |
451 flib_vector_destroy(vec); |
451 flib_vector_destroy(vec); |
452 } |
452 } |
453 |
453 |
454 if(!result) { |
454 if(!result) { |
455 netconn_setScheme(conn, scheme); |
455 netconn_setScheme(conn, scheme); |
456 } |
456 } |
457 return result; |
457 return result; |
458 } |
458 } |
459 |
459 |
460 int flib_netconn_send_startGame(flib_netconn *conn) { |
460 int flib_netconn_send_startGame(flib_netconn *conn) { |
461 return sendVoid(conn, "START_GAME"); |
461 return sendVoid(conn, "START_GAME"); |
462 } |
462 } |
463 |
463 |
464 int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn) { |
464 int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn) { |
465 return sendVoid(conn, "TOGGLE_RESTRICT_JOINS"); |
465 return sendVoid(conn, "TOGGLE_RESTRICT_JOINS"); |
466 } |
466 } |
467 |
467 |
468 int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn) { |
468 int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn) { |
469 return sendVoid(conn, "TOGGLE_RESTRICT_TEAMS"); |
469 return sendVoid(conn, "TOGGLE_RESTRICT_TEAMS"); |
470 } |
470 } |
471 |
471 |
472 int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) { |
472 int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) { |
473 if(!flib_strempty(chat)) { |
473 if(!flib_strempty(chat)) { |
474 return sendStr(conn, "TEAMCHAT", chat); |
474 return sendStr(conn, "TEAMCHAT", chat); |
475 } |
475 } |
476 return 0; |
476 return 0; |
477 } |
477 } |
478 |
478 |
479 int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) { |
479 int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) { |
480 int result = -1; |
480 int result = -1; |
481 if(!log_badargs_if2(conn==NULL, message==NULL && size>0)) { |
481 if(!log_badargs_if2(conn==NULL, message==NULL && size>0)) { |
482 char *base64encout = NULL; |
482 char *base64encout = NULL; |
483 base64_encode_alloc((const char*)message, size, &base64encout); |
483 base64_encode_alloc((const char*)message, size, &base64encout); |
484 if(base64encout) { |
484 if(base64encout) { |
485 result = flib_netbase_sendf(conn->netBase, "EM\n%s\n\n", base64encout); |
485 result = flib_netbase_sendf(conn->netBase, "EM\n%s\n\n", base64encout); |
486 } |
486 } |
487 free(base64encout); |
487 free(base64encout); |
488 } |
488 } |
489 return result; |
489 return result; |
490 } |
490 } |
491 |
491 |
492 int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError) { |
492 int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError) { |
493 return sendInt(conn, "ROUNDFINISHED", withoutError ? 1 : 0); |
493 return sendInt(conn, "ROUNDFINISHED", withoutError ? 1 : 0); |
494 } |
494 } |
495 |
495 |