Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions Source/Client/Networking/HostUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ private static void PrepareLocalServer(ServerSettings settings, bool fromReplay)
localServer.worldData.hostFactionId = Faction.OfPlayer.loadID;
localServer.worldData.spectatorFactionId = Multiplayer.WorldComp.spectatorFaction.loadID;

if (settings.steam)
localServer.TickEvent += SteamP2PIntegration.ServerSteamNetTick;

if (fromReplay)
{
localServer.gameTimer = TickPatch.Timer;
Expand Down Expand Up @@ -218,9 +215,11 @@ private static void StartArbiter()
{
Multiplayer.session.AddMsg("The Arbiter instance is starting...", false);

Multiplayer.LocalServer.liteNet.SetupArbiterConnection();
var arbiterNet = LiteNetArbiterManager.Create(Multiplayer.LocalServer);
if (arbiterNet == null) throw new Exception("Failed to setup Arbiter network.");
Multiplayer.LocalServer.netManagers.Add(arbiterNet);

string args = $"-batchmode -nographics -arbiter -logfile arbiter_log.txt -connect=127.0.0.1:{Multiplayer.LocalServer.liteNet.ArbiterPort}";
string args = $"-batchmode -nographics -arbiter -logfile arbiter_log.txt -connect=127.0.0.1:{arbiterNet.Port}";

if (GenCommandLine.TryGetCommandLineArg("savedatafolder", out string saveDataFolder))
args += $" \"-savedatafolder={saveDataFolder}\"";
Expand Down
99 changes: 61 additions & 38 deletions Source/Client/Networking/NetworkingSteam.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Multiplayer.Common;
using Steamworks;
using Verse;
using Verse.Steam;

namespace Multiplayer.Client.Networking
{
Expand Down Expand Up @@ -135,6 +136,66 @@ private void OnDisconnect()
}
}

public class SteamP2PNetManager : INetManager
{
private readonly MultiplayerServer server;

private SteamP2PNetManager(MultiplayerServer server) => this.server = server;

public static SteamP2PNetManager Create(MultiplayerServer server)
{
if (!SteamManager.Initialized) return null;
return new SteamP2PNetManager(server);
}

public void Tick()
{
foreach (var packet in SteamP2PIntegration.ReadPackets(0))
{
var playerManager = server.playerManager;
var player = playerManager.Players
.FirstOrDefault(p => p.conn is SteamBaseConn conn && conn.remoteId == packet.remote);

if (packet.joinPacket && player == null)
{
ConnectionBase conn = new SteamServerConn(packet.remote, packet.channel);

var preConnect = playerManager.OnPreConnect(packet.remote);
if (preConnect != null)
{
conn.Close(preConnect.Value);
continue;
}

conn.ChangeState(ConnectionStateEnum.ServerJoining);
player = playerManager.OnConnected(conn);
player.type = PlayerType.Steam;

player.steamId = (ulong)packet.remote;
player.steamPersonaName = SteamFriends.GetFriendPersonaName(packet.remote);
if (player.steamPersonaName.Length == 0)
player.steamPersonaName = "[unknown]";

conn.Send(Packets.Server_SteamAccept);
}

if (!packet.joinPacket && player != null)
{
player.HandleReceive(packet.data, packet.reliable);
}
}
}

public void Stop()
{
// Managed externally by Steamworks
}

public string GetDiagnosticsName() => "SteamP2P";

public string GetDiagnosticsInfo() => null;
}

public static class SteamP2PIntegration
{
private static Callback<P2PSessionConnectFail_t> p2pFail;
Expand Down Expand Up @@ -195,43 +256,5 @@ internal static IEnumerable<SteamPacket> ReadPackets(int recvChannel)
};
}
}

public static void ServerSteamNetTick(MultiplayerServer server)
{
foreach (var packet in ReadPackets(0))
{
var playerManager = server.playerManager;
var player = playerManager.Players
.FirstOrDefault(p => p.conn is SteamBaseConn conn && conn.remoteId == packet.remote);

if (packet.joinPacket && player == null)
{
ConnectionBase conn = new SteamServerConn(packet.remote, packet.channel);

var preConnect = playerManager.OnPreConnect(packet.remote);
if (preConnect != null)
{
conn.Close(preConnect.Value);
continue;
}

conn.ChangeState(ConnectionStateEnum.ServerJoining);
player = playerManager.OnConnected(conn);
player.type = PlayerType.Steam;

player.steamId = (ulong)packet.remote;
player.steamPersonaName = SteamFriends.GetFriendPersonaName(packet.remote);
if (player.steamPersonaName.Length == 0)
player.steamPersonaName = "[unknown]";

conn.Send(Packets.Server_SteamAccept);
}

if (!packet.joinPacket && player != null)
{
player.HandleReceive(packet.data, packet.reliable);
}
}
}
}
}
10 changes: 5 additions & 5 deletions Source/Client/Windows/ChatWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,11 @@ void LogNetData(string name, NetStatistics stats)

if (Multiplayer.LocalServer != null)
{
if (Multiplayer.LocalServer.liteNet.lanManager != null)
LogNetData("Lan Server", Multiplayer.LocalServer.liteNet.lanManager.Statistics);

//if (Multiplayer.LocalServer.net.netManager != null)
// LogNetData("Net Server", Multiplayer.LocalServer.net.netManager.Statistics);
foreach (var man in Multiplayer.LocalServer.netManagers)
{
text.AppendLine(man.GetDiagnosticsName());
text.AppendLine(man.GetDiagnosticsInfo() ?? "<no info>");
}

// todo thread problems?
// foreach (var p in Multiplayer.LocalServer.players.ToList())
Expand Down
84 changes: 75 additions & 9 deletions Source/Client/Windows/HostWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using Multiplayer.Client.Networking;
using Multiplayer.Client.Util;
using Multiplayer.Common;
using Multiplayer.Common.Util;
Expand Down Expand Up @@ -464,25 +466,89 @@ static bool TryParseEndpoints(ServerSettings settings)
static bool TryStartLocalServer(ServerSettings settings)
{
var localServer = new MultiplayerServer(settings);
var success = localServer.liteNet.StartNet();
var success = true;

if (success)
if (settings.direct) {
var liteNet = StartLiteNetManager(localServer, settings);
if (liteNet == null) success = false;
else localServer.netManagers.Add(liteNet);
}

if (settings.lan)
{
var lan = StartLanManager(localServer, settings);
if (lan == null) success = false;
else localServer.netManagers.Add(lan);
}

if (settings.steam)
{
Multiplayer.LocalServer = localServer;
return true;
var steam = StartSteamP2PManager(localServer, settings);
if (steam == null) success = false;
else localServer.netManagers.Add(steam);
}

foreach (var (endpoint, man) in localServer.liteNet.netManagers)
if (!success)
{
localServer.netManagers.ForEach(man => man.Stop());
return false;
}

Multiplayer.LocalServer = localServer;
return true;
}

private static INetManager StartLiteNetManager(MultiplayerServer server, ServerSettings settings)
{
var invalidEndpoint = settings.TryParseEndpoints(out var endpoints);
if (invalidEndpoint != null)
{
Messages.Message(
"MpInvalidEndpoint".Translate(invalidEndpoint),
MessageTypeDefOf.RejectInput,
false
);
return null;
}

if (LiteNetManager.Create(server, endpoints, out var liteNet)) return liteNet;

foreach (var (endpoint, man) in liteNet.netManagers)
{
if (man.IsRunning) continue;
Messages.Message($"Failed to bind direct on {endpoint}", MessageTypeDefOf.RejectInput, false);
}

if (localServer.liteNet.lanManager is { IsRunning: false })
Messages.Message($"Failed to bind LAN on {settings.lanAddress}", MessageTypeDefOf.RejectInput, false);
liteNet.Stop();
return null;
}

public static INetManager StartLanManager(MultiplayerServer server, ServerSettings settings)
{
if (!IPAddress.TryParse(settings.lanAddress, out var ipAddr))
{
Messages.Message(
"MpInvalidEndpoint".Translate(settings.lanAddress),
MessageTypeDefOf.RejectInput,
false
);
return null;
}

var man = LiteNetLanManager.Create(server, ipAddr);
if (man != null) return man;

Messages.Message($"Failed to bind LAN on {settings.lanAddress}", MessageTypeDefOf.RejectInput, false);
return null;
}

public static INetManager StartSteamP2PManager(MultiplayerServer server, ServerSettings settings)
{
var man = SteamP2PNetManager.Create(server);
if (man != null) return man;

localServer.liteNet.StopNet();
return false;
Messages.Message("Failed to start Steam networking", MessageTypeDefOf.RejectInput, false);
return null;
}

public override void PostClose()
Expand Down
10 changes: 10 additions & 0 deletions Source/Common/INetManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Multiplayer.Common;

public interface INetManager
{
public void Tick();
public void Stop();

public string GetDiagnosticsName();
public string? GetDiagnosticsInfo();
}
Loading
Loading