Devilution
Diablo devolved - magic behind the 1996 computer game
multi.cpp
Go to the documentation of this file.
1 
6 #include "all.h"
7 #include "../3rdParty/Storm/Source/storm.h"
8 #include "../DiabloUI/diabloui.h"
9 
11 
14 char szPlayerDescript[128];
35 BOOLEAN sgbTimeout;
36 char szPlayerName[128];
40 
45 const int event_types[3] = {
49 };
50 
51 void multi_msg_add(BYTE *pbMsg, BYTE bLen)
52 {
53  if (pbMsg && bLen) {
54  tmsg_add(pbMsg, bLen);
55  }
56 }
57 
58 void NetSendLoPri(BYTE *pbMsg, BYTE bLen)
59 {
60  if (pbMsg && bLen) {
61  multi_copy_packet(&sgLoPriBuf, pbMsg, bLen);
62  multi_send_packet(pbMsg, bLen);
63  }
64 }
65 
66 void multi_copy_packet(TBuffer *buf, void *packet, BYTE size)
67 {
68  BYTE *p;
69 
70  if (buf->dwNextWriteOffset + size + 2 > 0x1000) {
71  return;
72  }
73 
74  p = &buf->bData[buf->dwNextWriteOffset];
75  buf->dwNextWriteOffset += size + 1;
76  *p = size;
77  p++;
78  memcpy(p, packet, size);
79  p[size] = 0;
80 }
81 
82 void multi_send_packet(void *packet, BYTE dwSize)
83 {
84  TPkt pkt;
85 
86  NetRecvPlrData(&pkt);
87  pkt.hdr.wLen = dwSize + 19;
88  memcpy(pkt.body, packet, dwSize);
89  if (!SNetSendMessage(myplr, &pkt.hdr, pkt.hdr.wLen))
90  nthread_terminate_game("SNetSendMessage0");
91 }
92 
93 void NetRecvPlrData(TPkt *pkt)
94 {
95  pkt->hdr.wCheck = 'ip';
96  pkt->hdr.px = plr[myplr].WorldX;
97  pkt->hdr.py = plr[myplr].WorldY;
98  pkt->hdr.targx = plr[myplr]._ptargx;
99  pkt->hdr.targy = plr[myplr]._ptargy;
100  pkt->hdr.php = plr[myplr]._pHitPoints;
101  pkt->hdr.pmhp = plr[myplr]._pMaxHP;
102  pkt->hdr.bstr = plr[myplr]._pBaseStr;
103  pkt->hdr.bmag = plr[myplr]._pBaseMag;
104  pkt->hdr.bdex = plr[myplr]._pBaseDex;
105 }
106 
107 void NetSendHiPri(BYTE *pbMsg, BYTE bLen)
108 {
109  BYTE *hipri_body;
110  BYTE *lowpri_body;
111  DWORD len;
112  TPkt pkt;
113  int size;
114 
115  if (pbMsg && bLen) {
116  multi_copy_packet(&sgHiPriBuf, pbMsg, bLen);
117  multi_send_packet(pbMsg, bLen);
118  }
121  NetRecvPlrData(&pkt);
122  size = gdwNormalMsgSize - sizeof(TPktHdr);
123  hipri_body = multi_recv_packet(&sgHiPriBuf, pkt.body, &size);
124  lowpri_body = multi_recv_packet(&sgLoPriBuf, hipri_body, &size);
125  size = sync_all_monsters(lowpri_body, size);
126  len = gdwNormalMsgSize - size;
127  pkt.hdr.wLen = len;
128  if (!SNetSendMessage(-2, &pkt.hdr, len))
129  nthread_terminate_game("SNetSendMessage");
130  }
131 }
132 
133 BYTE *multi_recv_packet(TBuffer *pBuf, BYTE *body, int *size)
134 {
135  BYTE *src_ptr;
136  size_t chunk_size;
137 
138  if (pBuf->dwNextWriteOffset != 0) {
139  src_ptr = pBuf->bData;
140  while (TRUE) {
141  if (*src_ptr == 0)
142  break;
143  chunk_size = *src_ptr;
144  if (chunk_size > *size)
145  break;
146  src_ptr++;
147  memcpy(body, src_ptr, chunk_size);
148  body += chunk_size;
149  src_ptr += chunk_size;
150  *size -= chunk_size;
151  }
152  memcpy(pBuf->bData, src_ptr, (pBuf->bData - src_ptr) + pBuf->dwNextWriteOffset + 1);
153  pBuf->dwNextWriteOffset += (pBuf->bData - src_ptr);
154  return body;
155  }
156  return body;
157 }
158 
159 void multi_send_msg_packet(int pmask, BYTE *src, BYTE len)
160 {
161  DWORD v, p, t;
162  TPkt pkt;
163 
164  NetRecvPlrData(&pkt);
165  t = len + 19;
166  pkt.hdr.wLen = t;
167  memcpy(pkt.body, src, len);
168  for (v = 1, p = 0; p < MAX_PLRS; p++, v <<= 1) {
169  if (v & pmask) {
170  if (!SNetSendMessage(p, &pkt.hdr, t) && SErrGetLastError() != STORM_ERROR_INVALID_PLAYER) {
171  nthread_terminate_game("SNetSendMessage");
172  return;
173  }
174  }
175  }
176 }
177 
179 {
180  int i;
181 
182  for (i = 0; i < MAX_PLRS; i++) {
183  if (player_state[i] & 0x20000) {
184  if (gdwMsgLenTbl[i] == 4)
185  multi_parse_turn(i, *(DWORD *)glpMsgTbl[i]);
186  }
187  }
188 }
189 
190 void multi_parse_turn(int pnum, int turn)
191 {
192  DWORD absTurns;
193 
194  if (turn >> 31)
196  absTurns = turn & 0x7FFFFFFF;
197  if (sgbSentThisCycle < gdwTurnsInTransit + absTurns) {
198  if (absTurns >= 0x7FFFFFFF)
199  absTurns &= 0xFFFF;
200  sgbSentThisCycle = absTurns + gdwTurnsInTransit;
201  sgdwGameLoops = 4 * absTurns * sgbNetUpdateRate;
202  }
203 }
204 
206 {
207  int i;
208 
209  for (i = 0; i < MAX_PLRS; i++) {
210  if (player_state[i] & 0x10000 && i != pnum)
211  break;
212  }
213 
214  if (myplr == i) {
215  sgbSendDeltaTbl[pnum] = TRUE;
216  } else if (myplr == pnum) {
217  gbDeltaSender = i;
218  }
219 }
220 
221 void multi_player_left(int pnum, int reason)
222 {
223  sgbPlayerLeftGameTbl[pnum] = TRUE;
224  sgdwPlayerLeftReasonTbl[pnum] = reason;
226 }
227 
229 {
230  int i;
231 
232  for (i = 0; i < MAX_PLRS; i++) {
233  if (sgbPlayerLeftGameTbl[i]) {
234  if (gbBufferMsgs == 1)
236  else
237  multi_player_left_msg(i, 1);
238 
239  sgbPlayerLeftGameTbl[i] = FALSE;
241  }
242  }
243 }
244 
245 void multi_player_left_msg(int pnum, int left)
246 {
247  char *pszFmt;
248 
249  if (plr[pnum].plractive) {
250  RemovePlrFromMap(pnum);
251  RemovePortalMissile(pnum);
252  DeactivatePortal(pnum);
253  delta_close_portal(pnum);
254  RemovePlrMissiles(pnum);
255  if (left) {
256  pszFmt = "Player '%s' just left the game";
257  switch (sgdwPlayerLeftReasonTbl[pnum]) {
258  case 0x40000004:
259  pszFmt = "Player '%s' killed Diablo and left the game!";
261  break;
262  case 0x40000006:
263  pszFmt = "Player '%s' dropped due to timeout";
264  break;
265  }
266  EventPlrMsg(pszFmt, plr[pnum]._pName);
267  }
268  plr[pnum].plractive = FALSE;
269  plr[pnum]._pName[0] = '\0';
270  gbActivePlayers--;
271  }
272 }
273 
275 {
276  sgbTimeout = TRUE;
277  sglTimeoutStart = SDL_GetTicks();
278 }
279 
281 {
282  int i;
283  BOOL received;
284 
285  if (gbGameDestroyed) {
286  gbRunGame = FALSE;
287  return FALSE;
288  }
289 
290  for (i = 0; i < MAX_PLRS; i++) {
291  if (sgbSendDeltaTbl[i]) {
292  sgbSendDeltaTbl[i] = FALSE;
293  DeltaExportData(i);
294  }
295  }
296 
298  if (!nthread_recv_turns(&received)) {
300  return FALSE;
301  }
302 
303  sgbTimeout = FALSE;
304  if (received) {
306  NetSendHiPri(0, 0);
307  gbShouldValidatePackage = FALSE;
308  } else {
309  gbShouldValidatePackage = FALSE;
311  NetSendHiPri(0, 0);
312  }
313  }
314  multi_mon_seeds();
315 
316  return TRUE;
317 }
318 
319 // Microsoft VisualC 2-11/net runtime
321 {
322  return pBuf->dwNextWriteOffset == 0;
323 }
324 
326 {
327  int i;
328  DWORD l;
329 
330  sgdwGameLoops++;
331  l = (sgdwGameLoops >> 8) | (sgdwGameLoops << 24); // _rotr(sgdwGameLoops, 8)
332  for (i = 0; i < MAXMONSTERS; i++)
333  monster[i]._mAISeed = l + i;
334 }
335 
337 {
338  int i, nTicks, nState, nLowestActive, nLowestPlayer;
339  BYTE bGroupPlayers, bGroupCount;
340 
341  if (!sgbTimeout) {
342  return;
343  }
344 #ifdef _DEBUG
345  if (debug_mode_key_i) {
346  return;
347  }
348 #endif
349 
350  nTicks = SDL_GetTicks() - sglTimeoutStart;
351  if (nTicks > 20000) {
352  gbRunGame = FALSE;
353  return;
354  }
355  if (nTicks < 10000) {
356  return;
357  }
358 
359  nLowestActive = -1;
360  nLowestPlayer = -1;
361  bGroupPlayers = 0;
362  bGroupCount = 0;
363  for (i = 0; i < MAX_PLRS; i++) {
364  nState = player_state[i];
365  if (nState & 0x10000) {
366  if (nLowestPlayer == -1) {
367  nLowestPlayer = i;
368  }
369  if (nState & 0x40000) {
370  bGroupPlayers++;
371  if (nLowestActive == -1) {
372  nLowestActive = i;
373  }
374  } else {
375  bGroupCount++;
376  }
377  }
378  }
379 
383 
384  if (bGroupPlayers < bGroupCount) {
385  gbGameDestroyed = TRUE;
386  } else if (bGroupPlayers == bGroupCount) {
387  if (nLowestPlayer != nLowestActive) {
388  gbGameDestroyed = TRUE;
389  } else if (nLowestActive == myplr) {
391  }
392  } else if (nLowestActive == myplr) {
394  }
395 }
396 
398 {
399  int i;
400 
401  for (i = 0; i < MAX_PLRS; i++) {
402  if (!(player_state[i] & 0x40000) && player_state[i] & 0x10000) {
403  SNetDropPlayer(i, 0x40000006);
404  }
405  }
406 }
407 
409 {
410  int dx, dy;
411  TPktHdr *pkt;
412  DWORD dwMsgSize;
413  DWORD dwID;
414  BOOL cond;
415  char *data;
416 
419  while (SNetReceiveMessage((int *)&dwID, &data, (int *)&dwMsgSize)) {
420  dwRecCount++;
422  pkt = (TPktHdr *)data;
423  if (dwMsgSize < sizeof(TPktHdr))
424  continue;
425  if (dwID >= MAX_PLRS)
426  continue;
427  if (pkt->wCheck != 'ip')
428  continue;
429  if (pkt->wLen != dwMsgSize)
430  continue;
431  plr[dwID]._pownerx = pkt->px;
432  plr[dwID]._pownery = pkt->py;
433  if (dwID != myplr) {
434  // ASSERT: gbBufferMsgs != BUFFER_PROCESS (2)
435  plr[dwID]._pHitPoints = pkt->php;
436  plr[dwID]._pMaxHP = pkt->pmhp;
437  cond = gbBufferMsgs == 1;
438  plr[dwID]._pBaseStr = pkt->bstr;
439  plr[dwID]._pBaseMag = pkt->bmag;
440  plr[dwID]._pBaseDex = pkt->bdex;
441  if (!cond && plr[dwID].plractive && plr[dwID]._pHitPoints) {
442  if (currlevel == plr[dwID].plrlevel && !plr[dwID]._pLvlChanging) {
443  dx = abs(plr[dwID].WorldX - pkt->px);
444  dy = abs(plr[dwID].WorldY - pkt->py);
445  if ((dx > 3 || dy > 3) && dPlayer[pkt->px][pkt->py] == 0) {
446  FixPlrWalkTags(dwID);
447  plr[dwID]._poldx = plr[dwID].WorldX;
448  plr[dwID]._poldy = plr[dwID].WorldY;
449  FixPlrWalkTags(dwID);
450  plr[dwID].WorldX = pkt->px;
451  plr[dwID].WorldY = pkt->py;
452  plr[dwID]._px = pkt->px;
453  plr[dwID]._py = pkt->py;
454  dPlayer[plr[dwID].WorldX][plr[dwID].WorldY] = dwID + 1;
455  }
456  dx = abs(plr[dwID]._px - plr[dwID].WorldX);
457  dy = abs(plr[dwID]._py - plr[dwID].WorldY);
458  if (dx > 1 || dy > 1) {
459  plr[dwID]._px = plr[dwID].WorldX;
460  plr[dwID]._py = plr[dwID].WorldY;
461  }
462  MakePlrPath(dwID, pkt->targx, pkt->targy, TRUE);
463  } else {
464  plr[dwID].WorldX = pkt->px;
465  plr[dwID].WorldY = pkt->py;
466  plr[dwID]._px = pkt->px;
467  plr[dwID]._py = pkt->py;
468  plr[dwID]._ptargx = pkt->targx;
469  plr[dwID]._ptargy = pkt->targy;
470  }
471  }
472  }
473  multi_handle_all_packets(dwID, (BYTE *)(pkt + 1), dwMsgSize - sizeof(TPktHdr));
474  }
475  if (SErrGetLastError() != STORM_ERROR_NO_MESSAGES_WAITING)
476  nthread_terminate_game("SNetReceiveMsg");
477 }
478 
479 void multi_handle_all_packets(int pnum, BYTE *pData, int nSize)
480 {
481  int nLen;
482 
483  while (nSize != 0) {
484  nLen = ParseCmd(pnum, (TCmd *)pData);
485  if (nLen == 0) {
486  break;
487  }
488  pData += nLen;
489  nSize -= nLen;
490  }
491 }
492 
494 {
495  int cnt;
496  TPkt pkt;
497 
498  while (cnt = tmsg_get((BYTE *)&pkt, 512)) {
499  multi_handle_all_packets(myplr, (BYTE *)&pkt, cnt);
500  }
501 }
502 
503 void multi_send_zero_packet(int pnum, BYTE bCmd, BYTE *pbSrc, DWORD dwLen)
504 {
505  DWORD dwOffset, dwBody, dwMsg;
506  TPkt pkt;
507  TCmdPlrInfoHdr *p;
508 
512 
513  dwOffset = 0;
514 
515  while (dwLen != 0) {
516  pkt.hdr.wCheck = 'ip';
517  pkt.hdr.px = 0;
518  pkt.hdr.py = 0;
519  pkt.hdr.targx = 0;
520  pkt.hdr.targy = 0;
521  pkt.hdr.php = 0;
522  pkt.hdr.pmhp = 0;
523  pkt.hdr.bstr = 0;
524  pkt.hdr.bmag = 0;
525  pkt.hdr.bdex = 0;
526  p = (TCmdPlrInfoHdr *)pkt.body;
527  p->bCmd = bCmd;
528  p->wOffset = dwOffset;
529  dwBody = gdwLargestMsgSize - sizeof(pkt.hdr) - sizeof(*p);
530  if (dwLen < dwBody) {
531  dwBody = dwLen;
532  }
534  p->wBytes = dwBody;
535  memcpy(&pkt.body[sizeof(*p)], pbSrc, p->wBytes);
536  dwMsg = sizeof(pkt.hdr);
537  dwMsg += sizeof(*p);
538  dwMsg += p->wBytes;
539  pkt.hdr.wLen = dwMsg;
540  if (!SNetSendMessage(pnum, &pkt, dwMsg)) {
541  nthread_terminate_game("SNetSendMessage2");
542  return;
543  }
544 #if 0
545  if((DWORD)pnum >= MAX_PLRS) {
546  if(myplr != 0) {
547  debug_plr_tbl[0]++;
548  }
549  if(myplr != 1) {
550  debug_plr_tbl[1]++;
551  }
552  if(myplr != 2) {
553  debug_plr_tbl[2]++;
554  }
555  if(myplr != 3) {
556  debug_plr_tbl[3]++;
557  }
558  } else {
559  debug_plr_tbl[pnum]++;
560  }
561 #endif
562  pbSrc += p->wBytes;
563  dwLen -= p->wBytes;
564  dwOffset += p->wBytes;
565  }
566 }
567 
568 void NetClose()
569 {
570  if (!sgbNetInited) {
571  return;
572  }
573 
574  sgbNetInited = FALSE;
575  nthread_cleanup();
576  dthread_cleanup();
577  tmsg_cleanup();
578  multi_event_handler(FALSE);
579  SNetLeaveGame(3);
580  if (gbMaxPlayers > 1)
581  SDL_Delay(2000);
582 }
583 
584 void multi_event_handler(BOOL add)
585 {
586  DWORD i;
587  BOOL(STORMAPI * fn)
588  (int, SEVTHANDLER);
589 
590  if (add)
591  fn = SNetRegisterEventHandler;
592  else
593  fn = SNetUnregisterEventHandler;
594 
595  for (i = 0; i < 3; i++) {
596  if (!fn(event_types[i], multi_handle_events) && add) {
597  app_fatal("SNetRegisterEventHandler:\n%s", TraceLastError());
598  }
599  }
600 }
601 
603 {
604  DWORD LeftReason;
605  DWORD *data;
606 
607  switch (pEvt->eventid) {
609  data = (DWORD *)pEvt->data;
610  sgGameInitInfo.dwSeed = data[0];
611  sgGameInitInfo.bDiff = data[1];
612  sgbPlayerTurnBitTbl[pEvt->playerid] = TRUE;
613  break;
615  sgbPlayerLeftGameTbl[pEvt->playerid] = TRUE;
616  sgbPlayerTurnBitTbl[pEvt->playerid] = FALSE;
617  LeftReason = 0;
618  data = (DWORD *)pEvt->data;
619  if (data && (DWORD)pEvt->databytes >= 4)
620  LeftReason = data[0];
621  sgdwPlayerLeftReasonTbl[pEvt->playerid] = LeftReason;
622  if (LeftReason == 0x40000004)
624  sgbSendDeltaTbl[pEvt->playerid] = FALSE;
626 
627  if (gbDeltaSender == pEvt->playerid)
629  break;
631  ErrorPlrMsg((char *)pEvt->data);
632  break;
633  }
634 }
635 
636 BOOL NetInit(BOOL bSinglePlayer, BOOL *pfExitProgram)
637 {
638  int i;
639  _SNETPROGRAMDATA ProgramData;
640  _SNETUIDATA UiData;
641  _SNETPLAYERDATA plrdata;
642  unsigned int len;
643 
644  while (1) {
645  *pfExitProgram = FALSE;
646  SetRndSeed(0);
647  sgGameInitInfo.dwSeed = time(NULL);
649  memset(&ProgramData, 0, sizeof(ProgramData));
650  ProgramData.size = sizeof(ProgramData);
651 #ifdef SPAWN
652  ProgramData.programname = "Diablo Shareware";
653 #else
654  ProgramData.programname = "Diablo Retail";
655 #endif
656  ProgramData.programdescription = gszVersionNumber;
657  ProgramData.programid = 'DRTL';
658  ProgramData.versionid = 42;
659  ProgramData.maxplayers = MAX_PLRS;
660  ProgramData.initdata = &sgGameInitInfo;
661  ProgramData.initdatabytes = sizeof(sgGameInitInfo);
662  ProgramData.optcategorybits = 15;
663  ProgramData.lcid = 1033; /* LANG_ENGLISH */
664  memset(&plrdata, 0, sizeof(plrdata));
665  plrdata.size = sizeof(plrdata);
666  memset(&UiData, 0, sizeof(UiData));
667  UiData.size = sizeof(UiData);
668  UiData.artcallback = (void (*)())UiArtCallback;
669  UiData.createcallback = (void (*)())UiCreateGameCallback;
670  UiData.drawdesccallback = (void (*)())UiDrawDescCallback;
671  UiData.messageboxcallback = (void (*)())UiMessageBoxCallback;
672  UiData.soundcallback = (void (*)())UiSoundCallback;
673  UiData.authcallback = (void (*)())UiAuthCallback;
674  UiData.getdatacallback = (void (*)())UiGetDataCallback;
675  UiData.categorycallback = (void (*)())UiCategoryCallback;
677  UiData.changenamecallback = (void (*)())mainmenu_change_name;
678  UiData.profilebitmapcallback = (void (*)())UiProfileDraw;
679  UiData.profilecallback = (void (*)())UiProfileCallback;
680  UiData.profilefields = UiProfileGetString();
681  memset(sgbPlayerTurnBitTbl, 0, sizeof(sgbPlayerTurnBitTbl));
682  gbGameDestroyed = FALSE;
683  memset(sgbPlayerLeftGameTbl, 0, sizeof(sgbPlayerLeftGameTbl));
685  memset(sgbSendDeltaTbl, 0, sizeof(sgbSendDeltaTbl));
686  memset(plr, 0, sizeof(plr));
687  memset(sgwPackPlrOffsetTbl, 0, sizeof(sgwPackPlrOffsetTbl));
688  SNetSetBasePlayer(0);
689  if (bSinglePlayer) {
690  if (!multi_init_single(&ProgramData, &plrdata, &UiData))
691  return FALSE;
692  } else {
693  if (!multi_init_multi(&ProgramData, &plrdata, &UiData, pfExitProgram))
694  return FALSE;
695  }
696  sgbNetInited = TRUE;
697  sgbTimeout = FALSE;
698  delta_init();
699  InitPlrMsg();
702  gbShouldValidatePackage = FALSE;
703  sync_init();
705  dthread_start();
706  tmsg_start();
707  sgdwGameLoops = 0;
708  sgbSentThisCycle = 0;
710  gbSomebodyWonGameKludge = FALSE;
714  gbActivePlayers = 1;
715  plr[myplr].plractive = TRUE;
717  break;
718  NetClose();
719  gbSelectProvider = FALSE;
720  }
723 
724  for (i = 0; i < 17; i++) {
725  glSeedTbl[i] = GetRndSeed();
727  }
728  if (!SNetGetGameInfo(GAMEINFO_NAME, szPlayerName, 128, &len))
729  nthread_terminate_game("SNetGetGameInfo1");
730  if (!SNetGetGameInfo(GAMEINFO_PASSWORD, szPlayerDescript, 128, &len))
731  nthread_terminate_game("SNetGetGameInfo2");
732 
733  return TRUE;
734 }
735 
736 void buffer_init(TBuffer *pBuf)
737 {
738  pBuf->dwNextWriteOffset = 0;
739  pBuf->bData[0] = 0;
740 }
741 
742 void multi_send_pinfo(int pnum, char cmd)
743 {
744  PkPlayerStruct pkplr;
745 
746  PackPlayer(&pkplr, myplr, TRUE);
747  dthread_send_delta(pnum, cmd, &pkplr, sizeof(pkplr));
748 }
749 
750 int InitLevelType(int l)
751 {
752  if (l == 0)
753  return 0;
754  if (l >= 1 && l <= 4)
755  return 1;
756  if (l >= 5 && l <= 8)
757  return 2;
758  if (l >= 9 && l <= 12)
759  return 3;
760 
761  return 4;
762 }
763 
765 {
766  int x, y;
767 
768  if (!leveldebug || gbMaxPlayers > 1) {
769  currlevel = 0;
771  setlevel = FALSE;
772  }
773  x = 75;
774  y = 68;
775 #ifdef _DEBUG
776  if (debug_mode_key_inverted_v || debug_mode_key_d) {
777  x = 49;
778  y = 23;
779  }
780 #endif
781  x += plrxoff[myplr];
782  y += plryoff[myplr];
783  plr[myplr].WorldX = x;
784  plr[myplr].WorldY = y;
785  plr[myplr]._px = x;
786  plr[myplr]._py = y;
787  plr[myplr]._ptargx = x;
788  plr[myplr]._ptargy = y;
790  plr[myplr]._pLvlChanging = TRUE;
791  plr[myplr].pLvlLoad = 0;
794 }
795 
796 BOOL multi_init_single(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info)
797 {
798  int unused;
799 
800  if (!SNetInitializeProvider(SELCONN_LOOPBACK, client_info, user_info, ui_info, &fileinfo)) {
801  SErrGetLastError();
802  return FALSE;
803  }
804 
805  unused = 0;
806  if (!SNetCreateGame("local", "local", "local", 0, (char *)&sgGameInitInfo.dwSeed, 8, 1, "local", "local", &unused)) {
807  app_fatal("SNetCreateGame1:\n%s", TraceLastError());
808  }
809 
810  myplr = 0;
811  gbMaxPlayers = 1;
812 
813  return TRUE;
814 }
815 
816 BOOL multi_init_multi(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, BOOL *pfExitProgram)
817 {
818  BOOL first;
819  int playerId;
820  int type;
821 
822  for (first = TRUE;; first = FALSE) {
823  type = 0x00;
824  if (gbSelectProvider) {
825  if (!UiSelectProvider(0, client_info, user_info, ui_info, &fileinfo, &type)
826  && (!first || SErrGetLastError() != STORM_ERROR_REQUIRES_UPGRADE || !multi_upgrade(pfExitProgram))) {
827  return FALSE;
828  }
829  if (type == 'BNET')
830  plr[0].pBattleNet = 1;
831  }
832 
833  multi_event_handler(TRUE);
834  if (UiSelectGame(1, client_info, user_info, ui_info, &fileinfo, &playerId))
835  break;
836 
837  gbSelectProvider = TRUE;
838  }
839 
840  if ((DWORD)playerId >= MAX_PLRS) {
841  return FALSE;
842  } else {
843  myplr = playerId;
845 
847 
848  if (type == 'BNET')
849  plr[myplr].pBattleNet = 1;
850 
851  return TRUE;
852  }
853 }
854 
855 BOOL multi_upgrade(BOOL *pfExitProgram)
856 {
857  BOOL result;
858  int status;
859 
860  SNetPerformUpgrade((LPDWORD)&status);
861  result = TRUE;
862  if (status && status != 1) {
863  if (status != 2) {
864  if (status == -1) {
865  DrawDlg("Network upgrade failed");
866  }
867  } else {
868  *pfExitProgram = 1;
869  }
870 
871  result = FALSE;
872  }
873 
874  return result;
875 }
876 
877 void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, BOOL recv)
878 {
879  char *szEvent;
880 
881  if (myplr == pnum) {
882  return;
883  }
885 
886  if (sgwPackPlrOffsetTbl[pnum] != p->wOffset) {
887  sgwPackPlrOffsetTbl[pnum] = 0;
888  if (p->wOffset != 0) {
889  return;
890  }
891  }
892  if (!recv && sgwPackPlrOffsetTbl[pnum] == 0) {
894  }
895 
896  memcpy((char *)&netplr[pnum] + p->wOffset, &p[1], p->wBytes); /* todo: cast? */
897  sgwPackPlrOffsetTbl[pnum] += p->wBytes;
898  if (sgwPackPlrOffsetTbl[pnum] != sizeof(*netplr)) {
899  return;
900  }
901 
902  sgwPackPlrOffsetTbl[pnum] = 0;
903  multi_player_left_msg(pnum, 0);
904  plr[pnum]._pGFXLoad = 0;
905  UnPackPlayer(&netplr[pnum], pnum, TRUE);
906 
907  if (!recv) {
908  return;
909  }
910 
911  plr[pnum].plractive = TRUE;
912  gbActivePlayers++;
913 
914  if (sgbPlayerTurnBitTbl[pnum] != 0) {
915  szEvent = "Player '%s' (level %d) just joined the game";
916  } else {
917  szEvent = "Player '%s' (level %d) is already in the game";
918  }
919  EventPlrMsg(szEvent, plr[pnum]._pName, plr[pnum]._pLevel);
920 
921  LoadPlrGFX(pnum, PFILE_STAND);
922  SyncInitPlr(pnum);
923 
924  if (plr[pnum].plrlevel == currlevel) {
925  if (plr[pnum]._pHitPoints >> 6 > 0) {
926  StartStand(pnum, 0);
927  } else {
928  plr[pnum]._pgfxnum = 0;
929  LoadPlrGFX(pnum, PFILE_DEATH);
930  plr[pnum]._pmode = PM_DEATH;
931  NewPlrAnim(pnum, plr[pnum]._pDAnim[0], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth);
932  plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1;
933  plr[pnum]._pVar8 = 2 * plr[pnum]._pAnimLen;
934  dFlags[plr[pnum].WorldX][plr[pnum].WorldY] |= BFLAG_DEAD_PLAYER;
935  }
936  }
937 }
938 
sgbTimeout
BOOLEAN sgbTimeout
Definition: multi.cpp:35
multi_parse_turn
void multi_parse_turn(int pnum, int turn)
Definition: multi.cpp:190
multi_net_ping
void multi_net_ping()
Definition: multi.cpp:274
_SNETEVENT
Definition: structs.h:1266
PFILE_DEATH
@ PFILE_DEATH
Definition: enums.h:2847
TPktHdr::targx
BYTE targx
Definition: structs.h:894
tmsg_start
void tmsg_start()
Definition: tmsg.cpp:41
TPktHdr::bdex
BYTE bdex
Definition: structs.h:900
PlayerStruct::pLvlLoad
unsigned char pLvlLoad
Definition: structs.h:340
PlayerStruct::_pBaseStr
int _pBaseStr
Definition: structs.h:246
sglTimeoutStart
int sglTimeoutStart
Definition: multi.cpp:26
gdwNormalMsgSize
DWORD gdwNormalMsgSize
Definition: nthread.cpp:25
PlayerStruct::_pgfxnum
int _pgfxnum
Definition: structs.h:204
PlayerStruct::_pAnimFrame
int _pAnimFrame
Definition: structs.h:209
_SNETUIDATA::changenamecallback
void(* changenamecallback)()
Definition: structs.h:1351
currlevel
BYTE currlevel
Definition: gendung.cpp:40
PlayerStruct::_pMaxHP
int _pMaxHP
Definition: structs.h:259
PlayerStruct::_ptargx
int _ptargx
Definition: structs.h:192
gbActivePlayers
BYTE gbActivePlayers
Definition: multi.cpp:21
TPkt::hdr
TPktHdr hdr
Definition: structs.h:906
PlayerStruct::destAction
int destAction
Definition: structs.h:182
_SNETUIDATA::size
int size
Definition: structs.h:1323
MAX_PLRS
#define MAX_PLRS
Definition: defs.h:16
TPkt
Definition: structs.h:905
SetRndSeed
void SetRndSeed(int s)
Set the RNG seed.
Definition: engine.cpp:728
pfile_read_player_from_save
void pfile_read_player_from_save()
Definition: pfile.cpp:381
PlayerStruct::_pAnimLen
int _pAnimLen
Definition: structs.h:208
_SNETUIDATA::profilebitmapcallback
void(* profilebitmapcallback)()
Definition: structs.h:1340
sgwPackPlrOffsetTbl
WORD sgwPackPlrOffsetTbl[MAX_PLRS]
Definition: multi.cpp:15
PlayerStruct::_pBaseDex
int _pBaseDex
Definition: structs.h:250
gbBufferMsgs
BYTE gbBufferMsgs
Definition: msg.cpp:26
dthread_cleanup
void dthread_cleanup()
Definition: dthread.cpp:119
GAMEINFO_PASSWORD
@ GAMEINFO_PASSWORD
Definition: enums.h:2122
multi_mon_seeds
void multi_mon_seeds()
Definition: multi.cpp:325
PlayerStruct::WorldX
int WorldX
Definition: structs.h:188
FixPlrWalkTags
void FixPlrWalkTags(int pnum)
Definition: player.cpp:1507
MakePlrPath
void MakePlrPath(int pnum, int xx, int yy, BOOL endspace)
Definition: player.cpp:3526
glpMsgTbl
uintptr_t glpMsgTbl[MAX_PLRS]
Definition: nthread.cpp:17
_SNETUIDATA::authcallback
void(* authcallback)()
Definition: structs.h:1327
multi_msg_countdown
void multi_msg_countdown()
Definition: multi.cpp:178
multi_copy_packet
void multi_copy_packet(TBuffer *buf, void *packet, BYTE size)
Definition: multi.cpp:66
multi_upgrade
BOOL multi_upgrade(BOOL *pfExitProgram)
Definition: multi.cpp:855
nthread_send_and_recv_turn
DWORD nthread_send_and_recv_turn(DWORD cur_turn, int turn_delta)
Definition: nthread.cpp:47
SetupLocalCoords
void SetupLocalCoords()
Definition: multi.cpp:764
szPlayerDescript
char szPlayerDescript[128]
Definition: multi.cpp:14
event_types
const int event_types[3]
Contains the set of supported event types supported by the multiplayer event handler.
Definition: multi.cpp:45
_SNETPROGRAMDATA::size
int size
Definition: structs.h:1297
_SNETUIDATA::getdatacallback
void(* getdatacallback)()
Definition: structs.h:1334
TPktHdr
struct TPktHdr TPktHdr
gdwMsgLenTbl
DWORD gdwMsgLenTbl[MAX_PLRS]
Definition: nthread.cpp:12
_SNETPROGRAMDATA::maxplayers
int maxplayers
Definition: structs.h:1303
buffer_init
void buffer_init(TBuffer *pBuf)
Definition: multi.cpp:736
tmsg_cleanup
void tmsg_cleanup()
Definition: tmsg.cpp:46
multi_check_drop_player
void multi_check_drop_player()
Definition: multi.cpp:397
sgLoPriBuf
TBuffer sgLoPriBuf
Definition: multi.cpp:28
gdwTurnsInTransit
DWORD gdwTurnsInTransit
Definition: nthread.cpp:16
PlayerStruct::_poldy
int _poldy
Definition: structs.h:197
TPktHdr::targy
BYTE targy
Definition: structs.h:895
tmsg_get
int tmsg_get(BYTE *pbMsg, DWORD dwMaxLen)
Definition: tmsg.cpp:7
multi_send_packet
void multi_send_packet(void *packet, BYTE dwSize)
Definition: multi.cpp:82
dthread_send_delta
void dthread_send_delta(int pnum, char cmd, void *pbSrc, int dwLen)
Definition: dthread.cpp:32
_SNETEVENT::data
void * data
Definition: structs.h:1269
multi_handle_all_packets
void multi_handle_all_packets(int pnum, BYTE *pData, int nSize)
Definition: multi.cpp:479
gnDifficulty
int gnDifficulty
Definition: gendung.cpp:31
gnLevelTypeTbl
int gnLevelTypeTbl[NUMLEVELS]
Definition: diablo.cpp:16
NetInit
BOOL NetInit(BOOL bSinglePlayer, BOOL *pfExitProgram)
Definition: multi.cpp:636
sgGameInitInfo
_gamedata sgGameInitInfo
Definition: multi.cpp:24
PM_DEATH
@ PM_DEATH
Definition: enums.h:2051
InitLevelType
int InitLevelType(int l)
Definition: multi.cpp:750
TCmdPlrInfoHdr
Definition: structs.h:835
_SNETUIDATA
Definition: structs.h:1322
TPkt::body
BYTE body[493]
Definition: structs.h:907
sgdwGameLoops
DWORD sgdwGameLoops
Definition: multi.cpp:29
all.h
sgbPlayerTurnBitTbl
BOOLEAN sgbPlayerTurnBitTbl[MAX_PLRS]
Definition: multi.cpp:17
multi_check_pkt_valid
int multi_check_pkt_valid(TBuffer *pBuf)
Definition: multi.cpp:320
SELCONN_LOOPBACK
@ SELCONN_LOOPBACK
Definition: enums.h:2939
_SNETUIDATA::profilecallback
void(* profilecallback)()
Definition: structs.h:1338
nthread_start
void nthread_start(BOOL set_turn_upper_bit)
Definition: nthread.cpp:118
gbSelectProvider
BOOLEAN gbSelectProvider
Definition: multi.cpp:25
PFILE_STAND
@ PFILE_STAND
Definition: enums.h:2840
multi_handle_turn_upper_bit
void multi_handle_turn_upper_bit(int pnum)
Definition: multi.cpp:205
netplr
PkPlayerStruct netplr[MAX_PLRS]
Definition: multi.cpp:16
CMD_ACK_PLRINFO
@ CMD_ACK_PLRINFO
Definition: enums.h:2173
_SNETUIDATA::soundcallback
void(* soundcallback)()
Definition: structs.h:1332
sgbSentThisCycle
int sgbSentThisCycle
Definition: multi.cpp:19
_SNETPROGRAMDATA
Definition: structs.h:1296
gbMaxPlayers
BYTE gbMaxPlayers
Specifies the maximum number of players in a game, where 1 represents a single player game and 4 repr...
Definition: multi.cpp:34
multi_msg_add
void multi_msg_add(BYTE *pbMsg, BYTE bLen)
Definition: multi.cpp:51
recv_plrinfo
void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, BOOL recv)
Definition: multi.cpp:877
PlayerStruct::_pownerx
int _pownerx
Definition: structs.h:194
NewPlrAnim
void NewPlrAnim(int pnum, BYTE *Peq, int numFrames, int Delay, int width)
Definition: player.cpp:394
RemovePlrFromMap
void RemovePlrFromMap(int pnum)
Definition: player.cpp:1534
InitPlrMsg
void InitPlrMsg()
Definition: plrmsg.cpp:78
PlayerStruct::_px
int _px
Definition: structs.h:190
multi_handle_events
void multi_handle_events(_SNETEVENT *pEvt)
Definition: multi.cpp:602
sync_init
void sync_init()
Definition: sync.cpp:283
_SNETUIDATA::categorycallback
void(* categorycallback)()
Definition: structs.h:1335
DeltaExportData
void DeltaExportData(int pnum)
Definition: msg.cpp:190
multi_send_msg_packet
void multi_send_msg_packet(int pmask, BYTE *src, BYTE len)
Definition: multi.cpp:159
gszVersionNumber
char gszVersionNumber[MAX_PATH]
defined in dx.cpp
Definition: init.cpp:27
gbGameDestroyed
BOOLEAN gbGameDestroyed
Definition: multi.cpp:22
dwRecCount
int dwRecCount
Definition: msg.cpp:27
TPktHdr
Definition: structs.h:891
DeactivatePortal
void DeactivatePortal(int i)
Definition: portal.cpp:90
PlayerStruct::_pGFXLoad
int _pGFXLoad
Definition: structs.h:287
TPktHdr::py
BYTE py
Definition: structs.h:893
SyncInitPlr
void SyncInitPlr(int pnum)
Definition: player.cpp:3788
multi_process_tmsgs
void multi_process_tmsgs()
Definition: multi.cpp:493
sync_all_monsters
DWORD sync_all_monsters(const BYTE *pbBuf, DWORD dwMaxLen)
Definition: sync.cpp:11
_SNETPROGRAMDATA::versionid
int versionid
Definition: structs.h:1301
_gamedata
Definition: structs.h:1212
app_fatal
void app_fatal(const char *pszFmt,...)
Definition: appfat.cpp:18
multi_init_multi
BOOL multi_init_multi(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, BOOL *pfExitProgram)
Definition: multi.cpp:816
gbRunGame
BOOL gbRunGame
Definition: diablo.cpp:21
TBuffer::dwNextWriteOffset
DWORD dwNextWriteOffset
Definition: structs.h:962
_SNETUIDATA::selectnamecallback
int(* selectnamecallback)(const struct _SNETPROGRAMDATA *, const struct _SNETPLAYERDATA *, const struct _SNETUIDATA *, const struct _SNETVERSIONDATA *, DWORD provider, char *, DWORD, char *, DWORD, BOOL *)
Definition: structs.h:1341
DEVILUTION_END_NAMESPACE
#define DEVILUTION_END_NAMESPACE
Definition: types.h:10
EVENT_TYPE_PLAYER_MESSAGE
@ EVENT_TYPE_PLAYER_MESSAGE
Definition: enums.h:1973
monster
MonsterStruct monster[MAXMONSTERS]
Definition: monster.cpp:19
multi_player_left_msg
void multi_player_left_msg(int pnum, int left)
Definition: multi.cpp:245
multi_clear_left_tbl
void multi_clear_left_tbl()
Definition: multi.cpp:228
left
int left[8]
Definition: monster.cpp:58
_gamedata::bDiff
BYTE bDiff
Definition: structs.h:1214
sgbNetUpdateRate
DEVILUTION_BEGIN_NAMESPACE BYTE sgbNetUpdateRate
Definition: nthread.cpp:11
_SNETPLAYERDATA::size
int size
Definition: structs.h:1290
gbSomebodyWonGameKludge
DEVILUTION_BEGIN_NAMESPACE BOOLEAN gbSomebodyWonGameKludge
Definition: multi.cpp:12
nthread_terminate_game
void nthread_terminate_game(const char *pszFcn)
Definition: nthread.cpp:31
delta_close_portal
void delta_close_portal(int pnum)
Definition: msg.cpp:976
sgbSendDeltaTbl
BOOLEAN sgbSendDeltaTbl[MAX_PLRS]
Definition: multi.cpp:23
ErrorPlrMsg
char * ErrorPlrMsg(const char *pszMsg)
Definition: plrmsg.cpp:28
StartStand
void StartStand(int pnum, int dir)
Definition: player.cpp:1056
PlayerStruct::_pBaseMag
int _pBaseMag
Definition: structs.h:248
PlayerStruct::plractive
BOOLEAN plractive
Definition: structs.h:181
multi_recv_packet
BYTE * multi_recv_packet(TBuffer *pBuf, BYTE *body, int *size)
Definition: multi.cpp:133
player_state
int player_state[MAX_PLRS]
Definition: multi.cpp:39
TCmdPlrInfoHdr::wBytes
WORD wBytes
Definition: structs.h:838
PlayerStruct::_pLvlChanging
BOOLEAN _pLvlChanging
Definition: structs.h:236
_SNETPROGRAMDATA::initdata
_gamedata * initdata
Definition: structs.h:1304
dthread_remove_player
void dthread_remove_player(int pnum)
Definition: dthread.cpp:20
TPktHdr::pmhp
int pmhp
Definition: structs.h:897
UnPackPlayer
void UnPackPlayer(PkPlayerStruct *pPack, int pnum, BOOL killok)
Definition: pack.cpp:168
leveldebug
BOOL leveldebug
Definition: diablo.cpp:35
BFLAG_DEAD_PLAYER
@ BFLAG_DEAD_PLAYER
Definition: enums.h:1879
TPktHdr::bmag
BYTE bmag
Definition: structs.h:899
_SNETUIDATA::drawdesccallback
void(* drawdesccallback)()
Definition: structs.h:1329
_SNETPROGRAMDATA::lcid
int lcid
Definition: structs.h:1311
GetRndSeed
int GetRndSeed()
Get the current RNG seed.
Definition: engine.cpp:739
sgbNetInited
BOOL sgbNetInited
Definition: multi.cpp:38
PlayerStruct::_pownery
int _pownery
Definition: structs.h:195
TPktHdr::wCheck
WORD wCheck
Definition: structs.h:901
_SNETPROGRAMDATA::programdescription
char * programdescription
Definition: structs.h:1299
TCmdPlrInfoHdr::wOffset
WORD wOffset
Definition: structs.h:837
gbDeltaSender
BYTE gbDeltaSender
Definition: multi.cpp:37
TPktHdr::wLen
WORD wLen
Definition: structs.h:902
PM_NEWLVL
@ PM_NEWLVL
Definition: enums.h:2053
PlayerStruct::_ptargy
int _ptargy
Definition: structs.h:193
multi_handle_delta
int multi_handle_delta()
Definition: multi.cpp:280
NetSendHiPri
void NetSendHiPri(BYTE *pbMsg, BYTE bLen)
Definition: multi.cpp:107
setlevel
BOOLEAN setlevel
Definition: gendung.cpp:65
TPktHdr::php
int php
Definition: structs.h:896
nthread_cleanup
void nthread_cleanup()
Definition: nthread.cpp:199
plrxoff
int plrxoff[9]
Definition: player.cpp:32
TCmd
Definition: structs.h:708
_SNETEVENT::playerid
DWORD playerid
Definition: structs.h:1268
PlayerStruct::_poldx
int _poldx
Definition: structs.h:196
DTYPE_TOWN
@ DTYPE_TOWN
Definition: enums.h:1868
_SNETPROGRAMDATA::programid
int programid
Definition: structs.h:1300
nthread_recv_turns
BOOL nthread_recv_turns(BOOL *pfSendAsync)
Definition: nthread.cpp:77
glSeedTbl
DWORD glSeedTbl[NUMLEVELS]
Definition: diablo.cpp:20
_SNETPROGRAMDATA::initdatabytes
int initdatabytes
Definition: structs.h:1305
RemovePlrMissiles
void RemovePlrMissiles(int pnum)
Definition: player.cpp:1908
TPktHdr::bstr
BYTE bstr
Definition: structs.h:898
_SNETPROGRAMDATA::optcategorybits
int optcategorybits
Definition: structs.h:1307
szPlayerName
char szPlayerName[128]
Definition: multi.cpp:36
CMD_SEND_PLRINFO
@ CMD_SEND_PLRINFO
Definition: enums.h:2225
_SNETPLAYERDATA
Definition: structs.h:1289
EVENT_TYPE_PLAYER_LEAVE_GAME
@ EVENT_TYPE_PLAYER_LEAVE_GAME
Definition: enums.h:1972
fileinfo
DEVILUTION_BEGIN_NAMESPACE _SNETVERSIONDATA fileinfo
Definition: init.cpp:15
sgbPlayerLeftGameTbl
BOOLEAN sgbPlayerLeftGameTbl[MAX_PLRS]
Definition: multi.cpp:18
msg_wait_resync
BOOL msg_wait_resync()
Definition: msg.cpp:74
NetClose
void NetClose()
Definition: multi.cpp:568
EventPlrMsg
size_t EventPlrMsg(const char *pszFmt,...)
Definition: plrmsg.cpp:40
_SNETEVENT::eventid
DWORD eventid
Definition: structs.h:1267
myplr
int myplr
Definition: player.cpp:9
PlayerStruct::_pHitPoints
int _pHitPoints
Definition: structs.h:258
TCmdPlrInfoHdr::bCmd
BYTE bCmd
Definition: structs.h:836
multi_player_left
void multi_player_left(int pnum, int reason)
Definition: multi.cpp:221
NetSendLoPri
void NetSendLoPri(BYTE *pbMsg, BYTE bLen)
Definition: multi.cpp:58
gdwLargestMsgSize
DWORD gdwLargestMsgSize
Definition: nthread.cpp:24
_gamedata::dwSeed
int dwSeed
Definition: structs.h:1213
sgdwPlayerLeftReasonTbl
int sgdwPlayerLeftReasonTbl[MAX_PLRS]
Definition: multi.cpp:27
PlayerStruct::plrlevel
int plrlevel
Definition: structs.h:187
PkPlayerStruct
Definition: structs.h:1375
_SNETUIDATA::createcallback
void(* createcallback)()
Definition: structs.h:1328
PlayerStruct::pBattleNet
unsigned char pBattleNet
Definition: structs.h:341
RemovePortalMissile
void RemovePortalMissile(int id)
Definition: portal.cpp:103
dthread_start
void dthread_start()
Definition: dthread.cpp:58
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
mainmenu_change_name
void mainmenu_change_name(int arg1, int arg2, int arg3, int arg4, char *name_1, char *name_2)
Definition: mainmenu.cpp:31
multi_begin_timeout
void multi_begin_timeout()
Definition: multi.cpp:336
delta_init
void delta_init()
Definition: msg.cpp:301
_SNETUIDATA::profilefields
const char ** profilefields
Definition: structs.h:1339
sgHiPriBuf
TBuffer sgHiPriBuf
Definition: multi.cpp:13
PlayerStruct::_py
int _py
Definition: structs.h:191
TraceLastError
#define TraceLastError
Definition: appfat.h:15
DrawDlg
void DrawDlg(char *pszFmt,...)
Definition: appfat.cpp:58
ACTION_NONE
@ ACTION_NONE
Definition: enums.h:2906
dPlayer
char dPlayer[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:49
dFlags
char dFlags[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:56
PlayerStruct::_pVar8
int _pVar8
Definition: structs.h:284
TPktHdr::px
BYTE px
Definition: structs.h:892
TBuffer
Definition: structs.h:961
mainmenu_select_hero_dialog
int mainmenu_select_hero_dialog(const _SNETPROGRAMDATA *client_info, const _SNETPLAYERDATA *user_info, const _SNETUIDATA *ui_info, const _SNETVERSIONDATA *fileinfo, DWORD mode, char *cname, DWORD clen, char *cdesc, DWORD cdlen, BOOL *multi)
Definition: mainmenu.cpp:37
_SNETUIDATA::messageboxcallback
void(* messageboxcallback)()
Definition: structs.h:1331
PlayerStruct::_pmode
int _pmode
Definition: structs.h:179
plryoff
int plryoff[9]
Definition: player.cpp:33
PlayerStruct::WorldY
int WorldY
Definition: structs.h:189
PackPlayer
void PackPlayer(PkPlayerStruct *pPack, int pnum, BOOL manashield)
Definition: pack.cpp:35
ParseCmd
DWORD ParseCmd(int pnum, TCmd *pCmd)
Definition: msg.cpp:982
PlayerStruct::_pName
char _pName[PLR_NAME_LEN]
Definition: structs.h:237
TBuffer::bData
BYTE bData[4096]
Definition: structs.h:963
multi_process_network_packets
void multi_process_network_packets()
Definition: multi.cpp:408
NetRecvPlrData
void NetRecvPlrData(TPkt *pkt)
Definition: multi.cpp:93
multi_event_handler
void multi_event_handler(BOOL add)
Definition: multi.cpp:584
leveltype
BYTE leveltype
Definition: gendung.cpp:39
multi_init_single
BOOL multi_init_single(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info)
Definition: multi.cpp:796
GAMEINFO_NAME
@ GAMEINFO_NAME
Definition: enums.h:2121
MAXMONSTERS
#define MAXMONSTERS
Definition: defs.h:31
_SNETEVENT::databytes
DWORD databytes
Definition: structs.h:1270
plr
PlayerStruct plr[MAX_PLRS]
Definition: player.cpp:10
multi_send_zero_packet
void multi_send_zero_packet(int pnum, BYTE bCmd, BYTE *pbSrc, DWORD dwLen)
Definition: multi.cpp:503
msg_send_drop_pkt
void msg_send_drop_pkt(int pnum, int reason)
Definition: msg.cpp:29
tmsg_add
void tmsg_add(BYTE *pbMsg, BYTE bLen)
Definition: tmsg.cpp:26
LoadPlrGFX
void LoadPlrGFX(int pnum, player_graphic gfxflag)
Definition: player.cpp:134
EVENT_TYPE_PLAYER_CREATE_GAME
@ EVENT_TYPE_PLAYER_CREATE_GAME
Definition: enums.h:1970
gbShouldValidatePackage
BOOL gbShouldValidatePackage
Definition: multi.cpp:20
multi_send_pinfo
void multi_send_pinfo(int pnum, char cmd)
Definition: multi.cpp:742
_SNETPROGRAMDATA::programname
char * programname
Definition: structs.h:1298
_SNETUIDATA::artcallback
void(* artcallback)()
Definition: structs.h:1326