Skip to content

Commit

Permalink
Simplify API implementations by removing LiteNetLib dependency (#312)
Browse files Browse the repository at this point in the history
- Removed the LiteNetLib from CSM.API so implementing mods don't throw errors if CSM is not available.
  This is realized by removing the NetPeer field from the Player class.
- Also explain how the bundled protobuf-net.dll is created
- Update changelog panel

* Fix transport line synchronization, remove transport tool sync for now (which was broken anyway)
  • Loading branch information
kaenganxt committed Apr 14, 2023
1 parent 29272d3 commit eebcab0
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,4 @@ __pycache__/
.vscode/
assemblies/*
!assemblies/protobuf-net.dll
!assemblies/LICENSE.txt
9 changes: 9 additions & 0 deletions assemblies/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
protobuf-net.dll was built from https://github.com/protobuf-net/protobuf-net on tag 2.4.8
with the following config changes:
FeatureServiceModel = false
FeatureServiceModelConfiguration = false
PlatformXmlSerializer = false
PlatformBinaryFormatter = false

protobuf-net is licensed under the Apache License, Version 2.0.
See https://github.com/protobuf-net/protobuf-net/blob/main/Licence.txt
4 changes: 4 additions & 0 deletions examples/SampleExternalMod/SampleExternalMod.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@
<ItemGroup>
<PackageReference Include="CitiesHarmony.API">
<Version>2.0.0</Version>
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
<PackageReference Include="protobuf-net">
<Version>2.4.6</Version>
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
<PackageReference Include="CitiesSkylinesMultiplayer.API">
<Version>0.9.0</Version>
Expand All @@ -58,10 +60,12 @@
<Reference Include="Assembly-CSharp, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\assemblies\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICities, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\assemblies\ICities.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
Expand Down
3 changes: 0 additions & 3 deletions src/api/CSM.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\assemblies\protobuf-net.dll</HintPath>
</Reference>
<PackageReference Include="LiteNetLib">
<Version>0.9.4</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
12 changes: 2 additions & 10 deletions src/api/Networking/Player.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
using CSM.API.Networking.Status;
using LiteNetLib;

namespace CSM.API.Networking
{
public class Player
{
public string Username { get; set; }

public NetPeer NetPeer { get; set; }

public long Latency { get; set; }

public ClientStatus Status { get; set; }

public Player(NetPeer peer, string username)
public Player(string username)
{
Username = username;
NetPeer = peer;
Latency = -1;
}

public Player(string username) : this(null, username)
{
}

public Player() : this(null, null)
public Player()
{
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/basegame/Injections/Tools/TransportToolHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ public class PlayerTransportToolCommandHandler : BaseToolCommandHandler<PlayerTr
{
protected override void Configure(TransportTool tool, ToolController toolController, PlayerTransportToolCommand command) {
// TODO: somehow force the rendering to occur even when clients aren't viewing the transport layer
tool.m_prefab = PrefabCollection<TransportInfo>.GetPrefab(command.TransportInfo);
// TODO: Implement this correctly, the following breaks our transport line synchronisation
/*tool.m_prefab = PrefabCollection<TransportInfo>.GetPrefab(command.TransportInfo);
ReflectionHelper.SetAttr(tool, "m_lastEditLine", command.LastEditLine);
ReflectionHelper.SetAttr(tool, "m_hoverStopIndex", command.HoverStopIndex);
ReflectionHelper.SetAttr(tool, "m_hoverSegmentIndex", command.HoverSegmentIndex);
ReflectionHelper.SetAttr(tool, "m_hitPosition", command.HitPosition);
ReflectionHelper.SetAttr(tool, "m_hitPosition", command.HitPosition);*/
}

protected override CursorInfo GetCursorInfo(TransportTool tool)
Expand Down
1 change: 1 addition & 0 deletions src/csm/CSM.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<Compile Include="Networking\Config\ClientConfig.cs" />
<Compile Include="Networking\Config\ConfigData.cs" />
<Compile Include="Networking\Config\ServerConfig.cs" />
<Compile Include="Networking\CSMPlayer.cs" />
<Compile Include="Networking\IpAddress.cs" />
<Compile Include="Networking\MultiplayerManager.cs" />
<Compile Include="Networking\Server.cs" />
Expand Down
11 changes: 9 additions & 2 deletions src/csm/Commands/CommandInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ public void SendToClient(NetPeer peer, CommandBase command)
/// <param name="command">The command to send.</param>
public void SendToClient(Player player, CommandBase command)
{
SendToClient(player.NetPeer, command);
if (player is CSMPlayer csmPlayer)
{
SendToClient(csmPlayer.NetPeer, command);
}
else
{
Log.Warn("Trying to send packet to non-csm player, ignoring.");
}
}

/// <summary>
Expand All @@ -78,7 +85,7 @@ public void SendToClients(CommandBase command)
/// <param name="exclude">The player to not send the packet to.</param>
public void SendToOtherClients(CommandBase command, Player exclude)
{
foreach (Player player in MultiplayerManager.Instance.CurrentServer.ConnectedPlayers.Values)
foreach (CSMPlayer player in MultiplayerManager.Instance.CurrentServer.ConnectedPlayers.Values)
{
if (player.Equals(exclude))
continue;
Expand Down
3 changes: 2 additions & 1 deletion src/csm/Commands/Handler/Internal/ClientDisonnectHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ protected override void Handle(ClientDisconnectCommand command)

public override void OnClientDisconnect(Player player)
{
int clientId = player is CSMPlayer csmPlayer ? csmPlayer.NetPeer.Id : -2;
Command.SendToClients(new ClientDisconnectCommand
{
Username = player.Username,
ClientId = player.NetPeer.Id
ClientId = clientId
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public void HandleOnServer(ConnectionRequestCommand command, NetPeer peer)
}

// Add the new player as a connected player
Player newPlayer = new Player(peer, command.Username);
CSMPlayer newPlayer = new CSMPlayer(peer, command.Username);
MultiplayerManager.Instance.CurrentServer.ConnectedPlayers[peer.Id] = newPlayer;

// Send the result command
Expand Down
20 changes: 20 additions & 0 deletions src/csm/Networking/CSMPlayer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using CSM.API.Networking;
using LiteNetLib;

namespace CSM.Networking
{
public class CSMPlayer : Player
{
public NetPeer NetPeer { get; }

public CSMPlayer(NetPeer peer, string username) : base(username)
{
NetPeer = peer;
}

public CSMPlayer(string username) : base(username)
{
NetPeer = null;
}
}
}
16 changes: 8 additions & 8 deletions src/csm/Networking/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ public class Server
private int _keepAlive = 1;

// Connected clients
public Dictionary<int, Player> ConnectedPlayers { get; } = new Dictionary<int, Player>();
public Dictionary<int, CSMPlayer> ConnectedPlayers { get; } = new Dictionary<int, CSMPlayer>();

/// <summary>
/// Get the Player object of the server host
/// </summary>
public Player HostPlayer { get { return _hostPlayer; } }
public CSMPlayer HostPlayer { get { return _hostPlayer; } }
// The player instance for the host player
private Player _hostPlayer;
private CSMPlayer _hostPlayer;

// Config options for server
public ServerConfig Config { get; private set; }
Expand Down Expand Up @@ -137,7 +137,7 @@ public bool StartServer(ServerConfig serverConfig)
Status = ServerStatus.Running;

// Initialize host player
_hostPlayer = new Player(Config.Username);
_hostPlayer = new CSMPlayer(Config.Username);
_hostPlayer.Status = ClientStatus.Connected;
MultiplayerManager.Instance.PlayerList.Add(_hostPlayer.Username);

Expand Down Expand Up @@ -333,15 +333,15 @@ private void ListenerOnNetworkReceiveEvent(NetPeer peer, NetPacketReader reader,

private void ListenerOnNetworkLatencyUpdateEvent(NetPeer peer, int latency)
{
if (!ConnectedPlayers.TryGetValue(peer.Id, out Player player))
if (!ConnectedPlayers.TryGetValue(peer.Id, out CSMPlayer player))
return;

player.Latency = latency;
}

private void ListenerOnPeerDisconnectedEvent(NetPeer peer, DisconnectInfo disconnectInfo)
{
if (!ConnectedPlayers.TryGetValue(peer.Id, out Player player))
if (!ConnectedPlayers.TryGetValue(peer.Id, out CSMPlayer player))
return;

Log.Info($"Player {player.Username} lost connection! Reason: {disconnectInfo.Reason}");
Expand Down Expand Up @@ -381,7 +381,7 @@ public void HandlePlayerConnect(Player player)
}
}

public void HandlePlayerDisconnect(Player player)
public void HandlePlayerDisconnect(CSMPlayer player)
{
MultiplayerManager.Instance.PlayerList.Remove(player.Username);
this.ConnectedPlayers.Remove(player.NetPeer.Id);
Expand All @@ -408,7 +408,7 @@ private void ListenerOnNetworkErrorEvent(IPEndPoint endpoint, SocketError socket
/// <summary>
/// Get the Player object by username. Warning, expensive call!!!
/// </summary>
public Player GetPlayerByUsername(string username)
public CSMPlayer GetPlayerByUsername(string username)
{
if (username == HostPlayer.Username)
return HostPlayer;
Expand Down
19 changes: 15 additions & 4 deletions src/csm/Panels/MessagePanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,22 @@ public void DisplayReleaseNotes()
Version version = Assembly.GetAssembly(typeof(CSM)).GetName().Version;

string message = $"Version {version.Major}.{version.Minor}\n" +
"Last Update: November 15th, 2022\n\n" +
"Last Update: April 14th, 2023\n\n" +
"- Features:\n" +
" - Support Roads and Vehicles Update\n\n" +
" - Fixes:\n" +
" - Ignore order of mods for compatibility\n";
" - Better NAT traversal, now using our API server\n" +
" to negotiate connections\n" +
" -> This means you should no longer need\n" +
" Hamachi or similar VPN solutions!\n" +
" (Tell us on Discord about your experience)\n\n" +
" - You can now join using the Steam friends menu\n" +
" - New player cursors show the mouse position\n" +
" and current tool of other players\n" +
" - Save game download progress is now shown\n" +
" - Similar chat messages are now merged\n\n" +
"- Fixes:\n" +
" - Handle timeouts while joining correctly\n" +
" - Fix several exceptions from the log\n" +
" - Fix some game crashes";
SetMessage(message);

Show(true);
Expand Down

0 comments on commit eebcab0

Please sign in to comment.