X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_net.pas;h=63cb4dbf7f7c0cee17ed7d1bac6f84185e0e51b0;hb=05423e433609886fe611f74bbd48ef6de4dfcae3;hp=cbf5120782839a5703caa116a5d0041465411410;hpb=563e770b462d67b2c8265b0e2b53384152afb7c1;p=d2df-sdl.git diff --git a/src/game/g_net.pas b/src/game/g_net.pas index cbf5120..63cb4db 100644 --- a/src/game/g_net.pas +++ b/src/game/g_net.pas @@ -19,7 +19,7 @@ unit g_net; interface uses - e_log, e_msg, ENet, Classes, MAPDEF; + e_log, e_msg, ENet, Classes, MAPDEF{$IFDEF USE_MINIUPNPC}, miniupnpc;{$ELSE};{$ENDIF} const NET_PROTOCOL_VER = 173; @@ -136,9 +136,19 @@ var NetForcePlayerUpdate: Boolean = False; NetPredictSelf: Boolean = True; - NetGotKeys: Boolean = False; + NetForwardPorts: Boolean = False; NetGotEverything: Boolean = False; + NetGotKeys: Boolean = False; + +{$IFDEF USE_MINIUPNPC} + NetPortForwarded: Word = 0; + NetPongForwarded: Boolean = False; + NetIGDControl: AnsiString; + NetIGDService: TURLStr; +{$ENDIF} + + NetPortThread: TThreadID = 0; NetDumpFile: TStream; @@ -181,6 +191,9 @@ procedure g_Net_DumpSendBuffer(); procedure g_Net_DumpRecvBuffer(Buf: penet_uint8; Len: LongWord); procedure g_Net_DumpEnd(); +function g_Net_ForwardPorts(ForwardPongPort: Boolean = True): Boolean; +procedure g_Net_UnforwardPorts(); + implementation uses @@ -305,6 +318,12 @@ begin NetMode := NET_NONE; + if NetPortThread <> 0 then + WaitForThreadTerminate(NetPortThread, 66666); + + NetPortThread := 0; + g_Net_UnforwardPorts(); + if NetDump then g_Net_DumpEnd(); end; @@ -321,6 +340,12 @@ end; { /// SERVER FUNCTIONS /// } +function ForwardThread(Param: Pointer): PtrInt; +begin + Result := 0; + if not g_Net_ForwardPorts() then Result := -1; +end; + function g_Net_Host(IPAddr: LongWord; Port: enet_uint16; MaxClients: Cardinal = 16): Boolean; begin if NetMode <> NET_NONE then @@ -348,6 +373,8 @@ 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 @@ -1097,6 +1124,130 @@ begin NetDumpFile := nil; end; +function g_Net_ForwardPorts(ForwardPongPort: Boolean = True): Boolean; +{$IFDEF USE_MINIUPNPC} +var + DevList: PUPNPDev; + Urls: TUPNPUrls; + Data: TIGDDatas; + LanAddr: array [0..255] of Char; + StrPort: AnsiString; + Err, I: Integer; +begin + Result := False; + + if NetPortForwarded = NetPort then + begin + Result := True; + exit; + end; + + NetPongForwarded := False; + NetPortForwarded := 0; + + DevList := upnpDiscover(1000, nil, nil, 0, 0, Addr(Err)); + if DevList = nil then + begin + conwritefln('port forwarding failed: upnpDiscover() failed: %d', [Err]); + exit; + end; + + I := UPNP_GetValidIGD(DevList, @Urls, @Data, Addr(LanAddr[0]), 256); + + if I = 0 then + begin + conwriteln('port forwarding failed: could not find an IGD device on this LAN'); + FreeUPNPDevList(DevList); + FreeUPNPUrls(@Urls); + exit; + end; + + StrPort := IntToStr(NetPort); + I := UPNP_AddPortMapping( + Urls.controlURL, Addr(data.first.servicetype[1]), + PChar(StrPort), PChar(StrPort), Addr(LanAddr[0]), PChar('D2DF'), + PChar('UDP'), nil, PChar('0') + ); + + if I <> 0 then + begin + conwritefln('forwarding port %d failed: error %d', [NetPort, I]); + FreeUPNPDevList(DevList); + FreeUPNPUrls(@Urls); + exit; + end; + + if ForwardPongPort then + begin + StrPort := IntToStr(NetPort + 1); + I := UPNP_AddPortMapping( + Urls.controlURL, Addr(data.first.servicetype[1]), + PChar(StrPort), PChar(StrPort), Addr(LanAddr[0]), PChar('D2DF'), + PChar('UDP'), nil, PChar('0') + ); + + if I <> 0 then + begin + conwritefln('forwarding port %d failed: error %d', [NetPort + 1, I]); + NetPongForwarded := False; + end + else + begin + conwritefln('forwarded port %d successfully', [NetPort + 1]); + NetPongForwarded := True; + end; + end; + + conwritefln('forwarded port %d successfully', [NetPort]); + NetIGDControl := AnsiString(Urls.controlURL); + NetIGDService := data.first.servicetype; + NetPortForwarded := NetPort; + + FreeUPNPDevList(DevList); + FreeUPNPUrls(@Urls); + Result := True; +end; +{$ELSE} +begin + Result := False; +end; +{$ENDIF} + +procedure g_Net_UnforwardPorts(); +{$IFDEF USE_MINIUPNPC} +var + I: Integer; + StrPort: AnsiString; +begin + if NetPortForwarded = 0 then Exit; + + conwriteln('unforwarding ports...'); + + StrPort := IntToStr(NetPortForwarded); + I := UPNP_DeletePortMapping( + PChar(NetIGDControl), Addr(NetIGDService[1]), + PChar(StrPort), PChar('UDP'), nil + ); + conwritefln(' port %d: %d', [NetPortForwarded, I]); + + if NetPongForwarded then + begin + NetPongForwarded := False; + StrPort := IntToStr(NetPortForwarded + 1); + I := UPNP_DeletePortMapping( + PChar(NetIGDControl), Addr(NetIGDService[1]), + PChar(StrPort), PChar('UDP'), nil + ); + conwritefln(' port %d: %d', [NetPortForwarded + 1, I]); + end; + + NetPortForwarded := 0; +end; +{$ELSE} +begin +end; +{$ENDIF} + initialization NetIn.Alloc(NET_BUFSIZE);