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
2 changes: 1 addition & 1 deletion .github/workflows/build-launcher.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Build launcher
run: |
cd ReCap.Launcher
dotnet build --configuration ${{env.DOTNET_CONFIG}} --runtime ${{matrix.runtime}}
dotnet build ReCap.Launcher.csproj --configuration ${{env.DOTNET_CONFIG}} --runtime ${{matrix.runtime}}

- name: Upload artifacts
uses: actions/upload-artifact@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Build server
run: |
cd ReCap.Server
dotnet build --configuration ${{env.DOTNET_CONFIG}} --runtime ${{matrix.runtime}}
dotnet build ReCap.Server.csproj --configuration ${{env.DOTNET_CONFIG}} --runtime ${{matrix.runtime}}

- name: Upload artifacts
uses: actions/upload-artifact@v4
Expand Down
10 changes: 6 additions & 4 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[submodule "lib/SharpRakNet"]
path = lib/SharpRakNet
url = https://github.com/Resurrection-Capsule/SharpRakNet.git
branch = net8.0
[submodule "lib/RakNexus"]
path = lib/RakNexus
url = https://github.com/JeanxPereira/RakNexus.git
[submodule "lib/AssetData.Parser"]
path = lib/AssetData.Parser
url = https://github.com/JeanxPereira/AssetData.Parser.git
19 changes: 14 additions & 5 deletions ReCap.Server/Adapters/Blaze/BlazeServer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Sockets;
using Org.BouncyCastle.Crypto;
Expand All @@ -7,6 +7,7 @@
using ReCap.Server.Adapters.Blaze.Component;
using ReCap.Server.Adapters.Blaze.Component.GameManager;
using ReCap.Server.Config;
using ReCap.Server.Services;

namespace ReCap.Server.Adapters.Blaze;

Expand All @@ -28,7 +29,7 @@ public class BlazeServer
public int Port { get; }
public bool Running { get; private set; }

public BlazeServer(SqliteConfig newSqliteConfig, string name, IPAddress hostAddress, int port, bool isSecure, string hostname)
public BlazeServer(SqliteConfig newSqliteConfig, string name, IPAddress hostAddress, int port, bool isSecure, string hostname, GameService? sharedGameService = null)
{
Name = name;
IsSecure = isSecure;
Expand All @@ -53,19 +54,22 @@ public BlazeServer(SqliteConfig newSqliteConfig, string name, IPAddress hostAddr
});
}
else {
var gameService = sharedGameService ?? new GameService();
var gameManagerComponent = new GameManagerComponent(newSqliteConfig);
gameManagerComponent.GameHandler = gameService;

List<IComponent> components = new List<IComponent> {
new AssociationListsComponent(),
new AuthenticationComponent(newSqliteConfig),
new GameManagerComponent(newSqliteConfig),
gameManagerComponent,
new MessagingComponent(),
new PlaygroupsComponent(),
new RoomsComponent(),
new UserSessionsComponent(),
new UserSessionsComponent(newSqliteConfig),
new UtilComponent(),
new GameReportingComponent(),
new UnknownComponent1()
};
Dictionary<ushort, IComponent> Components = [];
foreach (var component in components) {
AttachComponent(component);
}
Expand Down Expand Up @@ -130,6 +134,11 @@ public void HandlePacket(Client client, Packet packet)
Log($"Unknown component: 0x{packet.Component:X}");
}

public Client? FindClientByUserId(ulong userId)
{
return Clients.FirstOrDefault(c => c.UserId == userId);
}

public void Disconnect(Client client)
{
Clients.Remove(client);
Expand Down
70 changes: 50 additions & 20 deletions ReCap.Server/Adapters/Blaze/Client.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
using System.Buffers;
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Sockets;
using Org.BouncyCastle.Tls;
using ReCap.Server.Adapters.Blaze.Component;
using ReCap.Server.Adapters.Blaze.Ssl;

namespace ReCap.Server.Adapters.Blaze;

public class Client
{
private static readonly Dictionary<(ushort, ushort), DateTime> _lastLogTime = new();
private static readonly TimeSpan _logThrottle = TimeSpan.FromSeconds(30);
private static readonly HashSet<(ushort component, ushort command)> _throttledPackets = new()
{
(0x7802, 0x19), // UserSessions -> updateUserSessionClientData
};

private byte[] ReceiveBuffer { get; }

private TcpClient TcpClient { get; }
Expand All @@ -23,6 +31,7 @@ public class Client

public ulong UserId { get; set; }
public string AuthToken { get; set; }
public UserSessionExtendedData ExtendedData { get; } = new();

public Client(BlazeServer server, TcpClient tcpClient)
{
Expand Down Expand Up @@ -72,7 +81,8 @@ public void RespondTo(Packet request, Tdf? response = null, uint error = 0)

private void SendPacket(Packet packet)
{
Log($"Sending {packet.ToString(Server.GetComponentAndCommandName(packet.Component, packet.Command, packet.Type == PacketType.Notification))}...");
if (!IsThrottled(packet.Component, packet.Command))
Log($"Sending {packet.ToString(Server.GetComponentAndCommandName(packet.Component, packet.Command, packet.Type == PacketType.Notification))}...");

packet.WriteTo(CommStream);

Expand Down Expand Up @@ -144,36 +154,37 @@ private async void Receive()
if (writeOffset <= 0)
continue;

if (writeOffset < Packet.SmallestValidHeaderSize)
continue;

try
{
using var ms = new MemoryStream(ReceiveBuffer, 0, writeOffset, false);
while (writeOffset >= Packet.SmallestValidHeaderSize)
{
using var ms = new MemoryStream(ReceiveBuffer, 0, writeOffset, false);

var packet = Packet.Parse(ms);
if (packet is null)
continue;
var packet = Packet.Parse(ms);
if (packet is null)
break; // Need more data for a complete packet

var totalPacketLength = (int)ms.Position;
var totalPacketLength = (int)ms.Position;

if (packet.Component != 0x2678) // If I don't ignore that specific component, the log gets spammed
{
Log($"Incoming packet: {packet.ToString(Server.GetComponentAndCommandName(packet.Component, packet.Command, packet.Type == PacketType.Notification))}");
}
if (!IsThrottled(packet.Component, packet.Command))
{
Log($"Incoming packet: {packet.ToString(Server.GetComponentAndCommandName(packet.Component, packet.Command, packet.Type == PacketType.Notification))}");
}

Server.HandlePacket(this, packet);
Server.HandlePacket(this, packet);

// Shift extra read bytes to the beginning of the buffer, if any
if (writeOffset > totalPacketLength)
Array.Copy(ReceiveBuffer, 0, ReceiveBuffer, totalPacketLength, writeOffset - totalPacketLength);
// Shift extra read bytes to the beginning of the buffer, if any
if (writeOffset > totalPacketLength)
Array.Copy(ReceiveBuffer, totalPacketLength, ReceiveBuffer, 0, writeOffset - totalPacketLength);

writeOffset -= totalPacketLength;
writeOffset -= totalPacketLength;
}
}
catch (Exception e)
{
Log($"Exception while handling incoming packet! Exception: {e}");
continue;
Disconnect();
return;
}

CommStream.Flush();
Expand All @@ -182,6 +193,25 @@ private async void Receive()
Disconnect();
}

private static bool IsThrottled(ushort component, ushort command)
{
if (!_throttledPackets.Contains((component, command)))
return false;

var key = (component, command);
var now = DateTime.UtcNow;

lock (_lastLogTime)
{
if (_lastLogTime.TryGetValue(key, out var last) && now - last < _logThrottle)
return true;

_lastLogTime[key] = now;
}

return false;
}

private async void Log(string message) => await Console.Out.WriteLineAsync($"[{Server.Name} Client: {EndPoint}]: {message}");
}

Loading
Loading