Skip to content

Commit

Permalink
Added support for per-team role vehicle spawner delays, renamed some …
Browse files Browse the repository at this point in the history
…team stuff
  • Loading branch information
benvalkin committed Dec 19, 2024
1 parent a15e8bf commit c470028
Show file tree
Hide file tree
Showing 18 changed files with 169 additions and 78 deletions.
Binary file modified Libraries/Assembly-CSharp.dll
Binary file not shown.
Binary file modified Libraries/SDG.NetPak.Runtime.dll
Binary file not shown.
Binary file modified Libraries/SDG.NetTransport.dll
Binary file not shown.
Binary file modified Libraries/UnityEx.dll
Binary file not shown.
Binary file modified Libraries/UnturnedDat.dll
Binary file not shown.
Binary file modified Libraries/com.rlabrecque.steamworks.net.dll
Binary file not shown.
42 changes: 42 additions & 0 deletions UncreatedWarfare/Database/SshTunnelHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Runtime.CompilerServices;
using System;
using Uncreated.Warfare.Database;
using DanielWillett.ReflectionTools;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

// only initialize if library exists
public static class SshTunnelHelper
{
public static void AddSshTunnelService(ContainerBuilder serviceCollection)
{
serviceCollection.RegisterType(GetServiceType())
.SingleInstance();
}

public static UniTask OpenIfAvailableAsync(ILifetimeScope serviceProvider, CancellationToken token)
{
string? configuredSshKey = serviceProvider.ResolveOptional<IConfiguration>()?.GetSection("database")?["ssh_key"];

if (string.IsNullOrEmpty(configuredSshKey))
return UniTask.CompletedTask;

object? service = serviceProvider.ResolveOptional(GetServiceType());
if (service != null)
{
return OpenAsync(service, token);
}

return UniTask.CompletedTask;
}

private static UniTask OpenAsync(object service, CancellationToken token)
{
SshTunnelService sshTunnel = (SshTunnelService)service;

return sshTunnel.StartAsync(token);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static Type GetServiceType() => typeof(SshTunnelService);
}
38 changes: 1 addition & 37 deletions UncreatedWarfare/Database/SshTunnelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,6 @@

namespace Uncreated.Warfare.Database;

// only initialize if library exists
public static class SshTunnelHelper
{
public static void AddIfAvailable(ContainerBuilder serviceCollection)
{
if (Type.GetType("Renci.SshNet.ISshClient, Renci.SshNet, Version=2024.2.0.1", false) == null)
return;

serviceCollection.RegisterType(GetServiceType())
.SingleInstance();
}

public static UniTask OpenIfAvailableAsync(ILifetimeScope serviceProvider, CancellationToken token)
{
if (Type.GetType("Renci.SshNet.ISshClient, Renci.SshNet", false) == null)
return UniTask.CompletedTask;

object? service = serviceProvider.ResolveOptional(GetServiceType());
if (service != null)
{
return OpenAsync(service, token);
}

return UniTask.CompletedTask;
}

private static UniTask OpenAsync(object service, CancellationToken token)
{
SshTunnelService sshTunnel = (SshTunnelService)service;

return sshTunnel.StartAsync(token);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static Type GetServiceType() => typeof(SshTunnelService);
}

[Ignore]
public class SshTunnelService : IDisposable
{
Expand All @@ -56,6 +19,7 @@ public SshTunnelService(IConfiguration systemConfig, ILogger<SshTunnelService> l
{
_systemConfig = systemConfig.GetSection("database");
_logger = logger;

}

public async UniTask StartAsync(CancellationToken cancellationToken)
Expand Down
11 changes: 11 additions & 0 deletions UncreatedWarfare/Layouts/Teams/LayoutRole.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Uncreated.Warfare.Layouts.Teams;
public enum LayoutRole
{
NotApplicable,
Blufor,
Opfor
}
11 changes: 11 additions & 0 deletions UncreatedWarfare/Layouts/Teams/TwoSidedTeamManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Uncreated.Warfare.Configuration;
using Uncreated.Warfare.Database.Abstractions;
using Uncreated.Warfare.Events;
Expand Down Expand Up @@ -89,6 +90,16 @@ public Team GetTeam(CSteamID groupId)

return Team.NoTeam;
}
public LayoutRole GetLayoutRole(Team team)
{
if (_blufor > -1 && team == _teams[_blufor])
return LayoutRole.Blufor;

if (_opfor > -1 && team == _teams[_opfor])
return LayoutRole.Opfor;

return LayoutRole.NotApplicable;
}

/// <inheritdoc />
public async UniTask JoinTeamAsync(WarfarePlayer player, Team team, CancellationToken token = default)
Expand Down
8 changes: 6 additions & 2 deletions UncreatedWarfare/Signs/VehicleBaySignInstanceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,16 @@ private void TranslateKitSign(StringBuilder bldr, WarfareVehicleInfo info, Vehic
case VehicleSpawnerState.Idle:
bldr.Append(_translations.VBSStateIdle.Translate(spawner.GetRespawnDueTime(), language, culture));
break;
case VehicleSpawnerState.LayoutDelayed:
bldr.Append(_translations.VBSStateLayoutDelayed.Translate(spawner.GetLayoutDelayTimeLeft(), language, culture));
break;
case VehicleSpawnerState.LayoutDisabled:
bldr.Append(_translations.VBSStateLayoutDisabled.Translate(language));
break;
case VehicleSpawnerState.Disposed:
bldr.Append(_translations.VBSStateDisposed.Translate(language));
break;

// todo delays

default:
bldr.Append(_translations.VBSStateReady.Translate(language));
break;
Expand Down Expand Up @@ -174,6 +175,9 @@ public class VehicleBaySignTranslations : PropertiesTranslationCollection
[TranslationData("Displays the state of the sign when the vehicle was left idle on the field.", Parameters = [ "Minutes", "Seconds" ])]
public readonly Translation<TimeSpan> VBSStateIdle = new Translation<TimeSpan>("<#ffcc00>Idle: {0}</color>", arg0Fmt: TimeAddon.Create(TimeFormatType.CountdownMinutesSeconds));

[TranslationData("Displays the state of the sign when the vehicle spawner is currently delayed by the current layout.")]
public readonly Translation<TimeSpan> VBSStateLayoutDelayed = new Translation<TimeSpan>("<#7094dd>Delayed: {0}</color>", arg0Fmt: TimeAddon.Create(TimeFormatType.CountdownMinutesSeconds));

[TranslationData("Displays the state of the sign when the vehicle spawner is disabled in the current layout.")]
public readonly Translation VBSStateLayoutDisabled = new Translation("<#798082>Disabled</color>");

Expand Down
25 changes: 0 additions & 25 deletions UncreatedWarfare/Vehicles/Spawners/Delays/ActionPhaseStartDelay.cs

This file was deleted.

20 changes: 16 additions & 4 deletions UncreatedWarfare/Vehicles/Spawners/Delays/ILayoutDelay.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
using System;
using Cysharp.Threading.Tasks;
using DanielWillett.ReflectionTools;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Stripe;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Text;
using System.Text.Json;
using Uncreated.Warfare.Configuration;
using Uncreated.Warfare.Configuration.TypeConverters;
using Uncreated.Warfare.Layouts;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;

namespace Uncreated.Warfare.Vehicles.Spawners.Delays;
public interface ILayoutDelay
public interface ILayoutDelay<TContext> where TContext : LayoutDelayContext
{
TimeSpan GetTimeLeft(Layout currentLayout);
}
TimeSpan GetTimeLeft(TContext context);
}
18 changes: 18 additions & 0 deletions UncreatedWarfare/Vehicles/Spawners/Delays/LayoutDelayContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using Uncreated.Warfare.Layouts;
using Uncreated.Warfare.Layouts.Teams;

namespace Uncreated.Warfare.Vehicles.Spawners.Delays;
public class LayoutDelayContext
{
public Layout CurrentLayout { get; }
public LayoutRole? AffectedTeam { get; }

public LayoutDelayContext(Layout currentLayout, LayoutRole affectedTeam = LayoutRole.NotApplicable)
{
CurrentLayout = currentLayout;
AffectedTeam = affectedTeam;
}
}
26 changes: 26 additions & 0 deletions UncreatedWarfare/Vehicles/Spawners/Delays/TimerDelay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using Uncreated.Warfare.Layouts;
using Uncreated.Warfare.Layouts.Phases;
using Uncreated.Warfare.Layouts.Teams;

namespace Uncreated.Warfare.Vehicles.Spawners.Delays;
public class TimerDelay : ILayoutDelay<LayoutDelayContext>
{
public TimeSpan Timer { get; set; }
public LayoutRole AffectedTeam { get; set; } = LayoutRole.NotApplicable;

public TimeSpan GetTimeLeft(LayoutDelayContext context)
{
if (AffectedTeam != LayoutRole.NotApplicable && AffectedTeam != context.AffectedTeam)
return TimeSpan.Zero;

if (context.CurrentLayout.ActivePhase is ActionPhase actionPhase)
{
return Timer - actionPhase.TimeElapsedSinceActive;
}

return Timer;
}
}
42 changes: 34 additions & 8 deletions UncreatedWarfare/Vehicles/Spawners/VehicleSpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
using Uncreated.Warfare.Layouts;
using Uncreated.Warfare.Vehicles.Spawners.Delays;

namespace Uncreated.Warfare.Vehicles.Spawners
{
Expand Down Expand Up @@ -54,6 +55,7 @@ public class VehicleSpawner : IRequestable<VehicleSpawner>, IDisposable
/// A vehicle that has been spawned from this spawn.
/// </summary>
public InteractableVehicle? LinkedVehicle { get; private set; }
public Team Team { get; private set; }
public IBuildable? Buildable { get; private set; }
public List<IBuildable> Signs { get; }
public string ServerSignText => "vbs_" + SpawnInfo.VehicleAsset.Guid.ToString("N", CultureInfo.InvariantCulture);
Expand All @@ -71,6 +73,8 @@ private set
}
}

public LayoutRole TeamLayoutRole { get; private set; }

public VehicleSpawner(VehicleSpawnInfo spawnerInfo, WarfareVehicleInfo vehicleInfo, ILoopTicker updateTicker, IServiceProvider layoutServiceProvider)
{
_logger = layoutServiceProvider.GetRequiredService<ILogger<VehicleSpawner>>();
Expand Down Expand Up @@ -136,6 +140,23 @@ private void ResolveBuildable(VehicleSpawnInfo spawnerInfo)
Buildable = new BuildableBarricade(buildableInfo.Drop);
}
}


if (Buildable != null)
{
Team = _teamManager.GetTeam(Buildable.Group);

if (_teamManager is TwoSidedTeamManager ts)
TeamLayoutRole = ts.GetLayoutRole(Team);
else
TeamLayoutRole = LayoutRole.NotApplicable;

}
else
{
TeamLayoutRole = LayoutRole.NotApplicable;
Team = Team.NoTeam;
}
}
private void ResolveSigns(VehicleSpawnInfo spawnerInfo)
{
Expand Down Expand Up @@ -237,7 +258,10 @@ private void Update(ILoopTicker ticker, TimeSpan timeSinceStart, TimeSpan deltaT

if (LinkedVehicle != null && !LinkedVehicle.isExploded && !LinkedVehicle.isDead && !LinkedVehicle.isDrowned)
{
State = VehicleSpawnerState.Ready;
if (IsDelayed(out _))
State = VehicleSpawnerState.LayoutDelayed;
else
State = VehicleSpawnerState.Ready;
_lastLocation = null;
_timeStartedIdle = DateTime.MaxValue;
_timeDestroyed = DateTime.MaxValue;
Expand Down Expand Up @@ -457,19 +481,21 @@ internal void UnlinkVehicle()
}
public bool IsDelayed(out TimeSpan timeLeft)
{
timeLeft = TimeSpan.Zero;

timeLeft = GetLayoutDelayTimeLeft();
return timeLeft > TimeSpan.Zero;
}
public TimeSpan GetLayoutDelayTimeLeft()
{
if (_vehicleSpawnerSelector == null || _currentLayout == null)
return false;
return TimeSpan.Zero;

if (!_vehicleSpawnerSelector.TryGetSpawnerConfiguration(SpawnInfo, out VehicleSpawnerLayoutConfiguration? configuration))
return false;
return TimeSpan.Zero;

if (configuration.Delay == null)
return false;
return TimeSpan.Zero;

timeLeft = configuration.Delay.GetTimeLeft(_currentLayout);
return timeLeft > TimeSpan.Zero;
return configuration.Delay.GetTimeLeft(new LayoutDelayContext(_currentLayout, TeamLayoutRole));
}
public bool IsEnabledInLayout() => _vehicleSpawnerSelector?.IsEnabledInLayout(SpawnInfo) ?? true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ namespace Uncreated.Warfare.Vehicles.Spawners;
public class VehicleSpawnerLayoutConfiguration
{
public string SpawnerName { get; set; }
public ActionPhaseStartDelay? Delay { get; set; }
public TimerDelay? Delay { get; set; }
}
4 changes: 3 additions & 1 deletion UncreatedWarfare/WarfareModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ private void ConfigureServices(ContainerBuilder bldr)

// Database

SshTunnelHelper.AddIfAvailable(bldr);
SshTunnelHelper.AddSshTunnelService(bldr);

bldr.RegisterType<DatabaseInterface>()
.AsSelf()
Expand Down Expand Up @@ -876,6 +876,8 @@ await Task.WhenAny(Task.Run(async () =>
}
else
{
_logger.LogDebug("Migrating database for real...");
//_logger.LogDebug($"Migrating database process: {dbContext.}");
await dbContext.Database.MigrateAsync(token).ConfigureAwait(false);
_logger.LogInformation("Migration completed.");
}
Expand Down

0 comments on commit c470028

Please sign in to comment.