Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.
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
29 changes: 13 additions & 16 deletions AutoBroadcast.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
using Exiled.API.Enums;
using Exiled.API.Features;
using LabApi.Loader.Features.Plugins;
using LabApi.Loader.Features.Plugins.Enums;

namespace AutoBroadcast;

public class AutoBroadcast : Plugin<Config>
{
public static AutoBroadcast Instance { get; set; } = null!;
private Handler? _eventHandler;

public static AutoBroadcast Instance { get; private set; } = null!;

public override string Name => "AutoBroadcast";
public override string Prefix => "AutoBroadcast";
public override string Description => "Auto-Broadcast plugin";

public override string Author => "@misfiy";
public override Version RequiredExiledVersion => new(9, 2, 1);
public override Version Version => new(1, 6, 3);
public override PluginPriority Priority => PluginPriority.Last;

private Handler eventHandler { get; set; } = null!;
public override Version RequiredApiVersion { get; } = new(LabApi.Features.LabApiProperties.CompiledVersion);
public override LoadPriority Priority => LoadPriority.Lowest;

public override void OnEnabled()
public override void Enable()
{
Instance = this;
eventHandler = new();

base.OnEnabled();
_eventHandler = new Handler();
}

public override void OnDisabled()
public override void Disable()
{
eventHandler = null!;
_eventHandler = null!;
Instance = null!;

base.OnDisabled();
}
}
22 changes: 12 additions & 10 deletions AutoBroadcast.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="ExMod.Exiled" Version="9.2.1" />
<PackageReference Include="Lib.Harmony" Version="2.2.2" />
</ItemGroup>

<ItemGroup>
<Reference Include="Assembly-CSharp-firstpass" HintPath="$(EXILED_REFERENCES)\Assembly-CSharp-firstpass.dll" />
<Reference Include="Mirror" HintPath="$(EXILED_REFERENCES)\Mirror.dll" />
<Reference Include="UnityEngine.CoreModule" HintPath ="$(EXILED_REFERENCES)\UnityEngine.CoreModule.dll" />
<Reference Include="UnityEngine.PhysicsModule" HintPath="$(EXILED_REFERENCES)\UnityEngine.PhysicsModule.dll" />
<Reference Include="Assembly-CSharp" HintPath="$(SL_REFERENCES)\Assembly-CSharp.dll" />
<Reference Include="CommandSystem.Core" HintPath="$(SL_REFERENCES)\CommandSystem.Core.dll" />
<Reference Include="LabApi" HintPath="$(SL_REFERENCES)\LabApi.dll" />
<Reference Include="NorthwoodLib" HintPath="$(SL_REFERENCES)\NorthwoodLib.dll" />
<Reference Include="Assembly-CSharp-firstpass" HintPath="$(SL_REFERENCES)\Assembly-CSharp-firstpass.dll" />
<Reference Include="Pooling" HintPath="$(SL_REFERENCES)\Pooling.dll" />
<Reference Include="Mirror" HintPath="$(SL_REFERENCES)\Mirror.dll" />
<Reference Include="mscorlib" HintPath="$(SL_REFERENCES)\mscorlib.dll" />
<Reference Include="UnityEngine" HintPath="$(SL_REFERENCES)\UnityEngine.dll" />
<Reference Include="UnityEngine.CoreModule" HintPath="$(SL_REFERENCES)\UnityEngine.CoreModule.dll" />
<Reference Include="UnityEngine.PhysicsModule" HintPath="$(SL_REFERENCES)\UnityEngine.PhysicsModule.dll" />
<Reference Include="Unity.TextMeshPro" HintPath="$(SL_REFERENCES)\Unity.TextMeshPro.dll" />
</ItemGroup>

</Project>
28 changes: 14 additions & 14 deletions Config.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Exiled.API.Interfaces;
using AutoBroadcast.Objects;
using PlayerRoles;

namespace AutoBroadcast;

public class Config : IConfig
public class Config
{
public bool IsEnabled { get; set; } = true;
public bool Debug { get; set; } = false;
Expand All @@ -20,23 +20,23 @@ public class Config : IConfig

public BroadCassie? RoundStart { get; set; } = new()
{
Broadcast = new()
Broadcast = new BroadcastSystem
{
Message = "Round has started!",
},
Cassie = new()
Cassie = new CassieBroadcast
{
Message = "Containment breach detected",
}
};

public BroadCassie? LastPlayerOnTeam { get; set; } = new()
{
Broadcast = new()
Broadcast = new BroadcastSystem
{
Message = "You are the last remaining on your team!",
},
Cassie = new()
Cassie = new CassieBroadcast
{
Message = "There is 1 {role} remaining!"
}
Expand All @@ -45,9 +45,9 @@ public class Config : IConfig
public Dictionary<int, BroadCassie> Delayed { get; set; } = new()
{
{
60, new()
60, new BroadCassie
{
Broadcast = new()
Broadcast = new BroadcastSystem
{
Message = "60 seconds have passed!",
}
Expand All @@ -58,9 +58,9 @@ public class Config : IConfig
public Dictionary<int, BroadCassie> Intervals { get; set; } = new()
{
{
30, new()
30, new BroadCassie
{
Broadcast = new()
Broadcast = new BroadcastSystem
{
Message = "I show every 30 seconds!",
UseHints = true,
Expand All @@ -72,9 +72,9 @@ public class Config : IConfig
public Dictionary<RoleTypeId, BroadCassie> SpawnBroadcasts { get; set; } = new()
{
{
RoleTypeId.Spectator, new()
RoleTypeId.Spectator, new BroadCassie
{
Broadcast = new()
Broadcast = new BroadcastSystem
{
Message = "You died!",
Duration = 5,
Expand All @@ -83,9 +83,9 @@ public class Config : IConfig
}
},
{
RoleTypeId.Overwatch, new()
RoleTypeId.Overwatch, new BroadCassie
{
Broadcast = new()
Broadcast = new BroadcastSystem
{
Message = "Overwatch initiated.",
Duration = 6,
Expand Down
97 changes: 50 additions & 47 deletions Handler.cs
Original file line number Diff line number Diff line change
@@ -1,101 +1,104 @@
using Exiled.Events.EventArgs.Player;
using Exiled.Events.EventArgs.Server;
using Exiled.API.Features;
using AutoBroadcast.Objects;
using MEC;
using Exiled.Events.EventArgs.Map;
using GameCore;
using LabApi.Events.Arguments.PlayerEvents;
using LabApi.Events.Arguments.ServerEvents;
using LabApi.Events.Handlers;
using LabApi.Features.Console;
using LabApi.Features.Wrappers;
using PlayerRoles;

namespace AutoBroadcast;

public class Handler
{
public static List<CoroutineHandle> Coroutines = new();
private static Config config => AutoBroadcast.Instance.Config;
public static readonly List<CoroutineHandle> Coroutines = new();

private static Config? Config => AutoBroadcast.Instance.Config;

public Handler()
{
Exiled.Events.Handlers.Server.RoundEnded += OnRoundEnded;
Exiled.Events.Handlers.Server.RoundStarted += OnRoundStart;
Exiled.Events.Handlers.Player.Verified += OnVerified;
Exiled.Events.Handlers.Player.Spawned += OnSpawned;
Exiled.Events.Handlers.Player.Died += OnDied;
ServerEvents.RoundEnded += OnRoundEnded;
ServerEvents.RoundStarted += OnRoundStart;
PlayerEvents.Joined += OnJoined;
PlayerEvents.Spawned += OnSpawned;
PlayerEvents.Death += OnDied;

if (AutoBroadcast.Instance.Config.NtfAnnouncementCassie != "DISABLED" && AutoBroadcast.Instance.Config.NtfAnnouncementCassieNoScps != "DISABLED")
if (Config?.NtfAnnouncementCassie != "DISABLED" && Config?.NtfAnnouncementCassieNoScps != "DISABLED")
Exiled.Events.Handlers.Map.AnnouncingNtfEntrance += OnAnnouncingNtf;
}

~Handler()
{
Exiled.Events.Handlers.Server.RoundEnded -= OnRoundEnded;
Exiled.Events.Handlers.Server.RoundStarted -= OnRoundStart;
Exiled.Events.Handlers.Player.Verified -= OnVerified;
Exiled.Events.Handlers.Player.Spawned -= OnSpawned;
Exiled.Events.Handlers.Player.Died -= OnDied;
ServerEvents.RoundEnded -= OnRoundEnded;
ServerEvents.RoundStarted -= OnRoundStart;
PlayerEvents.Joined -= OnJoined;
PlayerEvents.Spawned -= OnSpawned;
PlayerEvents.Death -= OnDied;

if (AutoBroadcast.Instance.Config.NtfAnnouncementCassie != "DISABLED" || AutoBroadcast.Instance.Config.NtfAnnouncementCassieNoScps != "DISABLED")
if (Config?.NtfAnnouncementCassie != "DISABLED" || Config?.NtfAnnouncementCassieNoScps != "DISABLED")
Exiled.Events.Handlers.Map.AnnouncingNtfEntrance -= OnAnnouncingNtf;
}

public void OnRoundStart()
{
Log.Debug("Round started");
config.RoundStart?.Broadcast?.Show();
config.RoundStart?.Cassie?.Send();
Logger.Debug("Round started");
Config?.RoundStart?.Broadcast?.Show();
Config?.RoundStart?.Cassie?.Send();

foreach (KeyValuePair<int, BroadCassie> kvp in config.Delayed)
foreach (KeyValuePair<int, BroadCassie> kvp in Config?.Delayed ?? new Dictionary<int, BroadCassie>())
{
Log.Debug("Running coroutine");
Logger.Debug("Running coroutine");
Coroutines.Add(Timing.CallDelayed(kvp.Key, delegate
{
kvp.Value.Broadcast?.Show();
kvp.Value.Cassie?.Send();
}));
}

foreach (KeyValuePair<int, BroadCassie> kvp in config.Intervals)
foreach (KeyValuePair<int, BroadCassie> kvp in Config.Intervals)
{
Log.Debug("Running coroutine");
Logger.Debug("Running coroutine");
Coroutines.Add(Timing.RunCoroutine(DoIntervalBroadcast(kvp.Key, kvp.Value)));
}
}

public void OnRoundEnded(RoundEndedEventArgs ev)
{
Log.Debug("Killing coroutines");
Logger.Debug("Killing coroutines");
foreach(CoroutineHandle coroutine in Coroutines)
{
Timing.KillCoroutines(coroutine);
Log.Debug("Killed a coroutine successfully!");
Logger.Debug("Killed a coroutine successfully!");
}

Coroutines.Clear();
Log.Debug("Killed all coroutines");
Logger.Debug("Killed all coroutines");
}

public void OnVerified(VerifiedEventArgs ev)
public void OnJoined(PlayerJoinedEventArgs ev)
{
if (config.JoinMessage != null && config.JoinMessage.Duration > 0 && !config.JoinMessage.Message.IsEmpty())
if (Config?.JoinMessage != null && Config.JoinMessage.Duration > 0 && !Config.JoinMessage.Message.IsEmpty())
{
Log.Debug("Showing Verified message to " + ev.Player.Nickname);
string message = config.JoinMessage.Message.Replace("%name%", ev.Player.Nickname);
ev.Player.Broadcast(config.JoinMessage.Duration, message, default, config.JoinMessage.Override);
Logger.Debug("Showing Verified message to " + ev.Player.Nickname);
string message = Config.JoinMessage.Message.Replace("%name%", ev.Player.Nickname);
Config.JoinMessage.Show(ev.Player);
};
}

public void OnAnnouncingNtf(AnnouncingNtfEntranceEventArgs ev)
{
string cassieMessage = string.Empty;

if (ev.ScpsLeft == 0 && AutoBroadcast.Instance.Config.NtfAnnouncementCassieNoScps != "DISABLED")
if (ev.ScpsLeft == 0 && Config.NtfAnnouncementCassieNoScps != "DISABLED")
{
Log.Debug("No SCPs cassie");
Logger.Debug("No SCPs cassie");
ev.IsAllowed = false;
cassieMessage = AutoBroadcast.Instance.Config.NtfAnnouncementCassieNoScps;
cassieMessage = Config.NtfAnnouncementCassieNoScps;
}
else if (ev.ScpsLeft >= 1 && AutoBroadcast.Instance.Config.NtfAnnouncementCassie != "DISABLED")
else if (ev.ScpsLeft >= 1 && Config.NtfAnnouncementCassie != "DISABLED")
{
Log.Debug("1 or more SCPs cassie");
Logger.Debug("1 or more SCPs cassie");
ev.IsAllowed = false;
cassieMessage = AutoBroadcast.Instance.Config.NtfAnnouncementCassie;
}
Expand All @@ -111,33 +114,33 @@ public void OnAnnouncingNtf(AnnouncingNtfEntranceEventArgs ev)
Cassie.Message(cassieMessage, isSubtitles: true);
}

public void OnSpawned(SpawnedEventArgs ev)
public void OnSpawned(PlayerSpawnedEventArgs ev)
{
if (config.SpawnBroadcasts.TryGetValue(ev.Player.Role.Type, out BroadCassie broadcast))
if (Config.SpawnBroadcasts.TryGetValue(ev.Player.Role, out BroadCassie broadcast))
{
Log.Debug($"Spawn Broadcast showing for {ev.Player.Role.Type}");
Logger.Debug($"Spawn Broadcast showing for {ev.Player.Role}");
broadcast.Broadcast?.Show(ev.Player);
broadcast.Cassie?.Send();
}
}

public void OnDied(DiedEventArgs ev)
public void OnDied(PlayerDeathEventArgs ev)
{
if (ev.TargetOldRole.GetTeam() is not Team.SCPs and not Team.OtherAlive and not Team.Dead)
{
List<Player> playerTeam = Player.Get(ev.TargetOldRole.GetTeam()).ToList();
if (playerTeam.Count == 1)
{
Log.Debug($"{ev.TargetOldRole.GetTeam()} has 1 person remaining on their team, starting LastPlayerAlive Broadcast/Cassie");
config.LastPlayerOnTeam?.Broadcast?.Show(playerTeam.FirstOrDefault());
config.LastPlayerOnTeam?.Cassie?.Send(ev.TargetOldRole);
Logger.Debug($"{ev.TargetOldRole.GetTeam()} has 1 person remaining on their team, starting LastPlayerAlive Broadcast/Cassie");
Config?.LastPlayerOnTeam?.Broadcast?.Show(playerTeam.FirstOrDefault());
Config?.LastPlayerOnTeam?.Cassie?.Send(ev.TargetOldRole);
}
}
}

public IEnumerator<float> DoIntervalBroadcast(int interval, BroadCassie message)
{
while (Round.IsStarted)
while (Round.IsRoundStarted)
{
yield return Timing.WaitForSeconds(interval);

Expand Down
Loading