void D_InitNetGame (void) { int i; int numplayers = 1; i = M_CheckParm("-net"); if (i && i < myargc-1) i++; server = netgame; if (!netgame) { playeringame[consoleplayer = 0] = true; } else { StartWifi(); // Get game info from server packet_header_t *packet = Z_Malloc(1000, PU_STATIC, NULL); struct setup_packet_s *sinfo = (void*)(packet+1); struct { packet_header_t head; short pn; } PACKEDATTR initpacket; iprintf("I_InitNetwork()\n"); I_InitNetwork(); udp_socket = I_Socket(0); //I_ConnectToServer(myargv[i]); iprintf("I_ConnectToServer()\n"); if (I_ConnectToServer(server_address[0]) != 0) iprintf("FAILURE!\n"); iprintf("Connected?\n"); do { iprintf("Send Init Packet\n"); do { // Send init packet initpacket.pn = doom_htons(wanted_player_number); packet_set(&initpacket.head, PKT_INIT, 0); I_SendPacket(&initpacket.head, sizeof(initpacket)); iprintf("Wait for packet\n"); I_WaitForPacket(5000); iprintf("Done\n"); } while (!I_GetPacket(packet, 1000)); iprintf("Got it!\n"); if (packet->type == PKT_DOWN) I_Error("Server aborted the game"); } while (packet->type != PKT_SETUP); iprintf("Out of loop!\n"); // Once we have been accepted by the server, we should tell it when we leave atexit(D_QuitNetGame); // Get info from the setup packet consoleplayer = sinfo->yourplayer; compatibility_level = sinfo->complevel; G_Compatibility(); startskill = sinfo->skill; deathmatch = sinfo->deathmatch; startmap = sinfo->level; startepisode = sinfo->episode; ticdup = sinfo->ticdup; xtratics = sinfo->extratic; G_ReadOptions(sinfo->game_options); lprintf(LO_INFO, "\tjoined game as player %d/%d; %d WADs specified\n", consoleplayer+1, numplayers = sinfo->players, sinfo->numwads); { char *p = sinfo->wadnames; int i = sinfo->numwads; while (i--) { D_AddFile(p, source_net); p += strlen(p) + 1; } } Z_Free(packet); } localcmds = netcmds[displayplayer = consoleplayer]; for (i=0; i<numplayers; i++) playeringame[i] = true; for (; i<MAXPLAYERS; i++) playeringame[i] = false; if (!playeringame[consoleplayer]) I_Error("D_InitNetGame: consoleplayer not in game"); }
void D_InitNetGame (void) { int i; int numplayers = 1; i = M_CheckParm("-net"); if (i && i < myargc-1) i++; if (!(netgame = server = !!i)) { playeringame[consoleplayer = 0] = TRUE; // e6y // for play, recording or playback using "single-player coop" mode. // Equivalent to using prboom_server with -N 1 netgame = M_CheckParm("-solo-net") || M_CheckParm("-net1"); } else { // Get game info from server packet_header_t *packet = Z_Malloc(1000, PU_STATIC, NULL); struct setup_packet_s *sinfo = (void*)(packet+1); struct { packet_header_t head; short pn; } PACKEDATTR initpacket; I_InitNetwork(); udp_socket = I_Socket(0); I_ConnectToServer(myargv[i]); do { do { // Send init packet initpacket.pn = doom_htons(wanted_player_number); packet_set(&initpacket.head, PKT_INIT, 0); I_SendPacket(&initpacket.head, sizeof(initpacket)); I_WaitForPacket(5000); } while (!I_GetPacket(packet, 1000)); if (packet->type == PKT_DOWN) I_Error("Server aborted the game"); } while (packet->type != PKT_SETUP); // Get info from the setup packet consoleplayer = sinfo->yourplayer; compatibility_level = sinfo->complevel; G_Compatibility(); startskill = sinfo->skill; deathmatch = sinfo->deathmatch; startmap = sinfo->level; startepisode = sinfo->episode; ticdup = sinfo->ticdup; xtratics = sinfo->extratic; G_ReadOptions(sinfo->game_options); lprintf(LO_INFO, "\tjoined game as player %d/%d; %d WADs specified\n", consoleplayer+1, numplayers = sinfo->players, sinfo->numwads); { char *p = sinfo->wadnames; int i = sinfo->numwads; while (i--) { D_AddFile(p, source_net); p += strlen(p) + 1; } } Z_Free(packet); } localcmds = netcmds[displayplayer = consoleplayer]; for (i=0; i<numplayers; i++) playeringame[i] = TRUE; for (; i<MAXPLAYERS; i++) playeringame[i] = FALSE; if (!playeringame[consoleplayer]) I_Error("D_InitNetGame: consoleplayer not in game"); }
dboolean G_ReadSaveData(pbuf_t *savebuffer, dboolean bail_on_errors, dboolean init_new) { int i; int savegame_compatibility = -1; complevel_t m_compatibility_level; skill_t m_gameskill; int m_gameepisode; int m_gamemap; //e6y: numeric version number of package should be zero before initializing // from savegame unsigned int packageversion = 0; unsigned char description[SAVESTRINGSIZE]; unsigned char save_version[VERSIONSIZE]; byte game_options[GAME_OPTION_SIZE]; unsigned int game_option_count; unsigned char safety_byte; buf_t byte_buf; M_BufferInit(&byte_buf); memset(description, 0, SAVESTRINGSIZE); memset(save_version, 0, VERSIONSIZE); M_PBufReadBytes(savebuffer, &byte_buf); if (M_BufferGetSize(&byte_buf) != SAVESTRINGSIZE) { I_Error("G_ReadSaveData: save string size mismatch (%zu != %u)", M_BufferGetSize(&byte_buf), SAVESTRINGSIZE ); } memcpy(description, M_BufferGetData(&byte_buf), M_BufferGetSize(&byte_buf)); M_BufferClear(&byte_buf); M_PBufReadBytes(savebuffer, &byte_buf); if (M_BufferGetSize(&byte_buf) != VERSIONSIZE) { I_Error("G_ReadSaveData: version size mismatch (%zu != %u)", M_BufferGetSize(&byte_buf), VERSIONSIZE ); } memcpy(save_version, M_BufferGetData(&byte_buf), M_BufferGetSize(&byte_buf)); M_BufferFree(&byte_buf); // CPhipps - read the description field, compare with supported ones for (i = 0; i < num_version_headers; i++) { char vcheck[VERSIONSIZE]; // killough 2/22/98: "proprietary" version string :-) sprintf(vcheck, version_headers[i].ver_printf, version_headers[i].version); if (!strncmp((const char *)save_version, vcheck, VERSIONSIZE)) { savegame_compatibility = version_headers[i].comp_level; break; } } if (savegame_compatibility == -1) { fprintf(stderr, "savegame_compatibility == -1 (%s)\n", save_version); if (bail_on_errors) { return false; } else if (forced_loadgame) { savegame_compatibility = MAX_COMPATIBILITY_LEVEL - 1; } else { G_LoadGameErr("Unrecognized savegame version!\nAre you sure? (y/n) "); return false; } } // CPhipps - always check savegames even when forced, // only print a warning if forced { // killough 3/16/98: check lump name checksum (independent of order) uint_64_t checksum; uint_64_t save_checksum = 0; if (MULTINET) checksum = 1; else checksum = G_Signature(); M_PBufReadLong(savebuffer, (int_64_t *)&save_checksum); if (save_checksum != checksum) { fprintf(stderr, "bad checksum: %" PRIu64 " != %" PRIu64 "\n", checksum, save_checksum ); if (bail_on_errors) return false; if (!forced_loadgame) { G_LoadGameErr("Incompatible Savegame!!!\n\nAre you sure?"); return false; } else { lprintf(LO_WARN, "G_DoLoadGame: Incompatible savegame\n"); } } } /*-----------------*/ /* CG: TODO: PWADs */ /*-----------------*/ M_PBufReadUInt(savebuffer, &packageversion); M_PBufReadInt(savebuffer, &m_compatibility_level); M_PBufReadInt(savebuffer, &m_gameskill); M_PBufReadInt(savebuffer, &m_gameepisode); M_PBufReadInt(savebuffer, &m_gamemap); if (!init_new) { if (m_compatibility_level != compatibility_level) { if (bail_on_errors) return false; I_Error("G_ReadSaveData: Mismatched compatibility level"); } if (m_gameskill != gameskill) { if (bail_on_errors) return false; I_Error("G_ReadSaveData: Mismatched game skill"); } if (m_gameepisode != gameepisode) { if (bail_on_errors) return false; I_Error("G_ReadSaveData: Mismatched episode"); } if (m_gamemap != gamemap) { if (bail_on_errors) return false; I_Error("G_ReadSaveData: Mismatched map"); } } compatibility_level = m_compatibility_level; gameskill = m_gameskill; gameepisode = m_gameepisode; gamemap = m_gamemap; M_PBufReadInt(savebuffer, &gametic); M_PBufReadBool(savebuffer, &levelTimer); M_PBufReadInt(savebuffer, &levelTimeCount); M_PBufReadBool(savebuffer, &levelFragLimit); M_PBufReadInt(savebuffer, &levelFragLimitCount); for (i = 0; i < MAXPLAYERS; i++) M_PBufReadBool(savebuffer, &playeringame[i]); // killough 2/28/98 for (dboolean b = false, i = MAXPLAYERS; i < MIN_MAXPLAYERS; i++) M_PBufReadBool(savebuffer, &b); M_PBufReadInt(savebuffer, &idmusnum); // jff 3/17/98 restore idmus music /* killough 3/1/98: Read game options * killough 11/98: move down to here */ M_PBufReadArray(savebuffer, &game_option_count); if (mbf_features && (game_option_count > GAME_OPTION_SIZE)) { I_Error("G_ReadSaveData: too many options (%d > %d)", game_option_count, GAME_OPTION_SIZE ); } else if ((!mbf_features) && game_option_count > OLD_GAME_OPTION_SIZE) { I_Error("G_ReadSaveData: too many options (%d > %d)", game_option_count, OLD_GAME_OPTION_SIZE ); } for (i = 0; i < game_option_count; i++) M_PBufReadUChar(savebuffer, &game_options[i]); G_ReadOptions(game_options); // killough 3/1/98: Read game options // load a base level if (init_new) G_InitNew(gameskill, gameepisode, gamemap); P_IdentReset(); /* get the times - killough 11/98: save entire word */ M_PBufReadInt(savebuffer, &leveltime); /* cph - total episode time */ //e6y: total level times are always saved since 2.4.8.1 M_PBufReadInt(savebuffer, &totalleveltimes); // killough 11/98: load revenant tracer state M_PBufReadInt(savebuffer, &basetic); // dearchive all the modifications P_MapStart(); P_UnArchiveWorld(savebuffer); P_UnArchivePlayers(savebuffer); P_UnArchiveThinkers(savebuffer); P_UnArchiveSpecials(savebuffer); P_UnArchiveRNG(savebuffer); // killough 1/18/98: load RNG information P_UnArchiveMap(savebuffer); // killough 1/22/98: load automap information S_ReloadChannelOrigins(); P_MapEnd(); R_ActivateSectorInterpolations();//e6y R_SmoothPlaying_Reset(NULL); // e6y if (musinfo.current_item != -1) S_ChangeMusInfoMusic(musinfo.current_item, true); RecalculateDrawnSubsectors(); M_PBufReadUChar(savebuffer, &safety_byte); if (safety_byte != 0xe6) I_Error("G_ReadSaveData: Bad savegame"); G_UpdateAverageSaveSize(M_PBufGetCapacity(savebuffer)); return true; }