Skip to content

Commit

Permalink
Added methods to maintain nat punch port open
Browse files Browse the repository at this point in the history
  • Loading branch information
trippyone committed Jun 17, 2024
1 parent bb1c59d commit 6ba6709
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 62 deletions.
59 changes: 59 additions & 0 deletions Fika.Core/Coop/Components/FikaServerStunQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections;
using UnityEngine;
using Fika.Core.Networking.NatPunch;
using Comfort.Common;
using Fika.Core.Networking;

namespace Fika.Core.Coop.Components
{
public class FikaServerStunQuery : MonoBehaviour
{
private Coroutine stunQueryRoutine;

public void StartServerStunQueryRoutine()
{
stunQueryRoutine = StartCoroutine(StunQuery());
}

public void StopServerStunQueryRoutine()
{
if (stunQueryRoutine != null)
{
StopCoroutine(stunQueryRoutine);
stunQueryRoutine = null;
}
}

private IEnumerator StunQuery()
{
while (true)
{
var fikaServer = Singleton<FikaServer>.Instance;

while (fikaServer == null || fikaServer.NetServer == null || fikaServer.NatPunchServer == null)
yield return null;

fikaServer.NetServer.Stop();

var localPort = 0;
var currentStunIpEndPoint = fikaServer.NatPunchServer.StunIpEndpoint;

if (currentStunIpEndPoint != null)
localPort = currentStunIpEndPoint.Local.Port;

var stunIpEndPoint = NatPunchUtils.CreateStunEndPoint(localPort);

fikaServer.NatPunchServer.StunIpEndpoint = stunIpEndPoint;

fikaServer.NetServer.Start(stunIpEndPoint.Local.Port);

yield return new WaitForSeconds(60);
}
}

private void OnDestroy()
{
StopServerStunQueryRoutine();
}
}
}
10 changes: 10 additions & 0 deletions Fika.Core/Coop/GameMode/CoopGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -858,8 +858,18 @@ public override async Task<LocalPlayer> vmethod_2(int playerId, Vector3 position
BackendConfigAbstractClass.Config.CharacterController.ClientPlayerMode, getSensitivity,
getAimingSensitivity, new GClass1456(), isServer ? 0 : 1000, statisticsManager);

if(FikaBackendUtils.IsHostNatPunch)
{
NetManagerUtils.DestroyPingingClient();
}

await NetManagerUtils.InitNetManager(isServer);

if (FikaPlugin.NatPunch.Value)
{
NetManagerUtils.StartServerStunQuery();
}

if (!CoopHandler.TryGetCoopHandler(out CoopHandler coopHandler))
{
Logger.LogError($"{nameof(vmethod_2)}:Unable to find {nameof(CoopHandler)}");
Expand Down
3 changes: 2 additions & 1 deletion Fika.Core/Coop/Utils/FikaBackendUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public static class FikaBackendUtils
public static string RemoteIp;
public static int RemotePort;
public static int LocalPort = 0;
public static bool IsHostNatPunch = false;
private static string groupId;

public static MatchmakerTimeHasCome.GClass3187 ScreenController;
Expand Down Expand Up @@ -76,7 +77,7 @@ public static bool JoinMatch(string profileId, string serverId, out CreateMatch
public static void CreateMatch(string profileId, string hostUsername, RaidSettings raidSettings)
{
long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
var body = new CreateMatch(profileId, hostUsername, timestamp, raidSettings, HostExpectedNumberOfPlayers, raidSettings.Side, raidSettings.SelectedDateTime, FikaPlugin.NatPunch.Value);
var body = new CreateMatch(profileId, hostUsername, timestamp, raidSettings, HostExpectedNumberOfPlayers, raidSettings.Side, raidSettings.SelectedDateTime);

FikaRequestHandler.RaidCreate(body);

Expand Down
46 changes: 46 additions & 0 deletions Fika.Core/Coop/Utils/NetManagerUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ public static void CreateNetManager(bool isServer)
}
}

public static void CreatePingingClient()
{
if (FikaGameObject == null)
{
FikaGameObject = new GameObject("FikaGameObject");
Object.DontDestroyOnLoad(FikaGameObject);
logger.LogInfo("FikaGameObject has been created!");
}

FikaPingingClient pingingClient = FikaGameObject.AddComponent<FikaPingingClient>();
Singleton<FikaPingingClient>.Create(pingingClient);
logger.LogInfo("FikaPingingClient has started!");
}

public static void DestroyNetManager(bool isServer)
{
if (FikaGameObject != null)
Expand All @@ -55,6 +69,17 @@ public static void DestroyNetManager(bool isServer)
}
}

public static void DestroyPingingClient()
{
if(FikaGameObject != null)
{
Singleton<FikaPingingClient>.Instance.NetClient.Stop();
Singleton<FikaPingingClient>.Instance.StopKeepAliveRoutine();
Singleton<FikaPingingClient>.TryRelease(Singleton<FikaPingingClient>.Instance);
logger.LogInfo("Destroyed FikaPingingClient");
}
}

public static Task InitNetManager(bool isServer)
{
if (FikaGameObject != null)
Expand Down Expand Up @@ -121,5 +146,26 @@ public static void StopPinger()
}
}
}

public static void StartServerStunQuery()
{
if (FikaGameObject != null)
{
FikaServerStunQuery fikaServerStunQuery = FikaGameObject.AddComponent<FikaServerStunQuery>();
fikaServerStunQuery.StartServerStunQueryRoutine();
}
}

public static void StopServerStunQuery()
{
if (FikaGameObject != null)
{
FikaServerStunQuery fikaServerStunQuery = FikaGameObject.GetComponent<FikaServerStunQuery>();
if (fikaServerStunQuery != null)
{
Object.Destroy(fikaServerStunQuery);
}
}
}
}
}
69 changes: 45 additions & 24 deletions Fika.Core/Networking/FikaPingingClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,26 @@
using LiteNetLib;
using LiteNetLib.Utils;
using SPT.Common.Http;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using UnityEngine;

namespace Fika.Core.Networking
{
internal class FikaPingingClient(string serverId) : INetEventListener
public class FikaPingingClient : MonoBehaviour, INetEventListener
{
public NetManager NetClient;
private readonly ManualLogSource _logger = Logger.CreateLogSource("Fika.PingingClient");
private readonly string serverId = serverId;
private readonly ManualLogSource _logger = BepInEx.Logging.Logger.CreateLogSource("Fika.PingingClient");
private IPEndPoint remoteEndPoint;
private IPEndPoint localEndPoint;
private IPEndPoint remoteStunEndPoint;
private int localPort = 0;
public bool Received = false;
private Coroutine keepAliveRoutine;

public bool Init()
public bool Init(string serverId)
{
NetClient = new(this)
{
Expand Down Expand Up @@ -63,6 +65,8 @@ public bool Init()

if (result.NatPunch)
{
FikaBackendUtils.IsHostNatPunch = true;

var localStunEndPoint = NatPunchUtils.CreateStunEndPoint();

var natPunchTask = Task.Run(async () =>
Expand Down Expand Up @@ -97,15 +101,10 @@ public bool Init()
return true;
}

public void PingEndPoint()
public void PingEndPoint(string message)
{
if (Received)
{
return;
}

NetDataWriter writer = new();
writer.Put("fika.hello");
writer.Put(message);

NetClient.SendUnconnectedMessage(writer, remoteEndPoint);
if (localEndPoint != null)
Expand All @@ -119,6 +118,28 @@ public void PingEndPoint()
}
}

public void StartKeepAliveRoutine()
{
keepAliveRoutine = StartCoroutine(KeepAlive());
}

public void StopKeepAliveRoutine()
{
if(keepAliveRoutine != null)
StopCoroutine(keepAliveRoutine);
}

public IEnumerator KeepAlive()
{
while(true)
{
PingEndPoint("fika.keepalive");
NetClient.PollEvents();

yield return new WaitForSeconds(1.0f);
}
}

public void OnConnectionRequest(ConnectionRequest request)
{
// Do nothing
Expand All @@ -141,24 +162,24 @@ public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelN

public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
{
if (Received)
{
return;
}
_logger.LogInfo("Received response from server, parsing...");

if (reader.TryGetString(out string result))
{
if (result == "fika.hello")
{
Received = true;
FikaBackendUtils.RemoteIp = remoteEndPoint.Address.ToString();
FikaBackendUtils.RemotePort = remoteEndPoint.Port;
FikaBackendUtils.LocalPort = localPort;
}
else
switch(result)
{
_logger.LogError("Data was not as expected");
case "fika.hello":
Received = true;
FikaBackendUtils.RemoteIp = remoteEndPoint.Address.ToString();
FikaBackendUtils.RemotePort = remoteEndPoint.Port;
FikaBackendUtils.LocalPort = localPort;
break;
case "fika.keepalive":
// Do nothing
break;
default:
_logger.LogError("Data was not as expected");
break;
}
}
else
Expand Down
51 changes: 33 additions & 18 deletions Fika.Core/Networking/FikaServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,8 @@ public async Task Init()
UseNativeSockets = FikaPlugin.NativeSockets.Value,
EnableStatistics = true
};


if (FikaPlugin.UseUPnP.Value)
if (FikaPlugin.UseUPnP.Value && !FikaPlugin.NatPunch.Value)
{
bool upnpFailed = false;

Expand Down Expand Up @@ -161,17 +160,13 @@ public async Task Init()

if (FikaPlugin.NatPunch.Value)
{
var stunIpEndPoint = NatPunchUtils.CreateStunEndPoint();

NatPunchServer = new FikaNatPunchServer(_netServer, stunIpEndPoint);
NatPunchServer = new FikaNatPunchServer(_netServer);
NatPunchServer.Connect();

if(!NatPunchServer.Connected)
{
Singleton<PreloaderUI>.Instance.ShowErrorScreen("Network Error", "Error when trying to connect to FikaNatPunchRelayService. Please ensure FikaNatPunchRelayService is enabled and the port is open.");
}

_netServer.Start(NatPunchServer.StunIpEndPoint.Local.Port);
}
else
{
Expand All @@ -186,7 +181,15 @@ public async Task Init()
}

logger.LogInfo("Started Fika Server");
NotificationManagerClass.DisplayMessageNotification($"Server started on port {_netServer.LocalPort}.",

string serverStartedMessage;

if (FikaPlugin.NatPunch.Value)
serverStartedMessage = "Server started with Nat Punching enabled.";
else
serverStartedMessage = $"Server started on port {_netServer.LocalPort}.";

NotificationManagerClass.DisplayMessageNotification(serverStartedMessage,
EFT.Communications.ENotificationDurationType.Default, EFT.Communications.ENotificationIconType.EntryPoint);

string[] Ips = [];
Expand All @@ -206,7 +209,7 @@ public async Task Init()
iconType: EFT.Communications.ENotificationIconType.Alert);
}

SetHostRequest body = new(Ips, Port);
SetHostRequest body = new(Ips, Port, FikaPlugin.NatPunch.Value);
FikaRequestHandler.UpdateSetHost(body);

FikaEventDispatcher.DispatchEvent(new FikaServerCreatedEvent(this));
Expand Down Expand Up @@ -780,16 +783,28 @@ public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketRead
{
if (reader.TryGetString(out string data))
{
if (data == "fika.hello")
{
NetDataWriter resp = new();
resp.Put(data);
_netServer.SendUnconnectedMessage(resp, remoteEndPoint);
logger.LogInfo("PingingRequest: Correct ping query, sending response");
}
else
NetDataWriter resp;

switch (data)
{
logger.LogError("PingingRequest: Data was not as expected");
case "fika.hello":
resp = new();
resp.Put(data);
_netServer.SendUnconnectedMessage(resp, remoteEndPoint);
logger.LogInfo("PingingRequest: Correct ping query, sending response");
break;

case "fika.keepalive":
resp = new();
resp.Put(data);
_netServer.SendUnconnectedMessage(resp, remoteEndPoint);
NetManagerUtils.StopServerStunQuery();
EFT.UI.ConsoleScreen.Log("received fika.keepalive");
break;

default:
logger.LogError("PingingRequest: Data was not as expected");
break;
}
}
else
Expand Down
Loading

0 comments on commit 6ba6709

Please sign in to comment.