82 conn->onEngineMessageCb = &defaultCallback_onEngineMessage; |
82 conn->onEngineMessageCb = &defaultCallback_onEngineMessage; |
83 } |
83 } |
84 |
84 |
85 static flib_gameconn *flib_gameconn_create_partial(bool record, const char *playerName, bool netGame) { |
85 static flib_gameconn *flib_gameconn_create_partial(bool record, const char *playerName, bool netGame) { |
86 flib_gameconn *result = NULL; |
86 flib_gameconn *result = NULL; |
87 if(!log_badparams_if(!playerName)) { |
87 flib_gameconn *tempConn = flib_calloc(1, sizeof(flib_gameconn)); |
88 flib_gameconn *tempConn = flib_calloc(1, sizeof(flib_gameconn)); |
88 if(tempConn) { |
89 if(tempConn) { |
89 tempConn->ipcBase = flib_ipcbase_create(); |
90 tempConn->ipcBase = flib_ipcbase_create(); |
90 tempConn->configBuffer = flib_vector_create(); |
91 tempConn->configBuffer = flib_vector_create(); |
91 tempConn->playerName = flib_strdupnull(playerName); |
92 tempConn->playerName = flib_strdupnull(playerName); |
92 if(tempConn->ipcBase && tempConn->configBuffer && tempConn->playerName) { |
93 if(tempConn->ipcBase && tempConn->configBuffer && tempConn->playerName) { |
93 if(record) { |
94 if(record) { |
94 tempConn->demoBuffer = flib_vector_create(); |
95 tempConn->demoBuffer = flib_vector_create(); |
|
96 } |
|
97 tempConn->state = AWAIT_CONNECTION; |
|
98 tempConn->netgame = netGame; |
|
99 clearCallbacks(tempConn); |
|
100 result = tempConn; |
|
101 tempConn = NULL; |
|
102 } |
95 } |
103 } |
96 tempConn->state = AWAIT_CONNECTION; |
104 flib_gameconn_destroy(tempConn); |
97 tempConn->netgame = netGame; |
105 } |
98 clearCallbacks(tempConn); |
|
99 result = tempConn; |
|
100 tempConn = NULL; |
|
101 } |
|
102 } |
|
103 flib_gameconn_destroy(tempConn); |
106 return result; |
104 return result; |
107 } |
105 } |
108 |
106 |
109 flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame) { |
107 flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame) { |
|
108 if(log_badargs_if2(playerName==NULL, setup==NULL)) { |
|
109 return NULL; |
|
110 } |
110 flib_gameconn *result = NULL; |
111 flib_gameconn *result = NULL; |
111 flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, netgame); |
112 flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, netgame); |
112 if(tempConn) { |
113 if(tempConn) { |
113 if(flib_ipc_append_fullconfig(tempConn->configBuffer, setup, netgame)) { |
114 if(flib_ipc_append_fullconfig(tempConn->configBuffer, setup, netgame)) { |
114 flib_log_e("Error generating full game configuration for the engine."); |
115 flib_log_e("Error generating full game configuration for the engine."); |
233 msgStart += (uint8_t)data[msgStart]+1; |
243 msgStart += (uint8_t)data[msgStart]+1; |
234 } |
244 } |
235 } |
245 } |
236 |
246 |
237 int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len) { |
247 int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len) { |
238 int result = -1; |
248 if(log_badargs_if2(conn==NULL, data==NULL && len>0)) { |
239 if(!log_badparams_if(!conn || (!data && len>0)) |
249 return -1; |
240 && !flib_ipcbase_send_raw(conn->ipcBase, data, len)) { |
250 } |
|
251 int result = flib_ipcbase_send_raw(conn->ipcBase, data, len); |
|
252 if(!result) { |
241 demo_append(conn, data, len); |
253 demo_append(conn, data, len); |
242 result = 0; |
|
243 } |
254 } |
244 return result; |
255 return result; |
245 } |
256 } |
246 |
257 |
247 int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg) { |
258 int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg) { |
248 int result = -1; |
259 if(log_badargs_if2(conn==NULL, msg==NULL)) { |
249 if(!conn || !msg) { |
260 return -1; |
250 flib_log_e("null parameter in flib_gameconn_send_textmsg"); |
261 } |
251 } else { |
|
252 uint8_t converted[257]; |
|
253 int size = snprintf((char*)converted+1, 256, "s%c%s", (char)msgtype, msg); |
|
254 if(size>0) { |
|
255 converted[0] = size>255 ? 255 : size; |
|
256 if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { |
|
257 demo_append(conn, converted, converted[0]+1); |
|
258 result = 0; |
|
259 } |
|
260 } |
|
261 } |
|
262 return result; |
|
263 } |
|
264 |
|
265 int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg) { |
|
266 int result = -1; |
262 int result = -1; |
267 uint8_t converted[257]; |
263 uint8_t converted[257]; |
268 if(!conn || !playername || !msg) { |
264 int size = snprintf((char*)converted+1, 256, "s%c%s", (char)msgtype, msg); |
269 flib_log_e("null parameter in flib_gameconn_send_chatmsg"); |
265 if(size>0) { |
270 } else if(format_chatmessage(converted, playername, msg)) { |
266 converted[0] = size>255 ? 255 : size; |
271 flib_log_e("Error formatting message in flib_gameconn_send_chatmsg"); |
267 if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { |
272 } else if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { |
268 demo_append(conn, converted, converted[0]+1); |
|
269 result = 0; |
|
270 } |
|
271 } |
|
272 return result; |
|
273 } |
|
274 |
|
275 int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg) { |
|
276 if(log_badargs_if3(conn==NULL, playername==NULL, msg==NULL)) { |
|
277 return -1; |
|
278 } |
|
279 uint8_t converted[257]; |
|
280 if(!format_chatmessage(converted, playername, msg) |
|
281 && !flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { |
273 demo_append(conn, converted, converted[0]+1); |
282 demo_append(conn, converted, converted[0]+1); |
274 result = 0; |
283 return 0; |
275 } |
284 } |
276 return result; |
285 return -1; |
277 } |
286 } |
278 |
287 |
279 void flib_gameconn_onConnect(flib_gameconn *conn, void (*callback)(void* context), void* context) { |
288 /** |
280 if(!conn) { |
289 * This macro generates a callback setter function. It uses the name of the callback to |
281 flib_log_e("null parameter in flib_gameconn_onConnect"); |
290 * automatically generate the function name and the fields to set, so a consistent naming |
282 } else { |
291 * convention needs to be enforced (not that that is a bad thing). If null is passed as |
283 conn->onConnectCb = callback ? callback : &defaultCallback_onConnect; |
292 * callback to the generated function, the defaultCb will be set instead (with conn |
284 conn->onConnectCtx = context; |
293 * as the context). |
285 } |
294 */ |
286 } |
295 #define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ |
287 |
296 void flib_gameconn_##cbName(flib_gameconn *conn, void (*callback)cbParameterTypes, void *context) { \ |
288 void flib_gameconn_onDisconnect(flib_gameconn *conn, void (*callback)(void* context, int reason), void* context) { |
297 if(!log_badargs_if(conn==NULL)) { \ |
289 if(!conn) { |
298 conn->cbName##Cb = callback ? callback : &defaultCb; \ |
290 flib_log_e("null parameter in flib_gameconn_onDisconnect"); |
299 conn->cbName##Ctx = callback ? context : conn; \ |
291 } else { |
300 } \ |
292 conn->onDisconnectCb = callback ? callback : &defaultCallback_onDisconnect; |
301 } |
293 conn->onDisconnectCtx = context; |
302 |
294 } |
303 /** |
295 } |
304 * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a |
296 |
305 * no-op callback function as well that is used as default. |
297 void flib_gameconn_onErrorMessage(flib_gameconn *conn, void (*callback)(void* context, const char *msg), void* context) { |
306 */ |
298 if(!conn) { |
307 #define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ |
299 flib_log_e("null parameter in flib_gameconn_onErrorMessage"); |
308 static void _noop_callback_##cbName cbParameterTypes {} \ |
300 } else { |
309 GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) |
301 conn->onErrorMessageCb = callback ? callback : &defaultCallback_onErrorMessage; |
310 |
302 conn->onErrorMessageCtx = context; |
311 GENERATE_CB_SETTER_AND_DEFAULT(onConnect, (void *context)); |
303 } |
312 GENERATE_CB_SETTER_AND_DEFAULT(onDisconnect, (void* context, int reason)); |
304 } |
313 GENERATE_CB_SETTER(onErrorMessage, (void* context, const char *msg), defaultCallback_onErrorMessage); |
305 |
314 GENERATE_CB_SETTER_AND_DEFAULT(onChat, (void* context, const char *msg, bool teamchat)); |
306 void flib_gameconn_onChat(flib_gameconn *conn, void (*callback)(void* context, const char *msg, bool teamchat), void* context) { |
315 GENERATE_CB_SETTER_AND_DEFAULT(onGameRecorded, (void *context, const uint8_t *record, int size, bool isSavegame)); |
307 if(!conn) { |
316 GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *em, size_t size)); |
308 flib_log_e("null parameter in flib_gameconn_onChat"); |
317 |
309 } else { |
318 #undef GENERATE_CB_SETTER_AND_DEFAULT |
310 conn->onChatCb = callback ? callback : &defaultCallback_onChat; |
319 #undef GENERATE_CB_SETTER |
311 conn->onChatCtx = context; |
|
312 } |
|
313 } |
|
314 |
|
315 void flib_gameconn_onGameRecorded(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *record, int size, bool isSavegame), void* context) { |
|
316 if(!conn) { |
|
317 flib_log_e("null parameter in flib_gameconn_onGameRecorded"); |
|
318 } else { |
|
319 conn->onGameRecordedCb = callback ? callback : &defaultCallback_onGameRecorded; |
|
320 conn->onGameRecordedCtx = context; |
|
321 } |
|
322 } |
|
323 |
|
324 void flib_gameconn_onEngineMessage(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *em, size_t size), void* context) { |
|
325 if(!conn) { |
|
326 flib_log_e("null parameter in flib_gameconn_onEngineMessage"); |
|
327 } else { |
|
328 conn->onEngineMessageCb = callback ? callback : &defaultCallback_onEngineMessage; |
|
329 conn->onEngineMessageCtx = context; |
|
330 } |
|
331 } |
|
332 |
320 |
333 static void flib_gameconn_wrappedtick(flib_gameconn *conn) { |
321 static void flib_gameconn_wrappedtick(flib_gameconn *conn) { |
334 if(conn->state == AWAIT_CONNECTION) { |
322 if(conn->state == AWAIT_CONNECTION) { |
335 flib_ipcbase_accept(conn->ipcBase); |
323 flib_ipcbase_accept(conn->ipcBase); |
336 switch(flib_ipcbase_state(conn->ipcBase)) { |
324 switch(flib_ipcbase_state(conn->ipcBase)) { |