Skip to content

Commit

Permalink
add option to allow certain users to debug scripts locally
Browse files Browse the repository at this point in the history
  • Loading branch information
compujuckel committed Apr 20, 2024
1 parent 3787933 commit 10943f3
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 19 deletions.
8 changes: 3 additions & 5 deletions AssettoServer/Network/Tcp/ACTcpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -768,13 +768,13 @@ internal void SendFirstUpdate()
_ = Task.Run(SendFirstUpdateAsync);
}

private Task SendFirstUpdateAsync()
private async Task SendFirstUpdateAsync()
{
try
{
var connectedCars = _entryCarManager.EntryCars.Where(c => c.Client != null || c.AiControlled).ToList();

SendPacket(new WelcomeMessage { Message = _cspServerExtraOptions.GenerateWelcomeMessage(this) });
SendPacket(new WelcomeMessage { Message = await _cspServerExtraOptions.GenerateWelcomeMessageAsync(this) });

_weatherManager.SendWeather(this);

Expand Down Expand Up @@ -823,7 +823,7 @@ private Task SendFirstUpdateAsync()
if (ChecksumStatus == ChecksumStatus.Failed)
{
KickForFailedChecksum();
return Task.CompletedTask;
return;
}

if (ChecksumStatus == ChecksumStatus.Pending)
Expand All @@ -845,8 +845,6 @@ private Task SendFirstUpdateAsync()
{
Log.Error(ex, "Error sending first update to {ClientName}", Name);
}

return Task.CompletedTask;
}

private void KickForFailedChecksum() => _ = _entryCarManager.KickAsync(this, KickReason.ChecksumFailed, null, null, $"{Name} failed the checksum check and has been kicked.");
Expand Down
67 changes: 58 additions & 9 deletions AssettoServer/Server/CSPServerScriptProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using AssettoServer.Network.Tcp;
using AssettoServer.Server.Configuration;
using AssettoServer.Server.UserGroup;
using IniParser.Model;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -16,10 +18,37 @@ public class CSPServerScriptProvider
internal List<Func<IActionResult>> Scripts { get; } = new();

private readonly CSPServerExtraOptions _cspServerExtraOptions;
private readonly IUserGroup? _debugUserGroup;

public CSPServerScriptProvider(CSPServerExtraOptions cspServerExtraOptions)
private string _serverScripts = "";
private string _serverScriptsDebug = "";

public CSPServerScriptProvider(CSPServerExtraOptions cspServerExtraOptions,
ACServerConfiguration configuration,
UserGroupManager userGroupManager,
CSPServerExtraOptions extraOptions)
{
_cspServerExtraOptions = cspServerExtraOptions;

if (!string.IsNullOrEmpty(configuration.Extra.DebugScriptUserGroup))
{
_debugUserGroup = userGroupManager.Resolve(configuration.Extra.DebugScriptUserGroup);
}

extraOptions.CSPServerExtraOptionsSending += OnExtraOptionsSending;
}

private async void OnExtraOptionsSending(ACTcpClient sender, CSPServerExtraOptionsSendingEventArgs args)
{
using var _ = args.GetDeferral();
if (_debugUserGroup != null && await _debugUserGroup.ContainsAsync(sender.Guid))
{
args.Builder.Append(_serverScriptsDebug);
}
else
{
args.Builder.Append(_serverScripts);
}
}

public virtual void AddScript(Stream stream, string? debugFilename = null, Dictionary<string, object>? configuration = null)
Expand All @@ -42,31 +71,51 @@ public virtual void AddScript(string script, string? debugFilename = null, Dicti
public virtual void AddScript(byte[] script, string? debugFilename = null, Dictionary<string, object>? configuration = null)
=> AddScriptInternal(() => new FileContentResult(script, "text/x-lua") { FileDownloadName = debugFilename }, debugFilename, configuration);

private void AddScriptInternal(Func<IActionResult> script, string? debugFilename = null, Dictionary<string, object>? configuration = null)
private string PrepareScriptSection(string address, string? debugFilename = null, Dictionary<string, object>? configuration = null)
{
var data = new IniData();
var scriptSection = data[$"SCRIPT_{10 + Scripts.Count}-{debugFilename}"];
scriptSection["SCRIPT"] = address;

if (configuration != null)
{
foreach ((string key, object value) in configuration)
{
scriptSection.AddKey(key, value.ToString());
}
}

return data.ToString();
}

private void AddScriptInternal(Func<IActionResult> script, string? debugFilename = null, Dictionary<string, object>? configuration = null)
{
string section;
if (Program.IsDebugBuild && !string.IsNullOrEmpty(debugFilename))
{
Log.Warning("Loading Lua script {File} locally, don't forget to sync changes for release", debugFilename);
scriptSection["SCRIPT"] = debugFilename;
section = PrepareScriptSection(debugFilename, debugFilename, configuration);
}
else
{
scriptSection["SCRIPT"] = $"'http://{{ServerIP}}:{{ServerHTTPPort}}/api/scripts/{Scripts.Count}'";
section = PrepareScriptSection($"'http://{{ServerIP}}:{{ServerHTTPPort}}/api/scripts/{Scripts.Count}'", debugFilename, configuration);
}

Scripts.Add(script);
_serverScripts += $"\r\n{section}\r\n";

if (configuration != null)
if (!string.IsNullOrEmpty(debugFilename))
{
foreach ((string key, object value) in configuration)
Dictionary<string, object>? debugConfig = null;
if (configuration != null)
{
scriptSection.AddKey(key, value.ToString());
debugConfig = new Dictionary<string, object>(configuration);
debugConfig.Remove("CHECKSUM");
}

section = PrepareScriptSection(debugFilename, debugFilename, debugConfig);
_serverScriptsDebug += $"\r\n{section}\r\n";
}

_cspServerExtraOptions.ExtraOptions += $"\r\n{data}\r\n";
Scripts.Add(script);
}
}
9 changes: 5 additions & 4 deletions AssettoServer/Server/Configuration/CSPServerExtraOptions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.IO;
using System.Text;
using System.Threading.Tasks;
using AssettoServer.Network.Tcp;
using AssettoServer.Shared.Network.Packets.Outgoing;
using AssettoServer.Shared.Utils;
Expand Down Expand Up @@ -41,7 +42,7 @@ public CSPServerExtraOptions(ACServerConfiguration configuration)
}
}

internal string GenerateWelcomeMessage(ACTcpClient client)
internal async Task<string> GenerateWelcomeMessageAsync(ACTcpClient client)
{
var sb = new StringBuilder();
sb.Append(WelcomeMessage);
Expand All @@ -53,15 +54,15 @@ internal string GenerateWelcomeMessage(ACTcpClient client)

sb.AppendLine(ExtraOptions);
sb.AppendLine(_configuration.CSPExtraOptions);
CSPServerExtraOptionsSending?.Invoke(client, new CSPServerExtraOptionsSendingEventArgs { Builder = sb });
await CSPServerExtraOptionsSending.InvokeAsync(client, new CSPServerExtraOptionsSendingEventArgs { Builder = sb });
var extraOptions = sb.ToString();

var encodedWelcomeMessage = CSPServerExtraOptionsParser.Encode(welcomeMessage, extraOptions);

if (_configuration.Extra.DebugWelcomeMessage)
{
File.WriteAllText(Path.Join(_configuration.BaseFolder, $"debug_welcome.{client.SessionId}.txt"), encodedWelcomeMessage);
File.WriteAllText(Path.Join(_configuration.BaseFolder, $"debug_csp_extra_options.{client.SessionId}.ini"), extraOptions);
await File.WriteAllTextAsync(Path.Join(_configuration.BaseFolder, $"debug_welcome.{client.SessionId}.txt"), encodedWelcomeMessage);
await File.WriteAllTextAsync(Path.Join(_configuration.BaseFolder, $"debug_csp_extra_options.{client.SessionId}.ini"), extraOptions);
}

if (encodedWelcomeMessage.Length > 2039 && client.CSPVersion is null or < CSPVersion.V0_1_77)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public partial class ACExtraConfiguration : ObservableObject
public ushort RconPort { get; init; } = 0;
[YamlMember(Description = "Dump contents of welcome message and CSP extra options to a file. For debug purposes only.", DefaultValuesHandling = DefaultValuesHandling.OmitDefaults)]
public bool DebugWelcomeMessage { get; init; } = false;
[YamlMember(Description = "Server scripts for this user group will be loaded locally and script checksums disabled. For debug purposes only.", DefaultValuesHandling = DefaultValuesHandling.OmitDefaults)]
public string? DebugScriptUserGroup { get; init; }
[YamlMember(Description = "Force clients to use track params (coordinates, time zone) specified on the server. CSP 0.1.79+ required")]
public bool ForceServerTrackParams { get; init; } = false;
[YamlMember(Description = "Allow cars to have multiple data checksums. Instead of a single checksummed data.acd, you can have multiple data*.acd files in the car folder and players can join with any of these files")]
Expand Down
2 changes: 1 addition & 1 deletion AssettoServer/Server/EventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class WelcomeMessageSendingEventArgs : EventArgs
public required StringBuilder Builder { get; init; }
}

public class CSPServerExtraOptionsSendingEventArgs : EventArgs
public class CSPServerExtraOptionsSendingEventArgs : DeferredEventArgs
{
public required StringBuilder Builder { get; init; }
}
Expand Down

0 comments on commit 10943f3

Please sign in to comment.