5 #include <enet/types.h>
7 #define MS_VERSION "0.1"
14 #define NET_MAXCLIENTS 64
16 #define NET_BUFSIZE 65536
18 #define NET_MSG_ADD 200
19 #define NET_MSG_RM 201
20 #define NET_MSG_LIST 202
22 #define LC_MS_INIT "D2DF master server starting on port %d...\n"
23 #define LC_MS_ADD "\nAdded server in slot #%d:\n%s:%d\n%s\n%s (%d)\n%d/%d plrs\nproto: %d pw?: %d\n"
24 #define LC_MS_UPD "\nUpdated server #%d (%s:%d):\n%s\n%s (%d)\n%d/%d plrs\nproto: %d pw?: %d\n"
25 #define LC_MS_RM "\nRemoved server #%d (%s:%d) by request.\n"
26 #define LC_MS_TIME "\nServer #%d (%s:%d) timed out.\n"
27 #define LC_MS_LIST "\nSent server list to %x:%u.\n"
28 #define LC_MS_DIE "\nD2DF master server shutting down...\n"
29 #define LC_MS_CONN "\nIncoming connection from %x:%u...\n"
41 enet_uint8 s_protocol
;
46 typedef struct ms_server_s ms_server
;
48 const char ms_game_ver
[] = "0.63";
50 int ms_timeout
= 100000;
55 enet_uint8 b_send
[NET_BUFSIZE
];
57 ENetHost
*ms_host
= NULL
;
58 ENetPeer
*ms_peers
[NET_MAXCLIENTS
];
59 ms_server ms_srv
[MS_MAXSRVS
];
60 enet_uint8 ms_count
= 0;
64 printf("Usage: d2df_master -p port_number [-t timeout_seconds]\n");
70 printf("Doom 2D Forever master server v%s\n", MS_VERSION
);
75 void d_error (const char *msg
, int fatal
) {
77 fprintf(stderr
, "FATAL ERROR: %s\n", msg
);
80 fprintf(stderr
, "ERROR: %s\n", msg
);
85 void d_getargs (int argc
, char *argv
[]) {
92 for (int i
= 1; i
< argc
; ++i
) {
93 if (!strcmp(argv
[i
], "-v")) {
97 } else if (!strcmp(argv
[i
], "-p")) {
99 d_error("Specify a port value!", 1);
102 ms_port
= atoi(argv
[++i
]);
104 } else if (!strcmp(argv
[i
], "-t") & (i
+ 1 < argc
)) {
105 ms_timeout
= atoi(argv
[++i
]) * 1000;
111 enet_uint8
b_read_uint8 (enet_uint8 buf
[], size_t *pos
) {
112 return buf
[(*pos
)++];
116 enet_uint16
b_read_uint16 (enet_uint8 buf
[], size_t *pos
) {
119 ret
= *(enet_uint16
*)(buf
+ *pos
);
120 *pos
+= sizeof(enet_uint16
);
126 char* b_read_dstring (enet_uint8 buf
[], size_t *pos
) {
129 size_t len
= b_read_uint8(buf
, pos
);
131 ret
= malloc(len
+ 1);
133 memmove(ret
, (char*)(buf
+ *pos
), len
);
141 void b_write_uint8 (enet_uint8 buf
[], size_t *pos
, enet_uint8 val
) {
146 void b_write_uint16 (enet_uint8 buf
[], size_t *pos
, enet_uint16 val
) {
147 *(enet_uint16
*)(buf
+ *pos
) = val
;
148 *pos
+= sizeof(enet_uint16
);
152 void b_write_dstring (enet_uint8 buf
[], size_t *pos
, const char* val
) {
153 enet_uint8 len
= strlen(val
);
154 b_write_uint8(buf
, pos
, len
);
156 memmove((char*)(buf
+ *pos
), val
, len
);
161 void b_write_server (enet_uint8 buf
[], size_t *pos
, ms_server s
) {
162 b_write_dstring(b_send
, pos
, s
.s_ip
);
163 b_write_uint16 (b_send
, pos
, s
.s_port
);
164 b_write_dstring(b_send
, pos
, s
.s_name
);
165 b_write_dstring(b_send
, pos
, s
.s_map
);
166 b_write_uint8 (b_send
, pos
, s
.s_mode
);
167 b_write_uint8 (b_send
, pos
, s
.s_plrs
);
168 b_write_uint8 (b_send
, pos
, s
.s_maxplrs
);
169 b_write_uint8 (b_send
, pos
, s
.s_protocol
);
170 b_write_uint8 (b_send
, pos
, s
.s_pw
);
174 int main (int argc
, char *argv
[]) {
175 d_getargs(argc
, argv
);
177 if (enet_initialize()) {
178 d_error("Could not init ENet!", 1);
182 printf(LC_MS_INIT
, ms_port
);
184 for (int i
= 0; i
< NET_MAXCLIENTS
; ++i
) ms_peers
[i
] = NULL
;
186 for (int i
= 0; i
< MS_MAXSRVS
; ++i
) {
188 ms_srv
[i
].s_ip
[0] = '\0';
189 ms_srv
[i
].s_name
[0] = '\0';
190 ms_srv
[i
].s_map
[0] = '\0';
195 addr
.host
= ENET_HOST_ANY
;
198 ms_host
= enet_host_create(&addr
, NET_MAXCLIENTS
, NET_CHANS
, 0, 0);
200 d_error("Could not create host on specified port!", 1);
204 atexit(enet_deinitialize
);
208 enet_uint8 msg
= 255;
211 enet_uint16 port
= 0;
219 enet_uint8 proto
= 0;
222 while (enet_host_service(ms_host
, &event
, 1) > 0) {
223 switch (event
.type
) {
224 case ENET_EVENT_TYPE_CONNECT
:
225 printf(LC_MS_CONN
, event
.peer
->address
.host
, event
.peer
->address
.port
);
227 case ENET_EVENT_TYPE_RECEIVE
:
228 if (!event
.peer
) continue;
230 msg
= b_read_uint8(event
.packet
->data
, &b_read
);
234 if (!event
.peer
) continue;
236 enet_address_get_host_ip(&(event
.peer
->address
), ip
, 17);
237 port
= b_read_uint16(event
.packet
->data
, &b_read
);
239 name
= b_read_dstring(event
.packet
->data
, &b_read
);
240 map
= b_read_dstring(event
.packet
->data
, &b_read
);
241 gm
= b_read_uint8(event
.packet
->data
, &b_read
);
243 pl
= b_read_uint8(event
.packet
->data
, &b_read
);
244 mpl
= b_read_uint8(event
.packet
->data
, &b_read
);
246 proto
= b_read_uint8(event
.packet
->data
, &b_read
);
247 pw
= b_read_uint8(event
.packet
->data
, &b_read
);
249 for (int i
= 0; i
< MS_MAXSRVS
; ++i
) {
250 if (ms_srv
[i
].used
) {
251 if ((strncmp(ip
, ms_srv
[i
].s_ip
, 16) == 0) && (ms_srv
[i
].s_port
== port
)) {
252 strncpy(ms_srv
[i
].s_map
, map
, 255);
253 strncpy(ms_srv
[i
].s_name
, name
, 255);
254 ms_srv
[i
].s_plrs
= pl
;
255 ms_srv
[i
].s_maxplrs
= mpl
;
257 ms_srv
[i
].s_mode
= gm
;
259 ms_srv
[i
].ttl
= ms_timeout
;
261 printf(LC_MS_UPD
, i
, ip
, port
, name
, map
, gm
, pl
, mpl
, proto
, pw
);
265 strncpy(ms_srv
[i
].s_ip
, ip
, 16);
266 strncpy(ms_srv
[i
].s_map
, map
, 255);
267 strncpy(ms_srv
[i
].s_name
, name
, 255);
268 ms_srv
[i
].s_port
= port
;
269 ms_srv
[i
].s_plrs
= pl
;
270 ms_srv
[i
].s_maxplrs
= mpl
;
272 ms_srv
[i
].s_mode
= gm
;
273 ms_srv
[i
].s_protocol
= proto
;
274 ms_srv
[i
].ttl
= ms_timeout
;
278 printf(LC_MS_ADD
, i
, ip
, port
, name
, map
, gm
, pl
, mpl
, proto
, pw
);
288 enet_address_get_host_ip(&(event
.peer
->address
), ip
, 17);
289 port
= b_read_uint16(event
.packet
->data
, &b_read
);
290 for (int i
= 0; i
< MS_MAXSRVS
; ++i
) {
291 if (ms_srv
[i
].used
) {
292 if ((strncmp(ip
, ms_srv
[i
].s_ip
, 16) == 0) && (ms_srv
[i
].s_port
== port
)) {
294 printf(LC_MS_RM
, i
, ip
, port
);
301 if (!event
.peer
) continue;
303 b_write_uint8(b_send
, &b_write
, NET_MSG_LIST
);
304 b_write_uint8(b_send
, &b_write
, ms_count
);
305 for (int i
= 0; i
< MS_MAXSRVS
; ++i
) {
306 if (ms_srv
[i
].used
) b_write_server(b_send
, &b_write
, ms_srv
[i
]);
309 ENetPacket
*p
= enet_packet_create(b_send
, b_write
, ENET_PACKET_FLAG_RELIABLE
);
310 enet_peer_send(event
.peer
, NET_CH_MAIN
, p
);
311 enet_host_flush(ms_host
);
313 printf(LC_MS_LIST
, event
.peer
->address
.host
, event
.peer
->address
.port
);
317 enet_packet_destroy(event
.packet
);
325 for (int i
= 0; i
< MS_MAXSRVS
; ++i
) {
326 if (ms_srv
[i
].used
) {
327 if (--(ms_srv
[i
].ttl
) == 0) {
329 printf(LC_MS_TIME
, i
, ms_srv
[i
].s_ip
, ms_srv
[i
].s_port
);