118 lines
3.3 KiB
C#
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();
|
|
}
|
|
}
|