Skip to content

Commit 673cede

Browse files
committed
* Get rid of CountedArray
* New parameter leaveOpen for CSPServerScriptProvider.AddScript (defaults to false) * Require CSP >= 0.2.0 for UDP client messages
1 parent f6b03d6 commit 673cede

File tree

12 files changed

+60
-80
lines changed

12 files changed

+60
-80
lines changed
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
namespace AssettoServer.Shared.Network.Packets.Outgoing;
22

3-
public readonly struct BatchedPositionUpdate : IOutgoingNetworkPacket
3+
public readonly ref struct BatchedPositionUpdate : IOutgoingNetworkPacket
44
{
55
public readonly uint Timestamp;
66
public readonly ushort Ping;
7-
public readonly ArraySegment<PositionUpdateOut> Updates;
7+
public readonly ReadOnlySpan<PositionUpdateOut> Updates;
88

9-
public BatchedPositionUpdate(uint timestamp, ushort ping, ArraySegment<PositionUpdateOut> updates)
9+
public BatchedPositionUpdate(uint timestamp, ushort ping, ReadOnlySpan<PositionUpdateOut> updates)
1010
{
1111
Timestamp = timestamp;
1212
Ping = ping;
@@ -18,10 +18,10 @@ public void ToWriter(ref PacketWriter writer)
1818
writer.Write((byte)ACServerProtocol.MegaPacket);
1919
writer.Write(Timestamp);
2020
writer.Write(Ping);
21-
writer.Write((byte)Updates.Count);
22-
for (int i = 0; i < Updates.Count; i++)
21+
writer.Write((byte)Updates.Length);
22+
for (int i = 0; i < Updates.Length; i++)
2323
{
2424
Updates[i].ToWriter(ref writer, true);
2525
}
2626
}
27-
}
27+
}

AssettoServer.Shared/Network/Packets/Outgoing/CSPPositionUpdate.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace AssettoServer.Shared.Network.Packets.Outgoing;
22

3-
public readonly struct CSPPositionUpdate : IOutgoingNetworkPacket
3+
public readonly ref struct CSPPositionUpdate : IOutgoingNetworkPacket
44
{
55
public const string CustomUpdateFormat = @"packet:
66
group:
@@ -23,9 +23,9 @@
2323
gas: byte, /255
2424
performanceDelta: short";
2525

26-
public readonly ArraySegment<PositionUpdateOut> Updates;
26+
public readonly ReadOnlySpan<PositionUpdateOut> Updates;
2727

28-
public CSPPositionUpdate(ArraySegment<PositionUpdateOut> updates)
28+
public CSPPositionUpdate(ReadOnlySpan<PositionUpdateOut> updates)
2929
{
3030
Updates = updates;
3131
}
@@ -34,8 +34,8 @@ public void ToWriter(ref PacketWriter writer)
3434
{
3535
writer.Write((byte)ACServerProtocol.Extended);
3636
writer.Write((byte)CSPMessageTypeUdp.CustomUpdate);
37-
writer.Write((byte)Updates.Count);
38-
for (int i = 0; i < Updates.Count; i++)
37+
writer.Write((byte)Updates.Length);
38+
for (int i = 0; i < Updates.Length; i++)
3939
{
4040
Updates[i].ToWriterCustom(ref writer);
4141
}

AssettoServer.Shared/Network/Packets/PacketWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public PacketWriter(Memory<byte> buffer)
2929
_writePosition = 0;
3030
}
3131

32-
public int WritePacket<TPacket>(in TPacket packet) where TPacket : IOutgoingNetworkPacket
32+
public int WritePacket<TPacket>(in TPacket packet) where TPacket : IOutgoingNetworkPacket, allows ref struct
3333
{
3434
packet.ToWriter(ref this);
3535
return _writePosition;

AssettoServer/Network/Tcp/ACTcpClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ public void SendPacket<TPacket>(TPacket packet) where TPacket : IOutgoingNetwork
279279
}
280280
}
281281

282-
public void SendPacketUdp<TPacket>(in TPacket packet) where TPacket : IOutgoingNetworkPacket
282+
public void SendPacketUdp<TPacket>(in TPacket packet) where TPacket : IOutgoingNetworkPacket, allows ref struct
283283
{
284284
if (UdpEndpoint == null) return;
285285

AssettoServer/Server/ACServer.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading.Tasks;
55
using System.Collections.Generic;
66
using System.Reflection;
7+
using System.Runtime.InteropServices;
78
using AssettoServer.Server.Configuration;
89
using AssettoServer.Server.Ai.Splines;
910
using AssettoServer.Server.Blacklist;
@@ -66,8 +67,7 @@ public ACServer(
6667
{
6768
if (_configuration.CSPTrackOptions.MinimumCSPVersion < CSPVersion.V0_1_77)
6869
{
69-
throw new ConfigurationException(
70-
"Client messages need a minimum required CSP version of 0.1.77 (1937)");
70+
throw new ConfigurationException("Client messages need a minimum required CSP version of 0.1.77 (1937)");
7171
}
7272

7373
cspFeatureManager.Add(new CSPFeature { Name = "CLIENT_MESSAGES", Mandatory = true });
@@ -76,16 +76,20 @@ public ACServer(
7676

7777
if (_configuration.Extra.EnableUdpClientMessages)
7878
{
79+
if (_configuration.CSPTrackOptions.MinimumCSPVersion < CSPVersion.V0_2_0)
80+
{
81+
throw new ConfigurationException("UDP Client messages need a minimum required CSP version of 0.2.0 (2651)");
82+
}
83+
7984
cspFeatureManager.Add(new CSPFeature { Name = "CLIENT_UDP_MESSAGES" });
8085
}
8186

8287
if (_configuration.Extra.EnableCustomUpdate)
8388
{
8489
cspFeatureManager.Add(new CSPFeature { Name = "CUSTOM_UPDATE" });
8590
}
86-
87-
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("AssettoServer.Server.Lua.assettoserver.lua")!;
88-
cspServerScriptProvider.AddScript(stream, "assettoserver.lua");
91+
92+
cspServerScriptProvider.AddScript(Assembly.GetExecutingAssembly().GetManifestResourceStream("AssettoServer.Server.Lua.assettoserver.lua")!, "assettoserver.lua");
8993

9094
if (_configuration.Extra.EnableCarReset)
9195
{
@@ -146,10 +150,10 @@ private void MainLoop(CancellationToken stoppingToken)
146150
int failedUpdateLoops = 0;
147151
int sleepMs = 1000 / _configuration.Server.RefreshRateHz;
148152
long nextTick = _sessionManager.ServerTimeMilliseconds;
149-
Dictionary<EntryCar, CountedArray<PositionUpdateOut>> positionUpdates = new();
153+
Dictionary<EntryCar, List<PositionUpdateOut>> positionUpdates = new();
150154
foreach (var entryCar in _entryCarManager.EntryCars)
151155
{
152-
positionUpdates[entryCar] = new CountedArray<PositionUpdateOut>(_entryCarManager.EntryCars.Length);
156+
positionUpdates[entryCar] = new List<PositionUpdateOut>(_entryCarManager.EntryCars.Length);
153157
}
154158

155159
Log.Information("Starting update loop with an update rate of {RefreshRateHz}hz", _configuration.Server.RefreshRateHz);
@@ -219,13 +223,13 @@ private void MainLoop(CancellationToken stoppingToken)
219223
{
220224
if (toClient.SupportsCSPCustomUpdate)
221225
{
222-
var packet = new CSPPositionUpdate(new ArraySegment<PositionUpdateOut>(updates.Array, i, Math.Min(chunkSize, updates.Count - i)));
226+
var packet = new CSPPositionUpdate(CollectionsMarshal.AsSpan(updates).Slice(i, Math.Min(chunkSize, updates.Count - i)));
223227
toClient.SendPacketUdp(in packet);
224228
}
225229
else
226230
{
227231
var packet = new BatchedPositionUpdate((uint)(_sessionManager.ServerTimeMilliseconds - toCar.TimeOffset), toCar.Ping,
228-
new ArraySegment<PositionUpdateOut>(updates.Array, i, Math.Min(chunkSize, updates.Count - i)));
232+
CollectionsMarshal.AsSpan(updates).Slice(i, Math.Min(chunkSize, updates.Count - i)));
229233
toClient.SendPacketUdp(in packet);
230234
}
231235
}

AssettoServer/Server/Ai/AiBehavior.cs

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ public AiBehavior(SessionManager sessionManager,
4848

4949
if (_configuration.Extra.AiParams.Debug)
5050
{
51-
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("AssettoServer.Server.Ai.ai_debug.lua")!;
52-
serverScriptProvider.AddScript(stream, "ai_debug.lua");
51+
serverScriptProvider.AddScript(Assembly.GetExecutingAssembly().GetManifestResourceStream("AssettoServer.Server.Ai.ai_debug.lua")!, "ai_debug.lua");
5352
}
5453

5554
_updateDurationTimer = Metrics.CreateSummary("assettoserver_aibehavior_update", "AiBehavior.Update Duration", MetricDefaults.DefaultQuantiles);
@@ -118,45 +117,42 @@ private async Task ObstacleDetectionAsync(CancellationToken stoppingToken)
118117

119118
private void SendDebugPackets()
120119
{
121-
CountedArray<byte> sessionIds = new(_entryCarManager.EntryCars.Length);
122-
CountedArray<byte> currentSpeeds = new(_entryCarManager.EntryCars.Length);
123-
CountedArray<byte> targetSpeeds = new(_entryCarManager.EntryCars.Length);
124-
CountedArray<byte> maxSpeeds = new(_entryCarManager.EntryCars.Length);
125-
CountedArray<short> closestAiObstacles = new(_entryCarManager.EntryCars.Length);
120+
var sessionIds = new byte[_entryCarManager.EntryCars.Length];
121+
var currentSpeeds = new byte[_entryCarManager.EntryCars.Length];
122+
var targetSpeeds = new byte[_entryCarManager.EntryCars.Length];
123+
var maxSpeeds = new byte[_entryCarManager.EntryCars.Length];
124+
var closestAiObstacles = new short[_entryCarManager.EntryCars.Length];
125+
126126
foreach (var player in _entryCarManager.ConnectedCars.Values)
127127
{
128128
if (player.Client?.HasSentFirstUpdate == false) continue;
129129

130-
sessionIds.Clear();
131-
currentSpeeds.Clear();
132-
targetSpeeds.Clear();
133-
maxSpeeds.Clear();
134-
closestAiObstacles.Clear();
135-
130+
var count = 0;
136131
foreach (var car in _entryCarManager.EntryCars)
137132
{
138133
if (!car.AiControlled) continue;
139134

140135
var (aiState, _) = car.GetClosestAiState(player.Status.Position);
141136
if (aiState == null) continue;
142137

143-
sessionIds.Add(car.SessionId);
144-
currentSpeeds.Add((byte)(aiState.CurrentSpeed * 3.6f));
145-
targetSpeeds.Add((byte)(aiState.TargetSpeed * 3.6f));
146-
maxSpeeds.Add((byte)(aiState.MaxSpeed * 3.6f));
147-
closestAiObstacles.Add((short)aiState.ClosestAiObstacleDistance);
138+
sessionIds[count] = car.SessionId;
139+
currentSpeeds[count] = (byte)(aiState.CurrentSpeed * 3.6f);
140+
targetSpeeds[count] = (byte)(aiState.TargetSpeed * 3.6f);
141+
maxSpeeds[count] = (byte)(aiState.MaxSpeed * 3.6f);
142+
closestAiObstacles[count] = (short)aiState.ClosestAiObstacleDistance;
143+
count++;
148144
}
149145

150-
for (int i = 0; i < sessionIds.Count; i += AiDebugPacket.Length)
146+
for (int i = 0; i < count; i += AiDebugPacket.Length)
151147
{
152148
var packet = new AiDebugPacket();
153149
Array.Fill(packet.SessionIds, (byte)255);
154150

155-
new ArraySegment<byte>(sessionIds.Array, i, Math.Min(AiDebugPacket.Length, sessionIds.Count - i)).CopyTo(packet.SessionIds);
156-
new ArraySegment<short>(closestAiObstacles.Array, i, Math.Min(AiDebugPacket.Length, sessionIds.Count - i)).CopyTo(packet.ClosestAiObstacles);
157-
new ArraySegment<byte>(currentSpeeds.Array, i, Math.Min(AiDebugPacket.Length, sessionIds.Count - i)).CopyTo(packet.CurrentSpeeds);
158-
new ArraySegment<byte>(maxSpeeds.Array, i, Math.Min(AiDebugPacket.Length, sessionIds.Count - i)).CopyTo(packet.MaxSpeeds);
159-
new ArraySegment<byte>(targetSpeeds.Array, i, Math.Min(AiDebugPacket.Length, sessionIds.Count - i)).CopyTo(packet.TargetSpeeds);
151+
new ArraySegment<byte>(sessionIds, i, Math.Min(AiDebugPacket.Length, count - i)).CopyTo(packet.SessionIds);
152+
new ArraySegment<short>(closestAiObstacles, i, Math.Min(AiDebugPacket.Length, count - i)).CopyTo(packet.ClosestAiObstacles);
153+
new ArraySegment<byte>(currentSpeeds, i, Math.Min(AiDebugPacket.Length, count - i)).CopyTo(packet.CurrentSpeeds);
154+
new ArraySegment<byte>(maxSpeeds, i, Math.Min(AiDebugPacket.Length, count - i)).CopyTo(packet.MaxSpeeds);
155+
new ArraySegment<byte>(targetSpeeds, i, Math.Min(AiDebugPacket.Length, count - i)).CopyTo(packet.TargetSpeeds);
160156

161157
player.Client?.SendPacket(packet);
162158
}

AssettoServer/Server/CSPServerScriptProvider.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,17 @@ private async void OnExtraOptionsSending(ACTcpClient sender, CSPServerExtraOptio
5151
}
5252
}
5353

54-
public virtual void AddScript(Stream stream, string? debugFilename = null, Dictionary<string, object>? configuration = null)
54+
public virtual void AddScript(Stream stream, string? debugFilename = null, Dictionary<string, object>? configuration = null, bool leaveOpen = false)
5555
{
5656
using var memory = new MemoryStream();
5757
stream.CopyTo(memory);
5858
var bytes = memory.ToArray();
5959
AddScript(bytes, debugFilename, configuration);
60+
61+
if (!leaveOpen)
62+
{
63+
stream.Dispose();
64+
}
6065
}
6166

6267
public virtual void AddScriptFile(string path, string? debugFilename = null, Dictionary<string, object>? configuration = null)

AssettoServer/Server/Steam/WebApiSteam.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ public WebApiSteam(ACServerConfiguration configuration)
1818

1919
if (string.IsNullOrEmpty(_configuration.Extra.SteamWebApiKey))
2020
{
21-
throw new ConfigurationException("Steam Web API key is required for Steam Authentication on this platform. Visit https://steamcommunity.com/dev/apikey to get a key");
21+
throw new ConfigurationException(
22+
"Steam Web API key is required for Steam Authentication on this platform. Visit https://steamcommunity.com/dev/apikey to get a key")
23+
{
24+
HelpLink = "https://steamcommunity.com/dev/apikey"
25+
};
2226
}
2327
}
2428

AssettoServer/Utils/CountedArray.cs

Lines changed: 0 additions & 22 deletions
This file was deleted.

AutoModerationPlugin/AutoModerationPlugin.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ public AutoModerationPlugin(AutoModerationConfiguration configuration,
4545

4646
if (serverConfiguration.Extra.EnableClientMessages)
4747
{
48-
using var streamReader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("AutoModerationPlugin.lua.automoderation.lua")!);
49-
scriptProvider.AddScript(streamReader.ReadToEnd(), "automoderation.lua");
48+
scriptProvider.AddScript(Assembly.GetExecutingAssembly().GetManifestResourceStream("AutoModerationPlugin.lua.automoderation.lua")!, "automoderation.lua");
5049
}
5150

5251
if (_configuration.AfkPenalty is { Enabled: true, Behavior: AfkPenaltyBehavior.MinimumSpeed })

0 commit comments

Comments
 (0)