Skip to content
This repository has been archived by the owner on Jul 18, 2020. It is now read-only.

Commit

Permalink
Improve Steam connections
Browse files Browse the repository at this point in the history
  • Loading branch information
Zetrith committed Dec 18, 2018
1 parent 49035b3 commit c064c15
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 99 deletions.
2 changes: 2 additions & 0 deletions Languages/English/Keyed/Multiplayer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@
<MpReplayOutdated>(Outdated)</MpReplayOutdated>
<MpReplayOutdatedDesc>This replay was made for protocol version {0}, but you are running version {1}.\n\nThe replay might not play correctly.</MpReplayOutdatedDesc>

<MpServerCloseConfirmation>Are you sure you want to close the server? Unsaved progress will be lost.</MpServerCloseConfirmation>

</LanguageData>
8 changes: 4 additions & 4 deletions Source/Client/ClientConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ private static void PostLoad()
[PacketHandler(Packets.Server_DisconnectReason)]
public void HandleDisconnectReason(ByteReader data)
{
string reason = data.ReadString();
Multiplayer.session.disconnectServerReason = reason;
string reasonKey = data.ReadString();
Multiplayer.session.disconnectServerReason = reasonKey.Translate();
}
}

Expand Down Expand Up @@ -349,8 +349,8 @@ public void HandleSteamAccept(ByteReader data)
[PacketHandler(Packets.Server_DisconnectReason)]
public void HandleDisconnectReason(ByteReader data)
{
string reason = data.ReadString();
Multiplayer.session.disconnectServerReason = reason;
string reasonKey = data.ReadString();
Multiplayer.session.disconnectServerReason = reasonKey.Translate();
}
}

Expand Down
49 changes: 43 additions & 6 deletions Source/Client/ClientNetworking.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static void TryConnect(IPAddress address, int port)
listener.NetworkReceiveEvent += (peer, reader, method) =>
{
byte[] data = reader.GetRemainingBytes();
Multiplayer.HandleReceive(data, method == DeliveryMethod.ReliableOrdered);
Multiplayer.HandleReceive(new ByteReader(data), method == DeliveryMethod.ReliableOrdered);
};

listener.NetworkErrorEvent += (endpoint, error) =>
Expand Down Expand Up @@ -123,6 +123,9 @@ public static void HostServer(ServerSettings settings, bool replay)
localServer.hostUsername = Multiplayer.username;
localServer.coopFactionId = Faction.OfPlayer.loadID;

if (settings.steam)
localServer.NetTick += TickSteamNet;

if (replay)
localServer.timer = TickPatch.Timer;

Expand Down Expand Up @@ -197,6 +200,37 @@ public static void HostServer(ServerSettings settings, bool replay)
}, "MpSaving", false, null);
}

private static void TickSteamNet(MultiplayerServer server)
{
foreach (var packet in MpUtil.ReadSteamPackets())
{
if (packet.joinPacket)
MpUtil.CleanSteamNet(0);

var player = server.players.FirstOrDefault(p => p.conn is SteamBaseConn conn && conn.remoteId == packet.remote);

if (packet.joinPacket && player == null)
{
IConnection conn = new SteamServerConn(packet.remote);
conn.State = ConnectionStateEnum.ServerJoining;
player = server.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);
}
}
}

private static void SetupLocalClient()
{
if (Multiplayer.session.localSettings.arbiter)
Expand Down Expand Up @@ -258,7 +292,7 @@ protected override void SendRaw(byte[] raw, bool reliable)
{
try
{
serverSide.HandleReceive(raw, reliable);
serverSide.HandleReceive(new ByteReader(raw), reliable);
}
catch (Exception e)
{
Expand Down Expand Up @@ -294,7 +328,7 @@ protected override void SendRaw(byte[] raw, bool reliable)
{
try
{
clientSide.HandleReceive(raw, reliable);
clientSide.HandleReceive(new ByteReader(raw), reliable);
}
catch (Exception e)
{
Expand Down Expand Up @@ -324,7 +358,11 @@ public SteamBaseConn(CSteamID remoteId)

protected override void SendRaw(byte[] raw, bool reliable)
{
SteamNetworking.SendP2PPacket(remoteId, raw, (uint)raw.Length, reliable ? EP2PSend.k_EP2PSendReliable : EP2PSend.k_EP2PSendUnreliable, reliable ? 0 : 1);
byte[] full = new byte[1 + raw.Length];
full[0] = reliable ? (byte)2 : (byte)0;
raw.CopyTo(full, 1);

SteamNetworking.SendP2PPacket(remoteId, full, (uint)full.Length, reliable ? EP2PSend.k_EP2PSendReliable : EP2PSend.k_EP2PSendUnreliable, 0);
}

public override void Close()
Expand Down Expand Up @@ -363,9 +401,8 @@ public class SteamClientConn : SteamBaseConn
public SteamClientConn(CSteamID remoteId) : base(remoteId)
{
MpUtil.CleanSteamNet(0);
MpUtil.CleanSteamNet(1);

SteamNetworking.SendP2PPacket(remoteId, new byte[0], 0, EP2PSend.k_EP2PSendReliable, 2);
SteamNetworking.SendP2PPacket(remoteId, new byte[] { 1 }, 1, EP2PSend.k_EP2PSendReliable, 0);
}

public override void OnError(EP2PSessionError error)
Expand Down
33 changes: 29 additions & 4 deletions Source/Client/MpUtil.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Harmony;
using Multiplayer.Common;
using Steamworks;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -97,13 +98,37 @@ public static string GetLocalIpAddress()
}
}

public static byte[] CleanSteamNet(int channel)
public static void CleanSteamNet(int channel)
{
byte[] last = null;
while (SteamNetworking.IsP2PPacketAvailable(out uint size, channel))
SteamNetworking.ReadP2PPacket(last = new byte[size], size, out uint sizeRead, out CSteamID remote, channel);
return last;
SteamNetworking.ReadP2PPacket(new byte[size], size, out uint sizeRead, out CSteamID remote, channel);
}

public static IEnumerable<SteamPacket> ReadSteamPackets()
{
while (SteamNetworking.IsP2PPacketAvailable(out uint size, 0))
{
byte[] data = new byte[size];
SteamNetworking.ReadP2PPacket(data, size, out uint sizeRead, out CSteamID remote, 0);

if (data.Length <= 0) continue;

var reader = new ByteReader(data);
byte info = reader.ReadByte();
bool joinPacket = (info & 1) > 0;
bool reliable = (info & 2) > 0;

yield return new SteamPacket() { remote = remote, data = reader, joinPacket = joinPacket, reliable = reliable };
}
}
}

public struct SteamPacket
{
public CSteamID remote;
public ByteReader data;
public bool joinPacket;
public bool reliable;
}

public static class SteamImages
Expand Down
2 changes: 1 addition & 1 deletion Source/Client/Multiplayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ public static void ExposeIdBlock(ref IdBlock block, string label)
}
}

public static void HandleReceive(byte[] data, bool reliable)
public static void HandleReceive(ByteReader data, bool reliable)
{
try
{
Expand Down
60 changes: 4 additions & 56 deletions Source/Client/OnMainThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ public void Update()
SendCursor();
}

if (SteamManager.Initialized)
{
ReadSteamPackets(2); // New connections
ReadSteamPackets(0); // Reliable
ReadSteamPackets(1); // Unreliable
}
if (Multiplayer.Client is SteamBaseConn steamConn && SteamManager.Initialized)
foreach (var packet in MpUtil.ReadSteamPackets())
if (steamConn.remoteId == packet.remote)
Multiplayer.HandleReceive(packet.data, packet.reliable);
}

private byte cursorSeq;
Expand Down Expand Up @@ -91,56 +89,6 @@ private void UpdateRichPresence()
lastSteamUpdate.Restart();
}

private void ReadSteamPackets(int channel)
{
while (SteamNetworking.IsP2PPacketAvailable(out uint size, channel))
{
byte[] data = new byte[size];
SteamNetworking.ReadP2PPacket(data, size, out uint sizeRead, out CSteamID remote, channel);
HandleSteamPacket(remote, data, channel);
}
}

private void HandleSteamPacket(CSteamID remote, byte[] data, int channel)
{
if (Multiplayer.Client is SteamBaseConn localConn && localConn.remoteId == remote)
Multiplayer.HandleReceive(data, channel == 0);

if (Multiplayer.LocalServer == null) return;

if (channel == 2)
{
MpUtil.CleanSteamNet(0);
MpUtil.CleanSteamNet(1);
MpUtil.CleanSteamNet(2);
SteamNetworking.CloseP2PChannelWithUser(remote, 2);
}

var server = Multiplayer.LocalServer;
server.Enqueue(() =>
{
var player = server.players.FirstOrDefault(p => p.conn is SteamBaseConn conn && conn.remoteId == remote);

if (channel == 2 && player == null)
{
IConnection conn = new SteamServerConn(remote);
conn.State = ConnectionStateEnum.ServerJoining;
player = server.OnConnected(conn);
player.type = PlayerType.Steam;

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

conn.Send(Packets.Server_SteamAccept);
}

if (channel != 2 && player != null)
player.HandleReceive(data, channel == 0);
});
}

private void UpdateSync()
{
foreach (SyncField f in Sync.bufferedFields)
Expand Down
48 changes: 31 additions & 17 deletions Source/Client/Patches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ public static class SteadyEnvironmentEffectsTickMarker
[MpPatch(typeof(OptionListingUtility), nameof(OptionListingUtility.DrawOptionListing))]
public static class MainMenuPatch
{
const string ServerClose = "Are you sure you want to close the server? Unsaved progress will be lost.";

static void Prefix(Rect rect, List<ListableOption> optList)
{
if (!MainMenuMarker.drawing) return;
Expand Down Expand Up @@ -111,27 +109,43 @@ static void Prefix(Rect rect, List<ListableOption> optList)

optList.RemoveAll(opt => opt.label == "Save".Translate() || opt.label == "LoadGame".Translate());

optList.Find(opt => opt.label == "QuitToMainMenu".Translate()).action = () =>
var quitMenuLabel = "QuitToMainMenu".Translate();
var saveAndQuitMenu = "SaveAndQuitToMainMenu".Translate();
var quitMenu = optList.Find(opt => opt.label == quitMenuLabel || opt.label == saveAndQuitMenu);

if (quitMenu != null)
{
Action action = () =>
quitMenu.label = quitMenuLabel;
quitMenu.action = () =>
{
OnMainThread.StopMultiplayer();
GenScene.GoToMainMenu();
Action action = () =>
{
OnMainThread.StopMultiplayer();
GenScene.GoToMainMenu();
};

if (Multiplayer.LocalServer != null)
Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation("MpServerCloseConfirmation".Translate(), action, true));
else
action();
};
}

if (Multiplayer.LocalServer != null)
Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation(ServerClose, action, true));
else
action();
};
var quitOSLabel = "QuitToOS".Translate();
var saveAndQuitOSLabel = "SaveAndQuitToOS".Translate();
var quitOS = optList.Find(opt => opt.label == quitOSLabel || opt.label == saveAndQuitOSLabel);

optList.Find(opt => opt.label == "QuitToOS".Translate()).action = () =>
if (quitOS != null)
{
if (Multiplayer.LocalServer != null)
Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation(ServerClose, () => Root.Shutdown(), true));
else
Root.Shutdown();
};
quitOS.label = quitOSLabel;
quitOS.action = () =>
{
if (Multiplayer.LocalServer != null)
Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation("MpServerCloseConfirmation".Translate(), () => Root.Shutdown(), true));
else
Root.Shutdown();
};
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Client/Replays.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ protected override void SendRaw(byte[] raw, bool reliable)
{
}

public override void HandleReceive(byte[] rawData, bool reliable)
public override void HandleReceive(ByteReader data, bool reliable)
{
}

Expand Down
8 changes: 6 additions & 2 deletions Source/Common/MultiplayerServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ static MultiplayerServer()

public bool ArbiterPlaying => PlayingPlayers.Any(p => p.IsArbiter && p.status == PlayerStatus.Playing);

public event Action<MultiplayerServer> NetTick;

public MultiplayerServer(ServerSettings settings)
{
this.settings = settings;
Expand Down Expand Up @@ -136,6 +138,8 @@ public void TickNet()
lanManager?.PollEvents();
arbiter?.PollEvents();

NetTick?.Invoke(this);

queue.RunQueue();
}

Expand Down Expand Up @@ -358,7 +362,7 @@ public void OnNetworkLatencyUpdate(NetPeer peer, int latency)
public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod method)
{
byte[] data = reader.GetRemainingBytes();
peer.GetConnection().serverPlayer.HandleReceive(data, method == DeliveryMethod.ReliableOrdered);
peer.GetConnection().serverPlayer.HandleReceive(new ByteReader(data), method == DeliveryMethod.ReliableOrdered);
}

public void OnNetworkError(IPEndPoint endPoint, SocketError socketError)
Expand Down Expand Up @@ -407,7 +411,7 @@ public ServerPlayer(int id, IConnection connection)
conn = connection;
}

public void HandleReceive(byte[] data, bool reliable)
public void HandleReceive(ByteReader data, bool reliable)
{
try
{
Expand Down
Loading

0 comments on commit c064c15

Please sign in to comment.