Skip to content

Commit 2fabb97

Browse files
committed
Add new ACTcpClient.LuaReady event, fix collision update, add noclip command (CSP 0.2.8+)
1 parent 19ef618 commit 2fabb97

File tree

10 files changed

+99
-75
lines changed

10 files changed

+99
-75
lines changed

AssettoServer/Commands/Modules/AdminModule.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
using AssettoServer.Server.Weather.Implementation;
1313
using AssettoServer.Server.Whitelist;
1414
using AssettoServer.Shared.Network.Packets.Outgoing;
15-
using AssettoServer.Shared.Network.Packets.Shared;
1615
using AssettoServer.Shared.Utils;
1716
using AssettoServer.Shared.Weather;
17+
using AssettoServer.Utils;
1818
using JetBrains.Annotations;
1919

2020
namespace AssettoServer.Commands.Modules;
@@ -269,6 +269,19 @@ public void Say([Remainder] string message)
269269
{
270270
Broadcast("CONSOLE: " + message);
271271
}
272+
273+
[Command("noclip"), RequireConnectedPlayer]
274+
public void NoClip(bool enable)
275+
{
276+
if (_configuration.CSPTrackOptions.MinimumCSPVersion is null or < CSPVersion.V0_2_8)
277+
{
278+
Reply("Noclip is disabled. Please set a minimum required CSP version of 0.2.8 (3424) or higher");
279+
return;
280+
}
281+
282+
Client?.EntryCar.SetCollisions(!enable);
283+
Reply(enable ? "Noclip enabled" : "Noclip disabled");
284+
}
272285

273286
#if DEBUG
274287
[Command("exception")]

AssettoServer/Network/CSPClientMessageHandler.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ public CSPClientMessageHandler(CSPClientMessageTypeManager cspClientMessageTypeM
2424
_entryCarManager = entryCarManager;
2525
_configuration = configuration;
2626

27-
cspClientMessageTypeManager.RegisterOnlineEvent<CollisionUpdatePacket>(OnCollisionUpdate);
27+
cspClientMessageTypeManager.RegisterOnlineEvent<CollisionUpdatePacket>((_, _) => { });
2828
cspClientMessageTypeManager.RegisterOnlineEvent<TeleportCarPacket>(OnTeleportCar);
29-
cspClientMessageTypeManager.RegisterOnlineEvent<RequestResetPacket>((client, _) => { OnResetCar(client); });
29+
cspClientMessageTypeManager.RegisterOnlineEvent<RequestResetPacket>(OnResetCar);
30+
cspClientMessageTypeManager.RegisterOnlineEvent<LuaReadyPacket>(OnLuaReady);
3031
}
3132

3233
public void OnCSPClientMessageUdp(ACTcpClient sender, PacketReader reader)
@@ -200,24 +201,21 @@ private void OnAdminPenaltyOut(ACTcpClient sender, PacketReader reader)
200201
}
201202
}
202203

203-
private void OnResetCar(ACTcpClient sender)
204+
private void OnResetCar(ACTcpClient sender, RequestResetPacket packet)
204205
{
205-
if (_configuration.Extra.EnableCarReset)
206-
sender.EntryCar.TryResetPosition();
206+
if (!_configuration.Extra.EnableCarReset) return;
207+
sender.EntryCar.TryResetPosition();
207208
}
208209

209210
private void OnTeleportCar(ACTcpClient sender, TeleportCarPacket packet)
210211
{
211212
if (!sender.IsAdministrator) return;
212-
213213
_entryCarManager.EntryCars[packet.Target].Client?.SendPacket(packet);
214214
}
215215

216-
private void OnCollisionUpdate(ACTcpClient sender, CollisionUpdatePacket packet)
216+
private void OnLuaReady(ACTcpClient sender, LuaReadyPacket packet)
217217
{
218-
if (!sender.IsAdministrator) return;
219-
220-
_entryCarManager.EntryCars[packet.Target].Client?.SendPacket(packet);
218+
sender.FireLuaReady();
221219
}
222220

223221
private static bool IsRanged(CSPClientMessageType type)
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
using System.Numerics;
2-
31
namespace AssettoServer.Network.ClientMessages;
42

53
[OnlineEvent(Key = "AS_CollisionUpdate")]
64
public class CollisionUpdatePacket : OnlineEvent<CollisionUpdatePacket>
75
{
86
[OnlineEventField(Name = "enabled")]
97
public bool Enabled;
10-
[OnlineEventField(Name = "target")]
11-
public byte Target;
128
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace AssettoServer.Network.ClientMessages;
2+
3+
[OnlineEvent(Key = "AS_LuaReady")]
4+
public class LuaReadyPacket : OnlineEvent<LuaReadyPacket>
5+
{
6+
[OnlineEventField(Name = "dummy")]
7+
public byte Dummy;
8+
}

AssettoServer/Network/Http/Authentication/ACClientAuthentication.cs

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

AssettoServer/Network/Tcp/ACTcpClient.cs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
using AssettoServer.Shared.Network.Packets.Outgoing;
2626
using AssettoServer.Shared.Network.Packets.Outgoing.Handshake;
2727
using AssettoServer.Shared.Network.Packets.Shared;
28-
using AssettoServer.Shared.Utils;
2928
using AssettoServer.Shared.Weather;
3029
using AssettoServer.Utils;
3130
using Serilog;
@@ -163,6 +162,11 @@ public class ACTcpClient : IClient
163162
/// Fires when a player has authorized for admin permissions.
164163
/// </summary>
165164
public event EventHandler<ACTcpClient, EventArgs>? LoggedInAsAdministrator;
165+
166+
/// <summary>
167+
/// Called when all Lua server scripts are loaded on the client. Warning: This can be called multiple times if scripts are reloaded!
168+
/// </summary>
169+
public event EventHandler<ACTcpClient, EventArgs>? LuaReady;
166170

167171
private class ACTcpClientLogEventEnricher : ILogEventEnricher
168172
{
@@ -234,6 +238,21 @@ public ACTcpClient(
234238
DisconnectTokenSource = new CancellationTokenSource();
235239

236240
ApiKey = Convert.ToHexString(RandomNumberGenerator.GetBytes(16));
241+
LuaReady += OnLuaReady;
242+
}
243+
244+
private void OnLuaReady(ACTcpClient sender, EventArgs args)
245+
{
246+
SendPacket(new ApiKeyPacket { Key = ApiKey });
247+
248+
var connectedCars = _entryCarManager.EntryCars.Where(c => c.Client != null || c.AiControlled).ToList();
249+
foreach (var car in connectedCars)
250+
{
251+
if (!car.EnableCollisions)
252+
{
253+
SendPacket(new CollisionUpdatePacket { SessionId = car.SessionId, Enabled = car.EnableCollisions });
254+
}
255+
}
237256
}
238257

239258
internal Task StartAsync()
@@ -1005,17 +1024,9 @@ internal void LoginAsAdministrator()
10051024
LoggedInAsAdministrator?.Invoke(this, EventArgs.Empty);
10061025
}
10071026

1008-
/// <summary>
1009-
/// Requires CSP Build >2796
1010-
/// </summary>
1011-
public void SendCollisionUpdatePacket(bool collisionEnabled)
1027+
internal void FireLuaReady()
10121028
{
1013-
_entryCarManager.BroadcastPacket(new CollisionUpdatePacket
1014-
{
1015-
SessionId = SessionId,
1016-
Enabled = collisionEnabled,
1017-
Target = SessionId
1018-
});
1029+
LuaReady?.Invoke(this, EventArgs.Empty);
10191030
}
10201031

10211032
public void SendChatMessage(string message, byte senderId = 255) => SendPacket(new ChatMessage { Message = message, SessionId = senderId });

AssettoServer/Server/EntryCar.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Numerics;
55
using System.Threading.Tasks;
6+
using AssettoServer.Network.ClientMessages;
67
using AssettoServer.Server.Ai;
78
using AssettoServer.Server.Ai.Splines;
89
using AssettoServer.Server.Configuration;
@@ -20,6 +21,7 @@ public partial class EntryCar : IEntryCar<ACTcpClient>
2021
{
2122
public ACTcpClient? Client { get; internal set; }
2223
public CarStatus Status { get; private set; } = new();
24+
public bool EnableCollisions { get; private set; } = true;
2325

2426
public bool ForceLights { get; internal set; }
2527

@@ -309,6 +311,22 @@ public bool IsInRange(EntryCar target, float range)
309311
var targetPosition = target.TargetCar != null ? target.TargetCar.Status.Position : target.Status.Position;
310312
return Vector3.DistanceSquared(Status.Position, targetPosition) < range * range;
311313
}
314+
315+
/// <summary>
316+
/// This is broken on CSP &lt; 0.2.8
317+
/// </summary>
318+
/// <param name="enable">Enable collisions</param>
319+
public void SetCollisions(bool enable)
320+
{
321+
if (EnableCollisions == enable) return;
322+
323+
EnableCollisions = enable;
324+
_entryCarManager.BroadcastPacket(new CollisionUpdatePacket
325+
{
326+
SessionId = SessionId,
327+
Enabled = EnableCollisions
328+
});
329+
}
312330

313331
public bool TryResetPosition()
314332
{
@@ -330,16 +348,14 @@ public bool TryResetPosition()
330348
var position = splinePoint.Position;
331349
var direction = - _spline.Operations.GetForwardVector(splinePoint.NextId);
332350

333-
Client?.SendCollisionUpdatePacket(false);
351+
SetCollisions(false);
334352

335353
_ = Task.Run(async () =>
336354
{
337355
await Task.Delay(500);
338-
339356
Client?.SendTeleportCarPacket(position, direction);
340357
await Task.Delay(10000);
341-
342-
Client?.SendCollisionUpdatePacket(true);
358+
SetCollisions(true);
343359
});
344360

345361
Logger.Information("Reset position for {Player} ({SessionId})",Client?.Name, Client?.SessionId);

AssettoServer/Server/Lua/assettoserver.lua

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
local license = [[
2-
Copyright (C) 2024 Niewiarowski, compujuckel
2+
Copyright (C) 2025 Niewiarowski, compujuckel
33
44
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
55
@@ -81,23 +81,35 @@ end)
8181

8282
local collisionUpdateEvent = ac.OnlineEvent({
8383
ac.StructItem.key("AS_CollisionUpdate"),
84-
enabled = ac.StructItem.boolean(),
85-
target = ac.StructItem.byte()
84+
enabled = ac.StructItem.boolean()
8685
}, function (sender, message)
8786
ac.debug("collision_update_index", sender.index)
8887
ac.debug("collision_update_enabled", message.enabled)
8988

90-
physics.disableCarCollisions(0, not message.enabled)
91-
if sender.index == 0 then
92-
for i, c in ac.iterateCars.ordered() do
93-
physics.disableCarCollisions(i, not message.enabled)
94-
end
95-
else
96-
physics.disableCarCollisions(sender.index, not message.enabled)
89+
physics.disableCarCollisions(sender.index, not message.enabled, true)
90+
end)
91+
92+
local teleportToPitsEvent = ac.OnlineEvent({
93+
ac.StructItem.key("AS_TeleportToPits"),
94+
dummy = ac.StructItem.byte()
95+
}, function (sender, message)
96+
if sender.index == 0 and ac.INIConfig.onlineExtras():get("EXTRA_RULES", "NO_BACK_TO_PITS", 0) == 0 then
97+
physics.teleportCarTo(0, ac.SpawnSet.Pits)
9798
end
9899
end)
99100

100-
apiKeyEvent({ key = "" })
101+
local requestResetCarEvent = ac.OnlineEvent({
102+
ac.StructItem.key("AS_RequestResetCar"),
103+
dummy = ac.StructItem.byte(),
104+
}, function (sender, message)
105+
if sender ~= nil then return end
106+
ac.debug("request_reset_car", message.dummy)
107+
end)
108+
109+
local luaReadyEvent = ac.OnlineEvent({
110+
ac.StructItem.key("AS_LuaReady"),
111+
dummy = ac.StructItem.byte()
112+
}, function () end)
101113

102114
local logoSize = vec2(68, 42)
103115
local srpLogoSize = vec2(244, 64)
@@ -267,22 +279,7 @@ end
267279

268280
ui.registerOnlineExtra(ui.Icons.Info, "AssettoServer", function () return true end, window_AssettoServer, nil, ui.OnlineExtraFlags.Tool)
269281

270-
local teleportToPitsEvent = ac.OnlineEvent({
271-
ac.StructItem.key("AS_TeleportToPits"),
272-
dummy = ac.StructItem.byte()
273-
}, function (sender, message)
274-
if sender.index == 0 and ac.INIConfig.onlineExtras():get("EXTRA_RULES", "NO_BACK_TO_PITS", 0) == 0 then
275-
physics.teleportCarTo(0, ac.SpawnSet.Pits)
276-
end
277-
end)
278-
279-
local requestResetCarEvent = ac.OnlineEvent({
280-
ac.StructItem.key("AS_RequestResetCar"),
281-
dummy = ac.StructItem.byte(),
282-
}, function (sender, message)
283-
if sender ~= nil then return end
284-
ac.debug("request_reset_car", message.dummy)
285-
end)
286-
287282
local resetCarControl = ac.ControlButton('__EXT_CMD_RESET', nil)
288-
resetCarControl:onPressed(function() requestResetCarEvent({dummy=0}) end)
283+
resetCarControl:onPressed(function() requestResetCarEvent({}) end)
284+
285+
luaReadyEvent({})

AssettoServer/Startup.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ public void ConfigureContainer(ContainerBuilder builder)
9292
builder.RegisterType<SignalHandler>().AsSelf().As<IHostedService>().SingleInstance();
9393
builder.RegisterType<UpnpService>().AsSelf().As<IAssettoServerAutostart>().SingleInstance();
9494
builder.RegisterType<ConfigurationSerializer>().AsSelf();
95-
builder.RegisterType<ACClientAuthentication>().AsSelf().SingleInstance().AutoActivate();
9695
builder.RegisterType<HttpInfoCache>().AsSelf().As<IAssettoServerAutostart>().SingleInstance();
9796
builder.RegisterType<DefaultCMContentProvider>().As<ICMContentProvider>().SingleInstance();
9897
builder.RegisterType<CommandService>().AsSelf().SingleInstance();

AssettoServer/Utils/CSPVersion.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ public static class CSPVersion
99
public const int V0_1_80_p389 = 2544;
1010
public const int V0_2_0 = 2651;
1111
public const int V0_2_3_p47 = 2796;
12+
public const int V0_2_8 = 3424;
1213
}

0 commit comments

Comments
 (0)