Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed port behavior of VotingPresetPlugin #114

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions AssettoServer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using AssettoServer.Server.Configuration;
using System;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AssettoServer.Server.Configuration;
using AssettoServer.Utils;
using Autofac.Extensions.DependencyInjection;
using CommandLine;
Expand All @@ -28,7 +28,7 @@ public static class Program
#else
public static readonly bool IsDebugBuild = false;
#endif

[UsedImplicitly(ImplicitUseKindFlags.Assign, ImplicitUseTargetFlags.WithMembers)]
private class Options
{
Expand Down Expand Up @@ -59,19 +59,20 @@ private class StartOptions
public string? Preset { get; init; }
public string? ServerCfgPath { get; init; }
public string? EntryListPath { get; init; }
public PortOverrides? PortOverrides { get; init; }
}

public static bool IsContentManager;
private static bool _loadPluginsFromWorkdir;
private static bool _generatePluginConfigs;
private static TaskCompletionSource<StartOptions> _restartTask = new();

internal static async Task Main(string[] args)
{
SetupFluentValidation();
SetupMetrics();
DetectContentManager();

var options = Parser.Default.ParseArguments<Options>(args).Value;
if (options == null) return;

Expand All @@ -85,21 +86,19 @@ internal static async Task Main(string[] args)

if (options.UseRandomPreset)
{

var presetsPath = Path.Join(AppContext.BaseDirectory, "presets");
var presets = Path.Exists(presetsPath) ?
Directory.EnumerateDirectories("presets").Select(Path.GetFileName).OfType<string>().ToArray() : [];

if (presets.Length > 0)
options.Preset = presets[Random.Shared.Next(presets.Length)];
else
else
Log.Warning("Presets directory does not exist or contain any preset");

}

string logPrefix = string.IsNullOrEmpty(options.Preset) ? "log" : options.Preset;
Logging.CreateDefaultLogger(logPrefix, IsContentManager, options.UseVerboseLogging);

AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
Log.Information("AssettoServer {Version}", ThisAssembly.AssemblyInformationalVersion);
if (IsContentManager)
Expand All @@ -113,12 +112,12 @@ internal static async Task Main(string[] args)
ServerCfgPath = options.ServerCfgPath,
EntryListPath = options.EntryListPath
};

while (true)
{
_restartTask = new TaskCompletionSource<StartOptions>();
using var cts = new CancellationTokenSource();
var serverTask = RunServerAsync(startOptions.Preset, startOptions.ServerCfgPath, startOptions.EntryListPath, options.UseVerboseLogging, cts.Token);
var serverTask = RunServerAsync(startOptions.Preset, startOptions.ServerCfgPath, startOptions.EntryListPath, startOptions.PortOverrides ,options.UseVerboseLogging, cts.Token);
var finishedTask = await Task.WhenAny(serverTask, _restartTask.Task);

if (finishedTask == _restartTask.Task)
Expand All @@ -132,29 +131,35 @@ internal static async Task Main(string[] args)
}
}

public static void RestartServer(string? preset, string? serverCfgPath = null, string? entryListPath = null)
public static void RestartServer(
string? preset,
string? serverCfgPath = null,
string? entryListPath = null,
PortOverrides? portOverrides = null)
{
Log.Information("Initiated in-process server restart");
_restartTask.SetResult(new StartOptions
{
Preset = preset,
ServerCfgPath = serverCfgPath,
EntryListPath = entryListPath
EntryListPath = entryListPath,
PortOverrides = portOverrides,
});
}

private static async Task RunServerAsync(
string? preset,
string? serverCfgPath,
string? entryListPath,
PortOverrides? portOverrides,
bool useVerboseLogging,
CancellationToken token = default)
{
var configLocations = ConfigurationLocations.FromOptions(preset, serverCfgPath, entryListPath);

try
{
var config = new ACServerConfiguration(preset, configLocations, _loadPluginsFromWorkdir, _generatePluginConfigs);
var config = new ACServerConfiguration(preset, configLocations, _loadPluginsFromWorkdir, _generatePluginConfigs, portOverrides);

if (config.Extra.LokiSettings != null
&& !string.IsNullOrEmpty(config.Extra.LokiSettings.Url)
Expand Down Expand Up @@ -192,7 +197,7 @@ private static async Task RunServerAsync(
.UseUrls($"http://0.0.0.0:{config.Server.HttpPort}");
})
.Build();

await host.RunAsync(token);
}
catch (Exception ex)
Expand Down Expand Up @@ -239,8 +244,8 @@ private static void SetupMetrics()
Metrics.ConfigureMeterAdapter(adapterOptions =>
{
// Disable a bunch of verbose / unnecessary default metrics
adapterOptions.InstrumentFilterPredicate = inst =>
inst.Name != "kestrel.active_connections"
adapterOptions.InstrumentFilterPredicate = inst =>
inst.Name != "kestrel.active_connections"
&& inst.Name != "http.server.active_requests"
&& inst.Name != "kestrel.queued_connections"
&& inst.Name != "http.server.request.duration"
Expand Down
17 changes: 13 additions & 4 deletions AssettoServer/Server/Configuration/ACServerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ public partial class ACServerConfiguration
*
* When "entryListPath" is set, it takes precedence and entry_list.ini will be loaded from the specified path.
*/
public ACServerConfiguration(string? preset, ConfigurationLocations locations, bool loadPluginsFromWorkdir, bool generatePluginConfigs)
public ACServerConfiguration(string? preset, ConfigurationLocations locations, bool loadPluginsFromWorkdir, bool generatePluginConfigs, PortOverrides? portOverrides)
{
Preset = preset;
BaseFolder = locations.BaseFolder;
LoadPluginsFromWorkdir = loadPluginsFromWorkdir;
GeneratePluginConfigs = generatePluginConfigs;
Server = LoadServerConfiguration(locations.ServerCfgPath);
Server = LoadServerConfiguration(locations.ServerCfgPath, portOverrides);
EntryList = LoadEntryList(locations.EntryListPath);
Setups = LoadSetups();
WelcomeMessage = LoadWelcomeMessage();
Expand Down Expand Up @@ -107,7 +107,7 @@ public ACServerConfiguration(string? preset, ConfigurationLocations locations, b
validator.ValidateAndThrow(this);
}

private ServerConfiguration LoadServerConfiguration(string path)
private ServerConfiguration LoadServerConfiguration(string path, PortOverrides? portOverrides)
{
Log.Debug("Loading server_cfg.ini from {Path}", path);
try
Expand All @@ -121,7 +121,16 @@ private ServerConfiguration LoadServerConfiguration(string path)
serverCfg.CopyTo(outFile);
}

return ServerConfiguration.FromFile(path);
var config = ServerConfiguration.FromFile(path);

if (portOverrides != null)
{
config.TcpPort = portOverrides.TcpPort;
config.UdpPort = portOverrides.UdpPort;
config.HttpPort = portOverrides.HttpPort;
}

return config;
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public class ServerConfiguration
[IniField("SERVER", "PASSWORD")] public string? Password { get; set; }
[IniField("SERVER", "ADMIN_PASSWORD")] public string? AdminPassword { get; set; }
[IniField("SERVER", "MAX_CLIENTS")] public int MaxClients { get; internal set; }
[IniField("SERVER", "UDP_PORT")] public ushort UdpPort { get; init; } = 9600;
[IniField("SERVER", "TCP_PORT")] public ushort TcpPort { get; init; } = 9600;
[IniField("SERVER", "HTTP_PORT")] public ushort HttpPort { get; init; } = 8081;
[IniField("SERVER", "UDP_PORT")] public ushort UdpPort { get; set; } = 9600;
[IniField("SERVER", "TCP_PORT")] public ushort TcpPort { get; set; } = 9600;
[IniField("SERVER", "HTTP_PORT")] public ushort HttpPort { get; set; } = 8081;
[IniField("SERVER", "CLIENT_SEND_INTERVAL_HZ")] public byte RefreshRateHz { get; init; } = 20;
[IniField("SERVER", "TRACK")] public string Track { get; internal set; } = "";
[IniField("SERVER", "CONFIG_TRACK")] public string TrackConfig { get; init; } = "";
Expand Down
8 changes: 8 additions & 0 deletions AssettoServer/Server/Configuration/PortOverrides.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace AssettoServer.Server.Configuration;

public class PortOverrides
{
public ushort TcpPort { get; set; }
public ushort UdpPort { get; set; }
public ushort HttpPort { get; set; }
}
23 changes: 15 additions & 8 deletions VotingPresetPlugin/Preset/PresetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class PresetManager : CriticalBackgroundService

private const string RestartKickReason = "SERVER RESTART FOR TRACK CHANGE (won't take long)";

public PresetManager(ACServerConfiguration acServerConfiguration,
public PresetManager(ACServerConfiguration acServerConfiguration,
EntryCarManager entryCarManager,
IHostApplicationLifetime applicationLifetime) : base(applicationLifetime)
{
Expand All @@ -30,7 +30,7 @@ public void SetPreset(PresetData preset)
{
CurrentPreset = preset;
_presetChangeRequested = true;

if (!CurrentPreset.IsInit)
_ = UpdatePreset();
}
Expand Down Expand Up @@ -60,10 +60,10 @@ private async Task UpdatePreset()
if (CurrentPreset.UpcomingType != null && !CurrentPreset.Type!.Equals(CurrentPreset.UpcomingType!))
{
Log.Information("Preset change to \'{Name}\' initiated", CurrentPreset.UpcomingType!.Name);

// Notify about restart
Log.Information("Restarting server");

if (_acServerConfiguration.Extra.EnableClientMessages)
{
// Reconnect clients
Expand All @@ -76,14 +76,21 @@ private async Task UpdatePreset()
_entryCarManager.BroadcastPacket(new CSPKickBanMessageOverride { Message = RestartKickReason });
_entryCarManager.BroadcastPacket(new KickCar { SessionId = 255, Reason = KickReason.Kicked });
}

var preset = new DirectoryInfo(CurrentPreset.UpcomingType!.PresetFolder).Name;

// Restart the server
var sleep = (CurrentPreset.TransitionDuration - 1) * 1000;
await Task.Delay(sleep);

Program.RestartServer(preset);

Program.RestartServer(
preset,
portOverrides: new PortOverrides
{
TcpPort = _acServerConfiguration.Server.TcpPort,
UdpPort = _acServerConfiguration.Server.UdpPort,
HttpPort = _acServerConfiguration.Server.HttpPort
});
}
}
}