Decompiled source of Tanuki Atlyss v2.0.8

BepInEx/plugins/Tanuki.Atlyss/Tanuki.Atlyss.API.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;
using Tanuki.Atlyss.API.Plugins;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Tanuki.Atlyss.API")]
[assembly: AssemblyDescription("The application programming interface of the Tanuki.Atlyss framework.")]
[assembly: AssemblyCompany("Tanuki")]
[assembly: AssemblyProduct("Tanuki.Atlyss.API")]
[assembly: AssemblyCopyright("Copyright © Tanuki 2025")]
[assembly: ComVisible(false)]
[assembly: Guid("23eaa990-ee53-4712-b72e-375fe536bf91")]
[assembly: AssemblyFileVersion("2.0.8")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("2.0.8.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Tanuki.Atlyss.API
{
	public interface IPlugin
	{
		string Name { get; }

		EState State { get; }

		void LoadPlugin();

		void UnloadPlugin(EState PluginState);
	}
}
namespace Tanuki.Atlyss.API.Plugins
{
	public enum EState
	{
		Loaded,
		Unloaded,
		Failure,
		Cancelled
	}
}
namespace Tanuki.Atlyss.API.Commands
{
	public interface ICommand
	{
		bool Execute(string[] Arguments);
	}
}
namespace Tanuki.Atlyss.API.Collections
{
	public class Translation
	{
		public Dictionary<string, string> Translations = new Dictionary<string, string>();

		public string this[string Key]
		{
			get
			{
				return Translations[Key];
			}
			set
			{
				Translations[Key] = value;
			}
		}

		public string Translate(string Key, params object[] Placeholder)
		{
			if (!Translations.TryGetValue(Key, out var value))
			{
				return "{" + Key + "}";
			}
			return string.Format(value, Placeholder);
		}
	}
}

BepInEx/plugins/Tanuki.Atlyss/Tanuki.Atlyss.Bootstrap.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using Tanuki.Atlyss.API;
using Tanuki.Atlyss.API.Commands;
using Tanuki.Atlyss.Bootstrap.Models.Configuration;
using Tanuki.Atlyss.Core;
using Tanuki.Atlyss.Core.Commands;
using Tanuki.Atlyss.Core.Plugins;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Tanuki.Atlyss.Bootstrap")]
[assembly: AssemblyDescription("BepInEx plugin for initial loading of the Tanuki.Atlyss framework.")]
[assembly: AssemblyCompany("Tanuki")]
[assembly: AssemblyProduct("Tanuki.Atlyss.Bootstrap")]
[assembly: AssemblyCopyright("Copyright © Tanuki 2025")]
[assembly: ComVisible(false)]
[assembly: Guid("9c00d52e-10b8-413f-9ee4-bfde81762442")]
[assembly: AssemblyFileVersion("2.0.8")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("2.0.8.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Tanuki.Atlyss.Bootstrap
{
	internal class Configuration
	{
		public static Configuration Instance;

		public Settings Settings;

		private Configuration()
		{
		}

		public static void Initialize()
		{
			if (Instance == null)
			{
				Instance = new Configuration();
			}
		}

		public void Load(ConfigFile ConfigFile)
		{
			Settings = new Settings(ref ConfigFile);
		}
	}
	[BepInPlugin("9c00d52e-10b8-413f-9ee4-bfde81762442", "Tanuki.Atlyss.Bootstrap", "2.0.8")]
	public class Main : Plugin
	{
		internal static Main Instance;

		private bool ShouldReloadConfiguration;

		public Main()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Configuration.Initialize();
			Tanuki.Initialize();
			Tanuki.Instance.Plugins.OnBeforePluginsReload += new BeforePluginsReload(BeforePluginsReload);
		}

		internal void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Tanuki.Atlyss by Timofey Tanuki / tanu.su");
			Instance = this;
			UpdateConfiguration();
		}

		internal void Start()
		{
			Tanuki.Instance.Load();
		}

		private void BeforePluginsReload()
		{
			((BaseUnityPlugin)this).Config.Reload();
			UpdateConfiguration();
			ShouldReloadConfiguration = false;
		}

		private void UpdateConfiguration()
		{
			Configuration.Instance.Load(((BaseUnityPlugin)this).Config);
			Tanuki.Instance.Settings.Language = Configuration.Instance.Settings.Language.Value;
		}

		public override void LoadPlugin()
		{
			if (ShouldReloadConfiguration)
			{
				BeforePluginsReload();
			}
			((Plugin)this).LoadPlugin();
		}

		protected override void Unload()
		{
			ShouldReloadConfiguration = true;
		}
	}
}
namespace Tanuki.Atlyss.Bootstrap.Models.Configuration
{
	internal class Settings
	{
		private const string Section = "Settings";

		public ConfigEntry<string> Language = ConfigFile.Bind<string>("Settings", "Language", "default", (ConfigDescription)null);

		public Settings(ref ConfigFile ConfigFile)
		{
		}
	}
}
namespace Tanuki.Atlyss.Bootstrap.Commands
{
	public class Help : ICommand
	{
		private class PluginEntry
		{
			public string Name;

			public List<CommandConfiguration> Active;

			public SortedSet<string> Inactive;

			public PluginEntry(string Name)
			{
				this.Name = Name;
				Active = new List<CommandConfiguration>();
				Inactive = new SortedSet<string>();
				base..ctor();
			}
		}

		public bool Execute(string[] Arguments)
		{
			SortedDictionary<string, PluginEntry> Groups = new SortedDictionary<string, PluginEntry>();
			if (Arguments.Length != 0)
			{
				Arguments = Arguments.Select((string x) => x.ToLower()).ToArray();
				foreach (IPlugin Plugin in Tanuki.Instance.Plugins.Plugins)
				{
					if (Arguments.Any((string x) => Plugin.Name.ToLower().Contains(x)))
					{
						Groups.Add(((object)Plugin).GetType().Assembly.GetName().Name, new PluginEntry(Plugin.Name));
					}
				}
				if (Groups.Count == 0)
				{
					ChatBehaviour._current.New_ChatMessage(((Plugin)Main.Instance).Translate("Commands.Help.PluginsNotFound", Array.Empty<object>()));
					return false;
				}
			}
			else
			{
				foreach (IPlugin plugin in Tanuki.Instance.Plugins.Plugins)
				{
					Groups.Add(((object)plugin).GetType().Assembly.GetName().Name, new PluginEntry(plugin.Name));
				}
			}
			CollectCommands(ref Groups);
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<string, PluginEntry> item in Groups)
			{
				if (item.Value.Active.Count == 0 && item.Value.Inactive.Count == 0)
				{
					continue;
				}
				stringBuilder.Append(((Plugin)Main.Instance).Translate("Commands.Help.Header", new object[1] { item.Value.Name }));
				if (item.Value.Active.Count > 0)
				{
					foreach (CommandConfiguration item2 in item.Value.Active.OrderBy((CommandConfiguration x) => x.Names[0]))
					{
						stringBuilder.Append(((Plugin)Main.Instance).Translate("Commands.Help.Active.Entry", new object[4]
						{
							item2.Names[0],
							string.IsNullOrEmpty(item2.Syntax) ? string.Empty : ((Plugin)Main.Instance).Translate("Commands.Help.Active.Entry.Syntax", new object[1] { item2.Syntax }),
							(item2.Names.Count > 1) ? ((Plugin)Main.Instance).Translate("Commands.Help.Active.Entry.Aliases", new object[1] { string.Join(((Plugin)Main.Instance).Translate("Commands.Help.Active.Entry.Aliases.Separator", Array.Empty<object>()), from x in item2.Names.Skip(1)
								select ((Plugin)Main.Instance).Translate("Commands.Help.Active.Entry.Aliases.Item", new object[1] { x })) }) : string.Empty,
							string.IsNullOrEmpty(item2.Help) ? string.Empty : ((Plugin)Main.Instance).Translate("Commands.Help.Active.Entry.Help", new object[1] { item2.Help })
						}));
					}
				}
				if (item.Value.Inactive.Count > 0)
				{
					stringBuilder.Append(((Plugin)Main.Instance).Translate("Commands.Help.Inactive", new object[1] { string.Join(((Plugin)Main.Instance).Translate("Commands.Help.Inactive.Separator", Array.Empty<object>()), item.Value.Inactive) }));
				}
			}
			ChatBehaviour._current.New_ChatMessage(stringBuilder.ToString());
			return false;
		}

		private void CollectCommands(ref SortedDictionary<string, PluginEntry> Groups)
		{
			foreach (KeyValuePair<ICommand, CommandConfiguration> command in Tanuki.Instance.Commands.Commands)
			{
				string name = ((object)command.Key).GetType().Assembly.GetName().Name;
				if (Groups.TryGetValue(name, out var value))
				{
					if (command.Value.Names == null)
					{
						value.Inactive.Add(((object)command.Key).GetType().Name);
					}
					else
					{
						value.Active.Add(command.Value);
					}
				}
			}
		}
	}
	public class Reload : ICommand
	{
		public bool Execute(string[] Arguments)
		{
			if (Arguments.Length == 0)
			{
				ChatBehaviour._current.New_ChatMessage(((Plugin)Main.Instance).Translate("Commands.Reload.Full", Array.Empty<object>()));
				Tanuki.Instance.Plugins.ReloadPlugins();
				return false;
			}
			Arguments = Arguments.Select((string x) => x.ToLower()).ToArray();
			List<IPlugin> list = new List<IPlugin>();
			foreach (IPlugin Plugin in Tanuki.Instance.Plugins.Plugins)
			{
				if (Arguments.Any((string x) => Plugin.Name.ToLower().Contains(x)))
				{
					list.Add(Plugin);
				}
			}
			if (list.Count > 0)
			{
				ChatBehaviour._current.New_ChatMessage(((Plugin)Main.Instance).Translate("Commands.Reload.Plugins", new object[1] { string.Join(((Plugin)Main.Instance).Translate("Commands.Reload.Plugins.Separator", Array.Empty<object>()), list.Select((IPlugin x) => x.Name)) }));
				list.ForEach((Action<IPlugin>)Tanuki.Instance.Plugins.ReloadPlugin);
				return false;
			}
			ChatBehaviour._current.New_ChatMessage(((Plugin)Main.Instance).Translate("Commands.Reload.PluginsNotFound", Array.Empty<object>()));
			return false;
		}
	}
}

BepInEx/plugins/Tanuki.Atlyss/Tanuki.Atlyss.Core.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Tanuki.Atlyss.API;
using Tanuki.Atlyss.API.Collections;
using Tanuki.Atlyss.API.Commands;
using Tanuki.Atlyss.API.Plugins;
using Tanuki.Atlyss.Core.Commands;
using Tanuki.Atlyss.Core.Plugins;
using Tanuki.Atlyss.Game;
using Tanuki.Atlyss.Game.Events.ChatBehaviour;
using Tanuki.Atlyss.Game.Fields;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Tanuki.Atlyss.Core")]
[assembly: AssemblyDescription("The core of the Tanuki.Atlyss framework.")]
[assembly: AssemblyCompany("Tanuki")]
[assembly: AssemblyProduct("Tanuki.Atlyss.Core")]
[assembly: AssemblyCopyright("Copyright © Tanuki 2025")]
[assembly: ComVisible(false)]
[assembly: Guid("a210d614-b1c7-4260-b7e1-7df2e73e1c8d")]
[assembly: AssemblyFileVersion("2.0.8")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("2.0.8.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Tanuki.Atlyss.Core
{
	public static class Environment
	{
		public static readonly string PluginTranslationFileFormat = "translation.properties";

		public static readonly string PluginCommandFileFormat = "command.json";

		public static readonly string PluginTranslationFileTemplate = "{0}.{1}";

		public static readonly string PluginCommandFileTemplate = "{0}.{1}";
	}
	public class Settings
	{
		public string Language;
	}
	public class Tanuki
	{
		public static Tanuki Instance;

		internal readonly ManualLogSource ManualLogSource = Logger.CreateLogSource("Tanuki.Atlyss.Core");

		public Settings Settings = new Settings();

		public global::Tanuki.Atlyss.Core.Commands.Manager Commands = new global::Tanuki.Atlyss.Core.Commands.Manager();

		public global::Tanuki.Atlyss.Core.Plugins.Manager Plugins = new global::Tanuki.Atlyss.Core.Plugins.Manager();

		private bool Loaded;

		private Tanuki()
		{
		}

		public static void Initialize()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (Instance == null)
			{
				Instance = new Tanuki();
				GameManager.Initialize();
				Main.Initialize();
				Main.Instance.Patch(typeof(Send_ChatMessage_Prefix));
				Send_ChatMessage_Prefix.OnInvoke += new EventHandler(Instance.Commands.OnSendMessage);
			}
		}

		public void Load()
		{
			if (!Loaded)
			{
				Loaded = true;
				Plugins.LoadPlugins();
			}
		}

		public void Reload()
		{
			Commands.RemoveAllCommands();
			Plugins.ReloadPlugins();
		}
	}
}
namespace Tanuki.Atlyss.Core.Plugins
{
	public class Manager
	{
		public delegate void BeforePluginsReload();

		public delegate void AfterPluginsReload();

		public readonly HashSet<IPlugin> Plugins = new HashSet<IPlugin>();

		public event BeforePluginsReload OnBeforePluginsReload;

		public event AfterPluginsReload OnAfterPluginsReload;

		internal void LoadPlugins()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				BaseUnityPlugin instance = value.Instance;
				if (instance != null && typeof(IPlugin).IsAssignableFrom(((object)instance).GetType()))
				{
					IPlugin val = (IPlugin)instance;
					if (Plugins.Add(val))
					{
						val.LoadPlugin();
					}
				}
			}
		}

		public void ReloadPlugins()
		{
			this.OnBeforePluginsReload?.Invoke();
			foreach (IPlugin plugin in Plugins)
			{
				ReloadPlugin(plugin);
			}
			this.OnAfterPluginsReload?.Invoke();
		}

		public void ReloadPlugin(IPlugin Plugin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Plugin.State != 1)
			{
				Plugin.UnloadPlugin((EState)1);
			}
			Plugin.LoadPlugin();
		}
	}
	public class Plugin : BaseUnityPlugin, IPlugin
	{
		private EState _State = (EState)1;

		protected readonly string Directory;

		public Translation Translation;

		public string Name { get; private set; }

		public EState State => _State;

		public Plugin()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			Name = ((object)this).GetType().Assembly.GetName().Name;
			Directory = Path.Combine(Paths.ConfigPath, Name);
			Translation = new Translation();
			if (!System.IO.Directory.Exists(Directory))
			{
				System.IO.Directory.CreateDirectory(Directory);
			}
		}

		public virtual void LoadPlugin()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Tanuki.Instance.Commands.RegisterCommands((IPlugin)(object)this);
			LoadTranslation();
			try
			{
				Load();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
				UnloadPlugin((EState)2);
				return;
			}
			_State = (EState)0;
		}

		public virtual void UnloadPlugin(EState PluginState)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Tanuki.Instance.Commands.DeregisterCommands((IPlugin)(object)this);
			try
			{
				Unload();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
				_State = (EState)2;
				return;
			}
			_State = PluginState;
		}

		protected virtual void Load()
		{
		}

		protected virtual void Unload()
		{
		}

		private void LoadTranslation()
		{
			string path = Path.Combine(Directory, string.Format(Environment.PluginTranslationFileTemplate, Tanuki.Instance.Settings.Language, Environment.PluginTranslationFileFormat));
			bool flag = File.Exists(path);
			if (!flag)
			{
				string[] files = System.IO.Directory.GetFiles(Directory);
				foreach (string text in files)
				{
					if (text.Contains(Environment.PluginTranslationFileFormat))
					{
						path = text;
						flag = true;
						break;
					}
				}
			}
			Translation.Translations.Clear();
			if (!flag)
			{
				return;
			}
			using FileStream stream = File.OpenRead(path);
			using StreamReader streamReader = new StreamReader(stream);
			int num = 0;
			string text2;
			while ((text2 = streamReader.ReadLine()) != null)
			{
				if (!text2.StartsWith("#"))
				{
					num = text2.IndexOf('=');
					if (num > 0)
					{
						Translation.Translations[text2.Substring(0, num)] = text2.Substring(num + 1);
					}
				}
			}
		}

		public string Translate(string Key, params object[] Placeholder)
		{
			return Translation.Translate(Key, Placeholder);
		}
	}
}
namespace Tanuki.Atlyss.Core.Commands
{
	public class Manager
	{
		public readonly Dictionary<string, ICommand> Aliases = new Dictionary<string, ICommand>();

		public readonly Dictionary<ICommand, CommandConfiguration> Commands = new Dictionary<ICommand, CommandConfiguration>();

		private static readonly HashSet<char> Quotes = new HashSet<char> { '"', '\'', '`' };

		public void RegisterCommands(IPlugin Plugin)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			bool flag = false;
			Dictionary<string, CommandConfiguration> CommandConfigurations = null;
			Assembly assembly = ((object)Plugin).GetType().Assembly;
			List<ICommand> list = new List<ICommand>();
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				if (!type.IsAbstract && !type.IsInterface && typeof(ICommand).IsAssignableFrom(type))
				{
					list.Add((ICommand)Activator.CreateInstance(type));
				}
			}
			string text = Path.Combine(Paths.ConfigPath, assembly.GetName().Name);
			string path = Path.Combine(text, string.Format(Environment.PluginCommandFileTemplate, Tanuki.Instance.Settings.Language, Environment.PluginCommandFileFormat));
			bool flag2 = File.Exists(path);
			if (!flag2)
			{
				string[] files = Directory.GetFiles(text);
				foreach (string text2 in files)
				{
					if (text2.Contains(Environment.PluginCommandFileFormat))
					{
						path = text2;
						flag2 = true;
						break;
					}
				}
			}
			if (flag2)
			{
				CommandConfigurations = JsonConvert.DeserializeObject<Dictionary<string, CommandConfiguration>>(File.ReadAllText(path));
			}
			if (CommandConfigurations == null)
			{
				CommandConfigurations = new Dictionary<string, CommandConfiguration>();
			}
			List<string> list2 = new List<string>();
			foreach (string CommandName in CommandConfigurations.Keys)
			{
				if (!list.Any((ICommand x) => ((object)x).GetType().Name == CommandName))
				{
					list2.Add(CommandName);
					flag = true;
				}
			}
			list2.ForEach(delegate(string x)
			{
				CommandConfigurations.Remove(x);
			});
			if (CommandConfigurations.Count != list.Count)
			{
				foreach (ICommand item in list)
				{
					string name = ((object)item).GetType().Name;
					if (!CommandConfigurations.ContainsKey(name))
					{
						CommandConfigurations.Add(name, new CommandConfiguration
						{
							Names = new List<string>(1) { name.ToLower() }
						});
					}
				}
				flag = true;
			}
			foreach (KeyValuePair<string, CommandConfiguration> CommandConfiguration in CommandConfigurations)
			{
				ICommand val = list.Where((ICommand x) => ((object)x).GetType().Name == CommandConfiguration.Key).First();
				Commands[val] = CommandConfiguration.Value;
				if (CommandConfiguration.Value.Names == null)
				{
					continue;
				}
				if (CommandConfiguration.Value.Names.Count == 0)
				{
					CommandConfiguration.Value.Names = null;
					continue;
				}
				for (int num = CommandConfiguration.Value.Names.Count - 1; num >= 0; num--)
				{
					string text3 = CommandConfiguration.Value.Names[num].ToLower();
					if (text3.Length == 0 || Enumerable.Contains(text3, ' ') || Aliases.ContainsKey(text3))
					{
						CommandConfiguration.Value.Names.RemoveAt(num);
						flag = true;
					}
					else
					{
						Aliases.Add(text3, val);
					}
				}
				if (CommandConfiguration.Value.Names.Count == 0)
				{
					CommandConfiguration.Value.Names = null;
				}
			}
			if (flag)
			{
				File.WriteAllText(path, JsonConvert.SerializeObject((object)CommandConfigurations, (Formatting)1));
			}
		}

		public void DeregisterCommands(IPlugin Plugin)
		{
			Assembly Assembly = ((object)Plugin).GetType().Assembly;
			ICommand[] array = Commands.Keys.Where((ICommand x) => ((object)x).GetType().Assembly == Assembly).ToArray();
			for (ushort num = 0; num < array.Length; num++)
			{
				RemoveCommand(array[num]);
			}
		}

		private void RemoveCommand(ICommand Command)
		{
			if (Commands.TryGetValue(Command, out var value))
			{
				value.Names?.ForEach(delegate(string x)
				{
					Aliases.Remove(x);
				});
				Type type = ((object)Command).GetType();
				if (typeof(IDisposable).IsAssignableFrom(type))
				{
					((IDisposable)Command).Dispose();
				}
				Commands.Remove(Command);
			}
		}

		public void RemoveAllCommands()
		{
			foreach (ICommand key in Commands.Keys)
			{
				RemoveCommand(key);
			}
		}

		public void OnSendMessage(string Message, ref bool ShouldAllow)
		{
			if (!Message.StartsWith("/"))
			{
				return;
			}
			int num = Message.IndexOf(' ');
			if (num < 0)
			{
				num = Message.Length;
			}
			string key = Message.Substring(0, num).TrimStart(new char[1] { '/' }).ToLower();
			if (!Aliases.TryGetValue(key, out var value))
			{
				return;
			}
			List<string> list = new List<string>();
			StringBuilder stringBuilder = new StringBuilder();
			char? c = null;
			bool flag = false;
			for (ushort num2 = (ushort)num; num2 < Message.Length; num2++)
			{
				char c2 = Message[num2];
				if (c.HasValue)
				{
					if (flag)
					{
						if (c2 == '\\' || Quotes.Contains(c2))
						{
							stringBuilder.Append(c2);
						}
						else
						{
							stringBuilder.Append('\\');
							stringBuilder.Append(c2);
						}
						flag = false;
					}
					else if (c2 == '\\')
					{
						flag = true;
					}
					else if (c2 == c)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Clear();
						c = null;
					}
					else
					{
						stringBuilder.Append(c2);
					}
				}
				else if (c2 == ' ')
				{
					if (stringBuilder.Length > 0)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Clear();
					}
				}
				else if (Quotes.Contains(c2))
				{
					if (stringBuilder.Length > 0)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Clear();
					}
					c = c2;
				}
				else
				{
					stringBuilder.Append(c2);
				}
			}
			if (flag)
			{
				stringBuilder.Append('\\');
			}
			if (stringBuilder.Length > 0)
			{
				list.Add(stringBuilder.ToString());
			}
			ShouldAllow = false;
			try
			{
				ShouldAllow = value.Execute(list.ToArray());
			}
			catch (Exception ex)
			{
				Tanuki.Instance.ManualLogSource.LogError((object)ex);
			}
		}
	}
	[Serializable]
	public class CommandConfiguration
	{
		[JsonProperty("Names")]
		public List<string> Names;

		[JsonProperty("Help")]
		public string Help;

		[JsonProperty("Syntax")]
		public string Syntax;
	}
}

BepInEx/plugins/Tanuki.Atlyss/Tanuki.Atlyss.Game.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Tanuki.Atlyss.Game")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCompany("Tanuki")]
[assembly: AssemblyProduct("Tanuki.Atlyss.Game")]
[assembly: AssemblyCopyright("Copyright © Tanuki 2025")]
[assembly: ComVisible(false)]
[assembly: Guid("195c12bf-79c2-4476-8340-d2198d1ffc95")]
[assembly: AssemblyFileVersion("2.0.8")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("2.0.8.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Tanuki.Atlyss.Game
{
	public class Main
	{
		public static Main Instance;

		private readonly Harmony Harmony;

		private readonly ManualLogSource ManualLogSource;

		private readonly HashSet<Type> Patches;

		private Main()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Harmony = new Harmony("Tanuki.Atlyss.Game");
			ManualLogSource = new ManualLogSource("Tanuki.Atlyss.Game");
			Patches = new HashSet<Type>();
		}

		public static void Initialize()
		{
			if (Instance == null)
			{
				Instance = new Main();
			}
		}

		public void Patch(Type Type)
		{
			if (!Patches.Contains(Type))
			{
				if (!Type.IsSealed || !Type.IsAbstract)
				{
					ManualLogSource.LogError((object)("Patch class " + Type.FullName + " must be static."));
					return;
				}
				if (!Type.IsDefined(typeof(HarmonyPatch), inherit: false))
				{
					ManualLogSource.LogError((object)("Patch class " + Type.FullName + " must have HarmonyPatch attribute."));
					return;
				}
				Harmony.CreateClassProcessor(Type).Patch();
				Patches.Add(Type);
			}
		}

		public void Patch(params Type[] Types)
		{
			foreach (Type type in Types)
			{
				Patch(type);
			}
		}
	}
}
namespace Tanuki.Atlyss.Game.Fields
{
	public class GameManager
	{
		public static GameManager Instance;

		private Dictionary<string, ScriptableItem> _CachedScriptableItems;

		private Dictionary<string, ScriptablePlayerRace> _CachedScriptableRaces;

		private Dictionary<string, ScriptableMapData> _CachedScriptableMapDatas;

		public Dictionary<string, ScriptableItem> CachedScriptableItems
		{
			get
			{
				if (_CachedScriptableItems == null)
				{
					_CachedScriptableItems = (Dictionary<string, ScriptableItem>)((object)GameManager._current).GetType().GetField("_cachedScriptableItems", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(GameManager._current);
				}
				return _CachedScriptableItems;
			}
		}

		public Dictionary<string, ScriptablePlayerRace> CachedScriptableRaces
		{
			get
			{
				if (_CachedScriptableRaces == null)
				{
					_CachedScriptableRaces = (Dictionary<string, ScriptablePlayerRace>)((object)GameManager._current).GetType().GetField("_cachedScriptableRaces", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(GameManager._current);
				}
				return _CachedScriptableRaces;
			}
		}

		public Dictionary<string, ScriptableMapData> CachedScriptableMapDatas
		{
			get
			{
				if (_CachedScriptableMapDatas == null)
				{
					_CachedScriptableMapDatas = (Dictionary<string, ScriptableMapData>)((object)GameManager._current).GetType().GetField("_cachedScriptableMapDatas", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(GameManager._current);
				}
				return _CachedScriptableMapDatas;
			}
		}

		private GameManager()
		{
		}

		public static void Initialize()
		{
			if (Instance == null)
			{
				Instance = new GameManager();
			}
		}
	}
}
namespace Tanuki.Atlyss.Game.Extensions
{
	public static class PlayerEquipment
	{
		public static EquipData UsableWeapon(this PlayerEquipment PlayerEquipment)
		{
			return PlayerEquipment._equips[Player._mainPlayer._pCombat._isUsingAltWeapon ? "Alt Weapon" : "Weapon"];
		}
	}
	public static class PlayerInventory
	{
		public static ItemData GetItem(this PlayerInventory PlayerInventory, int Slot, bool IsEquipped, ItemType ItemType)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			foreach (ItemData heldItem in PlayerInventory._heldItems)
			{
				if (heldItem._slotNumber == Slot && heldItem._isEquipped == IsEquipped)
				{
					ScriptableItem val = GameManager._current.Locate_Item(heldItem._itemName);
					if (val != null && val._itemType == ItemType)
					{
						return heldItem;
					}
				}
			}
			return null;
		}
	}
	public static class PlayerMove
	{
		public static void Teleport(this PlayerMove PlayerMove, Vector3 Position, Quaternion Rotation)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			((Collider)PlayerMove._playerController).enabled = false;
			((Component)PlayerMove).transform.SetPositionAndRotation(Position, Rotation);
			((Collider)PlayerMove._playerController).enabled = true;
		}

		public static void Teleport(this PlayerMove PlayerMove, Vector3 Position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			PlayerMove.Teleport(Position, ((Component)PlayerMove).transform.rotation);
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.StatusEntity
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Take_Damage_Prefix
	{
		public delegate void EventHandler(StatusEntity StatusEntity, ref DamageStruct _dmgStruct, ref bool ShouldAllow);

		public static event EventHandler OnInvoke;

		private static bool Prefix(StatusEntity __instance, ref DamageStruct _dmgStruct)
		{
			bool ShouldAllow = true;
			Take_Damage_Prefix.OnInvoke?.Invoke(__instance, ref _dmgStruct, ref ShouldAllow);
			return ShouldAllow;
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.ScriptablePlayerRace
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Init_ParamsCheck_Prefix
	{
		public delegate void EventHandler(PlayerAppearance_Profile PlayerAppearance, ref bool ShouldAllow);

		public static event EventHandler OnInvoke;

		private static bool Prefix(PlayerAppearance_Profile _aP, ref PlayerAppearance_Profile __result)
		{
			bool ShouldAllow = true;
			Init_ParamsCheck_Prefix.OnInvoke?.Invoke(_aP, ref ShouldAllow);
			if (!ShouldAllow)
			{
				__result = _aP;
			}
			return ShouldAllow;
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.Player
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class OnStartAuthority_Postfix
	{
		public delegate void EventHandler();

		public static event EventHandler OnInvoke;

		private static void Postfix()
		{
			OnStartAuthority_Postfix.OnInvoke?.Invoke();
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.PlayerMove
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Init_Jump_Postfix
	{
		public delegate void EventHandler(PlayerMove PlayerMove, float Force, float ForwardForce, float GravityMultiply, bool UseAnim);

		public static event EventHandler OnInvoke;

		private static void Postfix(PlayerMove __instance, float _force, float _forwardForce, float _gravityMultiply, bool _useAnim)
		{
			Init_Jump_Postfix.OnInvoke?.Invoke(__instance, _force, _forwardForce, _gravityMultiply, _useAnim);
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.PlayerCasting
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Cmd_InitSkill_Postfix
	{
		public delegate void EventHandler(PlayerCasting PlayerCasting);

		public static event EventHandler OnInvoke;

		private static void Postfix(PlayerCasting __instance)
		{
			Cmd_InitSkill_Postfix.OnInvoke?.Invoke(__instance);
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class New_CooldownSlot_Prefix
	{
		public delegate void EventHandler(PlayerCasting PlayerCasting, ref ScriptableSkill ScriptableSkill, ref bool ShouldAllow);

		public static event EventHandler OnInvoke;

		private static bool Prefix(PlayerCasting __instance, ref ScriptableSkill _setSkill)
		{
			bool ShouldAllow = true;
			New_CooldownSlot_Prefix.OnInvoke?.Invoke(__instance, ref _setSkill, ref ShouldAllow);
			return ShouldAllow;
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.AtlyssNetworkManager
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class OnStartClient_Postfix
	{
		public delegate void EventHandler();

		public static event EventHandler OnInvoke;

		private static void Postfix()
		{
			OnStartClient_Postfix.OnInvoke?.Invoke();
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class OnStopClient_Prefix
	{
		public delegate void EventHandler();

		public static event EventHandler OnInvoke;

		private static void Prefix()
		{
			OnStopClient_Prefix.OnInvoke?.Invoke();
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.LoadSceneManager
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Init_LoadScreenDisable_Postfix
	{
		public delegate void EventHandler();

		public static event EventHandler OnInvoke;

		private static void Postfix()
		{
			Init_LoadScreenDisable_Postfix.OnInvoke?.Invoke();
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.ItemObject
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Enable_GroundCheckToVelocityZero_Postfix
	{
		public delegate void EventHandler(ItemObject ItemObject);

		public static event EventHandler OnInvoke;

		private static void Postfix(ItemObject __instance)
		{
			Enable_GroundCheckToVelocityZero_Postfix.OnInvoke?.Invoke(__instance);
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.GameManager
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Cache_ScriptableAssets_Postfix
	{
		public delegate void EventHandler();

		public static event EventHandler OnInvoke;

		private static void Postfix()
		{
			Cache_ScriptableAssets_Postfix.OnInvoke?.Invoke();
		}
	}
}
namespace Tanuki.Atlyss.Game.Events.ChatBehaviour
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static class Send_ChatMessage_Prefix
	{
		public delegate void EventHandler(string Message, ref bool ShouldAllow);

		public static event EventHandler OnInvoke;

		private static bool Prefix(string _message)
		{
			if (string.IsNullOrEmpty(_message))
			{
				return true;
			}
			bool ShouldAllow = true;
			Send_ChatMessage_Prefix.OnInvoke?.Invoke(_message, ref ShouldAllow);
			if (ShouldAllow)
			{
				return true;
			}
			ChatBehaviour._current._chatAssets._chatInput.text = string.Empty;
			ChatBehaviour._current.Display_Chat(false);
			return false;
		}
	}
}