diff --git a/src/game/g_net.pas b/src/game/g_net.pas
index 85263e51e7e709388809188f5c664c832f9f84e3..4e2ed9a09f94f868abff12ccccba327c435a3b6d 100644 (file)
--- a/src/game/g_net.pas
+++ b/src/game/g_net.pas
-(* Copyright (C) DooM 2D:Forever Developers
+(* Copyright (C) Doom 2D: Forever Developers
*
* 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
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;
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}
NetDumpFile: TStream;
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
NetMode := NET_NONE;
+ g_Net_UnforwardPorts();
+
if NetDump then
g_Net_DumpEnd();
end;
NetAddr.host := IPAddr;
NetAddr.port := Port;
+ if NetForwardPorts then g_Net_ForwardPorts();
+
NetHost := enet_host_create(@NetAddr, NET_MAXCLIENTS, NET_CHANS, 0, 0);
if (NetHost = nil) then
ProcessLoading(true);
- e_PollInput();
-
if e_KeyPressed(IK_ESCAPE) or e_KeyPressed(IK_SPACE) then
OuterLoop := False;
end;
ProcessLoading(true);
- e_PollInput();
-
if e_KeyPressed(IK_ESCAPE) or e_KeyPressed(IK_SPACE) then
break;
end;
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;
+ ExtAddr: array [0..40] of Char;
+ StrPort: AnsiString;
+ Err, I: Integer;
+begin
+ Result := False;
+
+ if NetPortForwarded = NetPort then
+ begin
+ Result := True;
+ exit;
+ end;
+
+ conwriteln('trying to forward server ports...');
+
+ NetPongForwarded := False;
+ NetPortForwarded := 0;
+
+ DevList := upnpDiscover(2000, nil, nil, 0, 0, Addr(Err));
+ if DevList = nil then
+ begin
+ conwritefln(' upnpDiscover() failed: %d', [Err]);
+ exit;
+ end;
+
+ I := UPNP_GetValidIGD(DevList, @Urls, @Data, Addr(LanAddr[0]), 256);
+
+ if I = 0 then
+ begin
+ conwriteln(' could not find an IGD device on this LAN, aborting');
+ FreeUPNPDevList(DevList);
+ FreeUPNPUrls(@Urls);
+ exit;
+ end
+ else if I = 1 then
+ conwritefln(' found IGD @ %s', [Urls.controlURL])
+ else
+ conwritefln(' found some kind of UPNP device @ %s, maybe it''ll work', [Urls.controlURL]);
+
+ UPNP_GetExternalIPAddress(Urls.controlURL, Addr(data.first.servicetype[1]), Addr(ExtAddr[0]));
+ if ExtAddr[0] <> #0 then
+ conwritefln(' external IP address: %s', [Addr(ExtAddr[0])]);
+
+ 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);