25 #include <string.h> |
25 #include <string.h> |
26 #include <stdlib.h> |
26 #include <stdlib.h> |
27 #include <ctype.h> |
27 #include <ctype.h> |
28 |
28 |
29 static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { |
29 static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { |
30 flib_log_i("Net: [%i] %s", msgtype, msg); |
30 flib_log_i("Net: [%i] %s", msgtype, msg); |
31 } |
31 } |
32 |
32 |
33 static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { |
33 static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { |
34 flib_log_i("%s: %s", nick, msg); |
34 flib_log_i("%s: %s", nick, msg); |
35 } |
35 } |
36 |
36 |
37 // Change the name by suffixing it with a number. If it already ends in a number, increase that number by 1. |
37 // Change the name by suffixing it with a number. If it already ends in a number, increase that number by 1. |
38 static void defaultCallback_onNickTaken(void *context, const char *requestedNick) { |
38 static void defaultCallback_onNickTaken(void *context, const char *requestedNick) { |
39 flib_netconn *conn = context; |
39 flib_netconn *conn = context; |
40 size_t namelen = strlen(requestedNick); |
40 size_t namelen = strlen(requestedNick); |
41 int digits = 0; |
41 int digits = 0; |
42 while(digits<namelen && isdigit(requestedNick[namelen-1-digits])) { |
42 while(digits<namelen && isdigit(requestedNick[namelen-1-digits])) { |
43 digits++; |
43 digits++; |
44 } |
44 } |
45 long suffix = 0; |
45 long suffix = 0; |
46 if(digits>0) { |
46 if(digits>0) { |
47 suffix = atol(requestedNick+namelen-digits)+1; |
47 suffix = atol(requestedNick+namelen-digits)+1; |
48 } |
48 } |
49 char *newPlayerName = flib_asprintf("%.*s%li", namelen-digits, requestedNick, suffix); |
49 char *newPlayerName = flib_asprintf("%.*s%li", namelen-digits, requestedNick, suffix); |
50 if(newPlayerName) { |
50 if(newPlayerName) { |
51 flib_netconn_send_nick(conn, newPlayerName); |
51 flib_netconn_send_nick(conn, newPlayerName); |
52 } else { |
52 } else { |
53 flib_netconn_send_quit(conn, "Nick already taken."); |
53 flib_netconn_send_quit(conn, "Nick already taken."); |
54 } |
54 } |
55 free(newPlayerName); |
55 free(newPlayerName); |
56 } |
56 } |
57 |
57 |
58 // Default behavior: Quit |
58 // Default behavior: Quit |
59 static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { |
59 static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { |
60 flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); |
60 flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); |
61 } |
61 } |
62 |
62 |
63 void netconn_clearCallbacks(flib_netconn *conn) { |
63 void netconn_clearCallbacks(flib_netconn *conn) { |
64 flib_netconn_onMessage(conn, NULL, NULL); |
64 flib_netconn_onMessage(conn, NULL, NULL); |
65 flib_netconn_onConnected(conn, NULL, NULL); |
65 flib_netconn_onConnected(conn, NULL, NULL); |
66 flib_netconn_onDisconnected(conn, NULL, NULL); |
66 flib_netconn_onDisconnected(conn, NULL, NULL); |
67 flib_netconn_onRoomlist(conn, NULL, NULL); |
67 flib_netconn_onRoomlist(conn, NULL, NULL); |
68 flib_netconn_onRoomAdd(conn, NULL, NULL); |
68 flib_netconn_onRoomAdd(conn, NULL, NULL); |
69 flib_netconn_onRoomDelete(conn, NULL, NULL); |
69 flib_netconn_onRoomDelete(conn, NULL, NULL); |
70 flib_netconn_onRoomUpdate(conn, NULL, NULL); |
70 flib_netconn_onRoomUpdate(conn, NULL, NULL); |
71 flib_netconn_onClientFlags(conn, NULL, NULL); |
71 flib_netconn_onClientFlags(conn, NULL, NULL); |
72 flib_netconn_onChat(conn, NULL, NULL); |
72 flib_netconn_onChat(conn, NULL, NULL); |
73 flib_netconn_onLobbyJoin(conn, NULL, NULL); |
73 flib_netconn_onLobbyJoin(conn, NULL, NULL); |
74 flib_netconn_onLobbyLeave(conn, NULL, NULL); |
74 flib_netconn_onLobbyLeave(conn, NULL, NULL); |
75 flib_netconn_onRoomJoin(conn, NULL, NULL); |
75 flib_netconn_onRoomJoin(conn, NULL, NULL); |
76 flib_netconn_onRoomLeave(conn, NULL, NULL); |
76 flib_netconn_onRoomLeave(conn, NULL, NULL); |
77 flib_netconn_onNickTaken(conn, NULL, NULL); |
77 flib_netconn_onNickTaken(conn, NULL, NULL); |
78 flib_netconn_onPasswordRequest(conn, NULL, NULL); |
78 flib_netconn_onPasswordRequest(conn, NULL, NULL); |
79 flib_netconn_onEnterRoom(conn, NULL, NULL); |
79 flib_netconn_onEnterRoom(conn, NULL, NULL); |
80 flib_netconn_onLeaveRoom(conn, NULL, NULL); |
80 flib_netconn_onLeaveRoom(conn, NULL, NULL); |
81 flib_netconn_onTeamAdd(conn, NULL, NULL); |
81 flib_netconn_onTeamAdd(conn, NULL, NULL); |
82 flib_netconn_onTeamDelete(conn, NULL, NULL); |
82 flib_netconn_onTeamDelete(conn, NULL, NULL); |
83 flib_netconn_onRunGame(conn, NULL, NULL); |
83 flib_netconn_onRunGame(conn, NULL, NULL); |
84 flib_netconn_onTeamAccepted(conn, NULL, NULL); |
84 flib_netconn_onTeamAccepted(conn, NULL, NULL); |
85 flib_netconn_onHogCountChanged(conn, NULL, NULL); |
85 flib_netconn_onHogCountChanged(conn, NULL, NULL); |
86 flib_netconn_onTeamColorChanged(conn, NULL, NULL); |
86 flib_netconn_onTeamColorChanged(conn, NULL, NULL); |
87 flib_netconn_onEngineMessage(conn, NULL, NULL); |
87 flib_netconn_onEngineMessage(conn, NULL, NULL); |
88 flib_netconn_onSchemeChanged(conn, NULL, NULL); |
88 flib_netconn_onSchemeChanged(conn, NULL, NULL); |
89 flib_netconn_onMapChanged(conn, NULL, NULL); |
89 flib_netconn_onMapChanged(conn, NULL, NULL); |
90 flib_netconn_onScriptChanged(conn, NULL, NULL); |
90 flib_netconn_onScriptChanged(conn, NULL, NULL); |
91 flib_netconn_onWeaponsetChanged(conn, NULL, NULL); |
91 flib_netconn_onWeaponsetChanged(conn, NULL, NULL); |
92 flib_netconn_onServerVar(conn, NULL, NULL); |
92 flib_netconn_onServerVar(conn, NULL, NULL); |
93 } |
93 } |
94 |
94 |
95 /** |
95 /** |
96 * This macro generates a callback setter function. It uses the name of the callback to |
96 * This macro generates a callback setter function. It uses the name of the callback to |
97 * automatically generate the function name and the fields to set, so a consistent naming |
97 * automatically generate the function name and the fields to set, so a consistent naming |
98 * convention needs to be enforced (not that that is a bad thing). If null is passed as |
98 * convention needs to be enforced (not that that is a bad thing). If null is passed as |
99 * callback to the generated function, the defaultCb will be set instead (with conn |
99 * callback to the generated function, the defaultCb will be set instead (with conn |
100 * as the context). |
100 * as the context). |
101 */ |
101 */ |
102 #define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ |
102 #define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ |
103 void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \ |
103 void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \ |
104 if(!log_badargs_if(conn==NULL)) { \ |
104 if(!log_badargs_if(conn==NULL)) { \ |
105 conn->cbName##Cb = callback ? callback : &defaultCb; \ |
105 conn->cbName##Cb = callback ? callback : &defaultCb; \ |
106 conn->cbName##Ctx = callback ? context : conn; \ |
106 conn->cbName##Ctx = callback ? context : conn; \ |
107 } \ |
107 } \ |
108 } |
108 } |
109 |
109 |
110 /** |
110 /** |
111 * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a |
111 * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a |
112 * no-op callback function as well that is used as default. |
112 * no-op callback function as well that is used as default. |
113 */ |
113 */ |
114 #define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ |
114 #define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ |
115 static void _noop_callback_##cbName cbParameterTypes {} \ |
115 static void _noop_callback_##cbName cbParameterTypes {} \ |
116 GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) |
116 GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) |
117 |
117 |
118 GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage); |
118 GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage); |
119 GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context)); |
119 GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context)); |
120 GENERATE_CB_SETTER_AND_DEFAULT(onDisconnected, (void *context, int reason, const char *message)); |
120 GENERATE_CB_SETTER_AND_DEFAULT(onDisconnected, (void *context, int reason, const char *message)); |
121 GENERATE_CB_SETTER_AND_DEFAULT(onRoomlist, (void *context, const flib_room **rooms, int roomCount)); |
121 GENERATE_CB_SETTER_AND_DEFAULT(onRoomlist, (void *context, const flib_room **rooms, int roomCount)); |