X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_game.pas;h=3356c80981de79eb3f32169ebeb6aaf5403590a7;hb=1c9b34fa8d6a2bdd52cc3d0d2bf916c13d7b9bbf;hp=7b8324325dffae8ff5a131987a28a9326f555b87;hpb=dfc542926a3a356709f099050b2d2d59cb101e9d;p=d2df-sdl.git diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 7b83243..3356c80 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -2,8 +2,7 @@ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -102,7 +101,7 @@ procedure g_Game_StartClient(Addr: String; Port: Word; PW: String); procedure g_Game_Restart(); procedure g_Game_RestartLevel(); procedure g_Game_RestartRound(NoMapRestart: Boolean = False); -procedure g_Game_ClientWAD(NewWAD: String; WHash: TMD5Digest); +procedure g_Game_ClientWAD(NewWAD: String; const WHash: TMD5Digest); procedure g_Game_SaveOptions(); function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean; procedure g_Game_ChangeMap(const MapPath: String); @@ -211,7 +210,6 @@ const ANNOUNCE_ALL = 3; CONFIG_FILENAME = 'Doom2DF.cfg'; - LOG_FILENAME = 'Doom2DF.log'; TEST_MAP_NAME = '$$$_TEST_$$$'; @@ -385,7 +383,7 @@ uses g_triggers, g_monsters, e_sound, CONFIG, g_language, g_net, ENet, e_msg, g_netmsg, g_netmaster, - sfs, wadreader; + sfs, wadreader, g_system; var @@ -896,7 +894,7 @@ begin gDelayedEvents[n].DENum := Num; gDelayedEvents[n].DEStr := Str; if DEType = DE_GLOBEVENT then - gDelayedEvents[n].Time := (GetTimer() {div 1000}) + Time + gDelayedEvents[n].Time := (sys_GetTicks() {div 1000}) + Time else gDelayedEvents[n].Time := gTime + Time; Result := n; @@ -1343,8 +1341,10 @@ begin g_Sound_CreateWADEx('MUSIC_ROUNDMUS', GameWAD+':MUSIC\ROUNDMUS', True, True); g_Sound_CreateWADEx('MUSIC_STDENDMUS', GameWAD+':MUSIC\ENDMUS', True); +{$IFNDEF HEADLESS} g_Game_SetLoadingText(_lc[I_LOAD_MENUS], 0, False); g_Menu_Init(); +{$ENDIF} gMusic := TMusic.Create(); gMusic.SetByName('MUSIC_MENU'); @@ -1677,6 +1677,9 @@ begin Exit; end; + // process master server communications + g_Net_Slist_Pulse(); + case gState of STATE_INTERSINGLE, // Ñòàòèñòêà ïîñëå ïðîõîæäåíèÿ óðîâíÿ â Îäèíî÷íîé èãðå STATE_INTERCUSTOM, // Ñòàòèñòêà ïîñëå ïðîõîæäåíèÿ óðîâíÿ â Ñâîåé èãðå @@ -2124,19 +2127,18 @@ begin // send unexpected platform changes g_Map_NetSendInterestingPanels(); + g_Net_Slist_ServerUpdate(); + { if NetUseMaster then begin - if gTime >= NetTimeToMaster then + if (gTime >= NetTimeToMaster) or g_Net_Slist_IsConnectionInProgress then begin - if (NetMHost = nil) or (NetMPeer = nil) then - begin - if not g_Net_Slist_Connect then g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]); - end; - + if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Connect(false); // non-blocking connection to the master g_Net_Slist_Update; NetTimeToMaster := gTime + NetMasterRate; end; end; + } end else if (NetMode = NET_CLIENT) then begin @@ -2175,7 +2177,9 @@ begin //e_WriteLog('Read language file', MSG_NOTIFY); //g_Language_Load(DataDir + gLanguage + '.txt'); g_Language_Set(gLanguage); +{$IFNDEF HEADLESS} g_Menu_Reset(); +{$ENDIF} gLanguageChange := False; end; end; @@ -2189,7 +2193,7 @@ begin KeyPress(IK_F10); end; - Time := GetTimer() {div 1000}; + Time := sys_GetTicks() {div 1000}; // Îáðàáîòêà îòëîæåííûõ ñîáûòèé: if gDelayedEvents <> nil then @@ -2545,7 +2549,7 @@ var begin e_TextureFontGetSize(gStdFont, ww2, hh2); - g_ProcessMessages(); + sys_HandleInput; if g_Console_Action(ACTION_SCORES) then begin @@ -3509,7 +3513,7 @@ end; procedure DrawPlayer(p: TPlayer); var - px, py, a, b, c, d: Integer; + px, py, a, b, c, d, i: Integer; //R: TRect; begin if (p = nil) or (p.FDummy) then @@ -3664,8 +3668,21 @@ begin renderMapInternal(-c, -d, true); - if (gGameSettings.GameMode <> GM_SINGLE) and gPlayerIndicator then - p.DrawIndicator(); + if (gGameSettings.GameMode <> GM_SINGLE) and (gPlayerIndicator > 0) then + case gPlayerIndicator of + 1: + p.DrawIndicator(_RGB(255, 255, 255)); + + 2: + for i := 0 to High(gPlayers) do + if gPlayers[i] <> nil then + if gPlayers[i] = p then p.DrawIndicator(_RGB(255, 255, 255)) + else if (gPlayers[i].Team = p.Team) and (gPlayers[i].Team <> TEAM_NONE) then + if gPlayerIndicatorStyle = 1 then + gPlayers[i].DrawIndicator(_RGB(192, 192, 192)) + else gPlayers[i].DrawIndicator(gPlayers[i].GetColor); + end; + if p.FSpectator then e_TextureFontPrintEx(p.GameX + PLAYER_RECT_CX - 4, p.GameY + PLAYER_RECT_CY - 4, @@ -3721,7 +3738,7 @@ var begin if gExit = EXIT_QUIT then Exit; - Time := GetTimer() {div 1000}; + Time := sys_GetTicks() {div 1000}; FPSCounter := FPSCounter+1; if Time - FPSTime >= 1000 then begin @@ -4038,7 +4055,9 @@ begin g_ActiveWindow.Draw(); end; +{$IFNDEF HEADLESS} g_Console_Draw(); +{$ENDIF} if g_debug_Sounds and gGameOn then begin @@ -4074,7 +4093,9 @@ begin g_PlayerModel_FreeData(); g_Texture_DeleteAll(); g_Frames_DeleteAll(); +{$IFNDEF HEADLESS} //g_Menu_Free(); //k8: this segfaults after resolution change; who cares? +{$ENDIF} if NetInitDone then g_Net_Free; @@ -4083,7 +4104,7 @@ begin g_Game_DeleteTestMap(); gExit := EXIT_QUIT; - PushExitEvent(); + sys_RequestQuit; end; procedure g_FatalError(Text: String); @@ -4141,7 +4162,7 @@ end; procedure g_Game_ChangeResolution(newWidth, newHeight: Word; nowFull, nowMax: Boolean); begin - g_Window_SetSize(newWidth, newHeight, nowFull); + sys_SetDisplayMode(newWidth, newHeight, gBPP, nowFull); end; procedure g_Game_AddPlayer(Team: Byte = TEAM_NONE); @@ -4177,9 +4198,7 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_PlayerCreate(gPlayer1.UID); gPlayer1.Respawn(False, True); - - if g_Game_IsNet and NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerComes(); end; Exit; @@ -4209,9 +4228,7 @@ begin if g_Game_IsServer and g_Game_IsNet then MH_SEND_PlayerCreate(gPlayer2.UID); gPlayer2.Respawn(False, True); - - if g_Game_IsNet and NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerComes(); end; Exit; @@ -4234,9 +4251,7 @@ begin Pl.Kill(K_SIMPLEKILL, 0, HIT_DISCON); g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True); g_Player_Remove(Pl.UID); - - if g_Game_IsNet and NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end else gPlayer2 := nil; Exit; @@ -4250,9 +4265,7 @@ begin Pl.Kill(K_SIMPLEKILL, 0, HIT_DISCON); g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True); g_Player_Remove(Pl.UID); - - if g_Game_IsNet and NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end else begin gPlayer1 := nil; @@ -4260,6 +4273,7 @@ begin end; Exit; end; + g_Net_Slist_ServerPlayerLeaves(); end; procedure g_Game_Spectate(); @@ -4453,6 +4467,7 @@ procedure g_Game_StartServer(Map: String; GameMode: Byte; IPAddr: LongWord; Port: Word); begin g_Game_Free(); + g_Net_Slist_ServerClosed(); e_WriteLog('Starting net game (server)...', TMsgType.Notify); @@ -4527,11 +4542,14 @@ begin Exit; end; - g_Net_Slist_Set(NetSlistIP, NetSlistPort); + g_Net_Slist_Set(NetSlistIP, NetSlistPort, NetSlistList); + + g_Net_Slist_ServerStarted(); // Çàãðóçêà è çàïóñê êàðòû: if not g_Game_StartMap(Map, True) then begin + g_Net_Slist_ServerClosed(); g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Map])); Exit; end; @@ -4543,6 +4561,7 @@ begin g_Map_GetPointCount(RESPAWNPOINT_RED)+ g_Map_GetPointCount(RESPAWNPOINT_BLUE)) < 1 then begin + g_Net_Slist_ServerClosed(); g_FatalError(_lc[I_GAME_ERROR_GET_SPAWN]); Exit; end; @@ -4550,6 +4569,7 @@ begin // Íàñòðîéêè èãðîêîâ è áîòîâ: g_Player_Init(); + g_Net_Slist_ServerMapStarted(); NetState := NET_STATE_GAME; end; @@ -4591,6 +4611,10 @@ begin NetState := NET_STATE_AUTH; g_Game_SetLoadingText(_lc[I_LOAD_CONNECT], 0, False); + + // create (or update) map/resource databases + g_Res_CreateDatabases(true); + // Ñòàðòóåì êëèåíò if not g_Net_Connect(Addr, Port) then begin @@ -4606,14 +4630,24 @@ begin OuterLoop := True; while OuterLoop do begin - while (enet_host_service(NetHost, @NetEvent, 0) > 0) do + while (enet_host_service(NetHost, @NetEvent, 50) > 0) do begin if (NetEvent.kind = ENET_EVENT_TYPE_RECEIVE) then begin + if (NetEvent.channelID = NET_CHAN_DOWNLOAD_EX) then + begin + // ignore all download packets, they're processed by separate code + enet_packet_destroy(NetEvent.packet); + continue; + end; Ptr := NetEvent.packet^.data; if not InMsg.Init(Ptr, NetEvent.packet^.dataLength, True) then + begin + enet_packet_destroy(NetEvent.packet); continue; + end; + InMsg.ReadLongWord(); // skip size MID := InMsg.ReadByte(); if (MID = NET_MSG_INFO) and (State = 0) then @@ -4634,11 +4668,11 @@ begin gGameSettings.Options := InMsg.ReadLongWord(); T := InMsg.ReadLongWord(); - newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash); - if newResPath = '' then + //newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash); + //if newResPath = '' then begin - g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False); - newResPath := g_Res_DownloadWAD(WadName); + //g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False); + newResPath := g_Res_DownloadMapWAD(WadName, gWADHash); if newResPath = '' then begin g_FatalError(_lc[I_NET_ERR_HASH]); @@ -4646,6 +4680,7 @@ begin NetState := NET_STATE_NONE; Exit; end; + e_LogWritefln('using downloaded map wad [%s] for [%s]`', [newResPath, WadName], TMsgType.Notify); end; newResPath := ExtractRelativePath(MapsDir, newResPath); @@ -4701,8 +4736,7 @@ begin ProcessLoading(true); - if e_KeyPressed(IK_SPACE) or e_KeyPressed(IK_ESCAPE) or e_KeyPressed(VK_ESCAPE) or - e_KeyPressed(JOY0_JUMP) or e_KeyPressed(JOY1_JUMP) or e_KeyPressed(JOY2_JUMP) or e_KeyPressed(JOY3_JUMP) then + if g_Net_UserRequestExit() then begin State := 0; break; @@ -4765,6 +4799,7 @@ function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath: var NewWAD, ResName: String; I: Integer; + nws: AnsiString; begin g_Map_Free((Map <> gCurrentMapFileName) and (oldMapPath <> gCurrentMapFileName)); g_Player_RemoveAllCorpses(); @@ -4788,15 +4823,25 @@ begin ResName := g_ExtractFileName(Map); if g_Game_IsServer then begin - gWADHash := MD5File(MapsDir + NewWAD); - g_Game_LoadWAD(NewWAD); + nws := findDiskWad(MapsDir+NewWAD); + if (length(nws) = 0) then + begin + ResName := ''; + end + else + begin + if (g_Game_IsNet) then gWADHash := MD5File(nws); + //writeln('********: nws=', nws, ' : Map=', Map, ' : nw=', NewWAD, ' : resname=', ResName); + g_Game_LoadWAD(NewWAD); + end; end else // hash received in MC_RECV_GameEvent -> NET_EV_MAPSTART g_Game_ClientWAD(NewWAD, gWADHash); end else ResName := Map; - Result := g_Map_Load(MapsDir + gGameSettings.WAD + ':\' + ResName); + //writeln('********: gsw=', gGameSettings.WAD, '; rn=', ResName); + Result := (ResName <> '') and g_Map_Load(MapsDir + gGameSettings.WAD + ':\' + ResName); if Result then begin g_Player_ResetAll(Force or gLastMap, gGameSettings.GameType = GT_SINGLE); @@ -4865,14 +4910,7 @@ begin MH_SEND_GameEvent(NET_EV_MAPSTART, gGameSettings.GameMode, Map); // Ìàñòåðñåðâåð - if NetUseMaster then - begin - if (NetMHost = nil) or (NetMPeer = nil) then - if not g_Net_Slist_Connect then - g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]); - - g_Net_Slist_Update; - end; + g_Net_Slist_ServerMapStarted(); if NetClients <> nil then for I := 0 to High(NetClients) do @@ -4968,19 +5006,33 @@ begin gNextMap := Map; end; -procedure g_Game_ClientWAD(NewWAD: String; WHash: TMD5Digest); +procedure g_Game_ClientWAD(NewWAD: String; const WHash: TMD5Digest); var - gWAD: String; + gWAD, xwad: String; begin - if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then - Exit; - if not g_Game_IsClient then + if not g_Game_IsClient then Exit; + //e_LogWritefln('*** g_Game_ClientWAD: `%s`', [NewWAD]); + + gWAD := g_Res_DownloadMapWAD(ExtractFileName(NewWAD), WHash); + if gWAD = '' then + begin + g_Game_Free(); + g_FatalError(Format(_lc[I_GAME_ERROR_MAP_WAD], [ExtractFileName(NewWAD)])); Exit; + end; + + xwad := ExtractRelativePath(MapsDir, gWAD); + e_LogWritefln('using downloaded client map wad [%s] for [%s]`', [xwad, NewWAD], TMsgType.Notify); + NewWAD := xwad; + g_Game_LoadWAD(NewWAD); + + { + if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then Exit; gWAD := g_Res_SearchSameWAD(MapsDir, ExtractFileName(NewWAD), WHash); if gWAD = '' then begin g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False); - gWAD := g_Res_DownloadWAD(ExtractFileName(NewWAD)); + gWAD := g_Res_DownloadMapWAD(ExtractFileName(NewWAD), WHash); if gWAD = '' then begin g_Game_Free(); @@ -4990,6 +5042,7 @@ begin end; NewWAD := ExtractRelativePath(MapsDir, gWAD); g_Game_LoadWAD(NewWAD); + } end; procedure g_Game_RestartRound(NoMapRestart: Boolean = False); @@ -5427,8 +5480,7 @@ begin NetServerName := P[1]; if Length(NetServerName) > 64 then SetLength(NetServerName, 64); - if g_Game_IsServer and g_Game_IsNet and NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerRenamed(); end; g_Console_Add(cmd + ' = "' + NetServerName + '"'); @@ -5440,8 +5492,7 @@ begin NetPassword := P[1]; if Length(NetPassword) > 24 then SetLength(NetPassword, 24); - if g_Game_IsServer and g_Game_IsNet and NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerRenamed(); end; g_Console_Add(cmd + ' = "' + AnsiLowerCase(NetPassword) + '"'); @@ -5455,6 +5506,7 @@ begin begin b := 0; for a := 0 to High(NetClients) do + begin if NetClients[a].Used then begin Inc(b); @@ -5466,8 +5518,8 @@ begin MH_SEND_GameEvent(NET_EV_PLAYER_KICK, 0, s); end; end; - if NetUseMaster then - g_Net_Slist_Update; + end; + g_Net_Slist_ServerRenamed(); end; end; @@ -5478,17 +5530,7 @@ begin if (Length(P) > 1) then begin NetUseMaster := StrToIntDef(P[1], Byte(NetUseMaster)) > 0; - if g_Game_IsServer and g_Game_IsNet then - if NetUseMaster then - begin - if NetMPeer = nil then - if not g_Net_Slist_Connect() then - g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]); - g_Net_Slist_Update(); - end - else - if NetMPeer <> nil then - g_Net_Slist_Disconnect(); + if NetUseMaster then g_Net_Slist_Public() else g_Net_Slist_Private(); end; g_Console_Add(cmd + ' = ' + IntToStr(Byte(NetUseMaster))); @@ -6143,8 +6185,7 @@ begin enet_peer_disconnect(pl^.Peer, NET_DISC_KICK); g_Console_Add(Format(_lc[I_PLAYER_KICK], [s])); MH_SEND_GameEvent(NET_EV_PLAYER_KICK, 0, s); - if NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end else if gPlayers <> nil then for a := Low(gPlayers) to High(gPlayers) do if gPlayers[a] <> nil then @@ -6157,8 +6198,7 @@ begin gPlayers[a].Kill(K_SIMPLEKILL, 0, HIT_DISCON); g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [gPlayers[a].Name]), True); g_Player_Remove(gPlayers[a].UID); - if NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); // Åñëè íå ïåðåìåøàòü, ïðè äîáàâëåíèè íîâûõ áîòîâ ïîÿâÿòñÿ ñòàðûå g_Bot_MixNames(); end; @@ -6189,8 +6229,7 @@ begin enet_peer_disconnect(NetClients[a].Peer, NET_DISC_KICK); g_Console_Add(Format(_lc[I_PLAYER_KICK], [s])); MH_SEND_GameEvent(NET_EV_PLAYER_KICK, 0, s); - if NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end; end; end else @@ -6219,8 +6258,7 @@ begin enet_peer_disconnect(pl^.Peer, NET_DISC_TEMPBAN); g_Console_Add(Format(_lc[I_PLAYER_BAN], [s])); MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s); - if NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end else g_Console_Add(Format(_lc[I_NET_ERR_NAME404], [P[1]])); end else @@ -6250,8 +6288,7 @@ begin enet_peer_disconnect(NetClients[a].Peer, NET_DISC_TEMPBAN); g_Console_Add(Format(_lc[I_PLAYER_BAN], [s])); MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s); - if NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end; end else g_Console_Add(_lc[I_MSG_SERVERONLY]); @@ -6280,8 +6317,7 @@ begin g_Net_SaveBanList(); g_Console_Add(Format(_lc[I_PLAYER_BAN], [s])); MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s); - if NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end else g_Console_Add(Format(_lc[I_NET_ERR_NAME404], [P[1]])); end else @@ -6312,8 +6348,7 @@ begin g_Net_SaveBanList(); g_Console_Add(Format(_lc[I_PLAYER_BAN], [s])); MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s); - if NetUseMaster then - g_Net_Slist_Update; + g_Net_Slist_ServerPlayerLeaves(); end; end else g_Console_Add(_lc[I_MSG_SERVERONLY]);