Files
CommandHook/CommandHook/CommandHookModSystem.cs
T

118 lines
3.3 KiB
C#

using System.Collections.Frozen;
using System.Collections.Generic;
using HarmonyLib;
using Vintagestory.API.Common;
using Vintagestory.API.Server;
namespace CommandHook;
public class CommandHookModSystem : ModSystem
{
internal static CommandHookModSystem? Instance;
private FrozenDictionary<string, FrozenDictionary<string, CommandRegistration>> registrations =
FrozenDictionary<string, FrozenDictionary<string, CommandRegistration>>.Empty;
private Harmony? harmony;
public override bool ShouldLoad(EnumAppSide forSide) => forSide == EnumAppSide.Server;
public override void StartServerSide(ICoreServerAPI api)
{
Instance = this;
harmony = new Harmony(Mod.Info.ModID);
harmony.PatchAll();
Mod.Logger.Notification("Loaded");
}
public override void Dispose()
{
harmony?.UnpatchAll(Mod.Info.ModID);
Instance = null;
}
public void Register(
string modId,
CommandRegistration registration,
params string[] commandNames
)
{
var builder = Thaw();
foreach (var commandName in commandNames)
{
if (!builder.TryGetValue(commandName, out var target))
{
target = new Dictionary<string, CommandRegistration>();
builder[commandName] = target;
}
target[modId] = registration;
}
registrations = Freeze(builder);
}
public void Unregister(string modId, params string[] commandNames)
{
var builder = Thaw();
if (commandNames.Length == 0)
{
foreach (var (_, mods) in builder)
mods.Remove(modId);
}
else
{
foreach (var commandName in commandNames)
if (builder.TryGetValue(commandName, out var mods))
mods.Remove(modId);
}
registrations = Freeze(builder);
}
public bool FireBefore(string commandName, ref CommandData data)
{
if (registrations.TryGetValue(commandName, out var mods))
foreach (var (_, reg) in mods)
reg.Before?.Invoke(ref data);
return data.Cancel;
}
public void FireAfter(string commandName, ref CommandData data, TextCommandResult result)
{
if (registrations.TryGetValue(commandName, out var mods))
foreach (var (_, reg) in mods)
reg.After?.Invoke(ref data, result);
}
private Dictionary<string, Dictionary<string, CommandRegistration>> Thaw()
{
var builder = new Dictionary<string, Dictionary<string, CommandRegistration>>();
foreach (var (cmd, mods) in registrations)
{
var inner = new Dictionary<string, CommandRegistration>();
foreach (var (id, reg) in mods)
inner[id] = reg;
builder[cmd] = inner;
}
return builder;
}
private static FrozenDictionary<string, FrozenDictionary<string, CommandRegistration>> Freeze(
Dictionary<string, Dictionary<string, CommandRegistration>> builder
)
{
var pruned = new Dictionary<string, FrozenDictionary<string, CommandRegistration>>();
foreach (var (cmd, mods) in builder)
if (mods.Count > 0)
pruned[cmd] = mods.ToFrozenDictionary();
return pruned.ToFrozenDictionary();
}
}