mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Status host uses net.port by default, add UPnP port forwarding option (#2237)
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
This commit is contained in:
Submodule Lidgren.Network/Lidgren.Network updated: b5483c7a7e...1dd5c1f333
@@ -156,6 +156,9 @@ namespace Robust.Server.ServerStatus
|
||||
|
||||
private void RegisterCVars()
|
||||
{
|
||||
// Set status host binding to match network manager by default
|
||||
SetCVarIfUnmodified(CVars.StatusBind, $"*:{_netManager.Port}");
|
||||
|
||||
// Check build.json
|
||||
var path = PathHelpers.ExecutableRelativeFile("build.json");
|
||||
if (File.Exists(path))
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
|
||||
# Welcome to the example configuration file!
|
||||
# Remember that if this is in bin/Content.Server or such, it may be overwritten on build.
|
||||
# Consider copying it and using the --config-file and --data-dir options.
|
||||
|
||||
[log]
|
||||
path = "logs"
|
||||
format = "log_%(date)s-%(time)s.txt"
|
||||
@@ -9,19 +12,27 @@ enabled = false
|
||||
tickrate = 60
|
||||
port = 1212
|
||||
bindto = "::,0.0.0.0"
|
||||
# Automatic port forwarding!
|
||||
# Disabled by default because you may not want to do this.
|
||||
# upnp = true
|
||||
|
||||
# The status server is the TCP side, used by the launcher to determine engine version, etc.
|
||||
[status]
|
||||
# The status server is the TCP side, used by the launcher to determine engine version, etc.
|
||||
# To be clear: Disabling it makes the launcher unable to connect!
|
||||
enabled = true
|
||||
bind = "*:1212"
|
||||
|
||||
# This is the address and port the status server binds to.
|
||||
# The port is by default set based on net.port so it will follow what you set there.
|
||||
# bind = "*:1212"
|
||||
|
||||
# This is the address of the SS14 server as the launcher uses it.
|
||||
# This is only needed if you're proxying the status HTTP server.
|
||||
# This is only needed if you're proxying the status HTTP server -
|
||||
# by default the launcher will assume the address and port match that of the status server.
|
||||
# connectaddress = "udp://localhost:1212"
|
||||
|
||||
[game]
|
||||
hostname = "MyServer"
|
||||
# map = "maps/saltern.yml"
|
||||
# map = "Maps/saltern.yml"
|
||||
maxplayers = 64
|
||||
type = 1
|
||||
welcomemsg = "Welcome to the server!"
|
||||
@@ -62,6 +73,7 @@ loginlocal = true
|
||||
|
||||
# Build hash - this is a *capitalized* SHA256 hash of the client ZIP.
|
||||
# Optional in any case and automatically set if hosting a client ZIP.
|
||||
# This hash is an example only.
|
||||
# build = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"
|
||||
|
||||
[auth]
|
||||
|
||||
@@ -113,6 +113,12 @@ namespace Robust.Shared
|
||||
public static readonly CVarDef<bool> NetEncrypt =
|
||||
CVarDef.Create("net.encrypt", true, CVar.CLIENTONLY);
|
||||
|
||||
/// <summary>
|
||||
/// If true, use UPnP to automatically forward ports on startup if possible.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> NetUPnP =
|
||||
CVarDef.Create("net.upnp", false, CVar.SERVERONLY);
|
||||
|
||||
/**
|
||||
* SUS
|
||||
*/
|
||||
@@ -163,8 +169,10 @@ namespace Robust.Shared
|
||||
public static readonly CVarDef<bool> StatusEnabled =
|
||||
CVarDef.Create("status.enabled", true, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
|
||||
// Example: *:1212
|
||||
// But this is now autogenerated by default to match NetPort
|
||||
public static readonly CVarDef<string> StatusBind =
|
||||
CVarDef.Create("status.bind", "*:1212", CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
CVarDef.Create("status.bind", "", CVar.ARCHIVE | CVar.SERVERONLY);
|
||||
|
||||
public static readonly CVarDef<int> StatusMaxConnections =
|
||||
CVarDef.Create("status.max_connections", 5, CVar.SERVERONLY);
|
||||
|
||||
70
Robust.Shared/Network/NetManager.Upnp.cs
Normal file
70
Robust.Shared/Network/NetManager.Upnp.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Log;
|
||||
|
||||
namespace Robust.Shared.Network;
|
||||
|
||||
public partial class NetManager
|
||||
{
|
||||
private void InitUpnp()
|
||||
{
|
||||
var sawmill = Logger.GetSawmill("net.upnp");
|
||||
var port = Port;
|
||||
|
||||
var peers = _netPeers.Select(p => p.Peer).Where(p => p.Configuration.EnableUPnP).ToArray();
|
||||
if (peers.Length == 0)
|
||||
{
|
||||
sawmill.Warning("Can't UPnP forward: No IPv4-compatible NetPeers available.");
|
||||
return;
|
||||
}
|
||||
|
||||
// We DON'T want to hold up the main server on this!
|
||||
new Thread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var peer in peers)
|
||||
{
|
||||
// The way the NetUPnP code is written, we're doing guesswork anyway
|
||||
// It seems to be that the assumption in regards to IPv6 is "what?" w/ UPnP????
|
||||
// ATTENTION FUTURE 20KDC (or anyone else who comes by):
|
||||
// IF YOU GET IPv6 FOR REALSIES, WORK OUT HOW TO DEAL W/ THIS!
|
||||
var upnp = peer.UPnP;
|
||||
while (upnp.Status == UPnPStatus.Discovering)
|
||||
{
|
||||
// Sleep while the network thread does the work
|
||||
NetUtility.Sleep(250);
|
||||
}
|
||||
|
||||
// Clear these forwarding rules because we don't want any OTHER SS14 servers on our network (or different local IP addresses of ourself) conflicting
|
||||
upnp.DeleteForwardingRule(port, "UDP");
|
||||
upnp.DeleteForwardingRule(port, "TCP");
|
||||
var udpRes = upnp.ForwardPort(port, "RobustToolbox UDP", 0, "UDP");
|
||||
var tcpRes = upnp.ForwardPort(port, "RobustToolbox TCP", 0, "TCP");
|
||||
// Message needs to show in warning if something went wrong
|
||||
var message = $"UPnP setup for port {port} on peer {peer.Configuration.LocalAddress} results: TCP {tcpRes}, UDP {udpRes}";
|
||||
if (tcpRes && udpRes)
|
||||
{
|
||||
sawmill.Info(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
sawmill.Warning(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
sawmill.Warning($"UPnP threw an exception: {e}");
|
||||
}
|
||||
}).Start();
|
||||
}
|
||||
|
||||
private static bool UpnpCompatible(NetPeerConfiguration cfg)
|
||||
{
|
||||
return cfg.LocalAddress.AddressFamily == AddressFamily.InterNetwork || cfg.DualStack;
|
||||
}
|
||||
}
|
||||
@@ -349,6 +349,9 @@ namespace Robust.Shared.Network
|
||||
config.DualStack = true;
|
||||
}
|
||||
|
||||
if (UpnpCompatible(config))
|
||||
config.EnableUPnP = true;
|
||||
|
||||
var peer = IsServer ? (NetPeer) new NetServer(config) : new NetClient(config);
|
||||
peer.Start();
|
||||
_netPeers.Add(new NetPeerData(peer));
|
||||
@@ -365,6 +368,9 @@ namespace Robust.Shared.Network
|
||||
Logger.WarningS("net",
|
||||
"IPv6 Dual Stack is enabled but no IPv6 addresses have been bound to. This will not work.");
|
||||
}
|
||||
|
||||
if (_config.GetCVar(CVars.NetUPnP))
|
||||
InitUpnp();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Reference in New Issue
Block a user