Private
Public Access
1
0
Files
OrekiWoofsBeehives/OrekiWoofsBees.Common/Configs/ChatCommands.cs
2026-03-11 02:01:27 +01:00

100 lines
3.9 KiB
C#

using System;
using System.Reflection;
using Vintagestory.API.Common;
using Vintagestory.API.Config;
using Vintagestory.API.Server;
namespace OrekiWoofsBees.Common.Configs;
public static class ConfigCommands
{
public static void Register<T>(
IChatCommandApi chatApi,
string commandName,
string langDomain,
bool serverSide,
Func<T> getInstance,
Action<bool> saveConfig)
{
Register(chatApi.Create(commandName), chatApi, langDomain, serverSide, getInstance, saveConfig);
}
public static void Register<T>(
IChatCommand builder,
IChatCommandApi chatApi,
string langDomain,
bool serverSide,
Func<T> getInstance,
Action<bool> saveConfig)
{
if (serverSide)
builder = builder.RequiresPrivilege(Privilege.controlserver);
var p = chatApi.Parsers;
foreach (var prop in typeof(T).GetProperties())
{
var attr = prop.GetCustomAttribute<ConfigCommandAttribute>();
if (attr == null || attr.ServerSide != serverSide) continue;
var name = prop.Name;
var descKey = $"{langDomain}:config-desc-{name}";
OnCommandDelegate handler;
ICommandArgumentParser parser;
if (prop.PropertyType == typeof(int))
{
parser = p.OptionalIntRange("value", (int)attr.Min, (int)attr.Max);
handler = args => HandleOptional(args, name, descKey,
() => $"{prop.GetValue(getInstance())}",
() => { prop.SetValue(getInstance(), (int)args.Parsers[0].GetValue()!); saveConfig(serverSide); },
() => args.Parsers[0].GetValue() is int);
}
else if (prop.PropertyType == typeof(float))
{
parser = ParserExtensions.OptionalFloatRange("value", (float)attr.Min, (float)attr.Max);
handler = args => HandleOptional(args, name, descKey,
() => $"{(float)prop.GetValue(getInstance())!:G}",
() => { prop.SetValue(getInstance(), (float)args.Parsers[0].GetValue()!); saveConfig(serverSide); },
() => args.Parsers[0].GetValue() is float);
}
else if (prop.PropertyType == typeof(bool))
{
parser = p.OptionalBool("value");
handler = args => HandleOptional(args, name, descKey,
() => $"{prop.GetValue(getInstance())}",
() => { prop.SetValue(getInstance(), (bool)args.Parsers[0].GetValue()!); saveConfig(serverSide); },
() => args.Parsers[0].GetValue() is bool);
}
else if (prop.PropertyType == typeof(string))
{
parser = p.OptionalWordRange("value", attr.AllowedValues);
handler = args => HandleOptional(args, name, descKey,
() => $"{prop.GetValue(getInstance())}",
() => { prop.SetValue(getInstance(), (string)args.Parsers[0].GetValue()!); saveConfig(serverSide); },
() => args.Parsers[0].GetValue() is string);
}
else continue;
builder
.BeginSubCommand(name)
.WithDescription(Lang.Get(descKey))
.WithArgs(parser)
.HandleWith(handler)
.EndSubCommand();
}
}
private static TextCommandResult HandleOptional(
TextCommandCallingArgs args, string name, string descKey,
Func<string> formatValue, Action applyAndSave, Func<bool> canParse)
{
if (args.Parsers[0].IsMissing)
return TextCommandResult.Success($"{Lang.Get(descKey)}\n{name}={formatValue()}");
if (!canParse())
return TextCommandResult.Error("Couldn't parse.");
applyAndSave();
return TextCommandResult.Success($"{name}={formatValue()}");
}
}