From a0f4ab12854a4e1b0d759be761fb3b5de9a67cdb Mon Sep 17 00:00:00 2001 From: thisguyStan <53304086+thisguyStan@users.noreply.github.com> Date: Tue, 1 Jul 2025 16:21:26 +0200 Subject: [PATCH 1/5] Move TargetCar to ACTcpClient --- AssettoServer/Network/Tcp/ACTcpClient.cs | 5 +++-- AssettoServer/Server/EntryCar.cs | 9 ++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/AssettoServer/Network/Tcp/ACTcpClient.cs b/AssettoServer/Network/Tcp/ACTcpClient.cs index 48a457e2..ee76e4cf 100644 --- a/AssettoServer/Network/Tcp/ACTcpClient.cs +++ b/AssettoServer/Network/Tcp/ACTcpClient.cs @@ -66,6 +66,7 @@ public class ACTcpClient : IClient public bool SupportsCSPCustomUpdate { get; private set; } public int? CSPVersion { get; private set; } internal string ApiKey { get; } + public EntryCar? TargetCar { get; set; } private static ThreadLocal UdpSendBuffer { get; } = new(() => GC.AllocateArray(1500, true)); private byte[] TcpSendBuffer { get; } @@ -624,11 +625,11 @@ private void OnSpectateCar(PacketReader reader) var spectatePacket = reader.ReadPacket(); if (spectatePacket.SessionId == SessionId || spectatePacket.SessionId > _entryCarManager.EntryCars.Length) { - EntryCar.TargetCar = null; + TargetCar = null; } else { - EntryCar.TargetCar = _entryCarManager.EntryCars[spectatePacket.SessionId]; + TargetCar = _entryCarManager.EntryCars[spectatePacket.SessionId]; } } diff --git a/AssettoServer/Server/EntryCar.cs b/AssettoServer/Server/EntryCar.cs index 642d01ce..26dd13ce 100644 --- a/AssettoServer/Server/EntryCar.cs +++ b/AssettoServer/Server/EntryCar.cs @@ -49,7 +49,6 @@ public partial class EntryCar : IEntryCar public int OutsideNetworkBubbleUpdateRateMs { get; internal set; } internal long[] OtherCarsLastSentUpdateTime { get; } - public EntryCar? TargetCar { get; set; } private long LastFallCheckTime{ get; set; } /// @@ -155,7 +154,7 @@ internal void Reset() P2PCount = (short)(_configuration.Extra.EnableUnlimitedP2P ? 99 : 15), MandatoryPit = _configuration.Server.PitWindowStart < _configuration.Server.PitWindowEnd, }; - TargetCar = null; + if (Client != null) Client.TargetCar = null; } internal void SetActive() @@ -220,7 +219,7 @@ internal void UpdatePosition(in PositionUpdateIn positionUpdate) public bool GetPositionUpdateForCar(EntryCar toCar, out PositionUpdateOut positionUpdateOut) { CarStatus targetCarStatus; - var toTargetCar = toCar.TargetCar; + var toTargetCar = toCar.Client?.TargetCar; if (toTargetCar != null) { if (toTargetCar.AiControlled && toTargetCar.LastSeenAiState[toCar.SessionId] != null) @@ -272,7 +271,7 @@ public bool GetPositionUpdateForCar(EntryCar toCar, out PositionUpdateOut positi } float distanceSquared = Vector3.DistanceSquared(status.Position, targetCarStatus.Position); - if (TargetCar != null || distanceSquared > NetworkDistanceSquared) + if (Client?.TargetCar != null || distanceSquared > NetworkDistanceSquared) { if ((_sessionManager.ServerTimeMilliseconds - OtherCarsLastSentUpdateTime[toCar.SessionId]) < OutsideNetworkBubbleUpdateRateMs) { @@ -308,7 +307,7 @@ public bool GetPositionUpdateForCar(EntryCar toCar, out PositionUpdateOut positi public bool IsInRange(EntryCar target, float range) { - var targetPosition = target.TargetCar != null ? target.TargetCar.Status.Position : target.Status.Position; + var targetPosition = target.Client?.TargetCar != null ? target.Client.TargetCar.Status.Position : target.Status.Position; return Vector3.DistanceSquared(Status.Position, targetPosition) < range * range; } From 32187fdd7fadae5c9fb304735185d32f1dd0121c Mon Sep 17 00:00:00 2001 From: thisguyStan <53304086+thisguyStan@users.noreply.github.com> Date: Tue, 1 Jul 2025 19:58:06 +0200 Subject: [PATCH 2/5] Some progress :) --- .../Model}/ChecksumStatus.cs | 2 +- AssettoServer.Shared/Model/IClient.cs | 34 ++++++++- AssettoServer.Shared/Model/IEntryCar.cs | 29 ++++++-- .../Packets/Outgoing/CarListResponse.cs | 4 +- .../Packets/Outgoing/CurrentSessionUpdate.cs | 2 +- .../Packets/Outgoing/DriverInfoUpdate.cs | 2 +- AssettoServer/Commands/ACModuleBase.cs | 2 +- AssettoServer/Commands/ChatService.cs | 12 ++-- .../Commands/Contexts/ChatCommandContext.cs | 4 +- AssettoServer/Commands/Modules/AdminModule.cs | 22 +++--- .../Commands/Modules/GeneralModule.cs | 2 +- .../TypeParsers/ACClientTypeParser.cs | 31 ++++---- .../Network/CSPClientMessageHandler.cs | 14 ++-- .../ACClientAuthenticationHandler.cs | 5 +- .../Authentication/ACClientClaimsIdentity.cs | 2 +- AssettoServer/Network/Tcp/ACTcpServer.cs | 6 +- .../Tcp/{ACTcpClient.cs => PlayerClient.cs} | 71 ++++++++++--------- AssettoServer/Network/Tcp/SpectatorClient.cs | 8 +++ AssettoServer/Network/Udp/ACUdpServer.cs | 8 +-- AssettoServer/Network/Udp/UdpPluginServer.cs | 15 ++-- AssettoServer/Server/ACServer.cs | 17 ++--- AssettoServer/Server/Ai/AiBehavior.cs | 11 +-- .../Server/CSPClientMessageTypeManager.cs | 14 ++-- .../Server/CSPServerScriptProvider.cs | 2 +- .../Configuration/CSPServerExtraOptions.cs | 8 +-- .../Server/Configuration/Kunos/EntryList.cs | 1 + AssettoServer/Server/EntryCar.cs | 42 +++++------ AssettoServer/Server/EntryCarAi.cs | 7 -- AssettoServer/Server/EntryCarManager.cs | 45 ++++++------ AssettoServer/Server/EventArgs.cs | 2 +- .../Server/OpenSlotFilters/AiSlotFilter.cs | 1 + .../Server/OpenSlotFilters/IOpenSlotFilter.cs | 2 +- .../OpenSlotFilters/OpenSlotFilterBase.cs | 2 +- .../OpenSlotFilters/OpenSlotFilterChain.cs | 2 +- .../Server/OpenSlotFilters/SteamSlotFilter.cs | 2 +- .../OpenSlotFilters/WhitelistSlotFilter.cs | 2 +- AssettoServer/Server/SessionManager.cs | 16 ++--- AssettoServer/Server/SessionState.cs | 2 +- AssettoServer/Server/Steam/ISteam.cs | 2 +- AssettoServer/Server/Steam/NativeSteam.cs | 4 +- AssettoServer/Server/Steam/SteamManager.cs | 2 +- AssettoServer/Server/Steam/WebApiSteam.cs | 2 +- AssettoServer/Server/VoteManager.cs | 2 +- .../Implementation/IWeatherImplementation.cs | 2 +- .../VanillaWeatherImplementation.cs | 2 +- .../WeatherFxV1Implementation.cs | 2 +- .../Server/Weather/WeatherManager.cs | 2 +- AssettoServer/Startup.cs | 2 +- AutoModerationPlugin/AutoModerationPlugin.cs | 4 +- .../EntryCarAutoModeration.cs | 18 ++--- DiscordAuditPlugin/Discord.cs | 10 +-- FastTravelPlugin/FastTravelPlugin.cs | 2 +- GeoIPPlugin/GeoIP.cs | 2 +- RaceChallengePlugin/EntryCarRace.cs | 2 +- RaceChallengePlugin/RaceCommandModule.cs | 2 +- ReplayPlugin/ReplayCommandModule.cs | 2 +- ReplayPlugin/ReplayPlugin.cs | 2 +- ReportPlugin/AuditLog.cs | 2 +- ReportPlugin/ReportPlugin.cs | 14 ++-- TagModePlugin/TagModeCommandModule.cs | 2 +- TagModePlugin/TagModePlugin.cs | 6 +- VotingPresetPlugin/VotingPresetPlugin.cs | 2 +- VotingWeatherPlugin/VotingWeather.cs | 4 +- WordFilterPlugin/WordFilter.cs | 4 +- 64 files changed, 311 insertions(+), 242 deletions(-) rename {AssettoServer/Network/Tcp => AssettoServer.Shared/Model}/ChecksumStatus.cs (63%) rename AssettoServer/Network/Tcp/{ACTcpClient.cs => PlayerClient.cs} (94%) create mode 100644 AssettoServer/Network/Tcp/SpectatorClient.cs diff --git a/AssettoServer/Network/Tcp/ChecksumStatus.cs b/AssettoServer.Shared/Model/ChecksumStatus.cs similarity index 63% rename from AssettoServer/Network/Tcp/ChecksumStatus.cs rename to AssettoServer.Shared/Model/ChecksumStatus.cs index 40797dec..4b22ad35 100644 --- a/AssettoServer/Network/Tcp/ChecksumStatus.cs +++ b/AssettoServer.Shared/Model/ChecksumStatus.cs @@ -1,4 +1,4 @@ -namespace AssettoServer.Network.Tcp; +namespace AssettoServer.Shared.Model; public enum ChecksumStatus { diff --git a/AssettoServer.Shared/Model/IClient.cs b/AssettoServer.Shared/Model/IClient.cs index 2ed816ea..dee00f21 100644 --- a/AssettoServer.Shared/Model/IClient.cs +++ b/AssettoServer.Shared/Model/IClient.cs @@ -1,9 +1,41 @@ -namespace AssettoServer.Shared.Model; +using System.Numerics; +using AssettoServer.Shared.Network.Packets.Outgoing; +using Serilog; + +namespace AssettoServer.Shared.Model; public interface IClient { + public CarStatus Status { get; } + public byte SessionId { get; } public ulong Guid { get; } + public string HashedGuid { get; } public string? Name { get; } public string? Team { get; } public string? NationCode { get; } + + public bool IsAdministrator { get; } + public int SecurityLevel { get; } + public bool IsConnected { get; set; } + public ushort Ping { get; set; } + public int TimeOffset { get; set; } + public long LastPingTime { get; set; } + public long LastPongTime { get; set; } + public bool HasSentFirstUpdate { get; } + public bool HasUdpEndpoint { get; } + public bool IsDisconnectRequested { get; } + public ChecksumStatus ChecksumStatus { get; } + public int? CSPVersion { get; } + public bool SupportsCSPCustomUpdate { get; } + public IEntryCar EntryCar { get; } + public IEntryCar? TargetCar { get; set; } + + public ILogger Logger { get; } + + + public Task DisconnectAsync(); + public void SendFirstUpdate(); + public void SendPacket(TPacket packet) where TPacket : IOutgoingNetworkPacket; + public void SendPacketUdp(in TPacket packet) where TPacket : IOutgoingNetworkPacket; + public void SendTeleportCarPacket(Vector3 position, Vector3 direction, Vector3 velocity = default); } diff --git a/AssettoServer.Shared/Model/IEntryCar.cs b/AssettoServer.Shared/Model/IEntryCar.cs index b013700c..b0e7e86f 100644 --- a/AssettoServer.Shared/Model/IEntryCar.cs +++ b/AssettoServer.Shared/Model/IEntryCar.cs @@ -1,13 +1,34 @@ namespace AssettoServer.Shared.Model; -public interface IEntryCar where TClient : IClient +public interface IEntryCar { + public IClient? Client { get; set; } public byte SessionId { get; } - public bool IsSpectator { get; } public string Model { get; } public string Skin { get; } - public CarStatus Status { get; } - public TClient? Client { get; } + public bool IsSpectator { get; } + public float Ballast { get; set; } + public int Restrictor { get; set; } + public string? FixedSetup { get; } + public string LegalTyres { get; } + public bool ForceLights { get; set; } public bool AiControlled { get; } + public AiMode AiMode { get; set; } public string? AiName { get; } + + public bool IsInRange(IEntryCar target, float range); + public void Reset(); + public void SetActive(); + public void SetAiOverbooking(int count); + + public void SetCollisions(bool enable); + + public bool TryResetPosition(); +} + +public enum AiMode +{ + None, + Auto, + Fixed } diff --git a/AssettoServer.Shared/Network/Packets/Outgoing/CarListResponse.cs b/AssettoServer.Shared/Network/Packets/Outgoing/CarListResponse.cs index 5fe8bc0f..9e8d94f8 100644 --- a/AssettoServer.Shared/Network/Packets/Outgoing/CarListResponse.cs +++ b/AssettoServer.Shared/Network/Packets/Outgoing/CarListResponse.cs @@ -6,7 +6,7 @@ public class CarListResponse : IOutgoingNetworkPacket { public int PageIndex; public int EntryCarsCount; - public required IEnumerable> EntryCars; + public required IEnumerable EntryCars; public required Dictionary CarResults; public void ToWriter(ref PacketWriter writer) @@ -23,7 +23,7 @@ public void ToWriter(ref PacketWriter writer) writer.WriteUTF8String(CarResults[car.SessionId].Team); writer.WriteUTF8String(CarResults[car.SessionId].NationCode); writer.Write(car.IsSpectator); - writer.Write(car.Status.DamageZoneLevel); + writer.Write(car.Client?.Status.DamageZoneLevel ?? new DamageZoneLevel()); } } } diff --git a/AssettoServer.Shared/Network/Packets/Outgoing/CurrentSessionUpdate.cs b/AssettoServer.Shared/Network/Packets/Outgoing/CurrentSessionUpdate.cs index cd6622fa..989442c1 100644 --- a/AssettoServer.Shared/Network/Packets/Outgoing/CurrentSessionUpdate.cs +++ b/AssettoServer.Shared/Network/Packets/Outgoing/CurrentSessionUpdate.cs @@ -6,7 +6,7 @@ public class CurrentSessionUpdate : IOutgoingNetworkPacket { public Session? CurrentSession; public float TrackGrip; - public IEnumerable>? Grid; + public IEnumerable? Grid; public long StartTime; public void ToWriter(ref PacketWriter writer) diff --git a/AssettoServer.Shared/Network/Packets/Outgoing/DriverInfoUpdate.cs b/AssettoServer.Shared/Network/Packets/Outgoing/DriverInfoUpdate.cs index a761e52b..7727539e 100644 --- a/AssettoServer.Shared/Network/Packets/Outgoing/DriverInfoUpdate.cs +++ b/AssettoServer.Shared/Network/Packets/Outgoing/DriverInfoUpdate.cs @@ -4,7 +4,7 @@ namespace AssettoServer.Shared.Network.Packets.Outgoing; public class DriverInfoUpdate : IOutgoingNetworkPacket { - public required IEnumerable> ConnectedCars { get; init; } + public required IEnumerable ConnectedCars { get; init; } public void ToWriter(ref PacketWriter writer) { diff --git a/AssettoServer/Commands/ACModuleBase.cs b/AssettoServer/Commands/ACModuleBase.cs index c88039b5..05db86fb 100644 --- a/AssettoServer/Commands/ACModuleBase.cs +++ b/AssettoServer/Commands/ACModuleBase.cs @@ -8,7 +8,7 @@ namespace AssettoServer.Commands; [UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)] public class ACModuleBase : ModuleBase { - public ACTcpClient? Client => (Context as ChatCommandContext)?.Client; + public PlayerClient? Client => (Context as ChatCommandContext)?.Client; public void Reply(string message) => Context.Reply(message); diff --git a/AssettoServer/Commands/ChatService.cs b/AssettoServer/Commands/ChatService.cs index 79fd26f9..bcd9f649 100644 --- a/AssettoServer/Commands/ChatService.cs +++ b/AssettoServer/Commands/ChatService.cs @@ -19,13 +19,13 @@ namespace AssettoServer.Commands; public partial class ChatService { private readonly EntryCarManager _entryCarManager; - private readonly Func _chatContextFactory; + private readonly Func _chatContextFactory; private readonly CommandService _commandService; - public event EventHandler? MessageReceived; + public event EventHandler? MessageReceived; public ChatService(ACPluginLoader loader, - Func chatContextFactory, + Func chatContextFactory, ACClientTypeParser acClientTypeParser, EntryCarManager entryCarManager, CommandService commandService) @@ -45,12 +45,12 @@ public ChatService(ACPluginLoader loader, } } - private void OnClientConnected(ACTcpClient sender, EventArgs args) + private void OnClientConnected(PlayerClient sender, EventArgs args) { sender.ChatMessageReceived += OnChatMessageReceived; } - private async Task ProcessCommandAsync(ACTcpClient client, ChatMessage message) + private async Task ProcessCommandAsync(PlayerClient client, ChatMessage message) => await ProcessCommandAsync(_chatContextFactory(client), message.Message); public async Task ProcessCommandAsync(BaseCommandContext context, string command) @@ -74,7 +74,7 @@ private ValueTask OnCommandExecutionFailed(object? sender, CommandExecutionFaile return ValueTask.CompletedTask; } - private void OnChatMessageReceived(ACTcpClient sender, ChatMessageEventArgs args) + private void OnChatMessageReceived(PlayerClient sender, ChatMessageEventArgs args) { if (!CommandUtilities.HasPrefix(args.ChatMessage.Message, '/', out string commandStr)) { diff --git a/AssettoServer/Commands/Contexts/ChatCommandContext.cs b/AssettoServer/Commands/Contexts/ChatCommandContext.cs index 219c34b5..92325bff 100644 --- a/AssettoServer/Commands/Contexts/ChatCommandContext.cs +++ b/AssettoServer/Commands/Contexts/ChatCommandContext.cs @@ -6,12 +6,12 @@ namespace AssettoServer.Commands.Contexts; public class ChatCommandContext( - ACTcpClient client, + PlayerClient client, EntryCarManager entryEntryCarManager, IServiceProvider? serviceProvider = null) : BaseCommandContext(entryEntryCarManager, serviceProvider) { - public ACTcpClient Client { get; } = client; + public PlayerClient Client { get; } = client; public override bool IsAdministrator => Client.IsAdministrator; diff --git a/AssettoServer/Commands/Modules/AdminModule.cs b/AssettoServer/Commands/Modules/AdminModule.cs index 45870d3b..373a5385 100644 --- a/AssettoServer/Commands/Modules/AdminModule.cs +++ b/AssettoServer/Commands/Modules/AdminModule.cs @@ -46,7 +46,7 @@ public AdminModule(IWeatherImplementation weatherImplementation, } [Command("kick", "kick_id")] - public Task KickAsync(ACTcpClient player, [Remainder] string? reason = null) + public Task KickAsync(PlayerClient player, [Remainder] string? reason = null) { if (player.SessionId == Client?.SessionId) Reply("You cannot kick yourself."); @@ -62,7 +62,7 @@ public Task KickAsync(ACTcpClient player, [Remainder] string? reason = null) } [Command("ban", "ban_id")] - public Task BanAsync(ACTcpClient player, [Remainder] string? reason = null) + public Task BanAsync(PlayerClient player, [Remainder] string? reason = null) { if (player.SessionId == Client?.SessionId) Reply("You cannot ban yourself."); @@ -98,7 +98,7 @@ public void RestartSessionAsync() } [Command("pit")] - public void TeleportToPits([Remainder] ACTcpClient player) + public void TeleportToPits([Remainder] PlayerClient player) { _sessionManager.SendCurrentSession(player); player.SendChatMessage("You have been teleported to the pits."); @@ -183,13 +183,13 @@ public void SetGrip(float grip) } [Command("distance"), RequireConnectedPlayer] - public void GetDistance([Remainder] ACTcpClient player) + public void GetDistance([Remainder] PlayerClient player) { - Reply(Vector3.Distance(Client!.EntryCar.Status.Position, player.EntryCar.Status.Position).ToString(CultureInfo.InvariantCulture)); + Reply(Vector3.Distance(Client!.Status.Position, player.Status.Position).ToString(CultureInfo.InvariantCulture)); } [Command("forcelights")] - public void ForceLights(string toggle, [Remainder] ACTcpClient player) + public void ForceLights(string toggle, [Remainder] PlayerClient player) { bool forceLights = toggle == "on"; player.EntryCar.ForceLights = forceLights; @@ -198,11 +198,11 @@ public void ForceLights(string toggle, [Remainder] ACTcpClient player) } [Command("whois")] - public void WhoIs(ACTcpClient player) + public void WhoIs(PlayerClient player) { Reply($"IP: {((IPEndPoint?)player.TcpClient.Client.RemoteEndPoint)?.Redact(_configuration.Extra.RedactIpAddresses)}"); - Reply($"Profile: https://steamcommunity.com/profiles/{player.Guid}\nPing: {player.EntryCar.Ping}ms"); - Reply($"Position: {player.EntryCar.Status.Position}\nVelocity: {(int)(player.EntryCar.Status.Velocity.Length() * 3.6)}kmh"); + Reply($"Profile: https://steamcommunity.com/profiles/{player.Guid}\nPing: {player.Ping}ms"); + Reply($"Position: {player.Status.Position}\nVelocity: {(int)(player.Status.Velocity.Length() * 3.6)}kmh"); if (player.OwnerGuid.HasValue && player.Guid != player.OwnerGuid) { Reply($"Steam Family Sharing Owner: https://steamcommunity.com/profiles/{player.OwnerGuid}"); @@ -211,7 +211,7 @@ public void WhoIs(ACTcpClient player) // keep restrict for backwards compatibility [Command("restrict", "restrictor")] - public void Restrict(ACTcpClient player, int restrictor) + public void Restrict(PlayerClient player, int restrictor) { if (restrictor is > 400 or < 0) { @@ -225,7 +225,7 @@ public void Restrict(ACTcpClient player, int restrictor) } [Command("ballast")] - public void Ballast(ACTcpClient? player = null, float? ballastKg = null) + public void Ballast(PlayerClient? player = null, float? ballastKg = null) { if (player == null || ballastKg == null) { diff --git a/AssettoServer/Commands/Modules/GeneralModule.cs b/AssettoServer/Commands/Modules/GeneralModule.cs index d2991786..8ddd1368 100644 --- a/AssettoServer/Commands/Modules/GeneralModule.cs +++ b/AssettoServer/Commands/Modules/GeneralModule.cs @@ -30,7 +30,7 @@ public GeneralModule(WeatherManager weatherManager, [Command("ping"), RequireConnectedPlayer] public void Ping() - => Reply($"Pong! {Client!.EntryCar.Ping}ms."); + => Reply($"Pong! {Client!.Ping}ms."); [Command("time")] public void Time() diff --git a/AssettoServer/Commands/TypeParsers/ACClientTypeParser.cs b/AssettoServer/Commands/TypeParsers/ACClientTypeParser.cs index 2a8a77a4..c45fd167 100644 --- a/AssettoServer/Commands/TypeParsers/ACClientTypeParser.cs +++ b/AssettoServer/Commands/TypeParsers/ACClientTypeParser.cs @@ -7,7 +7,7 @@ namespace AssettoServer.Commands.TypeParsers; -public class ACClientTypeParser : TypeParser +public class ACClientTypeParser : TypeParser { private readonly EntryCarManager _entryCarManager; @@ -16,33 +16,34 @@ public ACClientTypeParser(EntryCarManager entryCarManager) _entryCarManager = entryCarManager; } - public override ValueTask> ParseAsync(Parameter parameter, string value, CommandContext context) + public override ValueTask> ParseAsync(Parameter parameter, string value, CommandContext context) { if (int.TryParse(value, out int result) && _entryCarManager.ConnectedCars.TryGetValue(result, out EntryCar? car) - && car.Client != null) + && car.Client is PlayerClient carClient) { - return TypeParserResult.Successful(car.Client); + return TypeParserResult.Successful(carClient); } if (ulong.TryParse(value, out ulong guid) - && _entryCarManager.ConnectedCars.FirstOrDefault(x => x.Value.Client?.Guid == guid) is { Value.Client: not null } guidCar) + && _entryCarManager.ConnectedCars.FirstOrDefault(x => x.Value.Client?.Guid == guid) is { Value.Client: not null } guidCar + && guidCar.Value.Client is PlayerClient guidCarClient) { - return TypeParserResult.Successful(guidCar.Value.Client); + return TypeParserResult.Successful(guidCarClient); } - ACTcpClient? exactMatch = null; - ACTcpClient? ignoreCaseMatch = null; - ACTcpClient? containsMatch = null; - ACTcpClient? ignoreCaseContainsMatch = null; + PlayerClient? exactMatch = null; + PlayerClient? ignoreCaseMatch = null; + PlayerClient? containsMatch = null; + PlayerClient? ignoreCaseContainsMatch = null; if (value.StartsWith('@')) value = value[1..]; foreach (EntryCar entryCar in _entryCarManager.EntryCars) { - ACTcpClient? client = entryCar.Client; - if (client != null && client.Name != null) + if (entryCar.Client is not PlayerClient client) continue; + if (client.Name != null) { if (client.Name == value) { @@ -58,7 +59,7 @@ public override ValueTask> ParseAsync(Parameter pa } } - ACTcpClient? bestMatch = null; + PlayerClient? bestMatch = null; if (exactMatch != null) bestMatch = exactMatch; else if (ignoreCaseMatch != null) @@ -69,8 +70,8 @@ public override ValueTask> ParseAsync(Parameter pa bestMatch = ignoreCaseContainsMatch; if (bestMatch != null) - return TypeParserResult.Successful(bestMatch); + return TypeParserResult.Successful(bestMatch); - return ValueTask.FromResult(TypeParserResult.Failed("This player is not connected.")); + return ValueTask.FromResult(TypeParserResult.Failed("This player is not connected.")); } } diff --git a/AssettoServer/Network/CSPClientMessageHandler.cs b/AssettoServer/Network/CSPClientMessageHandler.cs index bd60926a..0621d76d 100644 --- a/AssettoServer/Network/CSPClientMessageHandler.cs +++ b/AssettoServer/Network/CSPClientMessageHandler.cs @@ -30,7 +30,7 @@ public CSPClientMessageHandler(CSPClientMessageTypeManager cspClientMessageTypeM cspClientMessageTypeManager.RegisterOnlineEvent(OnLuaReady); } - public void OnCSPClientMessageUdp(ACTcpClient sender, PacketReader reader) + public void OnCSPClientMessageUdp(PlayerClient sender, PacketReader reader) { var packetType = reader.Read(); switch (packetType) @@ -70,7 +70,7 @@ public void OnCSPClientMessageUdp(ACTcpClient sender, PacketReader reader) } } - public void OnCSPClientMessageTcp(ACTcpClient sender, PacketReader reader) + public void OnCSPClientMessageTcp(PlayerClient sender, PacketReader reader) { var packetType = reader.Read(); @@ -118,7 +118,7 @@ public void OnCSPClientMessageTcp(ACTcpClient sender, PacketReader reader) } } - private void OnLuaMessage(ACTcpClient sender, PacketReader reader, CSPClientMessageType type, bool udp) + private void OnLuaMessage(PlayerClient sender, PacketReader reader, CSPClientMessageType type, bool udp) { float? range = IsRanged(type) ? (float)reader.Read() : null; byte? sessionId = IsTargeted(type) ? reader.Read() : null; @@ -172,7 +172,7 @@ private void OnLuaMessage(ACTcpClient sender, PacketReader reader, CSPClientMess } } - private static void OnHandshakeOut(ACTcpClient sender, PacketReader reader) + private static void OnHandshakeOut(PlayerClient sender, PacketReader reader) { var packet = reader.ReadPacket(); sender.InputMethod = packet.InputMethod; @@ -181,7 +181,7 @@ private static void OnHandshakeOut(ACTcpClient sender, PacketReader reader) sender.Name, sender.SessionId, packet.Version, packet.IsWeatherFxActive, packet.InputMethod, packet.IsRainFxActive, packet.UniqueKey); } - private void OnAdminPenaltyOut(ACTcpClient sender, PacketReader reader) + private void OnAdminPenaltyOut(PlayerClient sender, PacketReader reader) { if (sender.IsAdministrator) @@ -201,13 +201,13 @@ private void OnAdminPenaltyOut(ACTcpClient sender, PacketReader reader) } } - private void OnResetCar(ACTcpClient sender, RequestResetPacket packet) + private void OnResetCar(PlayerClient sender, RequestResetPacket packet) { if (!_configuration.Extra.EnableCarReset) return; sender.EntryCar.TryResetPosition(); } - private void OnLuaReady(ACTcpClient sender, LuaReadyPacket packet) + private void OnLuaReady(PlayerClient sender, LuaReadyPacket packet) { sender.FireLuaReady(); } diff --git a/AssettoServer/Network/Http/Authentication/ACClientAuthenticationHandler.cs b/AssettoServer/Network/Http/Authentication/ACClientAuthenticationHandler.cs index da6eacb2..c85c039d 100644 --- a/AssettoServer/Network/Http/Authentication/ACClientAuthenticationHandler.cs +++ b/AssettoServer/Network/Http/Authentication/ACClientAuthenticationHandler.cs @@ -2,6 +2,7 @@ using System.Security.Claims; using System.Text.Encodings.Web; using System.Threading.Tasks; +using AssettoServer.Network.Tcp; using AssettoServer.Server; using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging; @@ -35,10 +36,8 @@ protected override Task HandleAuthenticateAsync() } var apiKey = apiKeyHdr.ToString(); - if (_entryCarManager.EntryCars[carId].Client?.ApiKey == apiKey) + if (_entryCarManager.EntryCars[carId].Client is PlayerClient client && client.ApiKey == apiKey) { - var client = _entryCarManager.EntryCars[carId].Client!; - var claims = new List { new(ClaimTypes.NameIdentifier, client.Guid.ToString()), diff --git a/AssettoServer/Network/Http/Authentication/ACClientClaimsIdentity.cs b/AssettoServer/Network/Http/Authentication/ACClientClaimsIdentity.cs index f660f0d1..a780c5be 100644 --- a/AssettoServer/Network/Http/Authentication/ACClientClaimsIdentity.cs +++ b/AssettoServer/Network/Http/Authentication/ACClientClaimsIdentity.cs @@ -6,7 +6,7 @@ namespace AssettoServer.Network.Http.Authentication; public class ACClientClaimsIdentity : ClaimsIdentity { - public required ACTcpClient Client { get; init; } + public required PlayerClient Client { get; init; } public ACClientClaimsIdentity(IEnumerable? claims, string? authenticationType) : base(claims, authenticationType) { diff --git a/AssettoServer/Network/Tcp/ACTcpServer.cs b/AssettoServer/Network/Tcp/ACTcpServer.cs index 4c7fc863..12d15fdc 100644 --- a/AssettoServer/Network/Tcp/ACTcpServer.cs +++ b/AssettoServer/Network/Tcp/ACTcpServer.cs @@ -12,9 +12,9 @@ namespace AssettoServer.Network.Tcp; public class ACTcpServer : BackgroundService { private readonly ACServerConfiguration _configuration; - private readonly Func _acTcpClientFactory; + private readonly Func _acTcpClientFactory; - public ACTcpServer(Func acTcpClientFactory, ACServerConfiguration configuration) + public ACTcpServer(Func acTcpClientFactory, ACServerConfiguration configuration) { _acTcpClientFactory = acTcpClientFactory; _configuration = configuration; @@ -32,7 +32,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { TcpClient tcpClient = await listener.AcceptTcpClientAsync(stoppingToken); - ACTcpClient acClient = _acTcpClientFactory(tcpClient); + PlayerClient acClient = _acTcpClientFactory(tcpClient); await acClient.StartAsync(); } catch (OperationCanceledException) { } diff --git a/AssettoServer/Network/Tcp/ACTcpClient.cs b/AssettoServer/Network/Tcp/PlayerClient.cs similarity index 94% rename from AssettoServer/Network/Tcp/ACTcpClient.cs rename to AssettoServer/Network/Tcp/PlayerClient.cs index ee76e4cf..3afb6267 100644 --- a/AssettoServer/Network/Tcp/ACTcpClient.cs +++ b/AssettoServer/Network/Tcp/PlayerClient.cs @@ -33,8 +33,9 @@ namespace AssettoServer.Network.Tcp; -public class ACTcpClient : IClient +public class PlayerClient : IClient { + public CarStatus Status { get; internal set; } private ACUdpServer UdpServer { get; } public ILogger Logger { get; } public byte SessionId { get; set; } @@ -45,10 +46,14 @@ public class ACTcpClient : IClient public ulong Guid { get; internal set; } public string HashedGuid { get; private set; } = ""; public ulong? OwnerGuid { get; internal set; } - public EntryCar EntryCar { get; internal set; } = null!; + public IEntryCar EntryCar { get; internal set; } = null!; public bool IsDisconnectRequested => _disconnectRequested == 1; [MemberNotNullWhen(true, nameof(Name), nameof(Team), nameof(NationCode))] public bool HasSentFirstUpdate { get; private set; } + public ushort Ping { get; set; } + public int TimeOffset { get; set; } + public long LastPingTime { get; set; } + public long LastPongTime { get; set; } public bool IsConnected { get; set; } public TcpClient TcpClient { get; } @@ -66,7 +71,7 @@ public class ACTcpClient : IClient public bool SupportsCSPCustomUpdate { get; private set; } public int? CSPVersion { get; private set; } internal string ApiKey { get; } - public EntryCar? TargetCar { get; set; } + public IEntryCar? TargetCar { get; set; } private static ThreadLocal UdpSendBuffer { get; } = new(() => GC.AllocateArray(1500, true)); private byte[] TcpSendBuffer { get; } @@ -91,89 +96,89 @@ public class ACTcpClient : IClient /// /// Fires when a client passed the checksum checks. This does not mean that the player has finished loading, use ClientFirstUpdateSent for that. /// - public event EventHandler? ChecksumPassed; + public event EventHandler? ChecksumPassed; /// /// Fires when a client failed the checksum check. /// - public event EventHandler? ChecksumFailed; + public event EventHandler? ChecksumFailed; /// /// Fires when a client has sent a chat message. Set ChatEventArgs.Cancel = true to stop it from being broadcast to other players. /// - public event EventHandler? ChatMessageReceived; + public event EventHandler? ChatMessageReceived; /// /// Fires when a player has started disconnecting. /// - public event EventHandler? Disconnecting; + public event EventHandler? Disconnecting; /// /// Fires when a slot has been secured for a player and the handshake response is about to be sent. /// - public event EventHandler? HandshakeAccepted; + public event EventHandler? HandshakeAccepted; /// /// Fires when a client has sent the first position update and is visible to other players. /// - public event EventHandler? FirstUpdateSent; + public event EventHandler? FirstUpdateSent; /// /// Fires when a client collided with something. TargetCar will be null for environment collisions. /// There are up to 5 seconds delay before a collision is reported to the server. /// - public event EventHandler? Collision; + public event EventHandler? Collision; /// /// Fires when a client has changed tyre compound /// - public event EventHandler? TyreCompoundChange; + public event EventHandler? TyreCompoundChange; /// /// Fires when a client has received damage /// - public event EventHandler? Damage; + public event EventHandler? Damage; /// /// Fires when a client has used P2P /// - public event EventHandler? Push2Pass; + public event EventHandler? Push2Pass; /// /// Fires when a client received a penalty. /// - public event EventHandler? JumpStartPenalty; + public event EventHandler? JumpStartPenalty; /// /// Fires when a client has completed a lap /// - public event EventHandler? LapCompleted; + public event EventHandler? LapCompleted; /// /// Fires when a client has completed a sector /// - public event EventHandler? SectorSplit; + public event EventHandler? SectorSplit; /// /// Fires before sending the car list response /// - public event EventHandler? CarListResponseSending; + public event EventHandler? CarListResponseSending; /// /// Fires when a player has authorized for admin permissions. /// - public event EventHandler? LoggedInAsAdministrator; + public event EventHandler? LoggedInAsAdministrator; /// /// Called when all Lua server scripts are loaded on the client. Warning: This can be called multiple times if scripts are reloaded! /// - public event EventHandler? LuaReady; + public event EventHandler? LuaReady; private class ACTcpClientLogEventEnricher : ILogEventEnricher { - private readonly ACTcpClient _client; + private readonly PlayerClient _client; - public ACTcpClientLogEventEnricher(ACTcpClient client) + public ACTcpClientLogEventEnricher(PlayerClient client) { _client = client; } @@ -192,7 +197,7 @@ public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) } } - public ACTcpClient( + public PlayerClient( ACUdpServer udpServer, TcpClient tcpClient, SessionManager sessionManager, @@ -242,7 +247,7 @@ public ACTcpClient( LuaReady += OnLuaReady; } - private void OnLuaReady(ACTcpClient sender, EventArgs args) + private void OnLuaReady(PlayerClient sender, EventArgs args) { SendPacket(new ApiKeyPacket { Key = ApiKey }); @@ -702,7 +707,7 @@ private void OnChat(PacketReader reader) private void OnDamageUpdate(PacketReader reader) { DamageUpdateIncoming damageUpdate = reader.ReadPacket(); - EntryCar.Status.DamageZoneLevel = damageUpdate.DamageZoneLevel; + Status.DamageZoneLevel = damageUpdate.DamageZoneLevel; var update = new DamageUpdate { @@ -717,7 +722,7 @@ private void OnDamageUpdate(PacketReader reader) private void OnTyreCompoundChange(PacketReader reader) { TyreCompoundChangeRequest compoundChangeRequest = reader.ReadPacket(); - EntryCar.Status.CurrentTyreCompound = compoundChangeRequest.CompoundName; + Status.CurrentTyreCompound = compoundChangeRequest.CompoundName; var update = new TyreCompoundUpdate { @@ -732,7 +737,7 @@ private void OnTyreCompoundChange(PacketReader reader) private void OnMandatoryPitUpdate(PacketReader reader) { MandatoryPitRequest mandatoryPitRequest = reader.ReadPacket(); - EntryCar.Status.MandatoryPit = mandatoryPitRequest.MandatoryPit; + Status.MandatoryPit = mandatoryPitRequest.MandatoryPit; _entryCarManager.BroadcastPacket(new MandatoryPitUpdate { @@ -773,19 +778,19 @@ private void OnP2PUpdate(PacketReader reader) { SendPacket(new P2PUpdate { - P2PCount = EntryCar.Status.P2PCount, + P2PCount = Status.P2PCount, SessionId = SessionId }); } else { - if (!_configuration.Extra.EnableUnlimitedP2P && EntryCar.Status.P2PCount > 0) - EntryCar.Status.P2PCount--; + if (!_configuration.Extra.EnableUnlimitedP2P && Status.P2PCount > 0) + Status.P2PCount--; var update = new P2PUpdate { Active = push2Pass.Active, - P2PCount = EntryCar.Status.P2PCount, + P2PCount = Status.P2PCount, SessionId = SessionId }; @@ -840,13 +845,13 @@ private void OnLapCompletedMessageReceived(PacketReader reader) } } - internal void SendFirstUpdate() + public void SendFirstUpdate() { if (HasSentFirstUpdate) return; TcpClient.ReceiveTimeout = 0; - EntryCar.LastPongTime = _sessionManager.ServerTimeMilliseconds; + LastPongTime = _sessionManager.ServerTimeMilliseconds; HasSentFirstUpdate = true; _ = Task.Run(SendFirstUpdateAsync); @@ -970,7 +975,7 @@ internal bool TryAssociateUdp(SocketAddress endpoint) return true; } - internal async Task DisconnectAsync() + public async Task DisconnectAsync() { try { diff --git a/AssettoServer/Network/Tcp/SpectatorClient.cs b/AssettoServer/Network/Tcp/SpectatorClient.cs new file mode 100644 index 00000000..30678767 --- /dev/null +++ b/AssettoServer/Network/Tcp/SpectatorClient.cs @@ -0,0 +1,8 @@ +using AssettoServer.Shared.Model; + +namespace AssettoServer.Network.Tcp; + +public class SpectatorClient : IClient +{ + +} diff --git a/AssettoServer/Network/Udp/ACUdpServer.cs b/AssettoServer/Network/Udp/ACUdpServer.cs index 9a4985df..aa447b92 100644 --- a/AssettoServer/Network/Udp/ACUdpServer.cs +++ b/AssettoServer/Network/Udp/ACUdpServer.cs @@ -151,9 +151,9 @@ private void OnReceived(SocketAddress address, byte[] buffer, int size) else if (packetId == ACServerProtocol.PingPong) { long currentTime = _sessionManager.ServerTimeMilliseconds; - car.Ping = (ushort)(currentTime - packetReader.Read()); - car.TimeOffset = (int)currentTime - ((car.Ping / 2) + packetReader.Read()); - car.LastPongTime = currentTime; + client.Ping = (ushort)(currentTime - packetReader.Read()); + client.TimeOffset = (int)currentTime - ((client.Ping / 2) + packetReader.Read()); + client.LastPongTime = currentTime; } else if (_configuration.Extra.EnableUdpClientMessages && packetId == ACServerProtocol.Extended) { @@ -171,7 +171,7 @@ private void OnReceived(SocketAddress address, byte[] buffer, int size) } } - private void OnClientDisconnecting(ACTcpClient sender, EventArgs args) + private void OnClientDisconnecting(PlayerClient sender, EventArgs args) { if (sender.UdpEndpoint != null) { diff --git a/AssettoServer/Network/Udp/UdpPluginServer.cs b/AssettoServer/Network/Udp/UdpPluginServer.cs index eb27755d..3857c6e9 100644 --- a/AssettoServer/Network/Udp/UdpPluginServer.cs +++ b/AssettoServer/Network/Udp/UdpPluginServer.cs @@ -290,9 +290,10 @@ private void OnReceived(byte[] buffer, int size) case UdpPluginProtocol.KickUser: { byte sessionId = packetReader.Read(); - if (_entryCarManager.ConnectedCars.TryGetValue(sessionId, out EntryCar? car)) + if (_entryCarManager.ConnectedCars.TryGetValue(sessionId, out EntryCar? car) && + car.Client is PlayerClient playerClient) { - _ = Task.Run(() => _entryCarManager.KickAsync(car.Client, "You have been kicked.")); + _ = Task.Run(() => _entryCarManager.KickAsync(playerClient, "You have been kicked.")); } else { @@ -382,12 +383,12 @@ private void SendSessionInfo(short sessionId, bool isNew) }); } - private void OnClientFirstUpdate(ACTcpClient sender, EventArgs args) + private void OnClientFirstUpdate(PlayerClient sender, EventArgs args) { SendPacket(new ClientFirstUpdate{ SessionId = sender.SessionId }); } - private void OnClientDisconnected(ACTcpClient client, EventArgs args) + private void OnClientDisconnected(PlayerClient client, EventArgs args) { SendPacket(new CarDisconnected { @@ -399,7 +400,7 @@ private void OnClientDisconnected(ACTcpClient client, EventArgs args) }); } - private void OnClientConnected(ACTcpClient client, EventArgs args) + private void OnClientConnected(PlayerClient client, EventArgs args) { client.FirstUpdateSent += OnClientFirstUpdate; client.LapCompleted += OnLapCompleted; @@ -415,7 +416,7 @@ private void OnClientConnected(ACTcpClient client, EventArgs args) }); } - private void OnClientEvent(ACTcpClient sender, CollisionEventArgs args) + private void OnClientEvent(PlayerClient sender, CollisionEventArgs args) { SendPacket(new ClientEvent { @@ -428,7 +429,7 @@ private void OnClientEvent(ACTcpClient sender, CollisionEventArgs args) }); } - private void OnLapCompleted(ACTcpClient sender, LapCompletedEventArgs args) + private void OnLapCompleted(PlayerClient sender, LapCompletedEventArgs args) { SendPacket(args.Packet); } diff --git a/AssettoServer/Server/ACServer.cs b/AssettoServer/Server/ACServer.cs index 36a1d8ed..b834c14b 100644 --- a/AssettoServer/Server/ACServer.cs +++ b/AssettoServer/Server/ACServer.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using System.Collections.Generic; using System.Reflection; +using AssettoServer.Network.Tcp; using AssettoServer.Server.Configuration; using AssettoServer.Server.Ai.Splines; using AssettoServer.Server.Blacklist; @@ -133,9 +134,9 @@ private void OnWhitelistChanged(IWhitelistService sender, EventArgs args) { foreach (var client in _entryCarManager.ConnectedCars.Values.Select(c => c.Client)) { - if (client != null && !await sender.IsWhitelistedAsync(client.Guid)) + if (client is PlayerClient playerClient && !await sender.IsWhitelistedAsync(playerClient.Guid)) { - _ = _entryCarManager.KickAsync(client, "not being whitelisted"); + _ = _entryCarManager.KickAsync(playerClient, "not being whitelisted"); } } }); @@ -171,12 +172,12 @@ private void MainLoop(CancellationToken stoppingToken) { var fromCar = _entryCarManager.EntryCars[i]; var fromClient = fromCar.Client; - if (fromClient != null && fromClient.HasSentFirstUpdate && (_sessionManager.ServerTimeMilliseconds - fromCar.LastPingTime) > 1000) + if (fromClient != null && fromClient.HasSentFirstUpdate && (_sessionManager.ServerTimeMilliseconds - fromClient.LastPingTime) > 1000) { - fromCar.LastPingTime = _sessionManager.ServerTimeMilliseconds; - fromClient.SendPacketUdp(new PingUpdate((uint)fromCar.LastPingTime, fromCar.Ping)); + fromClient.LastPingTime = _sessionManager.ServerTimeMilliseconds; + fromClient.SendPacketUdp(new PingUpdate((uint)fromClient.LastPingTime, fromClient.Ping)); - if (_sessionManager.ServerTimeMilliseconds - fromCar.LastPongTime > 15000) + if (_sessionManager.ServerTimeMilliseconds - fromClient.LastPongTime > 15000) { fromClient.Logger.Information("{ClientName} has not sent a ping response for over 15 seconds", fromClient.Name); _ = fromClient.DisconnectAsync(); @@ -192,7 +193,7 @@ private void MainLoop(CancellationToken stoppingToken) var toCar = _entryCarManager.EntryCars[j]; var toClient = toCar.Client; if (toCar == fromCar - || toClient == null || !toClient.HasSentFirstUpdate || toClient.UdpEndpoint == null + || toClient == null || !toClient.HasSentFirstUpdate || !toClient.HasUdpEndpoint || !fromCar.GetPositionUpdateForCar(toCar, out var update)) continue; if (toClient.SupportsCSPCustomUpdate || fromCar.AiControlled) @@ -224,7 +225,7 @@ private void MainLoop(CancellationToken stoppingToken) } else { - var packet = new BatchedPositionUpdate((uint)(_sessionManager.ServerTimeMilliseconds - toCar.TimeOffset), toCar.Ping, + var packet = new BatchedPositionUpdate((uint)(_sessionManager.ServerTimeMilliseconds - toClient.TimeOffset), toClient.Ping, new ArraySegment(updates.Array, i, Math.Min(chunkSize, updates.Count - i))); toClient.SendPacketUdp(in packet); } diff --git a/AssettoServer/Server/Ai/AiBehavior.cs b/AssettoServer/Server/Ai/AiBehavior.cs index 9241fdd6..e280dd21 100644 --- a/AssettoServer/Server/Ai/AiBehavior.cs +++ b/AssettoServer/Server/Ai/AiBehavior.cs @@ -9,6 +9,7 @@ using AssettoServer.Network.Tcp; using AssettoServer.Server.Ai.Splines; using AssettoServer.Server.Configuration; +using AssettoServer.Shared.Model; using AssettoServer.Shared.Network.Packets.Outgoing; using AssettoServer.Utils; using Microsoft.Extensions.Hosting; @@ -67,19 +68,19 @@ public AiBehavior(SessionManager sessionManager, _sessionManager.SessionChanged += OnSessionChanged; } - private static void OnCollision(ACTcpClient sender, CollisionEventArgs args) + private static void OnCollision(PlayerClient sender, CollisionEventArgs args) { if (args.TargetCar?.AiControlled == true) { - var targetAiState = args.TargetCar.GetClosestAiState(sender.EntryCar.Status.Position); - if (targetAiState.AiState != null && targetAiState.DistanceSquared < 25 * 25) + var targetAiState = args.TargetCar.GetClosestAiState(sender.Status.Position); + if (targetAiState is { AiState: not null, DistanceSquared: < 25 * 25 }) { Task.Delay(Random.Shared.Next(100, 500)).ContinueWith(_ => targetAiState.AiState.StopForCollision()); } } } - private void OnClientChecksumPassed(ACTcpClient sender, EventArgs args) + private void OnClientChecksumPassed(PlayerClient sender, EventArgs args) { sender.EntryCar.SetAiControl(false); AdjustOverbooking(); @@ -344,7 +345,7 @@ private async Task UpdateAsync(CancellationToken stoppingToken) } } - private void OnClientDisconnected(ACTcpClient sender, EventArgs args) + private void OnClientDisconnected(PlayerClient sender, EventArgs args) { if (sender.EntryCar.AiMode != AiMode.None) { diff --git a/AssettoServer/Server/CSPClientMessageTypeManager.cs b/AssettoServer/Server/CSPClientMessageTypeManager.cs index 5c518741..b7a5ae0f 100644 --- a/AssettoServer/Server/CSPClientMessageTypeManager.cs +++ b/AssettoServer/Server/CSPClientMessageTypeManager.cs @@ -9,23 +9,23 @@ namespace AssettoServer.Server; public class CSPClientMessageTypeManager { - internal IReadOnlyDictionary> MessageTypes => _types; - internal IReadOnlyDictionary> RawMessageTypes => _rawTypes; + internal IReadOnlyDictionary> MessageTypes => _types; + internal IReadOnlyDictionary> RawMessageTypes => _rawTypes; - private readonly Dictionary> _types = new(); - private readonly Dictionary> _rawTypes = new(); + private readonly Dictionary> _types = new(); + private readonly Dictionary> _rawTypes = new(); - public void RegisterClientMessageType(uint type, Action handler) + public void RegisterClientMessageType(uint type, Action handler) { _types.Add(type, handler); } - public void RegisterRawClientMessageType(CSPClientMessageType type, Action handler) + public void RegisterRawClientMessageType(CSPClientMessageType type, Action handler) { _rawTypes.Add(type, handler); } - public void RegisterOnlineEvent(Action handler) where TEvent : OnlineEvent, new() + public void RegisterOnlineEvent(Action handler) where TEvent : OnlineEvent, new() { _types.Add(OnlineEvent.PacketType, (sender, reader) => { diff --git a/AssettoServer/Server/CSPServerScriptProvider.cs b/AssettoServer/Server/CSPServerScriptProvider.cs index 93cff053..cac618de 100644 --- a/AssettoServer/Server/CSPServerScriptProvider.cs +++ b/AssettoServer/Server/CSPServerScriptProvider.cs @@ -38,7 +38,7 @@ public CSPServerScriptProvider(CSPServerExtraOptions cspServerExtraOptions, extraOptions.CSPServerExtraOptionsSending += OnExtraOptionsSending; } - private async void OnExtraOptionsSending(ACTcpClient sender, CSPServerExtraOptionsSendingEventArgs args) + private async void OnExtraOptionsSending(PlayerClient sender, CSPServerExtraOptionsSendingEventArgs args) { using var _ = args.GetDeferral(); if (_debugUserGroup != null && await _debugUserGroup.ContainsAsync(sender.Guid)) diff --git a/AssettoServer/Server/Configuration/CSPServerExtraOptions.cs b/AssettoServer/Server/Configuration/CSPServerExtraOptions.cs index f4223342..380f6216 100644 --- a/AssettoServer/Server/Configuration/CSPServerExtraOptions.cs +++ b/AssettoServer/Server/Configuration/CSPServerExtraOptions.cs @@ -13,10 +13,10 @@ public class CSPServerExtraOptions { private readonly ACServerConfiguration _configuration; - public event EventHandler? WelcomeMessageSending; - public event EventHandler? CSPServerExtraOptionsSending; + public event EventHandler? WelcomeMessageSending; + public event EventHandler? CSPServerExtraOptionsSending; - public event EventHandler? WelcomeMessageSent; + public event EventHandler? WelcomeMessageSent; public string WelcomeMessage { get; set; } public string ExtraOptions { get; set; } @@ -42,7 +42,7 @@ public CSPServerExtraOptions(ACServerConfiguration configuration) } } - internal async Task GenerateWelcomeMessageAsync(ACTcpClient client) + internal async Task GenerateWelcomeMessageAsync(PlayerClient client) { var sb = new StringBuilder(); sb.Append(WelcomeMessage); diff --git a/AssettoServer/Server/Configuration/Kunos/EntryList.cs b/AssettoServer/Server/Configuration/Kunos/EntryList.cs index 74bdaf3a..f8933351 100644 --- a/AssettoServer/Server/Configuration/Kunos/EntryList.cs +++ b/AssettoServer/Server/Configuration/Kunos/EntryList.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using AssettoServer.Shared.Model; using AssettoServer.Utils; using IniParser; using IniParser.Model; diff --git a/AssettoServer/Server/EntryCar.cs b/AssettoServer/Server/EntryCar.cs index 26dd13ce..5eeee966 100644 --- a/AssettoServer/Server/EntryCar.cs +++ b/AssettoServer/Server/EntryCar.cs @@ -17,22 +17,18 @@ namespace AssettoServer.Server; -public partial class EntryCar : IEntryCar +public partial class EntryCar : IEntryCar { - public ACTcpClient? Client { get; internal set; } - public CarStatus Status { get; private set; } = new(); + public IClient? Client { get; set; } + public CarStatus Status { get; private set; } = new(); // TODO YET THIS SHIT public bool EnableCollisions { get; private set; } = true; - public bool ForceLights { get; internal set; } + public bool ForceLights { get; set; } public long LastActiveTime { get; internal set; } public bool HasUpdateToSend { get; internal set; } - public int TimeOffset { get; internal set; } public byte SessionId { get; } public uint LastRemoteTimestamp { get; internal set; } - public long LastPingTime { get; internal set; } - public long LastPongTime { get; internal set; } - public ushort Ping { get; internal set; } public DriverOptionsFlags DriverOptionsFlags { get; internal set; } public string LegalTyres { get; set; } = ""; @@ -40,8 +36,8 @@ public partial class EntryCar : IEntryCar public string Model { get; } public string Skin { get; } public int SpectatorMode { get; internal set; } - public float Ballast { get; internal set; } - public int Restrictor { get; internal set; } + public float Ballast { get; set; } + public int Restrictor { get; set; } public string? FixedSetup { get; internal set; } public List AllowedGuids { get; internal set; } = new(); @@ -137,27 +133,29 @@ private void OnSessionChanged(SessionManager sender, SessionChangedEventArgs arg /// /// Only call this function to do a clean reset of this EntryCar, e.g. when a player disconnects /// - internal void Reset() + public void Reset() { ResetInvoked?.Invoke(this, EventArgs.Empty); IsSpectator = false; SpectatorMode = 0; LastActiveTime = 0; HasUpdateToSend = false; - TimeOffset = 0; LastRemoteTimestamp = 0; - LastPingTime = 0; - Ping = 0; ForceLights = false; Status = new CarStatus { P2PCount = (short)(_configuration.Extra.EnableUnlimitedP2P ? 99 : 15), MandatoryPit = _configuration.Server.PitWindowStart < _configuration.Server.PitWindowEnd, }; - if (Client != null) Client.TargetCar = null; + + if (Client == null) return; + Client.TargetCar = null; + Client.Ping = 0; + Client.LastPingTime = 0; + Client.TimeOffset = 0; } - internal void SetActive() + public void SetActive() { LastActiveTime = _sessionManager.ServerTimeMilliseconds; } @@ -197,7 +195,7 @@ internal void UpdatePosition(in PositionUpdateIn positionUpdate) Log.Debug("Status flag from {0:X} to {1:X}", Status.StatusFlag, positionUpdate.StatusFlag); }*/ - Status.Timestamp = LastRemoteTimestamp + TimeOffset; + Status.Timestamp = LastRemoteTimestamp + Client?.TimeOffset ?? 0; Status.PakSequenceId = positionUpdate.PakSequenceId; Status.Position = positionUpdate.Position; Status.Rotation = positionUpdate.Rotation; @@ -284,8 +282,8 @@ public bool GetPositionUpdateForCar(EntryCar toCar, out PositionUpdateOut positi positionUpdateOut = new PositionUpdateOut(SessionId, AiControlled ? AiPakSequenceIds[toCar.SessionId]++ : status.PakSequenceId, - (uint)(status.Timestamp - toCar.TimeOffset), - Ping, + (uint)(status.Timestamp - Client?.TimeOffset ?? 0), + Client?.Ping ?? 0, status.Position, status.Rotation, status.Velocity, @@ -305,9 +303,11 @@ public bool GetPositionUpdateForCar(EntryCar toCar, out PositionUpdateOut positi return true; } - public bool IsInRange(EntryCar target, float range) + public bool IsInRange(IEntryCar target, float range) { - var targetPosition = target.Client?.TargetCar != null ? target.Client.TargetCar.Status.Position : target.Status.Position; + var targetPosition = (target.Client?.TargetCar != null + ? target.Client.TargetCar.Client?.Status.Position + : target.Client?.Status.Position) ?? Vector3.Zero; return Vector3.DistanceSquared(Status.Position, targetPosition) < range * range; } diff --git a/AssettoServer/Server/EntryCarAi.cs b/AssettoServer/Server/EntryCarAi.cs index f2f1675c..75d8aa5d 100644 --- a/AssettoServer/Server/EntryCarAi.cs +++ b/AssettoServer/Server/EntryCarAi.cs @@ -11,13 +11,6 @@ namespace AssettoServer.Server; -public enum AiMode -{ - None, - Auto, - Fixed -} - public partial class EntryCar { public bool AiControlled { get; set; } diff --git a/AssettoServer/Server/EntryCarManager.cs b/AssettoServer/Server/EntryCarManager.cs index 09f028ad..c11e78e2 100644 --- a/AssettoServer/Server/EntryCarManager.cs +++ b/AssettoServer/Server/EntryCarManager.cs @@ -9,6 +9,7 @@ using AssettoServer.Server.Blacklist; using AssettoServer.Server.Configuration; using AssettoServer.Server.OpenSlotFilters; +using AssettoServer.Shared.Model; using AssettoServer.Shared.Network.Packets.Incoming; using AssettoServer.Shared.Network.Packets.Outgoing; using AssettoServer.Shared.Network.Packets.Shared; @@ -31,22 +32,26 @@ public class EntryCarManager /// /// Fires when a client has secured a slot and established a TCP connection. /// - public event EventHandler? ClientConnected; + public event EventHandler? ClientConnected; + /// + /// Fires when a client has connected to a spectator slot and established a TCP connection. + /// + public event EventHandler? SpectatorConnected; /// /// Fires when a client has been kicked. /// - public event EventHandler? ClientKicked; + public event EventHandler? ClientKicked; /// /// Fires when a client has been banned. /// - public event EventHandler? ClientBanned; + public event EventHandler? ClientBanned; /// /// Fires when a player has disconnected. /// - public event EventHandler? ClientDisconnected; + public event EventHandler? ClientDisconnected; public EntryCarManager(ACServerConfiguration configuration, EntryCar.Factory entryCarFactory, IBlacklistService blacklist, IAdminService adminService, Lazy openSlotFilterChain) { @@ -57,7 +62,7 @@ public EntryCarManager(ACServerConfiguration configuration, EntryCar.Factory ent _openSlotFilterChain = openSlotFilterChain; } - public async Task KickAsync(ACTcpClient? client, string? reason = null, ACTcpClient? admin = null) + public async Task KickAsync(PlayerClient? client, string? reason = null, PlayerClient? admin = null) { if (client == null) return; @@ -67,7 +72,7 @@ public async Task KickAsync(ACTcpClient? client, string? reason = null, ACTcpCli await KickAsync(client, KickReason.Kicked, reason, clientReason, broadcastReason, admin); } - public async Task BanAsync(ACTcpClient? client, string? reason = null, ACTcpClient? admin = null) + public async Task BanAsync(PlayerClient? client, string? reason = null, PlayerClient? admin = null) { if (client == null) return; @@ -82,9 +87,9 @@ public async Task BanAsync(ACTcpClient? client, string? reason = null, ACTcpClie } } - public async Task KickAsync(ACTcpClient? client, KickReason reason, string? auditReason = null, string? clientReason = null, string? broadcastReason = null, ACTcpClient? admin = null) + public async Task KickAsync(IClient? client, KickReason reason, string? auditReason = null, string? clientReason = null, string? broadcastReason = null, PlayerClient? admin = null) { - if (client != null && !client.IsDisconnectRequested) + if (client is PlayerClient { IsDisconnectRequested: false } playerClient) { if (broadcastReason != null) { @@ -93,10 +98,10 @@ public async Task KickAsync(ACTcpClient? client, KickReason reason, string? audi if (clientReason != null) { - client.SendPacket(new CSPKickBanMessageOverride { Message = clientReason }); + playerClient.SendPacket(new CSPKickBanMessageOverride { Message = clientReason }); } - client.SendPacket(new KickCar { SessionId = client.SessionId, Reason = reason }); + playerClient.SendPacket(new KickCar { SessionId = playerClient.SessionId, Reason = reason }); var args = new ClientAuditEventArgs { @@ -106,20 +111,20 @@ public async Task KickAsync(ACTcpClient? client, KickReason reason, string? audi }; if (reason is KickReason.Kicked or KickReason.VoteKicked) { - client.Logger.Information("{ClientName} was kicked. Reason: {Reason}", client.Name, auditReason ?? "No reason given."); - ClientKicked?.Invoke(client, args); + playerClient.Logger.Information("{ClientName} was kicked. Reason: {Reason}", playerClient.Name, auditReason ?? "No reason given."); + ClientKicked?.Invoke(playerClient, args); } else if (reason is KickReason.VoteBanned or KickReason.VoteBlacklisted) { - client.Logger.Information("{ClientName} was banned. Reason: {Reason}", client.Name, auditReason ?? "No reason given."); - ClientBanned?.Invoke(client, args); + playerClient.Logger.Information("{ClientName} was banned. Reason: {Reason}", playerClient.Name, auditReason ?? "No reason given."); + ClientBanned?.Invoke(playerClient, args); } - await client.DisconnectAsync(); + await playerClient.DisconnectAsync(); } } - internal async Task DisconnectClientAsync(ACTcpClient client) + internal async Task DisconnectClientAsync(PlayerClient client) { try { @@ -147,7 +152,7 @@ internal async Task DisconnectClientAsync(ACTcpClient client) } } - public void BroadcastPacket(TPacket packet, ACTcpClient? sender = null) where TPacket : IOutgoingNetworkPacket + public void BroadcastPacket(TPacket packet, PlayerClient? sender = null) where TPacket : IOutgoingNetworkPacket { foreach (var car in EntryCars) { @@ -161,11 +166,11 @@ public void BroadcastPacket(TPacket packet, ACTcpClient? sender = null) public void BroadcastChat(string message, byte senderId = 255) => BroadcastPacket(new ChatMessage { SessionId = senderId, Message = message }); - public void BroadcastPacketUdp(in TPacket packet, ACTcpClient? sender = null, float? range = null, bool skipSender = true) where TPacket : IOutgoingNetworkPacket + public void BroadcastPacketUdp(in TPacket packet, PlayerClient? sender = null, float? range = null, bool skipSender = true) where TPacket : IOutgoingNetworkPacket { foreach (var car in EntryCars) { - if (car.Client is { HasSentFirstUpdate: true, UdpEndpoint: not null } + if (car.Client is { HasSentFirstUpdate: true, HasUdpEndpoint: true } && (!skipSender || car.Client != sender) && (!range.HasValue || (sender != null && sender.EntryCar.IsInRange(car, range.Value)))) { @@ -174,7 +179,7 @@ public void BroadcastPacketUdp(in TPacket packet, ACTcpClient? sender = } } - internal async Task TrySecureSlotAsync(ACTcpClient client, HandshakeRequest handshakeRequest) + internal async Task TrySecureSlotAsync(PlayerClient client, HandshakeRequest handshakeRequest) { try { diff --git a/AssettoServer/Server/EventArgs.cs b/AssettoServer/Server/EventArgs.cs index e19b1682..b9863387 100644 --- a/AssettoServer/Server/EventArgs.cs +++ b/AssettoServer/Server/EventArgs.cs @@ -39,7 +39,7 @@ public class ClientAuditEventArgs : EventArgs { public KickReason Reason { get; init; } public string? ReasonStr { get; init; } - public ACTcpClient? Admin { get; init; } + public PlayerClient? Admin { get; init; } } public class ChatEventArgs : CancelEventArgs diff --git a/AssettoServer/Server/OpenSlotFilters/AiSlotFilter.cs b/AssettoServer/Server/OpenSlotFilters/AiSlotFilter.cs index 141ef829..ff3beac6 100644 --- a/AssettoServer/Server/OpenSlotFilters/AiSlotFilter.cs +++ b/AssettoServer/Server/OpenSlotFilters/AiSlotFilter.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using AssettoServer.Server.Configuration; +using AssettoServer.Shared.Model; namespace AssettoServer.Server.OpenSlotFilters; diff --git a/AssettoServer/Server/OpenSlotFilters/IOpenSlotFilter.cs b/AssettoServer/Server/OpenSlotFilters/IOpenSlotFilter.cs index 839b252f..c87b53db 100644 --- a/AssettoServer/Server/OpenSlotFilters/IOpenSlotFilter.cs +++ b/AssettoServer/Server/OpenSlotFilters/IOpenSlotFilter.cs @@ -9,5 +9,5 @@ public interface IOpenSlotFilter { void SetNextFilter(IOpenSlotFilter next); ValueTask IsSlotOpen(EntryCar entryCar, ulong guid); - Task ShouldAcceptConnectionAsync(ACTcpClient client, HandshakeRequest request); + Task ShouldAcceptConnectionAsync(PlayerClient client, HandshakeRequest request); } diff --git a/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterBase.cs b/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterBase.cs index 6ae62a38..a7f644b3 100644 --- a/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterBase.cs +++ b/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterBase.cs @@ -22,7 +22,7 @@ public virtual async ValueTask IsSlotOpen(EntryCar entryCar, ulong guid) return await _nextFilter.IsSlotOpen(entryCar, guid); } - public virtual Task ShouldAcceptConnectionAsync(ACTcpClient client, HandshakeRequest request) + public virtual Task ShouldAcceptConnectionAsync(PlayerClient client, HandshakeRequest request) { return _nextFilter?.ShouldAcceptConnectionAsync(client, request) ?? Task.FromResult(null); } diff --git a/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterChain.cs b/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterChain.cs index 458d1d82..fb83c091 100644 --- a/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterChain.cs +++ b/AssettoServer/Server/OpenSlotFilters/OpenSlotFilterChain.cs @@ -30,7 +30,7 @@ public async ValueTask IsSlotOpen(EntryCar entryCar, ulong guid) return await _first.IsSlotOpen(entryCar, guid); } - public Task ShouldAcceptConnectionAsync(ACTcpClient client, HandshakeRequest request) + public Task ShouldAcceptConnectionAsync(PlayerClient client, HandshakeRequest request) { return _first.ShouldAcceptConnectionAsync(client, request); } diff --git a/AssettoServer/Server/OpenSlotFilters/SteamSlotFilter.cs b/AssettoServer/Server/OpenSlotFilters/SteamSlotFilter.cs index 176b2b9f..e1806a0a 100644 --- a/AssettoServer/Server/OpenSlotFilters/SteamSlotFilter.cs +++ b/AssettoServer/Server/OpenSlotFilters/SteamSlotFilter.cs @@ -15,7 +15,7 @@ public SteamSlotFilter(SteamManager steam) _steam = steam; } - public override async Task ShouldAcceptConnectionAsync(ACTcpClient client, HandshakeRequest request) + public override async Task ShouldAcceptConnectionAsync(PlayerClient client, HandshakeRequest request) { if (!await _steam.ValidateSessionTicketAsync(request.SessionTicket, request.Guid, client)) { diff --git a/AssettoServer/Server/OpenSlotFilters/WhitelistSlotFilter.cs b/AssettoServer/Server/OpenSlotFilters/WhitelistSlotFilter.cs index 381d199f..aec635b9 100644 --- a/AssettoServer/Server/OpenSlotFilters/WhitelistSlotFilter.cs +++ b/AssettoServer/Server/OpenSlotFilters/WhitelistSlotFilter.cs @@ -15,7 +15,7 @@ public WhitelistSlotFilter(IWhitelistService whitelist) _whitelist = whitelist; } - public override async Task ShouldAcceptConnectionAsync(ACTcpClient client, HandshakeRequest request) + public override async Task ShouldAcceptConnectionAsync(PlayerClient client, HandshakeRequest request) { if (!await _whitelist.IsWhitelistedAsync(request.Guid)) { diff --git a/AssettoServer/Server/SessionManager.cs b/AssettoServer/Server/SessionManager.cs index cb421caf..c17fbd12 100644 --- a/AssettoServer/Server/SessionManager.cs +++ b/AssettoServer/Server/SessionManager.cs @@ -120,7 +120,7 @@ protected override async Task ExecuteAsync(CancellationToken token) } } - public bool OnLapCompleted(ACTcpClient client, LapCompletedIncoming lap) + public bool OnLapCompleted(PlayerClient client, LapCompletedIncoming lap) { int timestamp = (int)ServerTimeMilliseconds; @@ -146,7 +146,7 @@ public bool OnLapCompleted(ACTcpClient client, LapCompletedIncoming lap) { entryCarResult.LastLap = lap.LapTime; entryCarResult.NumLaps++; - entryCarResult.TotalTime = (uint)(CurrentSession.SessionTimeMilliseconds - client.EntryCar.Ping / 2); + entryCarResult.TotalTime = (uint)(CurrentSession.SessionTimeMilliseconds - client.Ping / 2); if (lap.LapTime < entryCarResult.BestLap) { @@ -342,7 +342,7 @@ private void CalcOverTime() CurrentSession.OverTimeMilliseconds = 1; } - private void OnClientConnected(ACTcpClient client, EventArgs eventArgs) + private void OnClientConnected(PlayerClient client, EventArgs eventArgs) { var currentResult = CurrentSession.Results; @@ -480,7 +480,7 @@ public bool NextSession() return true; } - public void SendCurrentSession(ACTcpClient? target = null) + public void SendCurrentSession(IClient? target = null) { var packet = new CurrentSessionUpdate { @@ -493,7 +493,7 @@ public void SendCurrentSession(ACTcpClient? target = null) { foreach (var car in _entryCarManager.EntryCars.Where(c => c.Client is { HasSentFirstUpdate: true })) { - packet.StartTime = CurrentSession.StartTimeMilliseconds - car.TimeOffset; + packet.StartTime = CurrentSession.StartTimeMilliseconds - car.Client?.TimeOffset ?? 0; car.Client?.SendPacket(packet); } } @@ -512,9 +512,9 @@ private void SendSessionStart() { car.Client?.SendPacketUdp(new RaceStart() { - StartTime = (int)(CurrentSession.StartTimeMilliseconds - car.TimeOffset), - TimeOffset = (uint)(ServerTimeMilliseconds - car.TimeOffset), - Ping = car.Ping, + StartTime = (int)(CurrentSession.StartTimeMilliseconds - car.Client.TimeOffset), + TimeOffset = (uint)(ServerTimeMilliseconds - car.Client.TimeOffset), + Ping = car.Client.Ping, }); } diff --git a/AssettoServer/Server/SessionState.cs b/AssettoServer/Server/SessionState.cs index 1fdf2c86..d00e315a 100644 --- a/AssettoServer/Server/SessionState.cs +++ b/AssettoServer/Server/SessionState.cs @@ -32,7 +32,7 @@ public class SessionState public bool HasSentRaceOverPacket { get; set; } = false; public long LastRaceStartUpdateMilliseconds { get; set; } public Dictionary? Results { get; set; } - public IEnumerable>? Grid { get; set; } + public IEnumerable? Grid { get; set; } private readonly SessionManager _timeSource; diff --git a/AssettoServer/Server/Steam/ISteam.cs b/AssettoServer/Server/Steam/ISteam.cs index 29bdb8a9..735e8847 100644 --- a/AssettoServer/Server/Steam/ISteam.cs +++ b/AssettoServer/Server/Steam/ISteam.cs @@ -7,5 +7,5 @@ public interface ISteam { public const int AppId = 244210; - Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, ACTcpClient client); + Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, PlayerClient client); } diff --git a/AssettoServer/Server/Steam/NativeSteam.cs b/AssettoServer/Server/Steam/NativeSteam.cs index 432d29a3..d6dc7cb9 100644 --- a/AssettoServer/Server/Steam/NativeSteam.cs +++ b/AssettoServer/Server/Steam/NativeSteam.cs @@ -68,7 +68,7 @@ internal void HandleIncomingPacket(byte[] data, IPEndPoint endpoint) } } - public async Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, ACTcpClient client) + public async Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, PlayerClient client) { if (sessionTicket == null) return new SteamResult { ErrorReason = "Missing session ticket" }; @@ -130,7 +130,7 @@ void TicketValidateResponse(SteamId playerSteamId, SteamId ownerSteamId, AuthRes } } - private static void Client_OnDisconnecting(ACTcpClient sender, EventArgs args) + private static void Client_OnDisconnecting(PlayerClient sender, EventArgs args) { try { diff --git a/AssettoServer/Server/Steam/SteamManager.cs b/AssettoServer/Server/Steam/SteamManager.cs index 0d19aff3..33d1b8a5 100644 --- a/AssettoServer/Server/Steam/SteamManager.cs +++ b/AssettoServer/Server/Steam/SteamManager.cs @@ -20,7 +20,7 @@ public SteamManager(CSPFeatureManager cspFeatureManager, ISteam steam, IBlacklis }); } - public async Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, ACTcpClient client) + public async Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, PlayerClient client) { var result = await _steam.ValidateSessionTicketAsync(sessionTicket, guid, client); diff --git a/AssettoServer/Server/Steam/WebApiSteam.cs b/AssettoServer/Server/Steam/WebApiSteam.cs index 8ab271c9..7799eedd 100644 --- a/AssettoServer/Server/Steam/WebApiSteam.cs +++ b/AssettoServer/Server/Steam/WebApiSteam.cs @@ -22,7 +22,7 @@ public WebApiSteam(ACServerConfiguration configuration) } } - public async Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, ACTcpClient client) + public async Task ValidateSessionTicketAsync(byte[]? sessionTicket, ulong guid, PlayerClient client) { if (sessionTicket == null) return new SteamResult { ErrorReason = "Missing session ticket" }; diff --git a/AssettoServer/Server/VoteManager.cs b/AssettoServer/Server/VoteManager.cs index 52244370..dc32d2bd 100644 --- a/AssettoServer/Server/VoteManager.cs +++ b/AssettoServer/Server/VoteManager.cs @@ -27,7 +27,7 @@ public VoteManager(ACServerConfiguration configuration, EntryCarManager entryCar } - private void OnClientDisconnected(ACTcpClient sender, EventArgs args) => _state?.Votes.Remove(sender.SessionId); + private void OnClientDisconnected(PlayerClient sender, EventArgs args) => _state?.Votes.Remove(sender.SessionId); public async Task SetVote(byte sessionId, VoteType voteType, bool voteValue, byte target = 0) { diff --git a/AssettoServer/Server/Weather/Implementation/IWeatherImplementation.cs b/AssettoServer/Server/Weather/Implementation/IWeatherImplementation.cs index a47325e5..e88b7b40 100644 --- a/AssettoServer/Server/Weather/Implementation/IWeatherImplementation.cs +++ b/AssettoServer/Server/Weather/Implementation/IWeatherImplementation.cs @@ -5,5 +5,5 @@ namespace AssettoServer.Server.Weather.Implementation; public interface IWeatherImplementation { - public void SendWeather(WeatherData weather, ZonedDateTime dateTime, ACTcpClient? client = null); + public void SendWeather(WeatherData weather, ZonedDateTime dateTime, PlayerClient? client = null); } \ No newline at end of file diff --git a/AssettoServer/Server/Weather/Implementation/VanillaWeatherImplementation.cs b/AssettoServer/Server/Weather/Implementation/VanillaWeatherImplementation.cs index b683ed59..f4441644 100644 --- a/AssettoServer/Server/Weather/Implementation/VanillaWeatherImplementation.cs +++ b/AssettoServer/Server/Weather/Implementation/VanillaWeatherImplementation.cs @@ -17,7 +17,7 @@ public VanillaWeatherImplementation(IWeatherTypeProvider weatherTypeProvider, En _entryCarManager = entryCarManager; } - public void SendWeather(WeatherData weather, ZonedDateTime dateTime, ACTcpClient? client = null) + public void SendWeather(WeatherData weather, ZonedDateTime dateTime, PlayerClient? client = null) { var wfxParams = new WeatherFxParams { diff --git a/AssettoServer/Server/Weather/Implementation/WeatherFxV1Implementation.cs b/AssettoServer/Server/Weather/Implementation/WeatherFxV1Implementation.cs index adce3936..6344a572 100644 --- a/AssettoServer/Server/Weather/Implementation/WeatherFxV1Implementation.cs +++ b/AssettoServer/Server/Weather/Implementation/WeatherFxV1Implementation.cs @@ -15,7 +15,7 @@ public WeatherFxV1Implementation(EntryCarManager entryCarManager, CSPFeatureMana cspFeatureManager.Add(new CSPFeature { Name = "WEATHERFX_V1", Mandatory = true }); } - public void SendWeather(WeatherData weather, ZonedDateTime dateTime, ACTcpClient? client = null) + public void SendWeather(WeatherData weather, ZonedDateTime dateTime, PlayerClient? client = null) { var newWeather = new CSPWeatherUpdate { diff --git a/AssettoServer/Server/Weather/WeatherManager.cs b/AssettoServer/Server/Weather/WeatherManager.cs index 1c5eb679..cd75ed1b 100644 --- a/AssettoServer/Server/Weather/WeatherManager.cs +++ b/AssettoServer/Server/Weather/WeatherManager.cs @@ -84,7 +84,7 @@ public void SetCspWeather(WeatherFxType upcoming, int duration) _weatherImplementation.SendWeather(CurrentWeather, CurrentDateTime); } - public void SendWeather(ACTcpClient? client = null) => _weatherImplementation.SendWeather(CurrentWeather, CurrentDateTime, client); + public void SendWeather(PlayerClient? client = null) => _weatherImplementation.SendWeather(CurrentWeather, CurrentDateTime, client); private void UpdateSunPosition() { diff --git a/AssettoServer/Startup.cs b/AssettoServer/Startup.cs index ca1cd945..11a21dea 100644 --- a/AssettoServer/Startup.cs +++ b/AssettoServer/Startup.cs @@ -83,7 +83,7 @@ public void ConfigureContainer(ContainerBuilder builder) // No hosted services below this line builder.RegisterType().AsSelf(); - builder.RegisterType().AsSelf(); + builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); diff --git a/AutoModerationPlugin/AutoModerationPlugin.cs b/AutoModerationPlugin/AutoModerationPlugin.cs index 402b172c..30c44416 100644 --- a/AutoModerationPlugin/AutoModerationPlugin.cs +++ b/AutoModerationPlugin/AutoModerationPlugin.cs @@ -56,12 +56,12 @@ public AutoModerationPlugin(AutoModerationConfiguration configuration, _entryCarManager.ClientConnected += (sender, _) => sender.LoggedInAsAdministrator += OnAdminLoggedIn; } - private void OnFirstUpdateSent(ACTcpClient sender, EventArgs args) + private void OnFirstUpdateSent(PlayerClient sender, EventArgs args) { _instances[sender.SessionId].SetActive(); } - private void OnAdminLoggedIn(ACTcpClient sender, EventArgs args) + private void OnAdminLoggedIn(PlayerClient sender, EventArgs args) { _instances[sender.SessionId].AdminReset(); } diff --git a/AutoModerationPlugin/EntryCarAutoModeration.cs b/AutoModerationPlugin/EntryCarAutoModeration.cs index 118c8d35..35bbd17d 100644 --- a/AutoModerationPlugin/EntryCarAutoModeration.cs +++ b/AutoModerationPlugin/EntryCarAutoModeration.cs @@ -119,8 +119,8 @@ internal void AdminReset() public void Update() { - var client = _entryCar.Client; - if (client == null || !client.HasSentFirstUpdate || client.IsAdministrator) + var carClient = _entryCar.Client; + if (carClient is not PlayerClient { HasSentFirstUpdate: true } client || client.IsAdministrator) return; var oldFlags = CurrentFlags; @@ -138,7 +138,7 @@ public void Update() } } - private void UpdateAfkPenalty(ACTcpClient client) + private void UpdateAfkPenalty(PlayerClient client) { if (!_configuration.AfkPenalty.Enabled) return; @@ -166,11 +166,11 @@ private void UpdateAfkPenalty(ACTcpClient client) } } - private void UpdateHighPingPenalty(ACTcpClient client) + private void UpdateHighPingPenalty(PlayerClient client) { if (!_configuration.HighPingPenalty.Enabled) return; - if (_entryCar.Ping > _configuration.HighPingPenalty.MaximumPingMilliseconds) + if (client.Ping > _configuration.HighPingPenalty.MaximumPingMilliseconds) { HighPingSeconds++; @@ -191,7 +191,7 @@ private void UpdateHighPingPenalty(ACTcpClient client) } } - private void UpdateNoLightsPenalty(ACTcpClient client) + private void UpdateNoLightsPenalty(PlayerClient client) { if (!_configuration.NoLightsPenalty.Enabled) return; @@ -235,7 +235,7 @@ private void UpdateNoLightsPenalty(ACTcpClient client) } } - private void UpdateWrongWayPenalty(ACTcpClient client) + private void UpdateWrongWayPenalty(PlayerClient client) { if (!_configuration.WrongWayPenalty.Enabled || _aiSpline == null) return; @@ -276,7 +276,7 @@ private void UpdateWrongWayPenalty(ACTcpClient client) } } - private void UpdateBlockingRoadPenalty(ACTcpClient client) + private void UpdateBlockingRoadPenalty(PlayerClient client) { if (!_configuration.BlockingRoadPenalty.Enabled) return; @@ -328,7 +328,7 @@ private void UpdateSplinePoint() } } - private void TeleportToPits(ACTcpClient player, string reason) + private void TeleportToPits(PlayerClient player, string reason) { _sessionManager.SendCurrentSession(player); player.SendChatMessage($"You have been teleported to the pits for {reason}."); diff --git a/DiscordAuditPlugin/Discord.cs b/DiscordAuditPlugin/Discord.cs index 17654d0f..7686d495 100644 --- a/DiscordAuditPlugin/Discord.cs +++ b/DiscordAuditPlugin/Discord.cs @@ -51,7 +51,7 @@ public Discord(DiscordConfiguration configuration, EntryCarManager entryCarManag } } - private void OnClientConnected(ACTcpClient sender, EventArgs args) + private void OnClientConnected(PlayerClient sender, EventArgs args) { Task.Run(async () => { @@ -74,7 +74,7 @@ private void OnClientConnected(ACTcpClient sender, EventArgs args) }); } - private void OnClientDisconnected(ACTcpClient sender, EventArgs args) + private void OnClientDisconnected(PlayerClient sender, EventArgs args) { Task.Run(async () => { @@ -97,7 +97,7 @@ private void OnClientDisconnected(ACTcpClient sender, EventArgs args) }); } - private void OnClientBanned(ACTcpClient sender, ClientAuditEventArgs args) + private void OnClientBanned(PlayerClient sender, ClientAuditEventArgs args) { Task.Run(async () => { @@ -120,7 +120,7 @@ private void OnClientBanned(ACTcpClient sender, ClientAuditEventArgs args) }); } - private void OnClientKicked(ACTcpClient sender, ClientAuditEventArgs args) + private void OnClientKicked(PlayerClient sender, ClientAuditEventArgs args) { if (args.Reason != KickReason.ChecksumFailed) { @@ -146,7 +146,7 @@ private void OnClientKicked(ACTcpClient sender, ClientAuditEventArgs args) } } - private void OnChatMessageReceived(ACTcpClient sender, ChatEventArgs args) + private void OnChatMessageReceived(PlayerClient sender, ChatEventArgs args) { if (args.Message.StartsWith("\t\t\t\t$CSP0:") || string.IsNullOrWhiteSpace(args.Message) diff --git a/FastTravelPlugin/FastTravelPlugin.cs b/FastTravelPlugin/FastTravelPlugin.cs index a97a0ae4..3fe6ae74 100644 --- a/FastTravelPlugin/FastTravelPlugin.cs +++ b/FastTravelPlugin/FastTravelPlugin.cs @@ -54,7 +54,7 @@ public FastTravelPlugin(FastTravelConfiguration configuration, cspClientMessageTypeManager.RegisterOnlineEvent(OnFastTravelPacket); } - private void OnFastTravelPacket(ACTcpClient client, FastTravelPacket packet) + private void OnFastTravelPacket(PlayerClient client, FastTravelPacket packet) { var (splinePointId, _) = _aiSpline.WorldToSpline(packet.Position); diff --git a/GeoIPPlugin/GeoIP.cs b/GeoIPPlugin/GeoIP.cs index 9b3a4d5d..8e77d723 100644 --- a/GeoIPPlugin/GeoIP.cs +++ b/GeoIPPlugin/GeoIP.cs @@ -15,7 +15,7 @@ public GeoIP(EntryCarManager entryCarManager, GeoIPConfiguration configuration) entryCarManager.ClientConnected += OnClientConnected; } - private void OnClientConnected(ACTcpClient sender, EventArgs args) + private void OnClientConnected(PlayerClient sender, EventArgs args) { try { diff --git a/RaceChallengePlugin/EntryCarRace.cs b/RaceChallengePlugin/EntryCarRace.cs index 2a28b97d..83e3520a 100644 --- a/RaceChallengePlugin/EntryCarRace.cs +++ b/RaceChallengePlugin/EntryCarRace.cs @@ -139,7 +139,7 @@ private void ChallengeNearbyCar() foreach(EntryCar car in _entryCarManager.EntryCars) { - ACTcpClient? carClient = car.Client; + PlayerClient? carClient = car.Client; if(carClient != null && car != _entryCar) { float challengedAngle = (float)(Math.Atan2(_entryCar.Status.Position.X - car.Status.Position.X, _entryCar.Status.Position.Z - car.Status.Position.Z) * 180 / Math.PI); diff --git a/RaceChallengePlugin/RaceCommandModule.cs b/RaceChallengePlugin/RaceCommandModule.cs index 0a4def05..85a7118a 100644 --- a/RaceChallengePlugin/RaceCommandModule.cs +++ b/RaceChallengePlugin/RaceCommandModule.cs @@ -16,7 +16,7 @@ public RaceCommandModule(RaceChallengePlugin plugin) } [Command("race"), RequireConnectedPlayer] - public void Race(ACTcpClient player) + public void Race(PlayerClient player) => _plugin.GetRace(Client!.EntryCar).ChallengeCar(player.EntryCar); [Command("accept"), RequireConnectedPlayer] diff --git a/ReplayPlugin/ReplayCommandModule.cs b/ReplayPlugin/ReplayCommandModule.cs index fc5db7a3..874a1982 100644 --- a/ReplayPlugin/ReplayCommandModule.cs +++ b/ReplayPlugin/ReplayCommandModule.cs @@ -17,7 +17,7 @@ public ReplayCommandModule(ReplayManager replayManager) } [Command("replay")] - public void SaveReplay(int seconds, [Remainder] ACTcpClient? client = null) + public void SaveReplay(int seconds, [Remainder] PlayerClient? client = null) { var sessionId = client?.SessionId ?? Client?.SessionId; diff --git a/ReplayPlugin/ReplayPlugin.cs b/ReplayPlugin/ReplayPlugin.cs index 4c8c454c..0cff11e8 100644 --- a/ReplayPlugin/ReplayPlugin.cs +++ b/ReplayPlugin/ReplayPlugin.cs @@ -53,7 +53,7 @@ public ReplayPlugin(IHostApplicationLifetime applicationLifetime, scriptProvider.AddScript(streamReader.ReadToEnd(), "replay.lua"); } - private void OnUploadData(ACTcpClient sender, UploadDataPacket packet) + private void OnUploadData(PlayerClient sender, UploadDataPacket packet) { var data = _extraData.Data[packet.CarId]; data.WheelPositions = packet.WheelPositions; diff --git a/ReportPlugin/AuditLog.cs b/ReportPlugin/AuditLog.cs index 4daf8b70..b3451ab4 100644 --- a/ReportPlugin/AuditLog.cs +++ b/ReportPlugin/AuditLog.cs @@ -40,7 +40,7 @@ public readonly struct AuditClient public readonly string CarModel; public readonly string Skin; - public AuditClient(ACTcpClient client) + public AuditClient(PlayerClient client) { Name = client.Name ?? ""; SteamId = client.Guid; diff --git a/ReportPlugin/ReportPlugin.cs b/ReportPlugin/ReportPlugin.cs index 350e2f2f..18545d3a 100644 --- a/ReportPlugin/ReportPlugin.cs +++ b/ReportPlugin/ReportPlugin.cs @@ -23,7 +23,7 @@ public class ReportPlugin : IHostedService private readonly CSPServerExtraOptions _cspServerExtraOptions; private readonly GeoParamsManager _geoParamsManager; private readonly ACServerConfiguration _serverConfiguration; - private readonly Dictionary _reports = new(); + private readonly Dictionary _reports = new(); private readonly ConcurrentQueue _events = new(); public ReportPlugin( @@ -58,7 +58,7 @@ public ReportPlugin( Directory.CreateDirectory("reports"); } - private void OnClientFirstUpdateSent(ACTcpClient sender, EventArgs args) + private void OnClientFirstUpdateSent(PlayerClient sender, EventArgs args) { try { @@ -72,7 +72,7 @@ private void OnClientFirstUpdateSent(ACTcpClient sender, EventArgs args) } } - private void OnClientDisconnected(ACTcpClient sender, EventArgs args) + private void OnClientDisconnected(PlayerClient sender, EventArgs args) { try { @@ -88,7 +88,7 @@ private void OnClientDisconnected(ACTcpClient sender, EventArgs args) } } - private void OnChatMessage(ACTcpClient sender, ChatEventArgs args) + private void OnChatMessage(PlayerClient sender, ChatEventArgs args) { try { @@ -124,7 +124,7 @@ internal AuditLog GetAuditLog(DateTime timestamp) return new AuditLog(timestamp, entryList, _events.ToList()); } - internal async Task SubmitReport(ACTcpClient client, Replay replay, string reason) + internal async Task SubmitReport(PlayerClient client, Replay replay, string reason) { if (_webhook == null) return; @@ -157,13 +157,13 @@ internal async Task SubmitReport(ACTcpClient client, Replay replay, string reaso await _webhook.SendAsync(msg, new FileInfo(Path.Join("reports", $"{replay.Guid}.zip")), new FileInfo(Path.Join("reports", $"{replay.Guid}.json"))); } - public Replay? GetLastReplay(ACTcpClient client) + public Replay? GetLastReplay(PlayerClient client) { _reports.TryGetValue(client, out var report); return report; } - public void SetLastReplay(ACTcpClient client, Replay replay) => _reports[client] = replay; + public void SetLastReplay(PlayerClient client, Replay replay) => _reports[client] = replay; public Task StartAsync(CancellationToken cancellationToken) { diff --git a/TagModePlugin/TagModeCommandModule.cs b/TagModePlugin/TagModeCommandModule.cs index a1682cbf..78de045a 100644 --- a/TagModePlugin/TagModeCommandModule.cs +++ b/TagModePlugin/TagModeCommandModule.cs @@ -17,7 +17,7 @@ public TagModeCommandModule(TagModePlugin plugin) } [Command("tagstart"), RequireConnectedPlayer, RequireAdmin] - public async ValueTask Start([Remainder] ACTcpClient? player = null) + public async ValueTask Start([Remainder] PlayerClient? player = null) { var starter = player?.EntryCar; if (starter == null && !_plugin.TryPickRandomTagger(out starter)) diff --git a/TagModePlugin/TagModePlugin.cs b/TagModePlugin/TagModePlugin.cs index 83bf1fdb..b3841084 100644 --- a/TagModePlugin/TagModePlugin.cs +++ b/TagModePlugin/TagModePlugin.cs @@ -58,13 +58,13 @@ public TagModePlugin(ACServerConfiguration acServerConfiguration, NeutralColor = ColorTranslator.FromHtml(_configuration.NeutralColor); } - private void OnDisconnecting(ACTcpClient sender, EventArgs args) + private void OnDisconnecting(PlayerClient sender, EventArgs args) => Instances[sender.SessionId].OnDisconnecting(); - private void OnLuaReady(ACTcpClient sender, EventArgs args) + private void OnLuaReady(PlayerClient sender, EventArgs args) => Instances[sender.SessionId].OnLuaReady(); - private void OnCollision(ACTcpClient sender, CollisionEventArgs args) + private void OnCollision(PlayerClient sender, CollisionEventArgs args) => Instances[sender.SessionId].OnCollision(args); public override async Task StartAsync(CancellationToken cancellationToken) diff --git a/VotingPresetPlugin/VotingPresetPlugin.cs b/VotingPresetPlugin/VotingPresetPlugin.cs index 90ff3ed4..ba85c416 100644 --- a/VotingPresetPlugin/VotingPresetPlugin.cs +++ b/VotingPresetPlugin/VotingPresetPlugin.cs @@ -17,7 +17,7 @@ public class VotingPresetPlugin : BackgroundService private readonly VotingPresetConfiguration _configuration; private readonly List _votePresets; - private readonly List _alreadyVoted = new(); + private readonly List _alreadyVoted = new(); private readonly List _availablePresets = new(); private bool _votingOpen = false; diff --git a/VotingWeatherPlugin/VotingWeather.cs b/VotingWeatherPlugin/VotingWeather.cs index dd91c09b..029ba44a 100644 --- a/VotingWeatherPlugin/VotingWeather.cs +++ b/VotingWeatherPlugin/VotingWeather.cs @@ -14,7 +14,7 @@ public class VotingWeather : BackgroundService private readonly EntryCarManager _entryCarManager; private readonly VotingWeatherConfiguration _configuration; private readonly List _weathers; - private readonly List _alreadyVoted = new(); + private readonly List _alreadyVoted = new(); private readonly List _availableWeathers = new(); private bool _votingOpen = false; @@ -63,7 +63,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) } } - internal void CountVote(ACTcpClient client, int choice) + internal void CountVote(PlayerClient client, int choice) { if (!_votingOpen) { diff --git a/WordFilterPlugin/WordFilter.cs b/WordFilterPlugin/WordFilter.cs index d1eb1e7e..b7ecf806 100644 --- a/WordFilterPlugin/WordFilter.cs +++ b/WordFilterPlugin/WordFilter.cs @@ -21,7 +21,7 @@ public WordFilter(WordFilterConfiguration configuration, EntryCarManager entryCa chatService.MessageReceived += OnChatMessageReceived; } - private void OnChatMessageReceived(ACTcpClient sender, ChatEventArgs args) + private void OnChatMessageReceived(PlayerClient sender, ChatEventArgs args) { if (_configuration.BannableChatPatterns.Any(regex => Regex.Match(args.Message, regex, RegexOptions.IgnoreCase).Success)) { @@ -36,7 +36,7 @@ private void OnChatMessageReceived(ACTcpClient sender, ChatEventArgs args) } } - public override Task ShouldAcceptConnectionAsync(ACTcpClient client, HandshakeRequest request) + public override Task ShouldAcceptConnectionAsync(PlayerClient client, HandshakeRequest request) { if (_configuration.ProhibitedUsernamePatterns.Any(regex => Regex.Match(request.Name, regex, RegexOptions.IgnoreCase).Success)) { From 9047f1da533905bbed6e46a33f503ee337f64d05 Mon Sep 17 00:00:00 2001 From: thisguyStan <53304086+thisguyStan@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:29:23 +0200 Subject: [PATCH 3/5] slight correction --- AssettoServer.Shared/Model/IClient.cs | 2 +- AssettoServer/Server/EntryCar.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AssettoServer.Shared/Model/IClient.cs b/AssettoServer.Shared/Model/IClient.cs index dee00f21..304e2db4 100644 --- a/AssettoServer.Shared/Model/IClient.cs +++ b/AssettoServer.Shared/Model/IClient.cs @@ -6,7 +6,7 @@ namespace AssettoServer.Shared.Model; public interface IClient { - public CarStatus Status { get; } + public CarStatus Status { get; set; } public byte SessionId { get; } public ulong Guid { get; } public string HashedGuid { get; } diff --git a/AssettoServer/Server/EntryCar.cs b/AssettoServer/Server/EntryCar.cs index 5eeee966..8c350830 100644 --- a/AssettoServer/Server/EntryCar.cs +++ b/AssettoServer/Server/EntryCar.cs @@ -20,7 +20,7 @@ namespace AssettoServer.Server; public partial class EntryCar : IEntryCar { public IClient? Client { get; set; } - public CarStatus Status { get; private set; } = new(); // TODO YET THIS SHIT + public CarStatus Status { get; private set; } = new(); // TODO YEET THIS SHIT public bool EnableCollisions { get; private set; } = true; public bool ForceLights { get; set; } From 2ddf093768fb5321b4507ad91a2a285283d9acee Mon Sep 17 00:00:00 2001 From: thisguyStan <53304086+thisguyStan@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:50:13 +0200 Subject: [PATCH 4/5] small change to be up-to-date with upstream master --- AssettoServer.Shared/Model/IClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AssettoServer.Shared/Model/IClient.cs b/AssettoServer.Shared/Model/IClient.cs index 304e2db4..2c24764b 100644 --- a/AssettoServer.Shared/Model/IClient.cs +++ b/AssettoServer.Shared/Model/IClient.cs @@ -36,6 +36,6 @@ public interface IClient public Task DisconnectAsync(); public void SendFirstUpdate(); public void SendPacket(TPacket packet) where TPacket : IOutgoingNetworkPacket; - public void SendPacketUdp(in TPacket packet) where TPacket : IOutgoingNetworkPacket; + public void SendPacketUdp(in TPacket packet) where TPacket : IOutgoingNetworkPacket, allows ref struct; public void SendTeleportCarPacket(Vector3 position, Vector3 direction, Vector3 velocity = default); } From 16dec1240e751288556cf18b41661649f74be0ad Mon Sep 17 00:00:00 2001 From: thisguyStan <53304086+thisguyStan@users.noreply.github.com> Date: Tue, 1 Jul 2025 22:26:24 +0200 Subject: [PATCH 5/5] minor changes, 171 problems remaining --- AssettoServer.Shared/Model/IClient.cs | 7 ------- AssettoServer/Commands/ChatService.cs | 16 ++++++++++------ AssettoServer/Network/Tcp/PlayerClient.cs | 8 ++++---- AssettoServer/Server/EntryCar.cs | 6 ------ AssettoServer/Server/EntryCarManager.cs | 10 +++++----- AutoModerationPlugin/AutoModerationPlugin.cs | 2 +- AutoModerationPlugin/EntryCarAutoModeration.cs | 4 ++-- 7 files changed, 22 insertions(+), 31 deletions(-) diff --git a/AssettoServer.Shared/Model/IClient.cs b/AssettoServer.Shared/Model/IClient.cs index 2c24764b..9f462dc3 100644 --- a/AssettoServer.Shared/Model/IClient.cs +++ b/AssettoServer.Shared/Model/IClient.cs @@ -31,11 +31,4 @@ public interface IClient public IEntryCar? TargetCar { get; set; } public ILogger Logger { get; } - - - public Task DisconnectAsync(); - public void SendFirstUpdate(); - public void SendPacket(TPacket packet) where TPacket : IOutgoingNetworkPacket; - public void SendPacketUdp(in TPacket packet) where TPacket : IOutgoingNetworkPacket, allows ref struct; - public void SendTeleportCarPacket(Vector3 position, Vector3 direction, Vector3 velocity = default); } diff --git a/AssettoServer/Commands/ChatService.cs b/AssettoServer/Commands/ChatService.cs index bcd9f649..ff65c422 100644 --- a/AssettoServer/Commands/ChatService.cs +++ b/AssettoServer/Commands/ChatService.cs @@ -1,14 +1,13 @@ using System; -using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using System.Threading.Tasks; using AssettoServer.Commands.Contexts; using AssettoServer.Commands.TypeParsers; -using AssettoServer.Network.Rcon; using AssettoServer.Network.Tcp; using AssettoServer.Server; using AssettoServer.Server.Plugin; +using AssettoServer.Shared.Model; using AssettoServer.Shared.Network.Packets.Shared; using AssettoServer.Utils; using Qmmands; @@ -45,9 +44,14 @@ public ChatService(ACPluginLoader loader, } } - private void OnClientConnected(PlayerClient sender, EventArgs args) + private void OnClientConnected(IClient sender, EventArgs args) { - sender.ChatMessageReceived += OnChatMessageReceived; + switch (sender) + { + case PlayerClient client: + client.ChatMessageReceived += OnChatMessageReceived; + break; + } } private async Task ProcessCommandAsync(PlayerClient client, ChatMessage message) @@ -91,9 +95,9 @@ private void OnChatMessageReceived(PlayerClient sender, ChatMessageEventArgs arg foreach (var car in _entryCarManager.EntryCars) { - if (car.Client is { HasSentFirstUpdate: true }) + if (car.Client is PlayerClient { HasSentFirstUpdate: true } playerClient) { - car.Client?.SendPacket(car.Client?.CSPVersion < CSPVersion.V0_1_80_p389 ? oldVersionMessage : args.ChatMessage); + playerClient.SendPacket(car.Client?.CSPVersion < CSPVersion.V0_1_80_p389 ? oldVersionMessage : args.ChatMessage); } } } diff --git a/AssettoServer/Network/Tcp/PlayerClient.cs b/AssettoServer/Network/Tcp/PlayerClient.cs index da826c65..88e70d9c 100644 --- a/AssettoServer/Network/Tcp/PlayerClient.cs +++ b/AssettoServer/Network/Tcp/PlayerClient.cs @@ -35,7 +35,7 @@ namespace AssettoServer.Network.Tcp; public class PlayerClient : IClient { - public CarStatus Status { get; internal set; } + public CarStatus Status { get; set; } private ACUdpServer UdpServer { get; } public ILogger Logger { get; } public byte SessionId { get; set; } @@ -174,11 +174,11 @@ public class PlayerClient : IClient /// public event EventHandler? LuaReady; - private class ACTcpClientLogEventEnricher : ILogEventEnricher + private class PlayerClientLogEventEnricher : ILogEventEnricher { private readonly PlayerClient _client; - public ACTcpClientLogEventEnricher(PlayerClient client) + public PlayerClientLogEventEnricher(PlayerClient client) { _client = client; } @@ -215,7 +215,7 @@ public PlayerClient( UdpServer = udpServer; Logger = new LoggerConfiguration() .MinimumLevel.Debug() - .Enrich.With(new ACTcpClientLogEventEnricher(this)) + .Enrich.With(new PlayerClientLogEventEnricher(this)) .WriteTo.Logger(Log.Logger) .CreateLogger(); diff --git a/AssettoServer/Server/EntryCar.cs b/AssettoServer/Server/EntryCar.cs index 8c350830..92158bf0 100644 --- a/AssettoServer/Server/EntryCar.cs +++ b/AssettoServer/Server/EntryCar.cs @@ -20,18 +20,14 @@ namespace AssettoServer.Server; public partial class EntryCar : IEntryCar { public IClient? Client { get; set; } - public CarStatus Status { get; private set; } = new(); // TODO YEET THIS SHIT public bool EnableCollisions { get; private set; } = true; - public bool ForceLights { get; set; } - public long LastActiveTime { get; internal set; } public bool HasUpdateToSend { get; internal set; } public byte SessionId { get; } public uint LastRemoteTimestamp { get; internal set; } public DriverOptionsFlags DriverOptionsFlags { get; internal set; } public string LegalTyres { get; set; } = ""; - public bool IsSpectator { get; internal set; } public string Model { get; } public string Skin { get; } @@ -40,10 +36,8 @@ public partial class EntryCar : IEntryCar public int Restrictor { get; set; } public string? FixedSetup { get; internal set; } public List AllowedGuids { get; internal set; } = new(); - public float NetworkDistanceSquared { get; internal set; } public int OutsideNetworkBubbleUpdateRateMs { get; internal set; } - internal long[] OtherCarsLastSentUpdateTime { get; } private long LastFallCheckTime{ get; set; } diff --git a/AssettoServer/Server/EntryCarManager.cs b/AssettoServer/Server/EntryCarManager.cs index c11e78e2..54165317 100644 --- a/AssettoServer/Server/EntryCarManager.cs +++ b/AssettoServer/Server/EntryCarManager.cs @@ -156,9 +156,9 @@ public void BroadcastPacket(TPacket packet, PlayerClient? sender = null { foreach (var car in EntryCars) { - if (car.Client is { HasSentFirstUpdate: true } && car.Client != sender) + if (car.Client is PlayerClient { HasSentFirstUpdate: true } client && client != sender) { - car.Client?.SendPacket(packet); + client.SendPacket(packet); } } } @@ -170,11 +170,11 @@ public void BroadcastPacketUdp(in TPacket packet, PlayerClient? sender { foreach (var car in EntryCars) { - if (car.Client is { HasSentFirstUpdate: true, HasUdpEndpoint: true } - && (!skipSender || car.Client != sender) + if (car.Client is PlayerClient { HasSentFirstUpdate: true, HasUdpEndpoint: true } client + && (!skipSender || client != sender) && (!range.HasValue || (sender != null && sender.EntryCar.IsInRange(car, range.Value)))) { - car.Client?.SendPacketUdp(in packet); + client.SendPacketUdp(in packet); } } } diff --git a/AutoModerationPlugin/AutoModerationPlugin.cs b/AutoModerationPlugin/AutoModerationPlugin.cs index eba0eeff..aad86eb3 100644 --- a/AutoModerationPlugin/AutoModerationPlugin.cs +++ b/AutoModerationPlugin/AutoModerationPlugin.cs @@ -62,7 +62,7 @@ private void OnFirstUpdateSent(PlayerClient sender, EventArgs args) private void OnAdminLoggedIn(PlayerClient sender, EventArgs args) { - _instances[sender.SessionId].AdminReset(); + _instances[sender.SessionId].AdminReset(sender); } public override async Task StartAsync(CancellationToken cancellationToken) diff --git a/AutoModerationPlugin/EntryCarAutoModeration.cs b/AutoModerationPlugin/EntryCarAutoModeration.cs index 35bbd17d..1dec9809 100644 --- a/AutoModerationPlugin/EntryCarAutoModeration.cs +++ b/AutoModerationPlugin/EntryCarAutoModeration.cs @@ -108,12 +108,12 @@ private void OnResetInvoked(EntryCar sender, EventArgs args) CurrentFlags = 0; } - internal void AdminReset() + internal void AdminReset(PlayerClient client) { OnResetInvoked(_entryCar, EventArgs.Empty); if (_serverConfiguration.Extra.EnableClientMessages) { - _entryCar.Client?.SendPacket(new AutoModerationFlags { Flags = 0 }); + client.SendPacket(new AutoModerationFlags { Flags = 0 }); } }