X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_net.pas;h=45f507a53dcccadfe604224d5fccaa1f90f7666d;hb=847038a14751d192fcc4af172d7a963e28144c72;hp=261df8cad6e0aa6e08b42ccd41c3a312f8601410;hpb=a50544067b99f65e2b4882366521287607dd892f;p=d2df-sdl.git diff --git a/src/game/g_net.pas b/src/game/g_net.pas index 261df8c..45f507a 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 = 186; 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; - NetSlistIP: string = 'mpms.doom2d.org'; - NetSlistPort: Word = 25665; - NetSlistList: string = 'deadsoftware.ru:25665'; + NetMasterList: string = 'mpms.doom2d.org:25665, deadsoftware.ru:25665'; NetClientIP: string = '127.0.0.1'; NetClientPort: Word = 25666; @@ -180,6 +172,8 @@ var NetGotEverything: Boolean = False; NetGotKeys: Boolean = False; + NetDeafLevel: Integer = 0; + {$IFDEF USE_MINIUPNPC} NetPortForwarded: Word = 0; NetPongForwarded: Boolean = False; @@ -248,6 +242,8 @@ function g_Net_IsNetworkAvailable (): Boolean; procedure g_Net_InitLowLevel (); procedure g_Net_DeinitLowLevel (); +procedure NetServerCVars(P: SSArray); + implementation @@ -258,9 +254,9 @@ implementation 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; @@ -277,7 +273,10 @@ begin end; procedure g_Net_InitLowLevel (); + var v: ENetVersion; begin + v := enet_linked_version(); + e_LogWritefln('ENet Version: %s.%s.%s', [ENET_VERSION_GET_MAJOR(v), ENET_VERSION_GET_MINOR(v), ENET_VERSION_GET_PATCH(v)]); if enet_init_success then raise Exception.Create('wuta?!'); enet_init_success := (enet_initialize() = 0); end; @@ -531,7 +530,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); @@ -539,7 +538,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); @@ -661,7 +659,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; @@ -681,7 +679,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 @@ -1329,6 +1327,7 @@ var F: TextFile; IPstr: string; IP: LongWord; + path: AnsiString; begin NetIn.Clear(); NetOut.Clear(); @@ -1343,9 +1342,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 @@ -1497,8 +1497,6 @@ begin NetAddr.host := IPAddr; NetAddr.port := Port; - if NetForwardPorts then NetPortThread := BeginThread(ForwardThread); - NetHost := enet_host_create(@NetAddr, NET_MAXCLIENTS, NET_CHANS, 0, 0); if (NetHost = nil) then @@ -1509,6 +1507,8 @@ begin Exit; end; + if NetForwardPorts then NetPortThread := BeginThread(ForwardThread); + NetPongSock := enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM); if NetPongSock <> ENET_SOCKET_NULL then begin @@ -1611,7 +1611,7 @@ var Ping: array [0..9] of Byte; NPl: Byte; begin - if NetPongSock = ENET_SOCKET_NULL then Exit; + if (NetPongSock = ENET_SOCKET_NULL) or (NetHost = nil) then Exit; Buf.data := Addr(Ping[0]); Buf.dataLength := 2+8; @@ -1628,7 +1628,7 @@ begin NetOut.Clear(); NetOut.Write(Byte(Ord('D'))); NetOut.Write(Byte(Ord('F'))); - NetOut.Write(NetPort); + NetOut.Write(NetHost.address.port); NetOut.Write(ClTime); TMasterHost.writeInfo(NetOut); NPl := 0; @@ -1842,7 +1842,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: @@ -2184,22 +2184,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(); @@ -2237,7 +2243,10 @@ var begin Result := False; - if NetPortForwarded = NetPort then + if NetHost = nil then + exit; + + if NetPortForwarded = NetHost.address.port then begin Result := True; exit; @@ -2263,7 +2272,7 @@ begin exit; end; - StrPort := IntToStr(NetPort); + StrPort := IntToStr(NetHost.address.port); I := UPNP_AddPortMapping( Urls.controlURL, Addr(data.first.servicetype[1]), PChar(StrPort), PChar(StrPort), Addr(LanAddr[0]), PChar('D2DF'), @@ -2272,7 +2281,7 @@ begin if I <> 0 then begin - conwritefln('forwarding port %d failed: error %d', [NetPort, I]); + conwritefln('forwarding port %d failed: error %d', [NetHost.address.port, I]); FreeUPNPDevList(DevList); FreeUPNPUrls(@Urls); exit; @@ -2289,20 +2298,20 @@ 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; - conwritefln('forwarded port %d successfully', [NetPort]); + conwritefln('forwarded port %d successfully', [NetHost.address.port]); NetIGDControl := AnsiString(Urls.controlURL); NetIGDService := data.first.servicetype; - NetPortForwarded := NetPort; + NetPortForwarded := NetHost.address.port; FreeUPNPDevList(DevList); FreeUPNPUrls(@Urls); @@ -2334,12 +2343,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; @@ -2349,9 +2358,103 @@ 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('cl_deafen', @NetDeafLevel, '', 'filter server messages (0-3)'); + + 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);