Files
RebootKit/Runtime/Engine/Code/Foundation/ConfigVarsContainer.cs
2025-04-14 23:22:38 +02:00

153 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using RebootKit.Engine.Services.Console;
using UnityEngine;
using ZLinq;
namespace RebootKit.Engine.Foundation {
[AttributeUsage(AttributeTargets.Field)]
public class ConfigVarAttribute : Attribute {
public ConfigVarAttribute(string name, float defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
Name = name;
Description = description;
Value = new CVarValue(defaultValue);
Flags = flags;
}
public ConfigVarAttribute(string name, double defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
Name = name;
Description = description;
Value = new CVarValue(defaultValue);
Flags = flags;
}
public ConfigVarAttribute(string name, string defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
Name = name;
Description = description;
Value = new CVarValue(defaultValue);
Flags = flags;
}
public ConfigVarAttribute(string name, int defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
Name = name;
Description = description;
Value = new CVarValue(defaultValue);
Flags = flags;
}
internal string Name { get; }
internal string Description { get; }
internal CVarValue Value { get; }
internal CVarFlags Flags { get; }
}
public static class ConfigVarsContainer {
static readonly Logger s_logger = new(nameof(ConfigVarsContainer));
static readonly List<ConfigVar> s_configVars = new();
public static void Register(ConfigVar cvar) {
if (s_configVars.AsValueEnumerable().Any(c => c.name.Equals(cvar.name, StringComparison.Ordinal))) {
throw new Exception($"CVar with name '{cvar.name}' already exists");
}
s_configVars.Add(cvar);
s_logger.Info($"Registered CVar: {cvar.name}");
}
public static void Clear() {
s_configVars.Clear();
s_logger.Info("Cleared all CVars");
}
public static ConfigVar Get(string name) {
return s_configVars.AsValueEnumerable().FirstOrDefault(c => c.name.Equals(name, StringComparison.Ordinal));
}
public static IEnumerable<ConfigVar> All() => s_configVars;
public static void Init() {
Clear();
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies) {
Type[] types = assembly.GetTypes();
foreach (Type type in types) {
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
foreach (FieldInfo field in fields) {
if (Attribute.IsDefined(field, typeof(ConfigVarAttribute))) {
ConfigVarAttribute cvarAttribute = field.GetCustomAttribute<ConfigVarAttribute>();
ConfigVar cvar = Get(cvarAttribute.Name);
if (cvar == null) {
cvar = new ConfigVar(cvarAttribute.Name, cvarAttribute.Value, cvarAttribute.Description) {
flags = cvarAttribute.Flags
};
Register(cvar);
}
field.SetValue(null, cvar);
}
}
}
}
Load();
}
public static void Save() {
string path = Application.persistentDataPath + "/" + RConsts.k_CVarsFilename;
s_logger.Info("Saving cvars to file: " + path);
StringBuilder sb = new();
foreach (ConfigVar cvar in All()) {
if (!cvar.flags.HasFlag(CVarFlags.ReadOnly)) {
sb.AppendFormat("{0} {1}\n", cvar.name, cvar);
}
}
File.WriteAllText(path, sb.ToString());
}
public static void Load() {
string path = Application.persistentDataPath + "/" + RConsts.k_CVarsFilename;
if (!File.Exists(path)) {
s_logger.Info("CVar file not found, skipping load");
return;
}
s_logger.Info("Loading cvars from file: " + path);
string[] lines = File.ReadAllLines(path);
foreach (string line in lines) {
string[] parts = line.Split(' ');
if (parts.Length < 2) {
continue;
}
string name = parts[0];
string value = parts[1];
ConfigVar cvar = Get(name);
if (cvar != null) {
cvar.Value.CopyFrom(new CVarValue(value));
s_logger.Info($"Loaded CVar: {name} = {value}");
} else {
cvar = new ConfigVar(name, value) {
flags = CVarFlags.User
};
cvar.ParseFromString(value);
Register(cvar);
}
}
}
}
}