|
1 #include "netconn_internal.h" |
|
2 |
|
3 #include "../util/logging.h" |
|
4 #include "../util/util.h" |
|
5 |
|
6 #include <string.h> |
|
7 #include <stdlib.h> |
|
8 #include <ctype.h> |
|
9 |
|
10 static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { |
|
11 flib_log_i("Net: [%i] %s", msgtype, msg); |
|
12 } |
|
13 |
|
14 static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { |
|
15 flib_log_i("%s: %s", nick, msg); |
|
16 } |
|
17 |
|
18 // Change the name by suffixing it with a number. If it already ends in a number, increase that number by 1. |
|
19 static void defaultCallback_onNickTaken(void *context, const char *requestedNick) { |
|
20 flib_netconn *conn = context; |
|
21 size_t namelen = strlen(requestedNick); |
|
22 int digits = 0; |
|
23 while(digits<namelen && isdigit(requestedNick[namelen-1-digits])) { |
|
24 digits++; |
|
25 } |
|
26 long suffix = 0; |
|
27 if(digits>0) { |
|
28 suffix = atol(requestedNick+namelen-digits)+1; |
|
29 } |
|
30 char *newPlayerName = flib_asprintf("%.*s%li", namelen-digits, requestedNick, suffix); |
|
31 if(newPlayerName) { |
|
32 flib_netconn_send_nick(conn, newPlayerName); |
|
33 } else { |
|
34 flib_netconn_send_quit(conn, "Nick already taken."); |
|
35 } |
|
36 free(newPlayerName); |
|
37 } |
|
38 |
|
39 // Default behavior: Quit |
|
40 static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { |
|
41 flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); |
|
42 } |
|
43 |
|
44 void clearCallbacks(flib_netconn *conn) { |
|
45 flib_netconn_onMessage(conn, NULL, NULL); |
|
46 flib_netconn_onConnected(conn, NULL, NULL); |
|
47 flib_netconn_onDisconnected(conn, NULL, NULL); |
|
48 flib_netconn_onRoomAdd(conn, NULL, NULL); |
|
49 flib_netconn_onRoomDelete(conn, NULL, NULL); |
|
50 flib_netconn_onRoomUpdate(conn, NULL, NULL); |
|
51 flib_netconn_onChat(conn, NULL, NULL); |
|
52 flib_netconn_onLobbyJoin(conn, NULL, NULL); |
|
53 flib_netconn_onLobbyLeave(conn, NULL, NULL); |
|
54 flib_netconn_onRoomJoin(conn, NULL, NULL); |
|
55 flib_netconn_onRoomLeave(conn, NULL, NULL); |
|
56 flib_netconn_onNickTaken(conn, NULL, NULL); |
|
57 flib_netconn_onPasswordRequest(conn, NULL, NULL); |
|
58 flib_netconn_onRoomChiefStatus(conn, NULL, NULL); |
|
59 flib_netconn_onReadyState(conn, NULL, NULL); |
|
60 flib_netconn_onEnterRoom(conn, NULL, NULL); |
|
61 flib_netconn_onLeaveRoom(conn, NULL, NULL); |
|
62 flib_netconn_onTeamAdd(conn, NULL, NULL); |
|
63 flib_netconn_onTeamDelete(conn, NULL, NULL); |
|
64 flib_netconn_onRunGame(conn, NULL, NULL); |
|
65 flib_netconn_onTeamAccepted(conn, NULL, NULL); |
|
66 flib_netconn_onHogCountChanged(conn, NULL, NULL); |
|
67 flib_netconn_onTeamColorChanged(conn, NULL, NULL); |
|
68 flib_netconn_onEngineMessage(conn, NULL, NULL); |
|
69 flib_netconn_onCfgScheme(conn, NULL, NULL); |
|
70 flib_netconn_onMapChanged(conn, NULL, NULL); |
|
71 flib_netconn_onScriptChanged(conn, NULL, NULL); |
|
72 flib_netconn_onWeaponsetChanged(conn, NULL, NULL); |
|
73 flib_netconn_onAdminAccess(conn, NULL, NULL); |
|
74 flib_netconn_onServerVar(conn, NULL, NULL); |
|
75 } |
|
76 |
|
77 /** |
|
78 * This macro generates a callback setter function. It uses the name of the callback to |
|
79 * automatically generate the function name and the fields to set, so a consistent naming |
|
80 * convention needs to be enforced (not that that is a bad thing). If null is passed as |
|
81 * callback to the generated function, the defaultCb will be set instead (with conn |
|
82 * as the context). |
|
83 */ |
|
84 #define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ |
|
85 void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \ |
|
86 if(!conn) { \ |
|
87 flib_log_e("null parameter in flib_netconn_%s", #cbName); \ |
|
88 } else { \ |
|
89 conn->cbName##Cb = callback ? callback : &defaultCb; \ |
|
90 conn->cbName##Ctx = callback ? context : conn; \ |
|
91 } \ |
|
92 } |
|
93 |
|
94 /** |
|
95 * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a |
|
96 * no-op callback function as well that is used as default. |
|
97 */ |
|
98 #define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ |
|
99 static void _noop_callback_##cbName cbParameterTypes {} \ |
|
100 GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) |
|
101 |
|
102 GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage); |
|
103 GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context)); |
|
104 GENERATE_CB_SETTER_AND_DEFAULT(onDisconnected, (void *context, int reason, const char *message)); |
|
105 GENERATE_CB_SETTER_AND_DEFAULT(onRoomAdd, (void *context, const flib_roomlist_room *room)); |
|
106 GENERATE_CB_SETTER_AND_DEFAULT(onRoomDelete, (void *context, const char *name)); |
|
107 GENERATE_CB_SETTER_AND_DEFAULT(onRoomUpdate, (void *context, const char *oldName, const flib_roomlist_room *room)); |
|
108 GENERATE_CB_SETTER(onChat, (void *context, const char *nick, const char *msg), defaultCallback_onChat); |
|
109 GENERATE_CB_SETTER_AND_DEFAULT(onLobbyJoin, (void *context, const char *nick)); |
|
110 GENERATE_CB_SETTER_AND_DEFAULT(onLobbyLeave, (void *context, const char *nick, const char *partMsg)); |
|
111 GENERATE_CB_SETTER_AND_DEFAULT(onRoomJoin, (void *context, const char *nick)); |
|
112 GENERATE_CB_SETTER_AND_DEFAULT(onRoomLeave, (void *context, const char *nick, const char *partMessage)); |
|
113 GENERATE_CB_SETTER(onNickTaken, (void *context, const char *nick), defaultCallback_onNickTaken); |
|
114 GENERATE_CB_SETTER(onPasswordRequest, (void *context, const char *nick), defaultCallback_onPasswordRequest); |
|
115 GENERATE_CB_SETTER_AND_DEFAULT(onRoomChiefStatus, (void *context, bool chief)); |
|
116 GENERATE_CB_SETTER_AND_DEFAULT(onReadyState, (void *context, const char *nick, bool ready)); |
|
117 GENERATE_CB_SETTER_AND_DEFAULT(onEnterRoom, (void *context, bool chief)); |
|
118 GENERATE_CB_SETTER_AND_DEFAULT(onLeaveRoom, (void *context, int reason, const char *message)); |
|
119 GENERATE_CB_SETTER_AND_DEFAULT(onTeamAdd, (void *context, flib_team *team)); |
|
120 GENERATE_CB_SETTER_AND_DEFAULT(onTeamDelete, (void *context, const char *teamname)); |
|
121 GENERATE_CB_SETTER_AND_DEFAULT(onRunGame, (void *context)); |
|
122 GENERATE_CB_SETTER_AND_DEFAULT(onTeamAccepted, (void *context, const char *teamName)); |
|
123 GENERATE_CB_SETTER_AND_DEFAULT(onHogCountChanged, (void *context, const char *teamName, int hogs)); |
|
124 GENERATE_CB_SETTER_AND_DEFAULT(onTeamColorChanged, (void *context, const char *teamName, uint32_t colorRGB)); |
|
125 GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const char *message, int size)); |
|
126 GENERATE_CB_SETTER_AND_DEFAULT(onCfgScheme, (void *context, flib_cfg *scheme)); |
|
127 GENERATE_CB_SETTER_AND_DEFAULT(onMapChanged, (void *context, const flib_map *map, int changetype)); |
|
128 GENERATE_CB_SETTER_AND_DEFAULT(onScriptChanged, (void *context, const char *script)); |
|
129 GENERATE_CB_SETTER_AND_DEFAULT(onWeaponsetChanged, (void *context, flib_weaponset *weaponset)); |
|
130 GENERATE_CB_SETTER_AND_DEFAULT(onAdminAccess, (void *context)); |
|
131 GENERATE_CB_SETTER_AND_DEFAULT(onServerVar, (void *context, const char *name, const char *value)); |
|
132 |
|
133 #undef GENERATE_CB_SETTER_AND_DEFAULT |
|
134 #undef GENERATE_CB_SETTER |