|
1 /* |
|
2 * Hedgewars, a free turn based strategy game |
|
3 * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com> |
|
4 * |
|
5 * This program is free software; you can redistribute it and/or |
|
6 * modify it under the terms of the GNU General Public License |
|
7 * as published by the Free Software Foundation; either version 2 |
|
8 * of the License, or (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program; if not, write to the Free Software |
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
18 */ |
|
19 |
|
20 #include "netconn_internal.h" |
|
21 |
|
22 #include "../util/logging.h" |
|
23 #include "../util/util.h" |
|
24 |
|
25 #include <string.h> |
|
26 #include <stdlib.h> |
|
27 #include <ctype.h> |
|
28 |
|
29 static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { |
|
30 flib_log_i("Net: [%i] %s", msgtype, msg); |
|
31 } |
|
32 |
|
33 static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { |
|
34 flib_log_i("%s: %s", nick, msg); |
|
35 } |
|
36 |
|
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) { |
|
39 flib_netconn *conn = context; |
|
40 size_t namelen = strlen(requestedNick); |
|
41 int digits = 0; |
|
42 while(digits<namelen && isdigit(requestedNick[namelen-1-digits])) { |
|
43 digits++; |
|
44 } |
|
45 long suffix = 0; |
|
46 if(digits>0) { |
|
47 suffix = atol(requestedNick+namelen-digits)+1; |
|
48 } |
|
49 char *newPlayerName = flib_asprintf("%.*s%li", namelen-digits, requestedNick, suffix); |
|
50 if(newPlayerName) { |
|
51 flib_netconn_send_nick(conn, newPlayerName); |
|
52 } else { |
|
53 flib_netconn_send_quit(conn, "Nick already taken."); |
|
54 } |
|
55 free(newPlayerName); |
|
56 } |
|
57 |
|
58 // Default behavior: Quit |
|
59 static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { |
|
60 flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); |
|
61 } |
|
62 |
|
63 void netconn_clearCallbacks(flib_netconn *conn) { |
|
64 flib_netconn_onMessage(conn, NULL, NULL); |
|
65 flib_netconn_onConnected(conn, NULL, NULL); |
|
66 flib_netconn_onDisconnected(conn, NULL, NULL); |
|
67 flib_netconn_onRoomlist(conn, NULL, NULL); |
|
68 flib_netconn_onRoomAdd(conn, NULL, NULL); |
|
69 flib_netconn_onRoomDelete(conn, NULL, NULL); |
|
70 flib_netconn_onRoomUpdate(conn, NULL, NULL); |
|
71 flib_netconn_onClientFlags(conn, NULL, NULL); |
|
72 flib_netconn_onChat(conn, NULL, NULL); |
|
73 flib_netconn_onLobbyJoin(conn, NULL, NULL); |
|
74 flib_netconn_onLobbyLeave(conn, NULL, NULL); |
|
75 flib_netconn_onRoomJoin(conn, NULL, NULL); |
|
76 flib_netconn_onRoomLeave(conn, NULL, NULL); |
|
77 flib_netconn_onNickTaken(conn, NULL, NULL); |
|
78 flib_netconn_onPasswordRequest(conn, NULL, NULL); |
|
79 flib_netconn_onEnterRoom(conn, NULL, NULL); |
|
80 flib_netconn_onLeaveRoom(conn, NULL, NULL); |
|
81 flib_netconn_onTeamAdd(conn, NULL, NULL); |
|
82 flib_netconn_onTeamDelete(conn, NULL, NULL); |
|
83 flib_netconn_onRunGame(conn, NULL, NULL); |
|
84 flib_netconn_onTeamAccepted(conn, NULL, NULL); |
|
85 flib_netconn_onHogCountChanged(conn, NULL, NULL); |
|
86 flib_netconn_onTeamColorChanged(conn, NULL, NULL); |
|
87 flib_netconn_onEngineMessage(conn, NULL, NULL); |
|
88 flib_netconn_onSchemeChanged(conn, NULL, NULL); |
|
89 flib_netconn_onMapChanged(conn, NULL, NULL); |
|
90 flib_netconn_onScriptChanged(conn, NULL, NULL); |
|
91 flib_netconn_onWeaponsetChanged(conn, NULL, NULL); |
|
92 flib_netconn_onServerVar(conn, NULL, NULL); |
|
93 } |
|
94 |
|
95 /** |
|
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 |
|
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 |
|
100 * as the context). |
|
101 */ |
|
102 #define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ |
|
103 void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \ |
|
104 if(!log_badargs_if(conn==NULL)) { \ |
|
105 conn->cbName##Cb = callback ? callback : &defaultCb; \ |
|
106 conn->cbName##Ctx = callback ? context : conn; \ |
|
107 } \ |
|
108 } |
|
109 |
|
110 /** |
|
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. |
|
113 */ |
|
114 #define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ |
|
115 static void _noop_callback_##cbName cbParameterTypes {} \ |
|
116 GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) |
|
117 |
|
118 GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage); |
|
119 GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context)); |
|
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)); |
|
122 GENERATE_CB_SETTER_AND_DEFAULT(onRoomAdd, (void *context, const flib_room *room)); |
|
123 GENERATE_CB_SETTER_AND_DEFAULT(onRoomDelete, (void *context, const char *name)); |
|
124 GENERATE_CB_SETTER_AND_DEFAULT(onRoomUpdate, (void *context, const char *oldName, const flib_room *room)); |
|
125 GENERATE_CB_SETTER_AND_DEFAULT(onClientFlags, (void *context, const char *nick, const char *flags, bool newFlagState)); |
|
126 GENERATE_CB_SETTER(onChat, (void *context, const char *nick, const char *msg), defaultCallback_onChat); |
|
127 GENERATE_CB_SETTER_AND_DEFAULT(onLobbyJoin, (void *context, const char *nick)); |
|
128 GENERATE_CB_SETTER_AND_DEFAULT(onLobbyLeave, (void *context, const char *nick, const char *partMsg)); |
|
129 GENERATE_CB_SETTER_AND_DEFAULT(onRoomJoin, (void *context, const char *nick)); |
|
130 GENERATE_CB_SETTER_AND_DEFAULT(onRoomLeave, (void *context, const char *nick, const char *partMessage)); |
|
131 GENERATE_CB_SETTER(onNickTaken, (void *context, const char *nick), defaultCallback_onNickTaken); |
|
132 GENERATE_CB_SETTER(onPasswordRequest, (void *context, const char *nick), defaultCallback_onPasswordRequest); |
|
133 GENERATE_CB_SETTER_AND_DEFAULT(onEnterRoom, (void *context, bool chief)); |
|
134 GENERATE_CB_SETTER_AND_DEFAULT(onLeaveRoom, (void *context, int reason, const char *message)); |
|
135 GENERATE_CB_SETTER_AND_DEFAULT(onTeamAdd, (void *context, const flib_team *team)); |
|
136 GENERATE_CB_SETTER_AND_DEFAULT(onTeamDelete, (void *context, const char *teamname)); |
|
137 GENERATE_CB_SETTER_AND_DEFAULT(onRunGame, (void *context)); |
|
138 GENERATE_CB_SETTER_AND_DEFAULT(onTeamAccepted, (void *context, const char *teamName)); |
|
139 GENERATE_CB_SETTER_AND_DEFAULT(onHogCountChanged, (void *context, const char *teamName, int hogs)); |
|
140 GENERATE_CB_SETTER_AND_DEFAULT(onTeamColorChanged, (void *context, const char *teamName, int colorIndex)); |
|
141 GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *message, size_t size)); |
|
142 GENERATE_CB_SETTER_AND_DEFAULT(onSchemeChanged, (void *context, const flib_scheme *scheme)); |
|
143 GENERATE_CB_SETTER_AND_DEFAULT(onMapChanged, (void *context, const flib_map *map, int changetype)); |
|
144 GENERATE_CB_SETTER_AND_DEFAULT(onScriptChanged, (void *context, const char *script)); |
|
145 GENERATE_CB_SETTER_AND_DEFAULT(onWeaponsetChanged, (void *context, const flib_weaponset *weaponset)); |
|
146 GENERATE_CB_SETTER_AND_DEFAULT(onServerVar, (void *context, const char *name, const char *value)); |
|
147 |
|
148 #undef GENERATE_CB_SETTER_AND_DEFAULT |
|
149 #undef GENERATE_CB_SETTER |