X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_net.pas;h=fbc85eec75c06e797d0a006a452f9c33f9e16cbe;hb=36e374af750d9e3f049d97d9849a6629ff9b149b;hp=2518bede333e6272e934a02050124f2dbf992a9a;hpb=f8b890fbb992358cc8178e8636fda1f4b81de3d6;p=d2df-sdl.git diff --git a/src/game/g_net.pas b/src/game/g_net.pas index 2518bed..fbc85ee 100644 --- a/src/game/g_net.pas +++ b/src/game/g_net.pas @@ -18,10 +18,10 @@ unit g_net; interface uses - e_log, e_msg, ENet, Classes, md5, MAPDEF{$IFDEF USE_MINIUPNPC}, miniupnpc;{$ELSE};{$ENDIF} + e_log, e_msg, utils, ENet, Classes, md5, MAPDEF{$IFDEF USE_MINIUPNPC}, miniupnpc;{$ELSE};{$ENDIF} const - NET_PROTOCOL_VER = 182; + NET_PROTOCOL_VER = 185; NET_MAXCLIENTS = 24; NET_CHANS = 12; @@ -72,12 +72,6 @@ const BANLIST_FILENAME = 'banlist.txt'; NETDUMP_FILENAME = 'netdump'; - {$IF DEFINED(FREEBSD) OR DEFINED(DARWIN)} - NilThreadId = nil; - {$ELSE} - NilThreadId = 0; - {$ENDIF} - type TNetMapResourceInfo = record wadName: AnsiString; // wad file name, without a path @@ -147,9 +141,7 @@ var NetPongSock: ENetSocket = ENET_SOCKET_NULL; NetUseMaster: Boolean = True; - NetSlistAddr: ENetAddress; - NetSlistIP: string = 'mpms.doom2d.org'; - NetSlistPort: Word = 25665; + NetMasterList: string = 'mpms.doom2d.org:25665, deadsoftware.ru:25665'; NetClientIP: string = '127.0.0.1'; NetClientPort: Word = 25666; @@ -248,14 +240,21 @@ function g_Net_IsNetworkAvailable (): Boolean; procedure g_Net_InitLowLevel (); procedure g_Net_DeinitLowLevel (); +procedure NetServerCVars(P: SSArray); + implementation +// *enet_host_service()* +// fuck! https://www.mail-archive.com/enet-discuss@cubik.org/msg00852.html +// tl;dr: on shitdows, we can get -1 sometimes, and it is *NOT* a failure. +// thank you, enet. let's ignore failures altogether then. + uses SysUtils, - e_input, g_nethandler, g_netmsg, g_netmaster, g_player, g_window, g_console, - g_main, g_game, g_language, g_weapons, utils, ctypes, g_system, - g_map; + e_input, e_res, + g_nethandler, g_netmsg, g_netmaster, g_player, g_window, g_console, + g_main, g_game, g_language, g_weapons, ctypes, g_system, g_map; const FILE_CHUNK_SIZE = 8192; @@ -526,7 +525,7 @@ begin killClientByFT(nc^); exit; end; - if (ridx < 0) then fname := MapsDir+gGameSettings.WAD else fname := {GameDir+'/wads/'+}gExternalResources[ridx].diskName; + if (ridx < 0) then fname := gGameSettings.WAD else fname := gExternalResources[ridx].diskName; if (length(fname) = 0) then begin e_WriteLog('Invalid filename: '+fname, TMsgType.Warning); @@ -534,7 +533,6 @@ begin exit; end; tf.diskName := findDiskWad(fname); - //if (length(tf.diskName) = 0) then tf.diskName := findDiskWad(GameDir+'/wads/'+fname); if (length(tf.diskName) = 0) then begin e_LogWritefln('NETWORK: file "%s" not found!', [fname], TMsgType.Fatal); @@ -656,7 +654,7 @@ begin begin e_LogWritefln('client #%d requested map info', [nc.ID]); trans_omsg.Clear(); - dfn := findDiskWad(MapsDir+gGameSettings.WAD); + dfn := findDiskWad(gGameSettings.WAD); if (dfn = '') then dfn := '!wad_not_found!.wad'; //FIXME //md5 := MD5File(dfn); md5 := gWADHash; @@ -676,7 +674,7 @@ begin // packet type trans_omsg.Write(Byte(NTF_SERVER_MAP_INFO)); // map wad name - trans_omsg.Write(gGameSettings.WAD); + trans_omsg.Write(ExtractFileName(gGameSettings.WAD)); // map wad md5 trans_omsg.Write(md5); // map wad size @@ -767,13 +765,15 @@ begin ett := getNewTimeoutEnd(); repeat status := enet_host_service(NetHost, @ev, 300); + { if (status < 0) then begin g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' network error', True); Result := -1; exit; end; - if (status = 0) then + } + if (status <= 0) then begin // check for timeout ct := GetTimerMS(); @@ -946,13 +946,15 @@ begin ett := getNewTimeoutEnd(); repeat status := enet_host_service(NetHost, @ev, 300); + { if (status < 0) then begin g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' network error', True); Result := -1; exit; end; - if (status = 0) then + } + if (status <= 0) then begin // check for timeout ct := GetTimerMS(); @@ -1128,13 +1130,15 @@ begin repeat //stx := -GetTimerMS(); status := enet_host_service(NetHost, @ev, 300); + { if (status < 0) then begin g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' network error', True); Result := -1; exit; end; - if (status = 0) then + } + if (status <= 0) then begin // check for timeout ct := GetTimerMS(); @@ -1318,6 +1322,7 @@ var F: TextFile; IPstr: string; IP: LongWord; + path: AnsiString; begin NetIn.Clear(); NetOut.Clear(); @@ -1332,9 +1337,10 @@ begin NetPlrUID2 := -1; NetAddr.port := 25666; SetLength(NetBannedHosts, 0); - if FileExists(DataDir + BANLIST_FILENAME) then + path := BANLIST_FILENAME; + if e_FindResource(DataDirs, path) = true then begin - Assign(F, DataDir + BANLIST_FILENAME); + Assign(F, path); Reset(F); while not EOF(F) do begin @@ -1831,7 +1837,7 @@ end; function g_Net_Client_Update(): enet_size_t; begin Result := 0; - while (enet_host_service(NetHost, @NetEvent, 0) > 0) do + while (NetHost <> nil) and (enet_host_service(NetHost, @NetEvent, 0) > 0) do begin case NetEvent.kind of ENET_EVENT_TYPE_RECEIVE: @@ -2173,22 +2179,28 @@ procedure g_Net_SaveBanList(); var F: TextFile; I: Integer; + path: AnsiString; begin - Assign(F, DataDir + BANLIST_FILENAME); - Rewrite(F); - if NetBannedHosts <> nil then - for I := 0 to High(NetBannedHosts) do - if NetBannedHosts[I].Perm and (NetBannedHosts[I].IP > 0) then - Writeln(F, IpToStr(NetBannedHosts[I].IP)); - CloseFile(F); + path := e_GetWriteableDir(DataDirs); + if path <> '' then + begin + path := e_CatPath(path, BANLIST_FILENAME); + Assign(F, path); + Rewrite(F); + if NetBannedHosts <> nil then + for I := 0 to High(NetBannedHosts) do + if NetBannedHosts[I].Perm and (NetBannedHosts[I].IP > 0) then + Writeln(F, IpToStr(NetBannedHosts[I].IP)); + CloseFile(F) + end end; procedure g_Net_DumpStart(); begin if NetMode = NET_SERVER then - NetDumpFile := createDiskFile(NETDUMP_FILENAME + '_server') + NetDumpFile := e_CreateResource(LogDirs, NETDUMP_FILENAME + '_server') else - NetDumpFile := createDiskFile(NETDUMP_FILENAME + '_client'); + NetDumpFile := e_CreateResource(LogDirs, NETDUMP_FILENAME + '_client'); end; procedure g_Net_DumpSendBuffer(); @@ -2278,12 +2290,12 @@ begin if I <> 0 then begin - conwritefln('forwarding port %d failed: error %d', [NetPort + 1, I]); + conwritefln('forwarding port %d failed: error %d', [NET_PING_PORT, I]); NetPongForwarded := False; end else begin - conwritefln('forwarded port %d successfully', [NetPort + 1]); + conwritefln('forwarded port %d successfully', [NET_PING_PORT]); NetPongForwarded := True; end; end; @@ -2323,12 +2335,12 @@ begin if NetPongForwarded then begin NetPongForwarded := False; - StrPort := IntToStr(NetPortForwarded + 1); + StrPort := IntToStr(NET_PING_PORT); I := UPNP_DeletePortMapping( PChar(NetIGDControl), Addr(NetIGDService[1]), PChar(StrPort), PChar('UDP'), nil ); - conwritefln(' port %d: %d', [NetPortForwarded + 1, I]); + conwritefln(' port %d: %d', [NET_PING_PORT, I]); end; NetPortForwarded := 0; @@ -2338,9 +2350,102 @@ begin end; {$ENDIF} +procedure NetServerCVars(P: SSArray); +var + cmd, s: string; + a, b: Integer; +begin + cmd := LowerCase(P[0]); + case cmd of + 'sv_name': + begin + if (Length(P) > 1) and (Length(P[1]) > 0) then + begin + NetServerName := P[1]; + if Length(NetServerName) > 64 then + SetLength(NetServerName, 64); + g_Net_Slist_ServerRenamed(); + end; + g_Console_Add(cmd + ' "' + NetServerName + '"'); + end; + 'sv_passwd': + begin + if (Length(P) > 1) and (Length(P[1]) > 0) then + begin + NetPassword := P[1]; + if Length(NetPassword) > 24 then + SetLength(NetPassword, 24); + g_Net_Slist_ServerRenamed(); + end; + g_Console_Add(cmd + ' "' + AnsiLowerCase(NetPassword) + '"'); + end; + 'sv_maxplrs': + begin + if (Length(P) > 1) then + begin + NetMaxClients := nclamp(StrToIntDef(P[1], NetMaxClients), 1, NET_MAXCLIENTS); + if g_Game_IsServer and g_Game_IsNet then + begin + b := 0; + for a := 0 to High(NetClients) do + begin + if NetClients[a].Used then + begin + Inc(b); + if b > NetMaxClients then + begin + s := g_Player_Get(NetClients[a].Player).Name; + enet_peer_disconnect(NetClients[a].Peer, NET_DISC_FULL); + g_Console_Add(Format(_lc[I_PLAYER_KICK], [s])); + MH_SEND_GameEvent(NET_EV_PLAYER_KICK, 0, s); + end; + end; + end; + g_Net_Slist_ServerRenamed(); + end; + end; + g_Console_Add(cmd + ' ' + IntToStr(NetMaxClients)); + end; + 'sv_public': + begin + if (Length(P) > 1) then + begin + NetUseMaster := StrToIntDef(P[1], Byte(NetUseMaster)) <> 0; + if NetUseMaster then g_Net_Slist_Public() else g_Net_Slist_Private(); + end; + g_Console_Add(cmd + ' ' + IntToStr(Byte(NetUseMaster))); + end; + 'sv_port': + begin + if (Length(P) > 1) then + begin + if not g_Game_IsNet then + NetPort := nclamp(StrToIntDef(P[1], NetPort), 0, $FFFF) + else + g_Console_Add(_lc[I_MSG_NOT_NETGAME]); + end; + g_Console_Add(cmd + ' ' + IntToStr(Ord(NetUseMaster))); + end; + end; +end; initialization conRegVar('cl_downloadtimeout', @g_Net_DownloadTimeout, 0.0, 1000000.0, '', 'timeout in seconds, 0 to disable it'); + conRegVar('cl_predictself', @NetPredictSelf, '', 'predict local player'); + conRegVar('cl_forceplayerupdate', @NetForcePlayerUpdate, '', 'update net players on NET_MSG_PLRPOS'); + conRegVar('cl_interp', @NetInterpLevel, '', 'net player interpolation steps'); + conRegVar('cl_last_ip', @NetClientIP, '', 'address of the last you have connected to'); + conRegVar('cl_last_port', @NetClientPort, '', 'port of the last server you have connected to'); + + conRegVar('sv_forwardports', @NetForwardPorts, '', 'forward server port using miniupnpc (requires server restart)'); + conRegVar('sv_rcon', @NetAllowRCON, '', 'enable remote console'); + conRegVar('sv_rcon_password', @NetRCONPassword, '', 'remote console password'); + conRegVar('sv_update_interval', @NetUpdateRate, '', 'unreliable update interval'); + conRegVar('sv_reliable_interval', @NetRelupdRate, '', 'reliable update interval'); + conRegVar('sv_master_interval', @NetMasterRate, '', 'master server update interval'); + + conRegVar('net_master_list', @NetMasterList, '', 'list of master servers'); + SetLength(NetClients, 0); g_Net_DownloadTimeout := 60; NetIn.Alloc(NET_BUFSIZE);