1 /*
2 * XFrisk - The classic board game for X
3 * Copyright (C) 1993-1999 Elan Feingold (elan@aetherworks.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id: network.c,v 1.6 1999/12/26 15:06:09 morphy Exp $
20 *
21 * $Log: network.c,v $
22 * Revision 1.6 1999/12/26 15:06:09 morphy
23 * Doxygen comments
24 * Added static qualifier to local functions
25 * Miscellaneous editorial changes
26 *
27 */
28
29 /**
30 * Messaging interface to/from the network.
31 */
32
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <netdb.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41
42 #include "riskgame.h"
43 #include "types.h"
44 #include "network.h"
45 #include "debug.h"
46
47 /* Useful macro */
48 #define ReturnIfError(foo) if ((foo) <= 0) return (-1);
49
50 /* Local prototypes */
51 static Int32 _NET_SendString(Int32 iSocket, CString strCString);
52 static Int32 _NET_SendLong(Int32 iSocket, Int32 iLong);
53 static Int32 _NET_RecvString(Int32 iSocket, CString *pstrCString);
54 static Int32 _NET_SocketRead(Int32 iSocket, void *ptr, Int32 iNumBytes);
55 static Int32 _NET_SocketWrite(Int32 iSocket, void *ptr, Int32 iNumBytes);
56 static Int32 _NET_RecvLong(Int32 iSocket, Int32 *piLong);
57
58 /* Private to this routine */
59 static char strLogging[1024];
60
61
62 /**
63 * Send a message to the given socket, field by field.
64 *
65 * \bug void pointer
66 * \bug massive switch - case construct
67 *
68 * \b History:
69 * \arg 01.24.94 ESF Created
70 * \arg 01.28.94 ESF Added strFrom in MSG_MESSAGEPACKET.
71 * \arg 03.04.94 ESF Changed MSG_UPDATE mesage.
72 * \arg 03.05.94 ESF Added MSG_ENTERSTATE for fault tolerance.
73 * \arg 03.28.94 ESF Added MSG_DEADPLAYER & MSG_ENDOFGAME.
74 * \arg 03.28.94 ESF Changed MSG_REQUESTCARDS to ...CARD.
75 * \arg 03.29.94 ESF Changed MSG_UPDATECARDS to MSG_EXCHANGECARDS.
76 * \arg 03.29.94 ESF Changed uiReply to be an Int32.
77 * \arg 04.11.94 ESF Added a player parameter to MSG_CARDPACKET.
78 * \arg 04.11.94 ESF Added a killer paramter to MSG_DEADPLAYER.
79 * \arg 05.03.94 ESF Added MSG_OBJ*UPDATE msgs.
80 * \arg 05.03.94 ESF Removed MSG_REGISTERPLAYER and MSG_UPDATEARMIES.
81 * \arg 05.05.94 ESF Added MSG_OBJ* msgs.
82 * \arg 05.12.94 ESF Removed MSG_OBJ* msgs and added GAME messages.
83 * \arg 05.12.94 ESF Added MSG_DEREGISTERCLIENT.
84 * \arg 05.12.94 ESF Added MSG_DELETEMSGDST.
85 * \arg 05.13.94 ESF Added MSG_STARTREGISTRATION.
86 * \arg 05.15.94 ESF Added MSG_[FREE|ALLOC]PLAYER
87 * \arg 05.15.94 ESF Removed MSG_DEADPLAYER.
88 * \arg 05.17.94 ESF Added MSG_NETMESSAGE.
89 * \arg 07.27.94 ESF Removed MSG_STARTREGISTRATION.
90 * \arg 07.31.94 ESF Added MSG_NETPOPUP.
91 * \arg 08.03.94 ESF Fixed to return error message.
92 * \arg 08.28.94 ESF Added MSG_POPUPREGISTERBOX.
93 * \arg 09.31.94 ESF Changed MSG_ENDOFGAME to take a string parameter.
94 * \arg 10.29.94 ESF Added MSG_DICEROLL.
95 * \arg 10.30.94 ESF Added MSG_PLACENOTIFY.
96 * \arg 10.30.94 ESF Added MSG_ATTACKNOTIFY.
97 * \arg 10.30.94 ESF Added MSG_MOVENOTIFY.
98 * \arg 01.17.95 ESF Removed MSG_DELETEMSGDST.
99 * \arg 02.21.95 ESF Added MSG_HELLO, MSG_VERSION.
100 * \arg 02.21.95 ESF Modified MSG_REGISTERCLIENT to include type of client.
101 * \arg 02.23.95 ESF Added MSG_OLDREGISTERCLIENT for backwards compatibility.
102 * \arg 02.23.95 ESF Added MSG_SPECIESIDENT.
103 * \arg 24.08.95 JC Added MSG_MISSION.
104 * \arg 28.08.95 JC Added MSG_ENDOFMISSION and MSG_VICTORY.
105 * \arg 30.08.95 JC Added MSG_FORCEEXCHANGECARDS.
106 */
NET_SendMessage(Int32 iSocket,Int32 iMessType,void * pvMessage)107 Int32 NET_SendMessage(Int32 iSocket, Int32 iMessType, void *pvMessage)
108 {
109 Int32 i;
110
111 /* Send the message ID */
112 ReturnIfError(_NET_SendLong(iSocket, (Int32)iMessType));
113
114 switch(iMessType)
115 {
116 case MSG_OLDREGISTERCLIENT:
117 {
118 MsgOldRegisterClient *pmsgMess = (MsgOldRegisterClient *)pvMessage;
119
120 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strClientAddress));
121 }
122 break;
123
124 case MSG_REGISTERCLIENT:
125 {
126 MsgRegisterClient *pmsgMess = (MsgRegisterClient *)pvMessage;
127
128 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strClientAddress));
129 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iClientType));
130 }
131 break;
132
133 case MSG_EXCHANGECARDS:
134 {
135 MsgExchangeCards *pmsgMess = (MsgExchangeCards *)pvMessage;
136
137 for(i=0; i!=3; i++)
138 ReturnIfError(_NET_SendLong(iSocket, (Int32)pmsgMess->piCards[i]));
139 }
140 break;
141
142 case MSG_CARDPACKET:
143 {
144 MsgCardPacket *pmsgMess = (MsgCardPacket *)pvMessage;
145
146 ReturnIfError(_NET_SendLong(iSocket, (Int32)pmsgMess->iPlayer));
147 ReturnIfError(_NET_SendLong(iSocket, (Int32)pmsgMess->cdCard));
148 }
149 break;
150
151 case MSG_REPLYPACKET:
152 {
153 MsgReplyPacket *pmsgMess = (MsgReplyPacket *)pvMessage;
154
155 ReturnIfError(_NET_SendLong(iSocket, (Int32)pmsgMess->iReply));
156 }
157 break;
158
159 case MSG_SENDMESSAGE:
160 {
161 MsgSendMessage *pmsgMess = (MsgSendMessage *)pvMessage;
162
163 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strMessage));
164 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strDestination));
165 }
166 break;
167
168 case MSG_MESSAGEPACKET:
169 {
170 MsgMessagePacket *pmsgMess = (MsgMessagePacket *)pvMessage;
171
172 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strMessage));
173 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iFrom));
174 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iTo));
175 }
176 break;
177
178 case MSG_TURNNOTIFY:
179 {
180 MsgTurnNotify *pmsgMess = (MsgTurnNotify *)pvMessage;
181
182 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iPlayer));
183 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iClient));
184 }
185 break;
186
187 case MSG_CLIENTIDENT:
188 {
189 MsgClientIdent *pmsgMess = (MsgClientIdent *)pvMessage;
190 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iClientID));
191 }
192 break;
193
194 case MSG_REQUESTCARD:
195 {
196 MsgRequestCard *pmsgMess = (MsgRequestCard *)pvMessage;
197 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iPlayer));
198 }
199 break;
200
201 case MSG_ENTERSTATE:
202 {
203 MsgEnterState *pmsgMess = (MsgEnterState *)pvMessage;
204 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iState));
205 }
206 break;
207
208 case MSG_OBJSTRUPDATE:
209 {
210 MsgObjStrUpdate *pmsgMess = (MsgObjStrUpdate *)pvMessage;
211 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iField));
212 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iIndex1));
213 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iIndex2));
214 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strNewValue));
215 }
216 break;
217
218 case MSG_OBJINTUPDATE:
219 {
220 MsgObjIntUpdate *pmsgMess = (MsgObjIntUpdate *)pvMessage;
221 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iField));
222 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iIndex1));
223 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iIndex2));
224 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iNewValue));
225 }
226 break;
227
228 case MSG_FREEPLAYER:
229 {
230 MsgFreePlayer *pmsgMess = (MsgFreePlayer *)pvMessage;
231 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iPlayer));
232 }
233 break;
234
235 /* These happen to be identical, so we can lump them. */
236 case MSG_NETMESSAGE:
237 case MSG_NETPOPUP:
238 {
239 MsgNetMessage *pmsgMess = (MsgNetMessage *)pvMessage;
240 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strMessage));
241 }
242 break;
243
244 case MSG_ENDOFMISSION:
245 {
246 MsgEndOfMission *pmsgMess = (MsgEndOfMission *)pvMessage;
247 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iWinner));
248 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iTyp));
249 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iNum1));
250 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iNum2));
251 }
252 break;
253
254 case MSG_VICTORY:
255 {
256 MsgVictory *pmsgMess = (MsgVictory *)pvMessage;
257 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iWinner));
258 }
259 break;
260
261 case MSG_DICEROLL:
262 {
263 MsgDiceRoll *pmsgMess = (MsgDiceRoll *)pvMessage;
264
265 for (i=0; i!=3; i++)
266 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->pAttackDice[i]));
267
268 for (i=0; i!=3; i++)
269 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->pDefendDice[i]));
270
271 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iDefendingPlayer));
272 }
273 break;
274
275 case MSG_PLACENOTIFY:
276 {
277 MsgPlaceNotify *pmsgMess = (MsgPlaceNotify *)pvMessage;
278
279 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iCountry));
280 }
281 break;
282
283 case MSG_ATTACKNOTIFY:
284 {
285 MsgAttackNotify *pmsgMess = (MsgAttackNotify *)pvMessage;
286
287 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iSrcCountry));
288 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iDstCountry));
289 }
290 break;
291
292 case MSG_MOVENOTIFY:
293 {
294 MsgMoveNotify *pmsgMess = (MsgMoveNotify *)pvMessage;
295
296 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iSrcCountry));
297 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iDstCountry));
298 }
299 break;
300
301 case MSG_VERSION:
302 {
303 MsgVersion *pmsgMess = (MsgVersion *)pvMessage;
304
305 ReturnIfError(_NET_SendString(iSocket, pmsgMess->strVersion));
306 }
307 break;
308
309 case MSG_SPECIESIDENT:
310 {
311 MsgSpeciesIdent *pmsgMess = (MsgSpeciesIdent *)pvMessage;
312
313 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iSpeciesID));
314 }
315 break;
316
317 case MSG_FORCEEXCHANGECARDS:
318 {
319 MsgForceExchangeCards *pmsgMess = (MsgForceExchangeCards *)pvMessage;
320
321 ReturnIfError(_NET_SendLong(iSocket, pmsgMess->iPlayer));
322 }
323
324 case MSG_EXIT:
325 case MSG_STARTGAME:
326 case MSG_ENDTURN:
327 case MSG_DEREGISTERCLIENT:
328 case MSG_ALLOCPLAYER:
329 case MSG_POPUPREGISTERBOX:
330 case MSG_HELLO:
331 case MSG_MISSION:
332 case MSG_ENDOFGAME:
333 /* No parameters */
334 break;
335
336 default:
337 printf("NETWORK: Illegal message!\n");
338 }
339
340 return (1);
341 }
342
343
344 /**
345 * Receive one message from the network, field by field.
346 *
347 * \bug pointer to void pointer
348 * \bug massive switch - case construct
349 *
350 * \b History:
351 * \arg 01.24.94 ESF Created.
352 * \arg 01.27.94 ESF Fixed bug in MSG_MESSAGEPACKET case.
353 * \arg 01.28.94 ESF Added strFrom in MSG_MESSAGEPACKET.
354 * \arg 03.04.94 ESF Changed _UPDATE mesage.
355 * \arg 03.05.94 ESF Added _ENTERSTATE for fault tolerance.
356 * \arg 03.28.94 ESF Added MSG_DEADPLAYER & MSG_ENDOFGAME.
357 * \arg 03.28.94 ESF Changed MSG_REQUESTCARDS to ...CARD.
358 * \arg 03.29.94 ESF Changed MSG_UPDATECARDS to MSG_EXCHANGECARDS.
359 * \arg 03.29.94 ESF Changed uiReply to be an Int32.
360 * \arg 04.11.94 ESF Added a player parameter to MSG_CARDPACKET.
361 * \arg 04.11.94 ESF Added a killer paramter to MSG_DEADPLAYER.
362 * \arg 05.03.94 ESF Added MSG_OBJ*UPDATE msgs.
363 * \arg 05.03.94 ESF Removed MSG_REGISTERPLAYER and MSG_UPDATEARMIES.
364 * \arg 05.05.94 ESF Added MSG_OBJ* msgs.
365 * \arg 05.12.94 ESF Removed MSG_OBJ* msgs and added GAME messages.
366 * \arg 05.12.94 ESF Added MSG_DEREGISTERCLIENT.
367 * \arg 05.12.94 ESF Added MSG_DELETEMSGDST.
368 * \arg 05.13.94 ESF Added MSG_STARTREGISTRATION.
369 * \arg 05.15.94 ESF Added MSG_[FREE|ALLOC]PLAYER
370 * \arg 05.15.94 ESF Removed MSG_DEADPLAYER.
371 * \arg 05.17.94 ESF Added MSG_NETMESSAGE.
372 * \arg 07.27.94 ESF Removed MSG_STARTREGISTRATION.
373 * \arg 07.31.94 ESF Added MSG_NETPOPUP.
374 * \arg 08.03.94 ESF Fixed to return error message.
375 * \arg 08.28.94 ESF Added MSG_POPUPREGISTERBOX.
376 * \arg 09.31.94 ESF Changed MSG_ENDOFGAME to take a string parameter.
377 * \arg 10.29.94 ESF Added MSG_DICEROLL.
378 * \arg 10.30.94 ESF Added MSG_PLACENOTIFY.
379 * \arg 10.30.94 ESF Added MSG_ATTACKNOTIFY.
380 * \arg 10.30.94 ESF Added MSG_MOVENOTIFY.
381 * \arg 01.17.95 ESF Removed MSG_DELETEMSGDST.
382 * \arg 02.21.95 ESF Added MSG_HELLO, MSG_VERSION.
383 * \arg 02.21.95 ESF Modified MSG_REGISTERCLIENT to include type of client.
384 * \arg 02.23.95 ESF Added MSG_OLDREGISTERCLIENT.
385 * \arg 02.23.95 ESF Added MSG_SPECIESIDENT.
386 * \arg 24.08.95 JC Added MSG_MISSION.
387 * \arg 28.08.95 JC Added MSG_ENDOFMISSION and MSG_VICTORY.
388 * \arg 30.08.95 JC Added MSG_FORCEEXCHANGECARDS.
389 */
NET_RecvMessage(Int32 iSocket,Int32 * piMessType,void ** ppvMessage)390 Int32 NET_RecvMessage(Int32 iSocket, Int32 *piMessType, void **ppvMessage)
391 {
392 Int32 i;
393
394 /* Get the message ID */
395 ReturnIfError(_NET_RecvLong(iSocket, (Int32 *)piMessType));
396
397 switch(*piMessType)
398 {
399 case MSG_OLDREGISTERCLIENT:
400 {
401 MsgOldRegisterClient *pmsgMess =
402 (MsgOldRegisterClient *)MEM_Alloc(sizeof(MsgOldRegisterClient));
403
404 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strClientAddress));
405
406 *ppvMessage = (void *)pmsgMess;
407 }
408 break;
409
410 case MSG_REGISTERCLIENT:
411 {
412 MsgRegisterClient *pmsgMess =
413 (MsgRegisterClient *)MEM_Alloc(sizeof(MsgRegisterClient));
414
415 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strClientAddress));
416 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iClientType));
417
418 *ppvMessage = (void *)pmsgMess;
419 }
420 break;
421
422 case MSG_EXCHANGECARDS:
423 {
424 MsgExchangeCards *pmsgMess =
425 (MsgExchangeCards *)MEM_Alloc(sizeof(MsgExchangeCards));
426
427 for(i=0; i!=3; i++)
428 ReturnIfError(_NET_RecvLong(iSocket,
429 (Int32 *)&pmsgMess->piCards[i]));
430
431 *ppvMessage = (void *)pmsgMess;
432 }
433 break;
434
435 case MSG_CARDPACKET:
436 {
437 MsgCardPacket *pmsgMess =
438 (MsgCardPacket *)MEM_Alloc(sizeof(MsgCardPacket));
439
440 ReturnIfError(_NET_RecvLong(iSocket, (Int32 *)&pmsgMess->iPlayer));
441 ReturnIfError(_NET_RecvLong(iSocket, (Int32 *)&pmsgMess->cdCard));
442
443 *ppvMessage = (void *)pmsgMess;
444 }
445 break;
446
447 case MSG_REPLYPACKET:
448 {
449 MsgReplyPacket *pmsgMess =
450 (MsgReplyPacket *)MEM_Alloc(sizeof(MsgReplyPacket));
451
452 ReturnIfError(_NET_RecvLong(iSocket, (Int32 *)&pmsgMess->iReply));
453
454 *ppvMessage = (void *)pmsgMess;
455 }
456 break;
457
458 case MSG_SENDMESSAGE:
459 {
460 MsgSendMessage *pmsgMess =
461 (MsgSendMessage *)MEM_Alloc(sizeof(MsgSendMessage));
462
463 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strMessage));
464 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strDestination));
465
466 *ppvMessage = (void *)pmsgMess;
467 }
468 break;
469
470 case MSG_MESSAGEPACKET:
471 {
472 MsgMessagePacket *pmsgMess =
473 (MsgMessagePacket *)MEM_Alloc(sizeof(MsgMessagePacket));
474
475 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strMessage));
476 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iFrom));
477 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iTo));
478
479 *ppvMessage = (void *)pmsgMess;
480 }
481 break;
482
483 case MSG_TURNNOTIFY:
484 {
485 MsgTurnNotify *pmsgMess =
486 (MsgTurnNotify *)MEM_Alloc(sizeof(MsgTurnNotify));
487
488 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iPlayer));
489 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iClient));
490
491 *ppvMessage = (void *)pmsgMess;
492 }
493 break;
494
495 case MSG_CLIENTIDENT:
496 {
497 MsgClientIdent *pmsgMess =
498 (MsgClientIdent *)MEM_Alloc(sizeof(MsgClientIdent));
499
500 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iClientID));
501 *ppvMessage = (void *)pmsgMess;
502 }
503 break;
504
505 case MSG_REQUESTCARD:
506 {
507 MsgRequestCard *pmsgMess =
508 (MsgRequestCard *)MEM_Alloc(sizeof(MsgRequestCard));
509
510 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iPlayer));
511 *ppvMessage = (void *)pmsgMess;
512 }
513 break;
514
515 case MSG_ENTERSTATE:
516 {
517 MsgEnterState *pmsgMess =
518 (MsgEnterState *)MEM_Alloc(sizeof(MsgEnterState));
519
520 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iState));
521 *ppvMessage = (void *)pmsgMess;
522 }
523 break;
524
525 case MSG_OBJSTRUPDATE:
526 {
527 MsgObjStrUpdate *pmsgMess =
528 (MsgObjStrUpdate *)MEM_Alloc(sizeof(MsgObjStrUpdate));
529
530 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iField));
531 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iIndex1));
532 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iIndex2));
533 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strNewValue));
534 *ppvMessage = (void *)pmsgMess;
535 }
536 break;
537
538 case MSG_OBJINTUPDATE:
539 {
540 MsgObjIntUpdate *pmsgMess =
541 (MsgObjIntUpdate *)MEM_Alloc(sizeof(MsgObjIntUpdate));
542
543 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iField));
544 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iIndex1));
545 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iIndex2));
546 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iNewValue));
547 *ppvMessage = (void *)pmsgMess;
548 }
549 break;
550
551 case MSG_FREEPLAYER:
552 {
553 MsgFreePlayer *pmsgMess =
554 (MsgFreePlayer *)MEM_Alloc(sizeof(MsgFreePlayer));
555
556 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iPlayer));
557 *ppvMessage = (void *)pmsgMess;
558 }
559 break;
560
561 /* These happen to be identical, so we can lump them. */
562 case MSG_NETMESSAGE:
563 case MSG_NETPOPUP:
564 {
565 MsgNetMessage *pmsgMess =
566 (MsgNetMessage *)MEM_Alloc(sizeof(MsgNetMessage));
567
568 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strMessage));
569 *ppvMessage = (void *)pmsgMess;
570 }
571 break;
572
573 case MSG_ENDOFMISSION:
574 {
575 MsgEndOfMission *pmsgMess =
576 (MsgEndOfMission *)MEM_Alloc(sizeof(MsgEndOfMission));
577
578 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iWinner));
579 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iTyp));
580 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iNum1));
581 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iNum2));
582 *ppvMessage = (void *)pmsgMess;
583 }
584 break;
585
586 case MSG_VICTORY:
587 {
588 MsgVictory *pmsgMess =
589 (MsgVictory *)MEM_Alloc(sizeof(MsgVictory));
590
591 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iWinner));
592 *ppvMessage = (void *)pmsgMess;
593 }
594 break;
595
596 case MSG_DICEROLL:
597 {
598 MsgDiceRoll *pmsgMess =
599 (MsgDiceRoll *)MEM_Alloc(sizeof(MsgDiceRoll));
600
601 for (i=0; i!=3; i++)
602 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->pAttackDice[i]));
603
604 for (i=0; i!=3; i++)
605 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->pDefendDice[i]));
606
607 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iDefendingPlayer));
608
609 *ppvMessage = (void *)pmsgMess;
610 }
611 break;
612
613 case MSG_PLACENOTIFY:
614 {
615 MsgPlaceNotify *pmsgMess =
616 (MsgPlaceNotify *)MEM_Alloc(sizeof(MsgPlaceNotify));
617
618 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iCountry));
619
620 *ppvMessage = (void *)pmsgMess;
621 }
622 break;
623
624 case MSG_ATTACKNOTIFY:
625 {
626 MsgAttackNotify *pmsgMess =
627 (MsgAttackNotify *)MEM_Alloc(sizeof(MsgAttackNotify));
628
629 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iSrcCountry));
630 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iDstCountry));
631
632 *ppvMessage = (void *)pmsgMess;
633 }
634 break;
635
636 case MSG_MOVENOTIFY:
637 {
638 MsgMoveNotify *pmsgMess =
639 (MsgMoveNotify *)MEM_Alloc(sizeof(MsgMoveNotify));
640
641 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iSrcCountry));
642 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iDstCountry));
643
644 *ppvMessage = (void *)pmsgMess;
645 }
646 break;
647
648 case MSG_VERSION:
649 {
650 MsgVersion *pmsgMess =
651 (MsgVersion *)MEM_Alloc(sizeof(MsgVersion));
652
653 ReturnIfError(_NET_RecvString(iSocket, &pmsgMess->strVersion));
654
655 *ppvMessage = (void *)pmsgMess;
656 }
657 break;
658
659 case MSG_SPECIESIDENT:
660 {
661 MsgSpeciesIdent *pmsgMess =
662 (MsgSpeciesIdent *)MEM_Alloc(sizeof(MsgSpeciesIdent));
663
664 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iSpeciesID));
665
666 *ppvMessage = (void *)pmsgMess;
667 }
668 break;
669
670 case MSG_FORCEEXCHANGECARDS:
671 {
672 MsgForceExchangeCards *pmsgMess =
673 (MsgForceExchangeCards *)MEM_Alloc(sizeof(MsgForceExchangeCards));
674
675 ReturnIfError(_NET_RecvLong(iSocket, &pmsgMess->iPlayer));
676
677 *ppvMessage = (void *)pmsgMess;
678 }
679 break;
680
681 case MSG_EXIT:
682 case MSG_STARTGAME:
683 case MSG_ENDTURN:
684 case MSG_DEREGISTERCLIENT:
685 case MSG_ALLOCPLAYER:
686 case MSG_POPUPREGISTERBOX:
687 case MSG_HELLO:
688 case MSG_MISSION:
689 case MSG_ENDOFGAME:
690 *ppvMessage = NULL;
691 break;
692
693 default:
694 printf("NETWORK: Illegal message!\n");
695 }
696
697 return (1);
698 }
699
700 /************************************************************************
701 * FUNCTION: _NET_SendString
702 * HISTORY:
703 * 01.24.94 ESF Created.
704 * 08.03.94 ESF Fixed to return error message.
705 * 03.22.95 ESF Added handling for NULL strings.
706 * PURPOSE:
707 * NOTES:
708 ************************************************************************/
_NET_SendString(Int32 iSocket,CString strCString)709 static Int32 _NET_SendString(Int32 iSocket, CString strCString)
710 {
711 Int32 iLength;
712
713 /* Send the length and then the string itself */
714 if (strCString == NULL)
715 iLength = 0;
716 else
717 iLength = strlen(strCString)+1;
718
719 ReturnIfError(_NET_SendLong(iSocket, (Int32)iLength));
720 return (_NET_SocketWrite(iSocket, (Char *)strCString, (Int32)iLength));
721 }
722
723
724 /**
725 * Send a long integer to the given socket.
726 *
727 * \b History:
728 * 01.24.94 ESF Created
729 * 08.03.94 ESF Fixed to return error message.
730 */
_NET_SendLong(Int32 iSocket,Int32 iLong)731 static Int32 _NET_SendLong(Int32 iSocket, Int32 iLong)
732 {
733 Int32 iData = htonl(iLong);
734
735 return (_NET_SocketWrite(iSocket, &iData, sizeof(Int32)));
736 }
737
738
739 /**
740 * Receive a string from the given socket. First reads the length
741 * (32bit value), then the string data.
742 *
743 * \bug Assumes that a nul terminating byte is in the data stream
744 *
745 * \b History:
746 * \arg 01.24.94 ESF Created
747 * \arg 08.03.94 ESF Fixed to return error message.
748 * \arg 01.01.94 ESF Added check for correct number of bytes read.
749 * \arg 03.22.95 ESF Added handling for NULL strings.
750 */
_NET_RecvString(Int32 iSocket,CString * pstrCString)751 static Int32 _NET_RecvString(Int32 iSocket, CString *pstrCString)
752 {
753 Int32 iLength;
754 CString strTemp;
755 Int32 iRet;
756
757 /* Receive the length and then the byte stream */
758 ReturnIfError(_NET_RecvLong(iSocket, &iLength));
759
760 if (iLength)
761 {
762 strTemp = (CString)MEM_Alloc(iLength);
763 iRet = _NET_SocketRead(iSocket, strTemp, iLength);
764
765 /* Return an error if less than the string was read! */
766 if (iRet<0 || iRet!=iLength)
767 iRet = -1;
768 }
769 else
770 {
771 iRet = -1;
772 strTemp = NULL;
773 }
774
775 *pstrCString = strTemp;
776 return iRet;
777 }
778
779
780 /**
781 * Reads a 32bit value from the given socket.
782 *
783 * \b History:
784 * \arg 01.24.94 ESF Created
785 * \arg 08.03.94 ESF Fixed to return error message.
786 * \arg 01.01.94 ESF Added check for correct number of bytes read.
787 */
_NET_RecvLong(Int32 iSocket,Int32 * piLong)788 static Int32 _NET_RecvLong(Int32 iSocket, Int32 *piLong)
789 {
790 Int32 iRet = _NET_SocketRead(iSocket, piLong, sizeof(Int32));
791
792 /* Adjust for the network munging */
793 *piLong = ntohl(*piLong);
794
795 /* Return an error if read returns an error or if the wrong number
796 * of bytes come across -- there should be sizeof(Int32) bytes!
797 */
798
799 if (iRet<0 || iRet!=sizeof(Int32))
800 iRet = -1;
801
802 return iRet;
803 }
804
805
806 /**
807 * Reads the given number of bytes from the given socket.
808 *
809 * \b History:
810 * \arg 01.01.95 ESF Created.
811 * \arg 01.21.95 ESF Fixed non-ANSIness.
812 */
_NET_SocketRead(Int32 iSocket,void * ptr,Int32 iNumBytes)813 static Int32 _NET_SocketRead(Int32 iSocket, void *ptr, Int32 iNumBytes)
814 {
815 Int32 iBytesLeft, iRet;
816
817 /* We may have to do multiple read() calls here */
818 iBytesLeft = iNumBytes;
819
820 while (iBytesLeft > 0)
821 {
822 iRet = read(iSocket, ptr, iBytesLeft);
823
824 /* If an error occured, return */
825 if (iRet < 0)
826 return iRet;
827 else if (iRet == 0)
828 break; /* EOF */
829
830 iBytesLeft -= iRet;
831 ptr = (Byte *)ptr + iRet;
832 }
833
834 /* Return the number of bytes read */
835 return (iNumBytes - iBytesLeft);
836 }
837
838
839 /**
840 * Write the given number of bytes to the given socket.
841 *
842 * \b History:
843 * \arg 01.24.94 ESF Created
844 * \arg 08.03.94 ESF Fixed to return error message.
845 * \arg 01.01.94 ESF Added check for correct number of bytes read.
846 * \arg 01.21.95 ESF Fixed non-ANSIness.
847 */
_NET_SocketWrite(Int32 iSocket,void * ptr,Int32 iNumBytes)848 static Int32 _NET_SocketWrite(Int32 iSocket, void *ptr, Int32 iNumBytes)
849 {
850 Int32 iBytesLeft, iRet;
851
852 /* We may have to do multiple read() calls here */
853 iBytesLeft = iNumBytes;
854
855 while (iBytesLeft > 0)
856 {
857 iRet = write(iSocket, ptr, iBytesLeft);
858
859 /* If an error occured, return */
860 if (iRet < 0)
861 return iRet;
862
863 iBytesLeft -= iRet;
864 ptr = (Byte *)ptr + iRet;
865 }
866
867 /* Return the number of bytes read */
868 return (iNumBytes - iBytesLeft);
869 }
870
871
872 /**
873 * Free the memory allocated for the given message.
874 *
875 * \b History:
876 * \arg 06.24.94 ESF Created
877 * \arg 07.31.94 ESF Added MSG_NETPOPUP.
878 * \arg 09.31.94 ESF Changed MSG_ENDOFGAME to take a string parameter.
879 * \arg 10.29.94 ESF Added MSG_DICEROLL.
880 * \arg 10.30.94 ESF Added MSG_PLACENOTIFY.
881 * \arg 10.30.94 ESF Added MSG_ATTACKNOTIFY.
882 * \arg 10.30.94 ESF Added MSG_MOVENOTIFY.
883 * \arg 01.17.95 ESF Removed MSG_DELETEMSGDST.
884 * \arg 02.21.95 ESF Added MSG_HELLO, MSG_VERSION.
885 * \arg 02.21.95 ESF Modified MSG_REGISTERCLIENT to include type of client.
886 * \arg 02.23.95 ESF Added MSG_OLDREGISTERCLIENT.
887 * \arg 02.23.95 ESF Added MSG_SPECIESIDENT.
888 * \arg 24.08.95 JC Added MSG_MISSION.
889 * \arg 30.08.95 JC Added MSG_FORCEEXCHANGECARDS.
890 */
NET_DeleteMessage(Int32 iMessType,void * pvMessage)891 void NET_DeleteMessage(Int32 iMessType, void *pvMessage)
892 {
893 switch(iMessType)
894 {
895 case MSG_NOMESSAGE:
896 break;
897
898 case MSG_OLDREGISTERCLIENT:
899 {
900 MsgOldRegisterClient *pmsgMess = (MsgOldRegisterClient *)pvMessage;
901 MEM_Free(pmsgMess->strClientAddress);
902 MEM_Free(pmsgMess);
903 }
904 break;
905
906 case MSG_REGISTERCLIENT:
907 {
908 MsgRegisterClient *pmsgMess = (MsgRegisterClient *)pvMessage;
909 MEM_Free(pmsgMess->strClientAddress);
910 MEM_Free(pmsgMess);
911 }
912 break;
913
914 case MSG_EXCHANGECARDS:
915 MEM_Free(pvMessage);
916 break;
917
918 case MSG_CARDPACKET:
919 MEM_Free(pvMessage);
920 break;
921
922 case MSG_REPLYPACKET:
923 MEM_Free(pvMessage);
924 break;
925
926 case MSG_SENDMESSAGE:
927 {
928 MsgSendMessage *pmsgMess = (MsgSendMessage *)pvMessage;
929
930 MEM_Free(pmsgMess->strMessage);
931 MEM_Free(pmsgMess->strDestination);
932 MEM_Free(pvMessage);
933 }
934 break;
935
936 case MSG_MESSAGEPACKET:
937 {
938 MsgMessagePacket *pmsgMess = (MsgMessagePacket *)pvMessage;
939
940 MEM_Free(pmsgMess->strMessage);
941 MEM_Free(pvMessage);
942 }
943 break;
944
945 case MSG_TURNNOTIFY:
946 MEM_Free(pvMessage);
947 break;
948
949 case MSG_CLIENTIDENT:
950 MEM_Free(pvMessage);
951 break;
952
953 case MSG_REQUESTCARD:
954 MEM_Free(pvMessage);
955 break;
956
957 case MSG_ENTERSTATE:
958 MEM_Free(pvMessage);
959 break;
960
961 case MSG_OBJSTRUPDATE:
962 {
963 MsgObjStrUpdate *pmsgMess = (MsgObjStrUpdate*)pvMessage;
964
965 if (pmsgMess->strNewValue)
966 MEM_Free(pmsgMess->strNewValue);
967 MEM_Free(pvMessage);
968 }
969 break;
970
971 case MSG_OBJINTUPDATE:
972 MEM_Free(pvMessage);
973 break;
974
975 case MSG_FREEPLAYER:
976 MEM_Free(pvMessage);
977 break;
978
979 /* These happen to be identical, so we can lump them. */
980 case MSG_NETMESSAGE:
981 case MSG_NETPOPUP:
982 {
983 MsgNetMessage *pmsgMess = (MsgNetMessage *)pvMessage;
984 MEM_Free(pmsgMess->strMessage);
985 MEM_Free(pvMessage);
986 }
987 break;
988
989 case MSG_ENDOFMISSION:
990 MEM_Free(pvMessage);
991 break;
992
993 case MSG_VICTORY:
994 MEM_Free(pvMessage);
995 break;
996
997 case MSG_DICEROLL:
998 MEM_Free(pvMessage);
999 break;
1000
1001 case MSG_PLACENOTIFY:
1002 MEM_Free(pvMessage);
1003 break;
1004
1005 case MSG_ATTACKNOTIFY:
1006 MEM_Free(pvMessage);
1007 break;
1008
1009 case MSG_MOVENOTIFY:
1010 MEM_Free(pvMessage);
1011 break;
1012
1013 case MSG_VERSION:
1014 {
1015 MsgVersion *pmsgMess = (MsgVersion *)pvMessage;
1016 MEM_Free(pmsgMess->strVersion);
1017 MEM_Free(pvMessage);
1018 }
1019 break;
1020
1021 case MSG_SPECIESIDENT:
1022 MEM_Free(pvMessage);
1023 break;
1024
1025 case MSG_FORCEEXCHANGECARDS:
1026 MEM_Free(pvMessage);
1027 break;
1028
1029 case MSG_EXIT:
1030 case MSG_STARTGAME:
1031 case MSG_ENDTURN:
1032 case MSG_DEREGISTERCLIENT:
1033 case MSG_ALLOCPLAYER:
1034 case MSG_POPUPREGISTERBOX:
1035 case MSG_HELLO:
1036 case MSG_MISSION:
1037 case MSG_ENDOFGAME:
1038 /* No parameters */
1039 D_Assert(pvMessage == NULL, "Hum...this shouldn't happen.");
1040 break;
1041
1042 default:
1043 D_Assert(FALSE, "Add case for a new message in NET_DeleteMessage!");
1044 }
1045 }
1046
1047
1048 /**
1049 * Set socket options for better performance.
1050 *
1051 * \b History:
1052 * \arg 01.22.95 ESF Created.
1053 * \arg 02.27.95 ESF Added SO_REUSEADDR.
1054 * \arg 17.08.95 JC iOption -> &iOption.
1055 */
NET_SetCommLinkOptions(Int32 iSocket)1056 void NET_SetCommLinkOptions(Int32 iSocket)
1057 {
1058 #ifdef TCP_NODELAY
1059 {
1060 Int32 iOption = 1;
1061 if (setsockopt(iSocket, IPPROTO_TCP, TCP_NODELAY,
1062 (char *)&iOption, sizeof(iOption)) != 0)
1063 printf("NETWORK: Warning -- couldn't set TCP_NODELAY on CommLink!\n");
1064 }
1065 #endif
1066 #ifdef SO_REUSEADDR
1067 {
1068 Int32 iOption = 1;
1069 if (setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR,
1070 (char *)&iOption, sizeof(iOption)) != 0)
1071 printf("NETWORK: Warning -- couldn't set SO_REUSEADDR on CommLink!\n");
1072 }
1073 #endif
1074 }
1075
1076
1077 /**
1078 * Convert the given message to a human readable string for debugging.
1079 *
1080 * \b History:
1081 * \arg 03.19.95 ESF Created.
1082 * \arg 24.08.95 JC Added MSG_MISSION.
1083 * \arg 30.08.95 JC Added MSG_FORCEEXCHANGECARDS.
1084 */
NET_MessageToString(Int32 iMessType,void * pvMessage)1085 CString NET_MessageToString(Int32 iMessType, void *pvMessage)
1086 {
1087 switch (iMessType)
1088 {
1089 case MSG_NOMESSAGE:
1090 snprintf(strLogging, sizeof(strLogging), "MsgNoMessage()");
1091 break;
1092
1093 case MSG_OLDREGISTERCLIENT:
1094 snprintf(strLogging, sizeof(strLogging), "MsgOldRegisterClient(strClientAddress=\"%s\")",
1095 ((MsgOldRegisterClient *)pvMessage)->strClientAddress);
1096 break;
1097
1098 case MSG_REGISTERCLIENT:
1099 snprintf(strLogging, sizeof(strLogging), "MsgRegisterClient(strClientAddress=\"%s\","
1100 " iClientType=%s)",
1101 ((MsgRegisterClient *)pvMessage)->strClientAddress,
1102 ((MsgRegisterClient *)pvMessage)->iClientType ==
1103 CLIENT_NORMAL ? "CLIENT_NORMAL" :
1104 ((MsgRegisterClient *)pvMessage)->iClientType ==
1105 CLIENT_AI ? "CLIENT_AI" :
1106 ((MsgRegisterClient *)pvMessage)->iClientType ==
1107 CLIENT_STRICTOBSERVER ? "CLIENT_STRICTOBSERVER" :
1108 "*Unknown*");
1109 break;
1110
1111 case MSG_EXCHANGECARDS:
1112 snprintf(strLogging, sizeof(strLogging), "MsgExchangeCards(piCards={%d, %d, %d})",
1113 ((MsgExchangeCards *)pvMessage)->piCards[0],
1114 ((MsgExchangeCards *)pvMessage)->piCards[1],
1115 ((MsgExchangeCards *)pvMessage)->piCards[2]);
1116 break;
1117
1118 case MSG_CARDPACKET:
1119 snprintf(strLogging, sizeof(strLogging), "MsgCardPacket(iPlayer=%d, iCard=%d)",
1120 ((MsgCardPacket *)pvMessage)->iPlayer,
1121 ((MsgCardPacket *)pvMessage)->cdCard);
1122 break;
1123
1124 case MSG_REPLYPACKET:
1125 snprintf(strLogging, sizeof(strLogging), "MsgReplyPacket(iReply=%d)",
1126 ((MsgReplyPacket *)pvMessage)->iReply);
1127 break;
1128
1129 case MSG_SENDMESSAGE:
1130 snprintf(strLogging, sizeof(strLogging), "MsgSendMessage(strMessage=\"%s\", "
1131 "strDestination=\"%s\")",
1132 ((MsgSendMessage *)pvMessage)->strMessage,
1133 ((MsgSendMessage *)pvMessage)->strDestination);
1134 break;
1135
1136 case MSG_MESSAGEPACKET:
1137 snprintf(strLogging, sizeof(strLogging), "MsgMessagePacket(strMessage=\"%s\", "
1138 "iFrom=\"%d\", iTo=%d)",
1139 ((MsgMessagePacket *)pvMessage)->strMessage,
1140 ((MsgMessagePacket *)pvMessage)->iFrom,
1141 ((MsgMessagePacket *)pvMessage)->iTo);
1142 break;
1143
1144 case MSG_TURNNOTIFY:
1145 snprintf(strLogging, sizeof(strLogging), "MsgTurnNotify(iPlayer=%d, iClient=%d)",
1146 ((MsgTurnNotify *)pvMessage)->iPlayer,
1147 ((MsgTurnNotify *)pvMessage)->iClient);
1148 break;
1149
1150 case MSG_CLIENTIDENT:
1151 snprintf(strLogging, sizeof(strLogging), "MsgClientIdent(iClientID=%d)",
1152 ((MsgClientIdent *)pvMessage)->iClientID);
1153 break;
1154
1155 case MSG_REQUESTCARD:
1156 snprintf(strLogging, sizeof(strLogging), "MsgRequestCard(iPlayer=%d)",
1157 ((MsgRequestCard *)pvMessage)->iPlayer);
1158 break;
1159
1160 case MSG_ENTERSTATE:
1161 snprintf(strLogging, sizeof(strLogging), "MsgEnterState(iState=%d)",
1162 ((MsgEnterState *)pvMessage)->iState);
1163 break;
1164
1165 case MSG_OBJSTRUPDATE:
1166 snprintf(strLogging, sizeof(strLogging), "ObjStrUpdate(iField=%d, iIndex=[%d, %d], "
1167 "strNewValue=\"%s\")",
1168 ((MsgObjStrUpdate *)pvMessage)->iField,
1169 ((MsgObjStrUpdate *)pvMessage)->iIndex1,
1170 ((MsgObjStrUpdate *)pvMessage)->iIndex2,
1171 ((MsgObjStrUpdate *)pvMessage)->strNewValue);
1172 break;
1173
1174 case MSG_OBJINTUPDATE:
1175 snprintf(strLogging, sizeof(strLogging), "ObjIntUpdate(iField=%d, iIndex=[%d, %d], "
1176 "iNewValue=%d)",
1177 ((MsgObjIntUpdate *)pvMessage)->iField,
1178 ((MsgObjIntUpdate *)pvMessage)->iIndex1,
1179 ((MsgObjIntUpdate *)pvMessage)->iIndex2,
1180 ((MsgObjIntUpdate *)pvMessage)->iNewValue);
1181 break;
1182
1183 case MSG_FREEPLAYER:
1184 snprintf(strLogging, sizeof(strLogging), "MsgFreePlayer(iPlayer=%d)",
1185 ((MsgFreePlayer *)pvMessage)->iPlayer);
1186 break;
1187
1188 case MSG_NETMESSAGE:
1189 snprintf(strLogging, sizeof(strLogging), "MsgNetMessage(strMessage=\"%s\")",
1190 ((MsgNetMessage *)pvMessage)->strMessage);
1191 break;
1192
1193 case MSG_NETPOPUP:
1194 snprintf(strLogging, sizeof(strLogging), "MsgNetPopup(strMessage=\"%s\")",
1195 ((MsgNetPopup *)pvMessage)->strMessage);
1196 break;
1197
1198 case MSG_ENDOFMISSION:
1199 snprintf(strLogging, sizeof(strLogging), "MsgEndOfMission(iWinner=%d, iTyp=%d, iNum1=%d, iNum2=%d)",
1200 ((MsgEndOfMission *)pvMessage)->iWinner,
1201 ((MsgEndOfMission *)pvMessage)->iTyp,
1202 ((MsgEndOfMission *)pvMessage)->iNum1,
1203 ((MsgEndOfMission *)pvMessage)->iNum2);
1204 break;
1205
1206 case MSG_VICTORY:
1207 snprintf(strLogging, sizeof(strLogging), "MsgVictory(iWinner=%d)",
1208 ((MsgVictory *)pvMessage)->iWinner);
1209 break;
1210
1211 case MSG_ENDOFGAME:
1212 snprintf(strLogging, sizeof(strLogging), "MsgEndOfGame()");
1213 break;
1214
1215 case MSG_DICEROLL:
1216 snprintf(strLogging, sizeof(strLogging), "MsgDiceRoll(iDefendingPlayer=%d, "
1217 "pAttackDice={%d, %d, %d}, pDefendDice={%d, %d, %d})",
1218 ((MsgDiceRoll *)pvMessage)->iDefendingPlayer,
1219 ((MsgDiceRoll *)pvMessage)->pAttackDice[0],
1220 ((MsgDiceRoll *)pvMessage)->pAttackDice[1],
1221 ((MsgDiceRoll *)pvMessage)->pAttackDice[2],
1222 ((MsgDiceRoll *)pvMessage)->pDefendDice[0],
1223 ((MsgDiceRoll *)pvMessage)->pDefendDice[1],
1224 ((MsgDiceRoll *)pvMessage)->pDefendDice[2]);
1225 break;
1226
1227 case MSG_PLACENOTIFY:
1228 snprintf(strLogging, sizeof(strLogging), "MsgPlaceNotify(iCountry=%d)",
1229 ((MsgPlaceNotify *)pvMessage)->iCountry);
1230 break;
1231
1232 case MSG_ATTACKNOTIFY:
1233 snprintf(strLogging, sizeof(strLogging), "MsgAttackNotify(iSrcCountry=%d, iDstCountry=%d)",
1234 ((MsgAttackNotify *)pvMessage)->iSrcCountry,
1235 ((MsgAttackNotify *)pvMessage)->iDstCountry);
1236 break;
1237
1238 case MSG_MOVENOTIFY:
1239 snprintf(strLogging, sizeof(strLogging), "MsgMoveNotify(iSrcCountry=%d, iDstCountry=%d)",
1240 ((MsgMoveNotify *)pvMessage)->iSrcCountry,
1241 ((MsgMoveNotify *)pvMessage)->iDstCountry);
1242 break;
1243
1244 case MSG_VERSION:
1245 snprintf(strLogging, sizeof(strLogging), "MsgVersion(strVersion=\"%s\")",
1246 ((MsgVersion *)pvMessage)->strVersion);
1247 break;
1248
1249 case MSG_SPECIESIDENT:
1250 snprintf(strLogging, sizeof(strLogging), "MsgSpeciesIdent(iSpeciesID=%d)",
1251 ((MsgSpeciesIdent *)pvMessage)->iSpeciesID);
1252 break;
1253
1254 case MSG_FORCEEXCHANGECARDS:
1255 snprintf(strLogging, sizeof(strLogging), "MsgForceExchangeCards(iPlayer=%d)",
1256 ((MsgForceExchangeCards *)pvMessage)->iPlayer);
1257 break;
1258
1259 case MSG_EXIT:
1260 snprintf(strLogging, sizeof(strLogging), "MsgExit()");
1261 break;
1262
1263 case MSG_STARTGAME:
1264 snprintf(strLogging, sizeof(strLogging), "MsgStartGame()");
1265 break;
1266
1267 case MSG_ENDTURN:
1268 snprintf(strLogging, sizeof(strLogging), "MsgEndTurn()");
1269 break;
1270
1271 case MSG_DEREGISTERCLIENT:
1272 snprintf(strLogging, sizeof(strLogging), "MsgDeregisterClient()");
1273 break;
1274
1275 case MSG_ALLOCPLAYER:
1276 snprintf(strLogging, sizeof(strLogging), "MsgAllocPlayer()");
1277 break;
1278
1279 case MSG_POPUPREGISTERBOX:
1280 snprintf(strLogging, sizeof(strLogging), "MsgPopupRegisterBox()");
1281 break;
1282
1283 case MSG_HELLO:
1284 snprintf(strLogging, sizeof(strLogging), "MsgHello()");
1285 break;
1286
1287 case MSG_MISSION:
1288 snprintf(strLogging, sizeof(strLogging), "MsgMission()");
1289 break;
1290
1291 default:
1292 D_Assert(FALSE, "Add case to NET_StringToMessage!");
1293 }
1294
1295 return strLogging;
1296 }
1297
1298 /* EOF */
1299