diff options
Diffstat (limited to 'apps/plugins/sdl/progs/duke3d/Engine/src/mmulti.cpp')
-rw-r--r-- | apps/plugins/sdl/progs/duke3d/Engine/src/mmulti.cpp | 1213 |
1 files changed, 0 insertions, 1213 deletions
diff --git a/apps/plugins/sdl/progs/duke3d/Engine/src/mmulti.cpp b/apps/plugins/sdl/progs/duke3d/Engine/src/mmulti.cpp deleted file mode 100644 index 898751c6f2..0000000000 --- a/apps/plugins/sdl/progs/duke3d/Engine/src/mmulti.cpp +++ /dev/null | |||
@@ -1,1213 +0,0 @@ | |||
1 | |||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include <stdarg.h> | ||
6 | |||
7 | #include "enet.h" | ||
8 | |||
9 | //#include "buildqueue.h" | ||
10 | |||
11 | #include <vector> | ||
12 | |||
13 | |||
14 | //#define _DEBUG_NETWORKING_ | ||
15 | |||
16 | extern "C" | ||
17 | { | ||
18 | |||
19 | #include "platform.h" | ||
20 | #include "pragmas.h" | ||
21 | #include "signal.h" | ||
22 | #include "mmulti_stable.h" | ||
23 | |||
24 | #define MAXPLAYERS 16 | ||
25 | #define BAKSIZ 16384 | ||
26 | #define SIMULATEERRORS 0 | ||
27 | #define SHOWSENDPACKETS 0 | ||
28 | #define SHOWGETPACKETS 0 | ||
29 | #define PRINTERRORS 0 | ||
30 | |||
31 | #define MAX_PLAYERS 16 | ||
32 | #define BUILD_DEFAULT_UDP_PORT 1635 /* eh...why not? */ | ||
33 | #define CLIENT_POLL_DELAY 5000 /* ms between pings at peer-to-peer startup. */ | ||
34 | #define HEADER_PEER_GREETING 245 | ||
35 | #define HEADER_PEER_READY 244 | ||
36 | |||
37 | static int udpsocket = -1; | ||
38 | static short udpport = BUILD_DEFAULT_UDP_PORT; | ||
39 | |||
40 | #define updatecrc16(crc,dat) crc = (((crc<<8)&65535)^crctable[((((unsigned short)crc)>>8)&65535)^dat]) | ||
41 | |||
42 | static long incnt[MAXPLAYERS], outcntplc[MAXPLAYERS], outcntend[MAXPLAYERS]; | ||
43 | static char errorgotnum[MAXPLAYERS]; | ||
44 | static char errorfixnum[MAXPLAYERS]; | ||
45 | static char errorresendnum[MAXPLAYERS]; | ||
46 | #if (PRINTERRORS) | ||
47 | static char lasterrorgotnum[MAXPLAYERS]; | ||
48 | #endif | ||
49 | |||
50 | long crctable[256]; | ||
51 | int tmpmax[8]; //addfaz variable addition (you could probs think of something better) | ||
52 | unsigned int g_bAllPlayersFound = 0; | ||
53 | |||
54 | static char lastpacket[576], inlastpacket = 0; | ||
55 | static short lastpacketfrom, lastpacketleng; | ||
56 | |||
57 | extern long totalclock; /* MUST EXTERN 1 ANNOYING VARIABLE FROM GAME */ | ||
58 | static long timeoutcount = 60, resendagaincount = 4, lastsendtime[MAXPLAYERS]; | ||
59 | |||
60 | static short bakpacketptr[MAXPLAYERS][256], bakpacketlen[MAXPLAYERS][256]; | ||
61 | static char bakpacketbuf[BAKSIZ]; | ||
62 | static long bakpacketplc = 0; | ||
63 | |||
64 | short myconnectindex, numplayers; | ||
65 | short connecthead, connectpoint2[MAXPLAYERS]; | ||
66 | char syncstate = 0; | ||
67 | |||
68 | unsigned char g_bWaitingForAllReady = 0; | ||
69 | |||
70 | extern int _argc; | ||
71 | extern char **_argv; | ||
72 | |||
73 | #define MAXPACKETSIZE 2048 | ||
74 | typedef struct | ||
75 | { | ||
76 | short intnum; /* communication between Game and the driver */ | ||
77 | short command; /* 1-send, 2-get */ | ||
78 | short other; /* dest for send, set by get (-1 = no packet) */ | ||
79 | short numbytes; | ||
80 | short myconnectindex; | ||
81 | short numplayers; | ||
82 | short gametype; /* gametype: 1-serial,2-modem,3-net */ | ||
83 | short filler; | ||
84 | char buffer[MAXPACKETSIZE]; | ||
85 | long longcalladdress; | ||
86 | } gcomtype; | ||
87 | static gcomtype *gcom; | ||
88 | |||
89 | gcomtype g_LastPersonalPacket; | ||
90 | |||
91 | typedef struct | ||
92 | { | ||
93 | unsigned short other; | ||
94 | unsigned int bufferSize; | ||
95 | unsigned char buffer[MAXPACKETSIZE]; | ||
96 | }PACKET; | ||
97 | |||
98 | typedef std::vector<PACKET> PacketQueue; | ||
99 | PacketQueue incommingPacketQueue; | ||
100 | |||
101 | //typedef std::vector<PACKET> PacketQueue; | ||
102 | |||
103 | enum ECommitCMDs | ||
104 | { | ||
105 | COMMIT_CMD_SEND = 1, | ||
106 | COMMIT_CMD_GET = 2, | ||
107 | COMMIT_CMD_SENDTOALL = 3, | ||
108 | COMMIT_CMD_SENDTOALLOTHERS = 4, | ||
109 | COMMIT_CMD_SCORE = 5, | ||
110 | }; | ||
111 | |||
112 | typedef enum | ||
113 | { | ||
114 | udpmode_peer, | ||
115 | udpmode_server, | ||
116 | udpmode_client | ||
117 | } udpmodes; | ||
118 | static udpmodes udpmode = udpmode_peer; | ||
119 | |||
120 | enum EConnectionMode | ||
121 | { | ||
122 | CONN_MODE_CONNECTING = 0, | ||
123 | CONN_MODE_GREETING = 1, | ||
124 | CONN_MODE_WAITFORREADY = 2, | ||
125 | CONN_MODE_CONNECTED = 3, | ||
126 | CONN_MODE_DISCONNECTED = 4, | ||
127 | }; | ||
128 | EConnectionMode g_ConnMode = CONN_MODE_CONNECTING; | ||
129 | |||
130 | typedef struct { | ||
131 | unsigned int host; | ||
132 | short port; | ||
133 | unsigned short id; | ||
134 | unsigned short peer_idx; | ||
135 | unsigned short bHeardFrom; | ||
136 | unsigned char bReady; | ||
137 | } ADDRESS_STRUCT; | ||
138 | ADDRESS_STRUCT allowed_addresses[MAX_PLAYERS]; /* only respond to these IPs. */ | ||
139 | |||
140 | volatile int ctrlc_pressed = 0; | ||
141 | static void siginthandler(int sigint) | ||
142 | { | ||
143 | ctrlc_pressed = 1; | ||
144 | } | ||
145 | |||
146 | typedef struct | ||
147 | { | ||
148 | unsigned char dummy1; /* so these don't confuse game after load. */ | ||
149 | unsigned char dummy2; /* so these don't confuse game after load. */ | ||
150 | unsigned char dummy3; /* so these don't confuse game after load. */ | ||
151 | unsigned char header; /* always HEADER_PEER_GREETING (245). */ | ||
152 | unsigned short id; | ||
153 | } PacketPeerGreeting; | ||
154 | |||
155 | // unique id for determining "myconnectindex" | ||
156 | unsigned short my_id = 0; | ||
157 | |||
158 | unsigned short g_nPlayerIDList[MAX_PLAYERS]; | ||
159 | |||
160 | #define CONNECTION_DELAY 3000 | ||
161 | #define INITIAL_CONNECTION_DELAY 50 | ||
162 | #define INGAME_CONNECTION_DELAY 0 | ||
163 | #define POLL_DELAY 1000 | ||
164 | |||
165 | //ENetAddress address; | ||
166 | ENetHost* g_Server = 0; | ||
167 | //ENetEvent event; | ||
168 | ENetPeer* g_Peers[MAX_PLAYERS]; | ||
169 | |||
170 | short *g_other; | ||
171 | char *g_bufptr; | ||
172 | short g_nMessageLen; | ||
173 | unsigned char g_bAllGreetingsIn = 0; | ||
174 | |||
175 | // Prototypes | ||
176 | int CreateServer(char* ip, int nPort, int nMaxPlayers); | ||
177 | |||
178 | char *static_ipstring(int ip); | ||
179 | char *read_whole_file(const char *cfgfile); | ||
180 | char *get_token(char **ptr); | ||
181 | int parse_ip(const char *str, int *ip); | ||
182 | int parse_interface(char *str, int *ip, short *udpport); | ||
183 | int parse_udp_config(const char *cfgfile, gcomtype *gcom); | ||
184 | |||
185 | int connect_to_everyone(); | ||
186 | void HandleEvent(ENetEvent *pEvent); | ||
187 | unsigned int GetPeerIndex(ENetPeer* peer); | ||
188 | unsigned int GetOtherIndex(ENetPeer* peer); | ||
189 | void ServiceNetwork(); | ||
190 | void Send_Peer_Gretting(); | ||
191 | void Wait_For_Ready(); | ||
192 | |||
193 | void cleanup(void); | ||
194 | |||
195 | |||
196 | void stable_callcommit(void) | ||
197 | { | ||
198 | } | ||
199 | |||
200 | void stable_initcrc(void) | ||
201 | { | ||
202 | } | ||
203 | |||
204 | // Get CRC | ||
205 | long stable_getcrc(char *buffer, short bufleng) | ||
206 | { | ||
207 | long i, j; | ||
208 | |||
209 | j = 0; | ||
210 | for(i=bufleng-1;i>=0;i--) updatecrc16(j,buffer[i]); | ||
211 | return(j&65535); | ||
212 | } | ||
213 | |||
214 | void stable_initmultiplayers(char damultioption, char dacomrateoption, char dapriority) | ||
215 | { | ||
216 | long i; | ||
217 | gcomtype *retval; | ||
218 | int k; | ||
219 | |||
220 | // DO NOT DO THIS - it screws up the networking | ||
221 | //srand(enet_time_get_raw()); | ||
222 | |||
223 | for (i = _argc - 1; i > 0; i--) | ||
224 | { | ||
225 | const char *arg = _argv[i]; | ||
226 | char ch = *arg; | ||
227 | if ((ch == '-') || (ch == '/')) | ||
228 | { | ||
229 | if (stricmp(arg + 1, "net") == 0) | ||
230 | break; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | if ((i == 0) || (i+1 == _argc)) | ||
235 | { | ||
236 | numplayers = 1; myconnectindex = 0; | ||
237 | connecthead = 0; connectpoint2[0] = -1; | ||
238 | return; | ||
239 | } | ||
240 | |||
241 | // Zero out the peers buffer | ||
242 | //memset(g_Peers, 0, MAX_PLAYERS); | ||
243 | |||
244 | /* | ||
245 | for(k = 0; k < MAX_PLAYERS-1; ++k) | ||
246 | { | ||
247 | g_Peers[k] = NULL; | ||
248 | } | ||
249 | */ | ||
250 | |||
251 | |||
252 | |||
253 | if(enet_initialize() == -1) | ||
254 | { | ||
255 | printf("Error initializing ENet\n"); | ||
256 | } | ||
257 | |||
258 | atexit(cleanup); | ||
259 | |||
260 | retval = (gcomtype *)malloc(sizeof (gcomtype)); | ||
261 | if (retval != NULL) | ||
262 | { | ||
263 | int rc; | ||
264 | char *cfgfile = _argv[i+1]; | ||
265 | void (*oldsigint)(int); | ||
266 | |||
267 | memset(retval, '\0', sizeof (gcomtype)); | ||
268 | memset(allowed_addresses, '\0', sizeof (allowed_addresses)); | ||
269 | udpsocket = -1; | ||
270 | udpport = BUILD_DEFAULT_UDP_PORT; | ||
271 | udpmode = udpmode_peer; | ||
272 | |||
273 | oldsigint = signal(SIGINT, siginthandler); | ||
274 | rc = parse_udp_config(cfgfile, retval); | ||
275 | signal(SIGINT, oldsigint); | ||
276 | |||
277 | if(!rc) | ||
278 | { | ||
279 | printf("Network transport initialization error!\n"); | ||
280 | } | ||
281 | |||
282 | gcom = retval; | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | printf("Error allocating gcomtype!\n"); | ||
287 | } | ||
288 | |||
289 | numplayers = gcom->numplayers; | ||
290 | // myconnectindex = gcom->myconnectindex;//numplayers-1; | ||
291 | #if (SIMULATEERRORS != 0) | ||
292 | srand(myconnectindex*24572457+345356); | ||
293 | #endif | ||
294 | |||
295 | //g_Peers = (ENetPeer**)malloc(sizeof(ENetPeer*) * gcom->numplayers); | ||
296 | connect_to_everyone(); | ||
297 | |||
298 | connecthead = 0; | ||
299 | for(i=0;i<numplayers-1;i++) | ||
300 | { | ||
301 | connectpoint2[i] = i+1; | ||
302 | } | ||
303 | connectpoint2[numplayers-1] = -1; | ||
304 | |||
305 | for(i=0;i<numplayers;i++) | ||
306 | { | ||
307 | lastsendtime[i] = totalclock; | ||
308 | } | ||
309 | |||
310 | |||
311 | |||
312 | // Set our connection index | ||
313 | myconnectindex = gcom->myconnectindex;//numplayers-1; | ||
314 | |||
315 | } | ||
316 | |||
317 | void stable_sendpacket(long other, char *bufptr, long messleng) | ||
318 | { | ||
319 | |||
320 | if(other == (myconnectindex)) | ||
321 | { | ||
322 | #ifdef _DEBUG_NETWORKING_ | ||
323 | printf("Send Packet to myself %d : type: %d len: %d\n", other, bufptr[0], messleng); | ||
324 | #endif | ||
325 | memcpy(g_LastPersonalPacket.buffer, bufptr, messleng); | ||
326 | g_LastPersonalPacket.numbytes = (short)messleng; | ||
327 | g_LastPersonalPacket.command = 1; | ||
328 | } | ||
329 | else | ||
330 | { | ||
331 | |||
332 | #ifdef _DEBUG_NETWORKING_ | ||
333 | printf("Send Packet to peer %d : type: %d len: %d\n", other, bufptr[0], messleng); | ||
334 | #endif | ||
335 | |||
336 | ENetPacket * packet = enet_packet_create (bufptr, sizeof(char) * messleng, ENET_PACKET_FLAG_RELIABLE);//ENET_PACKET_FLAG_RELIABLE | ||
337 | //enet_peer_send (g_Peers[other], 0, packet); | ||
338 | enet_peer_send (g_Peers[allowed_addresses[other].peer_idx], 0, packet); | ||
339 | enet_host_flush(g_Server); | ||
340 | |||
341 | } | ||
342 | } | ||
343 | |||
344 | void stable_setpackettimeout(long datimeoutcount, long daresendagaincount) | ||
345 | { | ||
346 | //NOT USED for anything other than '/f4' | ||
347 | } | ||
348 | |||
349 | void stable_uninitmultiplayers(void) | ||
350 | { | ||
351 | //kill networking | ||
352 | |||
353 | /* | ||
354 | if(g_Peers) | ||
355 | { | ||
356 | free(g_Peers); | ||
357 | } | ||
358 | */ | ||
359 | incommingPacketQueue.clear(); | ||
360 | |||
361 | enet_deinitialize(); | ||
362 | } | ||
363 | |||
364 | void cleanup(void) | ||
365 | { | ||
366 | stable_uninitmultiplayers(); | ||
367 | } | ||
368 | |||
369 | void stable_sendlogon(void) | ||
370 | { | ||
371 | } | ||
372 | |||
373 | void stable_sendlogoff(void) | ||
374 | { | ||
375 | long i; | ||
376 | char tempbuf[2]; | ||
377 | |||
378 | tempbuf[0] = 255; | ||
379 | tempbuf[1] = myconnectindex; | ||
380 | for(i=connecthead;i>=0;i=connectpoint2[i]) | ||
381 | if (i != myconnectindex) | ||
382 | stable_sendpacket(i,tempbuf,2L); | ||
383 | } | ||
384 | |||
385 | int stable_getoutputcirclesize(void) | ||
386 | { | ||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | void stable_setsocket(short newsocket) | ||
391 | { | ||
392 | } | ||
393 | |||
394 | |||
395 | //------------------------------------------------- | ||
396 | // | ||
397 | // GetPacket | ||
398 | // | ||
399 | //------------------------------------------------- | ||
400 | short stable_getpacket(short *other, char *bufptr) | ||
401 | { | ||
402 | ENetEvent event; | ||
403 | g_nMessageLen = 0; | ||
404 | |||
405 | |||
406 | //clear out the early packet buffer first | ||
407 | if(incommingPacketQueue.size() > 0) | ||
408 | { | ||
409 | PacketQueue::iterator iter = incommingPacketQueue.begin(); | ||
410 | |||
411 | if(iter != incommingPacketQueue.end() ) | ||
412 | { | ||
413 | g_nMessageLen = (*iter).bufferSize; | ||
414 | *other = (*iter).other; | ||
415 | memcpy(bufptr , (*iter).buffer, g_nMessageLen); | ||
416 | |||
417 | // Delete this entry now that we're done with it. | ||
418 | incommingPacketQueue.erase(iter); | ||
419 | } | ||
420 | } | ||
421 | else | ||
422 | if (enet_host_service (g_Server, & event, INGAME_CONNECTION_DELAY) > 0) | ||
423 | { | ||
424 | // setup the pointers. | ||
425 | g_other = other; | ||
426 | |||
427 | HandleEvent(&event); | ||
428 | |||
429 | if(event.type == ENET_EVENT_TYPE_RECEIVE) | ||
430 | { | ||
431 | memcpy(bufptr, &lastpacket[0], g_nMessageLen); | ||
432 | } | ||
433 | |||
434 | }else // check to see if we have a packet of our own to deliver to ourselves. | ||
435 | { | ||
436 | if(g_LastPersonalPacket.command == 1) | ||
437 | { | ||
438 | *other = gcom->numplayers -1;//myconnectindex; | ||
439 | memcpy(bufptr, &g_LastPersonalPacket.buffer[0], g_nMessageLen); | ||
440 | |||
441 | //reset it | ||
442 | g_LastPersonalPacket.command = 0; | ||
443 | |||
444 | return g_LastPersonalPacket.numbytes; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | return g_nMessageLen; | ||
449 | } | ||
450 | |||
451 | void stable_flushpackets(void) | ||
452 | { | ||
453 | //STUB | ||
454 | } | ||
455 | |||
456 | void stable_genericmultifunction(long other, char *bufptr, long messleng, long command) | ||
457 | { | ||
458 | |||
459 | } | ||
460 | |||
461 | // | ||
462 | // | ||
463 | // | ||
464 | int connect_to_everyone() | ||
465 | { | ||
466 | ENetAddress address; | ||
467 | ENetEvent event; | ||
468 | int i; | ||
469 | int bWaiting = 1; | ||
470 | int bCreatedPeers = 0; | ||
471 | |||
472 | while(bWaiting) | ||
473 | { | ||
474 | printf( (g_bAllPlayersFound) ? "." : "Waiting for connections...\n"); | ||
475 | |||
476 | //wait for conencts to/from them | ||
477 | if (enet_host_service (g_Server, & event, (bCreatedPeers == 1) ? CONNECTION_DELAY : INITIAL_CONNECTION_DELAY) > 0) | ||
478 | { | ||
479 | HandleEvent(&event); | ||
480 | } | ||
481 | |||
482 | //Create peer and connect to it | ||
483 | //enet_address_set_host (& address, m_szAddr); | ||
484 | |||
485 | if(bCreatedPeers == 0) | ||
486 | { | ||
487 | for(i = 0; i < gcom->numplayers-1; ++i) | ||
488 | { | ||
489 | ENetPeer *peer; | ||
490 | char szHostName[64]; | ||
491 | |||
492 | |||
493 | address.host = allowed_addresses[i].host; //ip; | ||
494 | address.port = allowed_addresses[i].port; //m_nPort; | ||
495 | |||
496 | |||
497 | |||
498 | enet_address_get_host(&address, szHostName, 64); | ||
499 | printf("Creating peer: %s:%d\n", szHostName, address.port); | ||
500 | |||
501 | g_Peers[i] = enet_host_connect (g_Server, & address, 2); | ||
502 | |||
503 | if(g_Peers[i] == NULL) | ||
504 | { | ||
505 | printf("Error creating peer! \n"); | ||
506 | //return 1; | ||
507 | }else | ||
508 | { | ||
509 | allowed_addresses[i].peer_idx = i; | ||
510 | } | ||
511 | |||
512 | } | ||
513 | bCreatedPeers = 1; | ||
514 | } | ||
515 | |||
516 | if(g_bAllPlayersFound == 1) | ||
517 | { | ||
518 | bWaiting = 0; | ||
519 | } | ||
520 | |||
521 | } | ||
522 | |||
523 | printf("Negotiating connection order...\n"); | ||
524 | Send_Peer_Gretting(); | ||
525 | Wait_For_Ready(); | ||
526 | |||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | void Send_Peer_Gretting() | ||
531 | { | ||
532 | int i; | ||
533 | |||
534 | g_ConnMode = CONN_MODE_GREETING; | ||
535 | |||
536 | while (my_id == 0) /* player number is based on id, low to high. */ | ||
537 | { | ||
538 | my_id = (unsigned short)enet_time_get_raw();//(unsigned short) rand(); | ||
539 | } | ||
540 | |||
541 | printf("My client id is %d\n", my_id); | ||
542 | |||
543 | for(i = 0; i < MAX_PLAYERS; ++i) | ||
544 | { | ||
545 | allowed_addresses[i].id = 0; | ||
546 | } | ||
547 | |||
548 | PacketPeerGreeting greetpacket; | ||
549 | memset(&greetpacket, '\0', sizeof (greetpacket)); | ||
550 | greetpacket.header = HEADER_PEER_GREETING; | ||
551 | greetpacket.id = BUILDSWAP_INTEL16(my_id); | ||
552 | |||
553 | // Create the greeting packet | ||
554 | ENetPacket * packet = enet_packet_create (&greetpacket, sizeof(PacketPeerGreeting), ENET_PACKET_FLAG_RELIABLE);//ENET_PACKET_FLAG_RELIABLE | ||
555 | |||
556 | printf("Broadcasting Greating...\n"); | ||
557 | |||
558 | // Broadcast it to all the peers | ||
559 | enet_host_broadcast(g_Server, 0, packet); | ||
560 | |||
561 | // Flush the send buffer | ||
562 | enet_host_flush(g_Server); | ||
563 | |||
564 | while(CONN_MODE_GREETING == g_ConnMode) | ||
565 | { | ||
566 | ENetEvent event; | ||
567 | if (enet_host_service (g_Server, & event, CONNECTION_DELAY) > 0) | ||
568 | { | ||
569 | int nAllIDsIn = 1; | ||
570 | |||
571 | |||
572 | HandleEvent(&event); | ||
573 | |||
574 | // are all the id's in yet? | ||
575 | for(i = 0; i < (gcom->numplayers-1); ++i) | ||
576 | { | ||
577 | if(allowed_addresses[i].id == 0) | ||
578 | { | ||
579 | nAllIDsIn = 0; | ||
580 | break; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | // add our ID to the list for sorting | ||
585 | allowed_addresses[gcom->numplayers-1].id = my_id; | ||
586 | |||
587 | //check the validity of the ID and sort them. | ||
588 | if(nAllIDsIn == 1) | ||
589 | { | ||
590 | int iteration = 0; | ||
591 | int k = 0; | ||
592 | unsigned short nCurrentHigh = 0; | ||
593 | |||
594 | printf("Sorting player IDs...\n"); | ||
595 | |||
596 | for(iteration = 0; iteration < gcom->numplayers; ++iteration) | ||
597 | { | ||
598 | //g_nPlayerIDList[i] | ||
599 | for(k = iteration+1; k < gcom->numplayers; ++k) | ||
600 | { | ||
601 | if(allowed_addresses[iteration].id == allowed_addresses[k].id) | ||
602 | { | ||
603 | printf("ERROR!!!!! Two players with the same Unique ID found, please restart...\n"); | ||
604 | } | ||
605 | else | ||
606 | { | ||
607 | // if it's valid, then goto sort it | ||
608 | if(allowed_addresses[k].id > allowed_addresses[iteration].id) | ||
609 | { | ||
610 | //swap'm | ||
611 | //unsigned short nTemp = allowed_addresses[iteration]; | ||
612 | ADDRESS_STRUCT tempAddress; | ||
613 | |||
614 | // Swap the positions | ||
615 | memcpy(&tempAddress, &allowed_addresses[iteration], sizeof(ADDRESS_STRUCT)); | ||
616 | memcpy(&allowed_addresses[iteration], &allowed_addresses[k], sizeof(ADDRESS_STRUCT)); | ||
617 | memcpy(&allowed_addresses[k], &tempAddress, sizeof(ADDRESS_STRUCT)); | ||
618 | } | ||
619 | } | ||
620 | } | ||
621 | |||
622 | } | ||
623 | |||
624 | // Find our slot | ||
625 | printf("Finding our player index...\n"); | ||
626 | |||
627 | for(i = 0; i < (gcom->numplayers); ++i) | ||
628 | { | ||
629 | printf("Index[%d] = %d\n", i, allowed_addresses[i].id); | ||
630 | |||
631 | |||
632 | if(allowed_addresses[i].id == my_id) | ||
633 | { | ||
634 | gcom->myconnectindex = i; | ||
635 | printf("You are player #%d\n", i); | ||
636 | |||
637 | // We're all greated, switch to waiting for all ready | ||
638 | g_ConnMode = CONN_MODE_WAITFORREADY; | ||
639 | break; | ||
640 | } | ||
641 | |||
642 | } | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | |||
647 | } | ||
648 | |||
649 | void Wait_For_Ready() | ||
650 | { | ||
651 | |||
652 | g_bWaitingForAllReady = gcom->numplayers-1; | ||
653 | |||
654 | // Create the greeting packet | ||
655 | unsigned char message = HEADER_PEER_READY; | ||
656 | |||
657 | ENetPacket * packet = enet_packet_create (&message, sizeof(unsigned char), ENET_PACKET_FLAG_RELIABLE);//ENET_PACKET_FLAG_RELIABLE | ||
658 | |||
659 | printf("Broadcasting Ready Packet...\n"); | ||
660 | |||
661 | // Broadcast it to all the peers | ||
662 | enet_host_broadcast(g_Server, 0, packet); | ||
663 | |||
664 | // Flush the send buffer | ||
665 | enet_host_flush(g_Server); | ||
666 | |||
667 | //g_ConnMode = CONN_MODE_CONNECTED;//CONN_MODE_WAITFORREADY; | ||
668 | |||
669 | while(g_bWaitingForAllReady > 0) | ||
670 | { | ||
671 | ENetEvent event; | ||
672 | if (enet_host_service (g_Server, & event, CONNECTION_DELAY) > 0) | ||
673 | { | ||
674 | int i; | ||
675 | |||
676 | HandleEvent(&event); | ||
677 | |||
678 | g_bWaitingForAllReady = gcom->numplayers-1; | ||
679 | for(i = 0; i < gcom->numplayers; ++i) | ||
680 | { | ||
681 | if(allowed_addresses[i].bReady == 1) | ||
682 | { | ||
683 | --g_bWaitingForAllReady; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | // Check to make sure we didn't subtract 1 from 0 to make 255. (unsigned char) | ||
688 | if(g_bWaitingForAllReady > gcom->numplayers) | ||
689 | { | ||
690 | printf("Error: we have a problem with the waiting for ready packets...\n"); | ||
691 | } | ||
692 | |||
693 | } | ||
694 | } | ||
695 | |||
696 | printf("All players are ready. Start sending game data...\n"); | ||
697 | |||
698 | g_ConnMode = CONN_MODE_CONNECTED; | ||
699 | } | ||
700 | |||
701 | void HandleEvent(ENetEvent *pEvent) | ||
702 | { | ||
703 | switch(pEvent->type) | ||
704 | { | ||
705 | case ENET_EVENT_TYPE_CONNECT: | ||
706 | { | ||
707 | //bServerConnected = true; | ||
708 | ENetAddress address; | ||
709 | int i; | ||
710 | |||
711 | address.host = pEvent->peer->address.host; //ip; | ||
712 | address.port = pEvent->peer->address.port; //m_nPort; | ||
713 | char szHostName[64]; | ||
714 | enet_address_get_host(&address, szHostName, 64); | ||
715 | |||
716 | printf("Connection Established with: (%s)\n", szHostName); | ||
717 | |||
718 | for(i = 0; i < gcom->numplayers-1; ++i) | ||
719 | { | ||
720 | if(allowed_addresses[i].host == address.host) | ||
721 | { | ||
722 | allowed_addresses[i].bHeardFrom = 1; | ||
723 | } | ||
724 | } | ||
725 | |||
726 | for(i = 0; i < gcom->numplayers-1; ++i) | ||
727 | { | ||
728 | if(allowed_addresses[i].bHeardFrom == 0) | ||
729 | { | ||
730 | return; | ||
731 | } | ||
732 | } | ||
733 | |||
734 | // All players have been found... YAY! | ||
735 | g_bAllPlayersFound = 1; | ||
736 | printf("All Players Connected...\n"); | ||
737 | |||
738 | } | ||
739 | break; | ||
740 | case ENET_EVENT_TYPE_RECEIVE: | ||
741 | { | ||
742 | g_nMessageLen = (short)pEvent->packet->dataLength; | ||
743 | |||
744 | |||
745 | |||
746 | switch(g_ConnMode) | ||
747 | { | ||
748 | |||
749 | case CONN_MODE_GREETING: | ||
750 | { | ||
751 | PacketPeerGreeting packet; | ||
752 | unsigned int nPeerIndex; | ||
753 | int i; | ||
754 | |||
755 | if(pEvent->packet->data[0] != HEADER_PEER_GREETING) | ||
756 | { | ||
757 | printf("Invalid greeting!!!!\n"); | ||
758 | } | ||
759 | |||
760 | printf("Received greeting from (%x)...\n", pEvent->peer->address.host); | ||
761 | |||
762 | memcpy(&packet, pEvent->packet->data, g_nMessageLen); | ||
763 | if(packet.header == HEADER_PEER_GREETING) | ||
764 | { | ||
765 | // Find the peer's index | ||
766 | nPeerIndex = GetPeerIndex(pEvent->peer); | ||
767 | |||
768 | // Set the id for the peer | ||
769 | //g_nPlayerIDList[nPeerIndex] = packet.id; | ||
770 | allowed_addresses[nPeerIndex].id = packet.id; | ||
771 | |||
772 | } | ||
773 | } | ||
774 | break; | ||
775 | case CONN_MODE_WAITFORREADY: | ||
776 | { | ||
777 | if(pEvent->packet->data[0] == HEADER_PEER_READY) | ||
778 | { | ||
779 | allowed_addresses[GetOtherIndex(pEvent->peer)].bReady = 1; | ||
780 | } | ||
781 | else | ||
782 | { | ||
783 | printf("Invalid READY packet!!!\n"); | ||
784 | } | ||
785 | |||
786 | |||
787 | } | ||
788 | break; | ||
789 | case CONN_MODE_CONNECTED: | ||
790 | default: | ||
791 | { | ||
792 | if(g_ConnMode != CONN_MODE_CONNECTED) | ||
793 | { | ||
794 | PACKET packet; | ||
795 | packet.other = GetOtherIndex(pEvent->peer); | ||
796 | packet.bufferSize = g_nMessageLen; | ||
797 | memcpy(packet.buffer, pEvent->packet->data, g_nMessageLen); | ||
798 | incommingPacketQueue.push_back(packet); | ||
799 | printf("Saving early packet...\n"); | ||
800 | break; | ||
801 | } | ||
802 | |||
803 | if(pEvent->packet->data[0] == 16) | ||
804 | { | ||
805 | printf("PACKET 16: len:[%d]\n", g_nMessageLen); | ||
806 | } | ||
807 | |||
808 | #ifdef _DEBUG_NETWORKING_LEVEL2_ | ||
809 | printf("RECEIVE: type[%d] len:[%d]\n", pEvent->packet->data[0], g_nMessageLen); | ||
810 | #endif | ||
811 | memcpy(&lastpacket[0], pEvent->packet->data, g_nMessageLen); | ||
812 | *g_other = GetOtherIndex(pEvent->peer); | ||
813 | } | ||
814 | break; | ||
815 | } | ||
816 | |||
817 | /*if(g_nMessageLen > 0) | ||
818 | { | ||
819 | switch(pEvent->packet->data[0]) | ||
820 | { | ||
821 | case HEADER_PEER_GREETING: | ||
822 | { | ||
823 | PacketPeerGreeting packet; | ||
824 | unsigned int nPeerIndex; | ||
825 | int i; | ||
826 | |||
827 | printf("Received greeting from (%x)...\n", pEvent->peer->address.host); | ||
828 | |||
829 | memcpy(&packet, pEvent->packet->data, g_nMessageLen); | ||
830 | if(packet.header == HEADER_PEER_GREETING) | ||
831 | { | ||
832 | // Find the peer's index in the g_Peers[] array | ||
833 | nPeerIndex = GetPeerIndex(pEvent->peer); | ||
834 | |||
835 | // Set the id for the peer | ||
836 | //g_nPlayerIDList[nPeerIndex] = packet.id; | ||
837 | allowed_addresses[nPeerIndex].id = packet.id; | ||
838 | |||
839 | } | ||
840 | } | ||
841 | break; | ||
842 | case HEADER_PEER_READY: | ||
843 | { | ||
844 | unsigned int nOtherIndex; | ||
845 | |||
846 | printf("Received ready from (%x)...\n", pEvent->peer->address.host); | ||
847 | nOtherIndex = GetOtherIndex(pEvent->peer); | ||
848 | |||
849 | allowed_addresses[nOtherIndex].bReady = 1; | ||
850 | |||
851 | } | ||
852 | break; | ||
853 | |||
854 | |||
855 | default: | ||
856 | { | ||
857 | |||
858 | if((g_bWaitingForAllReady) || (g_ConnMode == CONN_MODE_GREETING)) | ||
859 | { | ||
860 | PACKET packet; | ||
861 | packet.other = GetOtherIndex(pEvent->peer); | ||
862 | packet.bufferSize = g_nMessageLen; | ||
863 | memcpy(packet.buffer, pEvent->packet->data, g_nMessageLen); | ||
864 | incommingPacketQueue.push_back(packet); | ||
865 | printf("Saving early packet...\n"); | ||
866 | break; | ||
867 | } | ||
868 | |||
869 | |||
870 | #ifdef _DEBUG_NETWORKING_LEVEL2_ | ||
871 | printf("RECEIVE: type[%d] len:[%d]\n", pEvent->packet->data[0], g_nMessageLen); | ||
872 | #endif | ||
873 | memcpy(&lastpacket[0], pEvent->packet->data, g_nMessageLen); | ||
874 | |||
875 | // find the correct index in the allowed_addresses[] array. | ||
876 | *g_other = GetOtherIndex(pEvent->peer); | ||
877 | } | ||
878 | break; | ||
879 | } | ||
880 | } | ||
881 | else | ||
882 | { | ||
883 | printf("Error: we received a Zero length packet!\n"); | ||
884 | }*/ | ||
885 | |||
886 | // Destroy the packet now that we're done with it. | ||
887 | enet_packet_destroy (pEvent->packet); | ||
888 | } | ||
889 | break; | ||
890 | case ENET_EVENT_TYPE_DISCONNECT: | ||
891 | { | ||
892 | printf("DISCONNECT: someone left!\n"); | ||
893 | } | ||
894 | break; | ||
895 | default: | ||
896 | { | ||
897 | printf("Error: unknown event! : %d\n", pEvent->type); | ||
898 | } | ||
899 | break; | ||
900 | } | ||
901 | } | ||
902 | |||
903 | unsigned int GetPeerIndex(ENetPeer* peer) | ||
904 | { | ||
905 | int i; | ||
906 | for(i = 0; i < gcom->numplayers; ++i) | ||
907 | { | ||
908 | if(peer->address.host == allowed_addresses[i].host) | ||
909 | { | ||
910 | return allowed_addresses[i].peer_idx; | ||
911 | //return i; | ||
912 | } | ||
913 | } | ||
914 | |||
915 | printf("Error: GetPeerIndex failed to find the corrent index!\n"); | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | unsigned int GetOtherIndex(ENetPeer* peer) | ||
920 | { | ||
921 | int i; | ||
922 | for(i = 0; i < gcom->numplayers; ++i) | ||
923 | { | ||
924 | if(peer->address.host == allowed_addresses[i].host) | ||
925 | { | ||
926 | return i;//allowed_addresses[i].peer_idx; | ||
927 | //return i; | ||
928 | } | ||
929 | } | ||
930 | |||
931 | printf("Error: GetOtherIndex failed to find the corrent index!\n"); | ||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | void ServiceNetwork() | ||
936 | { | ||
937 | ENetEvent event; | ||
938 | if (enet_host_service (g_Server, & event, INGAME_CONNECTION_DELAY) > 0) | ||
939 | { | ||
940 | HandleEvent(&event); | ||
941 | } | ||
942 | } | ||
943 | |||
944 | //************************************************************** | ||
945 | //* Network Transport Functions | ||
946 | //************************************************************** | ||
947 | int CreateServer(char* ip, int nPort, int nMaxPlayers) | ||
948 | { | ||
949 | |||
950 | ENetAddress address; | ||
951 | |||
952 | printf("Creating server of %d players on port %d.\n", nMaxPlayers, nPort); | ||
953 | |||
954 | /* Bind the server to the default localhost. | ||
955 | * A specific host address can be specified by | ||
956 | * enet_address_set_host (& address, "x.x.x.x"); | ||
957 | */ | ||
958 | address.host = enet_address_set_host (& address, ip);//nIp;//ENET_HOST_ANY; | ||
959 | /* Bind the server to port 1234. */ | ||
960 | address.port = nPort; | ||
961 | |||
962 | g_Server = enet_host_create (& address /* the address to bind the server host to */, | ||
963 | nMaxPlayers /* allow up to 32 clients and/or outgoing connections */, | ||
964 | 0 /* assume any amount of incoming bandwidth */, | ||
965 | 0 /* assume any amount of outgoing bandwidth */); | ||
966 | |||
967 | if (g_Server == NULL) | ||
968 | { | ||
969 | printf("Error creating server!\n"); | ||
970 | return 1; | ||
971 | } | ||
972 | |||
973 | return 0; | ||
974 | } | ||
975 | |||
976 | //************************************************************** | ||
977 | //* Network Config File Functions | ||
978 | //************************************************************** | ||
979 | |||
980 | #include "cache1d.h" /* kopen4load for cfg file. */ | ||
981 | #include "display.h" /* getticks */ | ||
982 | |||
983 | #define IPSEG1(ip) ((((unsigned int) ip) & 0xFF000000) >> 24) | ||
984 | #define IPSEG2(ip) ((((unsigned int) ip) & 0x00FF0000) >> 16) | ||
985 | #define IPSEG3(ip) ((((unsigned int) ip) & 0x0000FF00) >> 8) | ||
986 | #define IPSEG4(ip) ((((unsigned int) ip) & 0x000000FF) ) | ||
987 | |||
988 | char *static_ipstring(int ip) | ||
989 | { | ||
990 | static char s[16]; | ||
991 | sprintf(s, "%u.%u.%u.%u", IPSEG1(ip), IPSEG2(ip), IPSEG3(ip), IPSEG4(ip)); | ||
992 | return(s); | ||
993 | } | ||
994 | |||
995 | char *read_whole_file(const char *cfgfile) | ||
996 | { | ||
997 | char *buf; | ||
998 | long len, rc; | ||
999 | long handle; | ||
1000 | |||
1001 | if (cfgfile == NULL) | ||
1002 | return(NULL); | ||
1003 | |||
1004 | handle = kopen4load(cfgfile, 0); | ||
1005 | if (handle == -1) | ||
1006 | { | ||
1007 | printf("ERROR: Failed to open config file [%s].\n", cfgfile); | ||
1008 | return(NULL); | ||
1009 | } | ||
1010 | |||
1011 | len = kfilelength(handle); | ||
1012 | buf = (char *) malloc(len + 2); | ||
1013 | if (!buf) | ||
1014 | { | ||
1015 | kclose(handle); | ||
1016 | return(NULL); | ||
1017 | } | ||
1018 | |||
1019 | rc = kread(handle, buf, len); | ||
1020 | kclose(handle); | ||
1021 | if (rc != len) | ||
1022 | { | ||
1023 | free(buf); | ||
1024 | return(NULL); | ||
1025 | } | ||
1026 | |||
1027 | buf[len] = '\0'; | ||
1028 | buf[len+1] = '\0'; | ||
1029 | return(buf); | ||
1030 | } | ||
1031 | |||
1032 | char *get_token(char **ptr) | ||
1033 | { | ||
1034 | char *retval; | ||
1035 | char *p = *ptr; | ||
1036 | if (*p == '\0') | ||
1037 | return(NULL); | ||
1038 | |||
1039 | while ((*p != '\0') && (isspace(*p))) | ||
1040 | p++; | ||
1041 | |||
1042 | if (*p == '\0') /* nothing but whitespace. */ | ||
1043 | return(NULL); | ||
1044 | |||
1045 | retval = p; | ||
1046 | while ((*p != '\0') && (!isspace(*p))) | ||
1047 | p++; | ||
1048 | |||
1049 | *p = '\0'; | ||
1050 | *ptr = p + 1; | ||
1051 | |||
1052 | /*printf("Got token [%s].\n", retval);*/ | ||
1053 | return(retval); | ||
1054 | } | ||
1055 | |||
1056 | int parse_ip(const char *str, int *ip) | ||
1057 | { | ||
1058 | int ip1, ip2, ip3, ip4; | ||
1059 | |||
1060 | if (stricmp(str, "any") == 0) | ||
1061 | { | ||
1062 | *ip = 0; | ||
1063 | return(1); | ||
1064 | } | ||
1065 | |||
1066 | if (sscanf(str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) | ||
1067 | { | ||
1068 | printf("\"%s\" is not a valid IP address.\n", str); | ||
1069 | return(0); | ||
1070 | } | ||
1071 | |||
1072 | /* we _should_ check that 0 <= ip? <= 255, but it'll fail later anyhow. */ | ||
1073 | |||
1074 | *ip = ( ((ip1 & 0xFF) << 24) | | ||
1075 | ((ip2 & 0xFF) << 16) | | ||
1076 | ((ip3 & 0xFF) << 8) | | ||
1077 | ((ip4 & 0xFF) ) ); | ||
1078 | |||
1079 | return(1); | ||
1080 | } | ||
1081 | |||
1082 | int parse_interface(char *str, int *ip, short *udpport) | ||
1083 | { | ||
1084 | char *ptr = strchr(str, ':'); | ||
1085 | if (ptr) /* portnum specified? */ | ||
1086 | *ptr = '\0'; | ||
1087 | |||
1088 | if (!parse_ip(str, ip)) | ||
1089 | return(0); | ||
1090 | |||
1091 | *udpport = BUILD_DEFAULT_UDP_PORT; | ||
1092 | if (ptr != NULL) /* port specified? */ | ||
1093 | { | ||
1094 | ptr++; | ||
1095 | if (stricmp(ptr, "any") == 0) | ||
1096 | *udpport = 0; | ||
1097 | else | ||
1098 | *udpport = (short) atoi(ptr); | ||
1099 | } | ||
1100 | |||
1101 | return(1); | ||
1102 | } | ||
1103 | |||
1104 | int parse_udp_config(const char *cfgfile, gcomtype *gcom) | ||
1105 | { | ||
1106 | char *buf; | ||
1107 | char *tok; | ||
1108 | char *ptr; | ||
1109 | int ip = 0; /* interface */ | ||
1110 | int bcast = 0; | ||
1111 | |||
1112 | buf = read_whole_file(cfgfile); /* we must free this. */ | ||
1113 | if (buf == NULL) | ||
1114 | return(0); | ||
1115 | |||
1116 | ptr = buf; | ||
1117 | while ((tok = get_token(&ptr)) != NULL) | ||
1118 | { | ||
1119 | int bogus = 1; | ||
1120 | |||
1121 | if (stricmp(tok, "interface") == 0) | ||
1122 | { | ||
1123 | if ( (tok = get_token(&ptr)) && | ||
1124 | (parse_interface(tok, &ip, &udpport)) ) | ||
1125 | { | ||
1126 | bogus = 0; | ||
1127 | } | ||
1128 | printf("Interface %s:%d chosen.\n", | ||
1129 | static_ipstring(ip), (int) udpport); | ||
1130 | } | ||
1131 | |||
1132 | else if (stricmp(tok, "mode") == 0) | ||
1133 | { | ||
1134 | if ((tok = get_token(&ptr)) != NULL) | ||
1135 | { | ||
1136 | bogus = 0; | ||
1137 | if (stricmp(tok, "server") == 0) | ||
1138 | udpmode = udpmode_server; | ||
1139 | else if (stricmp(tok, "client") == 0) | ||
1140 | udpmode = udpmode_client; | ||
1141 | else if (stricmp(tok, "peer") == 0) | ||
1142 | udpmode = udpmode_peer; | ||
1143 | else | ||
1144 | bogus = 1; | ||
1145 | |||
1146 | if (!bogus) | ||
1147 | printf("You want to be in [%s] mode\n", tok); | ||
1148 | } | ||
1149 | } | ||
1150 | |||
1151 | else if (stricmp(tok, "broadcast") == 0) | ||
1152 | { | ||
1153 | if ((tok = get_token(&ptr)) != NULL) | ||
1154 | { | ||
1155 | bcast = atoi(tok); | ||
1156 | if (bcast > MAX_PLAYERS - 1) | ||
1157 | { | ||
1158 | printf("WARNING: Too many broadcast players.\n"); | ||
1159 | bcast = MAX_PLAYERS - 1; | ||
1160 | } | ||
1161 | |||
1162 | bogus = 0; | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | else if (stricmp(tok, "allow") == 0) | ||
1167 | { | ||
1168 | int host; | ||
1169 | short port=BUILD_DEFAULT_UDP_PORT; | ||
1170 | if ((tok = get_token(&ptr)) != NULL) | ||
1171 | { | ||
1172 | if (gcom->numplayers >= MAX_PLAYERS - 1) | ||
1173 | printf("WARNING: Too many allowed IP addresses.\n"); | ||
1174 | |||
1175 | else if (parse_interface(tok, &host, &port)) | ||
1176 | { | ||
1177 | ENetAddress address; | ||
1178 | enet_address_set_host(&address, static_ipstring(host)); | ||
1179 | printf("Adding: %s:%d to the list of allowed addresses.\n", static_ipstring(host), port); | ||
1180 | allowed_addresses[gcom->numplayers].host = address.host; | ||
1181 | allowed_addresses[gcom->numplayers].port = port; | ||
1182 | gcom->numplayers++; | ||
1183 | bogus = 0; | ||
1184 | } | ||
1185 | } | ||
1186 | } | ||
1187 | |||
1188 | if (bogus) | ||
1189 | printf("bogus token! [%s]\n", tok); | ||
1190 | } | ||
1191 | |||
1192 | free(buf); | ||
1193 | |||
1194 | // Create the server | ||
1195 | int ret = CreateServer(static_ipstring(ip), udpport, gcom->numplayers); | ||
1196 | gcom->numplayers++; //that's you | ||
1197 | |||
1198 | if(ret == 0) | ||
1199 | { | ||
1200 | return 1; | ||
1201 | } | ||
1202 | |||
1203 | return(0); | ||
1204 | } | ||
1205 | |||
1206 | |||
1207 | |||
1208 | |||
1209 | } // end extern "C" | ||
1210 | |||
1211 | /* end of mmulti.cpp ... */ | ||
1212 | |||
1213 | |||