Decompiled source of Mods Communicator Chat Control v0.0.2

OutwardModsCommunicatorChatControl.dll

Decompiled 2 months ago
using System;
using System.Collections;
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.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using OutwardModsCommunicator.EventBus;
using OutwardModsCommunicator.Managers;
using OutwardModsCommunicatorChatControl.Events;
using OutwardModsCommunicatorChatControl.Events.Publishers;
using OutwardModsCommunicatorChatControl.Utility.Enums;
using OutwardModsCommunicatorChatControl.Utility.Helpers;
using SideLoader;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OutwardModsCommunicatorChatControl")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OutwardModsCommunicatorChatControl")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace OutwardModsCommunicatorChatControl
{
	[BepInPlugin("gymmed.mods_communicator_chat_control", "Mods Communicator Chat Control", "0.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class OMCCC : BaseUnityPlugin
	{
		public const string GUID = "gymmed.mods_communicator_chat_control";

		public const string NAME = "Mods Communicator Chat Control";

		public const string VERSION = "0.0.2";

		public static string prefix = "[Mods-Communicator-Chat-Control]";

		public const string EVENTS_LISTENER_GUID = "gymmed.mods_communicator_chat_control_*";

		internal static ManualLogSource Log;

		internal void Awake()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			LogMessage("Hello world from Mods Communicator Chat Control 0.0.2!");
			new Harmony("gymmed.mods_communicator_chat_control").PatchAll();
			EventBusPublisher.SendCommands();
		}

		internal void Update()
		{
		}

		public static void LogMessage(string message)
		{
			Log.LogMessage((object)(prefix + " " + message));
		}

		public static void LogStatusMessage(string message, ChatLogStatus status = ChatLogStatus.Info)
		{
			LogMessage($"[{status}] {message}");
		}

		public static void LogSL(string message)
		{
			SL.Log(prefix + " " + message);
		}

		public static string GetProjectLocation()
		{
			return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		}
	}
}
namespace OutwardModsCommunicatorChatControl.Utility.Helpers
{
	public static class CharacterHelpers
	{
		public static Character TryToFindOtherCharacterInLobby(Character mainCharacter, string otherCharName)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Character val = null;
			foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
			{
				val = item.ControlledCharacter;
				if ((Object)(object)val != (Object)null && val.UID != mainCharacter.UID && string.Equals(otherCharName, val.Name))
				{
					return val;
				}
			}
			return null;
		}

		public static Character TryToFindOtherCharacterInLobby(Character mainCharacter)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Character val = null;
			foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
			{
				val = item.ControlledCharacter;
				if ((Object)(object)val != (Object)null && val.UID != mainCharacter.UID)
				{
					return val;
				}
			}
			return val;
		}

		public static bool IsCharacterInDistance(Character firstCharacter, Character secondCharacter, float minimumDistance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)firstCharacter).transform.position - ((Component)secondCharacter).transform.position;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			float num = minimumDistance * minimumDistance;
			if (sqrMagnitude > num)
			{
				return false;
			}
			return true;
		}

		public static bool HasManualMovement(Character character)
		{
			CharacterControl characterControl = character.CharacterControl;
			LocalCharacterControl val = (LocalCharacterControl)(object)((characterControl is LocalCharacterControl) ? characterControl : null);
			if (val == null)
			{
				return false;
			}
			if (((Vector2)(ref ((CharacterControl)val).m_moveInput)).sqrMagnitude > 0.01f)
			{
				return true;
			}
			return false;
		}
	}
	public static class ChatHelpers
	{
		public static void SendChatLog(ChatPanel panel, string message, ChatLogStatus status = ChatLogStatus.Info)
		{
			panel.ChatMessageReceived("System", ChatLogStatusHelper.GetChatLogText(message, status));
		}

		public static void SendChatLog(Character character, string message, ChatLogStatus status = ChatLogStatus.Info)
		{
			CharacterUI characterUI = character.CharacterUI;
			if ((Object)(object)((characterUI != null) ? characterUI.ChatPanel : null) == (Object)null)
			{
				OMCCC.LogMessage("ChatHelpers@SendChatLog provided character with missing chatPanel!");
			}
			else
			{
				SendChatLog(character.CharacterUI.ChatPanel, message, status);
			}
		}

		public static void SendChatOrLog(Character character, string message, ChatLogStatus status = ChatLogStatus.Info)
		{
			CharacterUI characterUI = character.CharacterUI;
			if ((Object)(object)((characterUI != null) ? characterUI.ChatPanel : null) == (Object)null)
			{
				OMCCC.LogStatusMessage(message, status);
			}
			else
			{
				SendChatLog(character.CharacterUI.ChatPanel, message, status);
			}
		}
	}
	public static class CollectionValueParser
	{
		public static (object result, string error) TryParse(Type collectionType, string valueString)
		{
			if (collectionType == null || string.IsNullOrWhiteSpace(valueString))
			{
				return (null, "Type or value is null/empty");
			}
			if (!IsCollectionType(collectionType))
			{
				return (null, "Type '" + collectionType.Name + "' is not a collection type");
			}
			Type elementType = GetElementType(collectionType);
			if (elementType == null)
			{
				return (null, "Cannot determine element type for '" + collectionType.Name + "'");
			}
			string[] array = valueString.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length == 0)
			{
				return (null, "No values provided");
			}
			if (collectionType.IsArray)
			{
				return TryParseArray(elementType, array);
			}
			return TryParseCollection(collectionType, elementType, array);
		}

		private static (object result, string error) TryParseArray(Type elementType, string[] values)
		{
			List<object> list = new List<object>();
			for (int i = 0; i < values.Length; i++)
			{
				var (item, text) = ParseValue(elementType, values[i]);
				if (text != null)
				{
					return (null, $"Invalid value at position {i + 1}: {text}");
				}
				list.Add(item);
			}
			try
			{
				Array array = Array.CreateInstance(elementType, list.Count);
				for (int j = 0; j < list.Count; j++)
				{
					array.SetValue(list[j], j);
				}
				return (array, null);
			}
			catch (Exception ex)
			{
				return (null, "Failed to create array: " + ex.Message);
			}
		}

		private static (object result, string error) TryParseCollection(Type collectionType, Type elementType, string[] values)
		{
			List<object> list = new List<object>();
			for (int i = 0; i < values.Length; i++)
			{
				var (item, text) = ParseValue(elementType, values[i]);
				if (text != null)
				{
					return (null, $"Invalid value at position {i + 1}: {text}");
				}
				list.Add(item);
			}
			try
			{
				bool num = IsSetType(collectionType);
				bool flag = IsListType(collectionType);
				bool flag2 = typeof(ICollection).IsAssignableFrom(collectionType);
				bool flag3 = typeof(IEnumerable).IsAssignableFrom(collectionType);
				object obj;
				if (num || (flag3 && !flag && collectionType.GetConstructor(Type.EmptyTypes) != null))
				{
					Type type = typeof(HashSet<>).MakeGenericType(elementType);
					obj = Activator.CreateInstance(type);
					MethodInfo method = type.GetMethod("Add");
					foreach (object item2 in list)
					{
						method.Invoke(obj, new object[1] { item2 });
					}
				}
				else if (flag || (flag2 && collectionType.GetConstructor(Type.EmptyTypes) != null))
				{
					Type type2 = typeof(List<>).MakeGenericType(elementType);
					obj = Activator.CreateInstance(type2);
					MethodInfo method2 = type2.GetMethod("Add");
					foreach (object item3 in list)
					{
						method2.Invoke(obj, new object[1] { item3 });
					}
				}
				else
				{
					if (!collectionType.IsAssignableFrom(typeof(List<>).MakeGenericType(elementType)))
					{
						return (null, "Cannot instantiate collection type '" + collectionType.Name + "'");
					}
					Type type3 = typeof(List<>).MakeGenericType(elementType);
					obj = Activator.CreateInstance(type3);
					MethodInfo method3 = type3.GetMethod("Add");
					foreach (object item4 in list)
					{
						method3.Invoke(obj, new object[1] { item4 });
					}
				}
				return (obj, null);
			}
			catch (Exception ex)
			{
				return (null, "Failed to create collection: " + ex.Message);
			}
		}

		private static (object result, string error) ParseValue(Type targetType, string valueString)
		{
			if (string.IsNullOrWhiteSpace(valueString))
			{
				return (null, "Empty value");
			}
			valueString = valueString.Trim();
			if (targetType.IsEnum)
			{
				try
				{
					return (Enum.Parse(targetType, valueString, ignoreCase: true), null);
				}
				catch
				{
					string text = string.Join(", ", Enum.GetNames(targetType));
					return (null, "Invalid enum value. Expected one of: " + text);
				}
			}
			(object value, string error) tuple = EventArgumentParser.TryParseScalar(targetType, valueString);
			var (item, _) = tuple;
			if (tuple.error == null)
			{
				return (item, null);
			}
			return (null, "Cannot convert '" + valueString + "' to " + targetType.Name);
		}

		public static bool IsCollectionType(Type type)
		{
			if (type == null)
			{
				return false;
			}
			if (type.IsArray)
			{
				return true;
			}
			if (typeof(IEnumerable).IsAssignableFrom(type))
			{
				if (type.IsGenericType)
				{
					Type genericTypeDefinition = type.GetGenericTypeDefinition();
					if (genericTypeDefinition == typeof(HashSet<>) || genericTypeDefinition == typeof(List<>) || genericTypeDefinition == typeof(IList<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IEnumerable<>))
					{
						return true;
					}
				}
				if (typeof(ICollection).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null)
				{
					return true;
				}
			}
			return false;
		}

		public static Type GetElementType(Type collectionType)
		{
			if (collectionType == null)
			{
				return null;
			}
			if (collectionType.IsArray)
			{
				return collectionType.GetElementType();
			}
			if (collectionType.IsGenericType)
			{
				Type[] genericArguments = collectionType.GetGenericArguments();
				if (genericArguments.Length != 0)
				{
					return genericArguments[0];
				}
			}
			Type[] interfaces = collectionType.GetInterfaces();
			foreach (Type type in interfaces)
			{
				if (!type.IsGenericType)
				{
					continue;
				}
				Type genericTypeDefinition = type.GetGenericTypeDefinition();
				if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IList<>))
				{
					Type[] genericArguments2 = type.GetGenericArguments();
					if (genericArguments2.Length != 0)
					{
						return genericArguments2[0];
					}
				}
			}
			return null;
		}

		private static bool IsSetType(Type type)
		{
			if (type == null)
			{
				return false;
			}
			if (type.IsGenericType)
			{
				Type genericTypeDefinition = type.GetGenericTypeDefinition();
				if (!(genericTypeDefinition == typeof(HashSet<>)))
				{
					return genericTypeDefinition == typeof(ISet<>);
				}
				return true;
			}
			return false;
		}

		private static bool IsListType(Type type)
		{
			if (type == null)
			{
				return false;
			}
			if (type.IsGenericType)
			{
				Type genericTypeDefinition = type.GetGenericTypeDefinition();
				if (!(genericTypeDefinition == typeof(List<>)) && !(genericTypeDefinition == typeof(IList<>)))
				{
					return genericTypeDefinition == typeof(IList<>);
				}
				return true;
			}
			return typeof(IList).IsAssignableFrom(type);
		}
	}
	public static class EventArgumentParser
	{
		private static readonly HashSet<Type> WhitelistedScalarTypes = new HashSet<Type>
		{
			typeof(string),
			typeof(int),
			typeof(float),
			typeof(bool),
			typeof(double),
			typeof(long),
			typeof(decimal),
			typeof(char)
		};

		public static bool CanParse(Type type)
		{
			if (type == null)
			{
				return false;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				return CanParse(Nullable.GetUnderlyingType(type));
			}
			if (WhitelistedScalarTypes.Contains(type))
			{
				return true;
			}
			if (type.IsEnum)
			{
				return true;
			}
			if (CollectionValueParser.IsCollectionType(type))
			{
				Type elementType = CollectionValueParser.GetElementType(type);
				if (elementType != null)
				{
					return CanParseScalar(elementType);
				}
				return false;
			}
			return false;
		}

		private static bool CanParseScalar(Type type)
		{
			if (type == null)
			{
				return false;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				return CanParseScalar(Nullable.GetUnderlyingType(type));
			}
			if (WhitelistedScalarTypes.Contains(type))
			{
				return true;
			}
			if (type.IsEnum)
			{
				return true;
			}
			return false;
		}

		public static bool IsEventPublishable(EventDefinition eventDef, out string unsupportedParam)
		{
			unsupportedParam = null;
			object obj;
			if (eventDef == null)
			{
				obj = null;
			}
			else
			{
				EventSchema schema = eventDef.Schema;
				obj = ((schema != null) ? schema.Fields : null);
			}
			if (obj == null)
			{
				return true;
			}
			foreach (KeyValuePair<string, Type> field in eventDef.Schema.Fields)
			{
				if (!CanParse(field.Value))
				{
					unsupportedParam = field.Key;
					return false;
				}
			}
			return true;
		}

		public static (bool success, object value, string error) TryParseWithDetails(Type targetType, string valueString)
		{
			if (targetType == null)
			{
				return (false, null, "Target type is null");
			}
			if (string.IsNullOrEmpty(valueString))
			{
				return (false, null, "Value is null or empty");
			}
			if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				return TryParseWithDetails(Nullable.GetUnderlyingType(targetType), valueString);
			}
			if (CollectionValueParser.IsCollectionType(targetType))
			{
				var (item, text) = CollectionValueParser.TryParse(targetType, valueString);
				return (text == null, item, text);
			}
			var (item2, text2) = TryParseScalar(targetType, valueString);
			return (text2 == null, item2, text2);
		}

		public static bool TryParse(Type targetType, string value, out object result)
		{
			result = null;
			if (value == null)
			{
				return false;
			}
			var (flag, obj, _) = TryParseWithDetails(targetType, value);
			if (flag)
			{
				result = obj;
				return true;
			}
			return false;
		}

		internal static (object value, string error) TryParseScalar(Type targetType, string valueString)
		{
			if (string.IsNullOrWhiteSpace(valueString))
			{
				return (null, "Empty value");
			}
			valueString = valueString.Trim();
			if (targetType == typeof(string))
			{
				return (valueString, null);
			}
			if (targetType == typeof(int))
			{
				if (int.TryParse(valueString, out var result))
				{
					return (result, null);
				}
				return (null, "Cannot convert '" + valueString + "' to int");
			}
			if (targetType == typeof(float))
			{
				if (float.TryParse(valueString, out var result2))
				{
					return (result2, null);
				}
				return (null, "Cannot convert '" + valueString + "' to float");
			}
			if (targetType == typeof(double))
			{
				if (double.TryParse(valueString, out var result3))
				{
					return (result3, null);
				}
				return (null, "Cannot convert '" + valueString + "' to double");
			}
			if (targetType == typeof(long))
			{
				if (long.TryParse(valueString, out var result4))
				{
					return (result4, null);
				}
				return (null, "Cannot convert '" + valueString + "' to long");
			}
			if (targetType == typeof(decimal))
			{
				if (decimal.TryParse(valueString, out var result5))
				{
					return (result5, null);
				}
				return (null, "Cannot convert '" + valueString + "' to decimal");
			}
			if (targetType == typeof(bool))
			{
				switch (valueString.ToLowerInvariant())
				{
				case "true":
				case "1":
				case "yes":
				case "on":
					return (true, null);
				case "false":
				case "0":
				case "no":
				case "off":
					return (false, null);
				default:
					return (null, "Cannot convert '" + valueString + "' to bool. Expected: true/false, 1/0, yes/no, on/off");
				}
			}
			if (targetType == typeof(char))
			{
				if (char.TryParse(valueString, out var result6))
				{
					return (result6, null);
				}
				return (null, "Cannot convert '" + valueString + "' to char");
			}
			if (targetType.IsEnum)
			{
				try
				{
					return (Enum.Parse(targetType, valueString, ignoreCase: true), null);
				}
				catch
				{
					string text = string.Join(", ", Enum.GetNames(targetType));
					return (null, "Invalid enum value. Expected one of: " + text);
				}
			}
			return (null, "Cannot parse type " + targetType.Name);
		}
	}
	public static class EventBusHelpers
	{
		public static IReadOnlyDictionary<string, Dictionary<string, EventDefinition>> GetRegisteredEvents()
		{
			return EventBus.GetRegisteredEvents();
		}

		public static bool TryGetEvent(string modNamespace, string eventName, out EventDefinition eventDef)
		{
			eventDef = null;
			IReadOnlyDictionary<string, Dictionary<string, EventDefinition>> registeredEvents = GetRegisteredEvents();
			if (registeredEvents == null)
			{
				return false;
			}
			if (!registeredEvents.TryGetValue(modNamespace, out var value))
			{
				return false;
			}
			return value.TryGetValue(eventName, out eventDef);
		}

		public static bool TryFindEvent(string eventName, out string foundNamespace, out EventDefinition eventDef)
		{
			eventDef = null;
			foundNamespace = null;
			IReadOnlyDictionary<string, Dictionary<string, EventDefinition>> registeredEvents = GetRegisteredEvents();
			if (registeredEvents == null)
			{
				return false;
			}
			foreach (KeyValuePair<string, Dictionary<string, EventDefinition>> item in registeredEvents)
			{
				if (item.Value.TryGetValue(eventName, out eventDef))
				{
					foundNamespace = item.Key;
					return true;
				}
			}
			return false;
		}

		public static void SendEventNotFound(ChatPanel panel, string modNamespace, string eventName)
		{
			ChatHelpers.SendChatLog(panel, "Event '" + eventName + "' not found in mod '" + modNamespace + "'", ChatLogStatus.Error);
		}

		public static void SendModNotFound(ChatPanel panel, string modNamespace)
		{
			ChatHelpers.SendChatLog(panel, "Mod '" + modNamespace + "' not found", ChatLogStatus.Error);
		}

		public static void SendMissingParams(ChatPanel panel)
		{
			ChatHelpers.SendChatLog(panel, "Missing --mod or --event parameter. Usage: /event --mod=<namespace> --event=<name>", ChatLogStatus.Warning);
		}

		public static void SendEventInfo(ChatPanel panel, string modNamespace, string eventName, EventDefinition eventDef)
		{
			ChatHelpers.SendChatLog(panel, modNamespace + "." + eventName, ChatLogStatus.Success);
			string text = (string.IsNullOrEmpty(eventDef.Description) ? "(no description)" : eventDef.Description);
			ChatHelpers.SendChatLog(panel, "Description: " + text);
			if (eventDef.Schema.Fields.Count > 0)
			{
				ChatHelpers.SendChatLog(panel, "Parameters:");
				{
					foreach (KeyValuePair<string, Type> field in eventDef.Schema.Fields)
					{
						string text2 = eventDef.Schema.GetDescription(field.Key) ?? "(no description)";
						ChatHelpers.SendChatLog(panel, "  - " + field.Key + " (" + GetTypeName(field.Value) + "): " + text2);
					}
					return;
				}
			}
			ChatHelpers.SendChatLog(panel, "No parameters defined.");
		}

		private static string GetTypeName(Type type)
		{
			if (type == null)
			{
				return "Unknown";
			}
			if (type.IsGenericType)
			{
				string obj = type.Name.Split(new char[1] { '`' })[0];
				string text = string.Join(", ", from t in type.GetGenericArguments()
					select t.Name);
				return obj + "<" + text + ">";
			}
			return type.Name;
		}
	}
	public static class GenericTypeParser
	{
		private static readonly Dictionary<string, Type> SimpleTypeMap = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"string",
				typeof(string)
			},
			{
				"int",
				typeof(int)
			},
			{
				"bool",
				typeof(bool)
			},
			{
				"float",
				typeof(float)
			},
			{
				"double",
				typeof(double)
			},
			{
				"decimal",
				typeof(decimal)
			},
			{
				"long",
				typeof(long)
			},
			{
				"short",
				typeof(short)
			},
			{
				"byte",
				typeof(byte)
			},
			{
				"char",
				typeof(char)
			},
			{
				"object",
				typeof(object)
			},
			{
				"void",
				typeof(void)
			},
			{
				"hashset",
				typeof(HashSet<>)
			},
			{
				"list",
				typeof(List<>)
			},
			{
				"dictionary",
				typeof(Dictionary<, >)
			},
			{
				"queue",
				typeof(Queue<>)
			},
			{
				"stack",
				typeof(Stack<>)
			},
			{
				"set",
				typeof(HashSet<>)
			}
		};

		public static Type Parse(string typeString)
		{
			if (string.IsNullOrWhiteSpace(typeString))
			{
				return null;
			}
			typeString = typeString.Trim();
			int num = typeString.IndexOf('[');
			int num2 = typeString.IndexOf('<');
			if (num >= 0 && (num2 < 0 || num < num2))
			{
				return ParseArrayType(typeString);
			}
			if (num2 >= 0)
			{
				return ParseGenericType(typeString);
			}
			return ParseSimpleType(typeString);
		}

		private static Type ParseArrayType(string typeString)
		{
			int num = typeString.IndexOf('[');
			if (num < 0)
			{
				return null;
			}
			string typeString2 = typeString.Substring(0, num);
			string text = typeString.Substring(num);
			Type type = Parse(typeString2);
			if (type == null)
			{
				return null;
			}
			if (text == "[]")
			{
				return type.MakeArrayType();
			}
			int num2 = 1;
			for (int i = 1; i < text.Length; i++)
			{
				if (text[i] == ',')
				{
					num2++;
				}
			}
			return type.MakeArrayType(num2);
		}

		private static Type ParseGenericType(string typeString)
		{
			int num = typeString.IndexOf('<');
			int num2 = typeString.LastIndexOf('>');
			if (num < 0 || num2 < 0 || num2 <= num)
			{
				return null;
			}
			string typeName = typeString.Substring(0, num);
			List<Type> list = ParseGenericArguments(typeString.Substring(num + 1, num2 - num - 1));
			if (list == null || list.Count == 0)
			{
				return null;
			}
			Type type = ParseSimpleType(typeName);
			if (type == null)
			{
				return null;
			}
			try
			{
				return type.MakeGenericType(list.ToArray());
			}
			catch (Exception)
			{
				return null;
			}
		}

		private static List<Type> ParseGenericArguments(string argsString)
		{
			List<Type> list = new List<Type>();
			int num = 0;
			int num2 = 0;
			for (int i = 0; i <= argsString.Length; i++)
			{
				switch ((i < argsString.Length) ? argsString[i] : ',')
				{
				case '<':
				case '[':
					num++;
					break;
				case '>':
				case ']':
					num--;
					break;
				case ',':
				{
					if (num != 0)
					{
						break;
					}
					string text = argsString.Substring(num2, i - num2).Trim();
					if (!string.IsNullOrEmpty(text))
					{
						Type type = Parse(text);
						if (type == null)
						{
							return null;
						}
						list.Add(type);
					}
					num2 = i + 1;
					break;
				}
				}
			}
			if (num2 < argsString.Length)
			{
				string text2 = argsString.Substring(num2).Trim();
				if (!string.IsNullOrEmpty(text2))
				{
					Type type2 = Parse(text2);
					if (type2 == null)
					{
						return null;
					}
					list.Add(type2);
				}
			}
			return list;
		}

		private static Type ParseSimpleType(string typeName)
		{
			if (string.IsNullOrWhiteSpace(typeName))
			{
				return null;
			}
			typeName = typeName.Trim();
			if (SimpleTypeMap.TryGetValue(typeName, out var value))
			{
				return value;
			}
			if (typeName.EndsWith("?"))
			{
				Type type = ParseSimpleType(typeName.Substring(0, typeName.Length - 1));
				if (type != null)
				{
					return typeof(Nullable<>).MakeGenericType(type);
				}
				return null;
			}
			return FindTypeInAssemblies(typeName);
		}

		private static Type FindTypeInAssemblies(string typeName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			if (Enumerable.Contains(typeName, '.') || Enumerable.Contains(typeName, '+'))
			{
				Type type = TryResolveNestedClass(typeName);
				if (type != null)
				{
					return type;
				}
			}
			Assembly[] array = assemblies;
			foreach (Assembly assembly in array)
			{
				try
				{
					Type type2 = assembly.GetType(typeName, throwOnError: false, ignoreCase: true);
					if (type2 != null)
					{
						return type2;
					}
				}
				catch
				{
				}
			}
			array = assemblies;
			foreach (Assembly assembly2 in array)
			{
				try
				{
					string name = typeName;
					int num = typeName.LastIndexOf('.');
					if (num >= 0)
					{
						name = typeName.Substring(num + 1);
					}
					Type type3 = assembly2.GetType(name, throwOnError: false, ignoreCase: true);
					if (type3 != null)
					{
						return type3;
					}
				}
				catch
				{
				}
			}
			array = assemblies;
			foreach (Assembly assembly3 in array)
			{
				try
				{
					Type[] types = assembly3.GetTypes();
					foreach (Type type4 in types)
					{
						if (string.Equals(type4.Name, typeName, StringComparison.OrdinalIgnoreCase) || string.Equals(type4.FullName, typeName, StringComparison.OrdinalIgnoreCase))
						{
							return type4;
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static Type TryResolveNestedClass(string typeName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			List<string> list = new List<string>();
			list.Add(typeName);
			if (Enumerable.Contains(typeName, '.'))
			{
				string[] array = typeName.Split(new char[1] { '.' });
				for (int i = 1; i < array.Length; i++)
				{
					string item = string.Join(".", array, 0, array.Length - i) + "+" + string.Join("+", array, array.Length - i, i);
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
				list.Add(typeName.Replace(".", "+"));
			}
			if (Enumerable.Contains(typeName, '+'))
			{
				string item2 = typeName.Replace("+", ".");
				if (!list.Contains(item2))
				{
					list.Add(item2);
				}
				string[] array2 = typeName.Split(new char[1] { '+' });
				for (int j = 1; j < array2.Length; j++)
				{
					string item3 = string.Join("+", array2, 0, array2.Length - j) + "." + string.Join(".", array2, array2.Length - j, j);
					if (!list.Contains(item3))
					{
						list.Add(item3);
					}
				}
			}
			Assembly[] array3 = assemblies;
			foreach (Assembly assembly in array3)
			{
				try
				{
					foreach (string item4 in list)
					{
						try
						{
							Type type = assembly.GetType(item4, throwOnError: false, ignoreCase: true);
							if (type != null)
							{
								return type;
							}
						}
						catch
						{
						}
					}
				}
				catch
				{
				}
			}
			array3 = assemblies;
			foreach (Assembly assembly2 in array3)
			{
				try
				{
					Type[] types = assembly2.GetTypes();
					foreach (Type type2 in types)
					{
						string fullName = type2.FullName;
						if (fullName != null)
						{
							string a = (Enumerable.Contains(fullName, '+') ? fullName.Substring(fullName.LastIndexOf('+') + 1) : (Enumerable.Contains(fullName, '.') ? fullName.Substring(fullName.LastIndexOf('.') + 1) : fullName));
							string b = (Enumerable.Contains(typeName, '+') ? typeName.Substring(typeName.LastIndexOf('+') + 1) : (Enumerable.Contains(typeName, '.') ? typeName.Substring(typeName.LastIndexOf('.') + 1) : typeName));
							if (string.Equals(a, b, StringComparison.OrdinalIgnoreCase))
							{
								return type2;
							}
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}

		public static bool IsGenericType(string typeString)
		{
			if (!string.IsNullOrWhiteSpace(typeString) && Enumerable.Contains(typeString, '<'))
			{
				return Enumerable.Contains(typeString, '>');
			}
			return false;
		}

		public static bool IsArrayType(string typeString)
		{
			if (!string.IsNullOrWhiteSpace(typeString) && Enumerable.Contains(typeString, '['))
			{
				return Enumerable.Contains(typeString, ']');
			}
			return false;
		}
	}
}
namespace OutwardModsCommunicatorChatControl.Utility.Enums
{
	public enum ChatCommandsManagerParams
	{
		CommandName,
		CommandParameters,
		CommandAction,
		IsCheatCommand,
		CommandDescription,
		CommandRequiresDebugMode
	}
	public static class ChatCommandsManagerParamsHelper
	{
		private static readonly Dictionary<ChatCommandsManagerParams, (string key, Type type)> _registry = new Dictionary<ChatCommandsManagerParams, (string, Type)>
		{
			[ChatCommandsManagerParams.CommandName] = ("command", typeof(string)),
			[ChatCommandsManagerParams.CommandParameters] = ("parameters", typeof(Dictionary<string, (string, string)>)),
			[ChatCommandsManagerParams.CommandAction] = ("function", typeof(Action<Character, Dictionary<string, string>>)),
			[ChatCommandsManagerParams.IsCheatCommand] = ("isCheatCommand", typeof(bool)),
			[ChatCommandsManagerParams.CommandDescription] = ("description", typeof(string)),
			[ChatCommandsManagerParams.CommandRequiresDebugMode] = ("debugMode", typeof(bool))
		};

		public static (string key, Type type) Get(ChatCommandsManagerParams param)
		{
			return _registry[param];
		}
	}
	public enum ChatLogStatus
	{
		Info,
		Success,
		Warning,
		Error
	}
	public static class ChatLogStatusHelper
	{
		public static string GetChatLogText(string message, ChatLogStatus status = ChatLogStatus.Info)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			return status switch
			{
				ChatLogStatus.Success => Global.SetTextColor(message, Global.LIGHT_GREEN), 
				ChatLogStatus.Warning => Global.SetTextColor(message, Global.LIGHT_ORANGE), 
				ChatLogStatus.Error => "<color=#" + UnityEngineExtensions.ToHex(Global.LIGHT_RED) + ">" + message + "</color>", 
				_ => message, 
			};
		}
	}
}
namespace OutwardModsCommunicatorChatControl.Tests
{
	public static class EventArgumentParserTests
	{
		public static void RunAllTests()
		{
			try
			{
				OMCCC.LogMessage("[TEST] Starting EventArgumentParser tests...");
				TestScalarInt();
				TestScalarFloat();
				TestScalarBool();
				TestScalarString();
				TestScalarChar();
				TestScalarEnum();
				TestArrayInt();
				TestArrayString();
				TestArrayEnum();
				TestListInt();
				TestHashSetInt();
				TestIEnumerableInt();
				TestScalarIntError();
				TestArrayIntError();
				TestEnumError();
				OMCCC.LogMessage("[TEST] All EventArgumentParser tests completed successfully!");
			}
			catch (Exception ex)
			{
				OMCCC.LogMessage("[TEST ERROR] Test suite failed: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		private static void TestScalarInt()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(int), "42");
			Assert(condition, "int parsing should succeed");
			Assert(obj is int && (int)obj == 42, "int value should be 42");
			OMCCC.LogMessage("[PASS] Scalar int test");
		}

		private static void TestScalarFloat()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(float), "3.14");
			Assert(condition, "float parsing should succeed");
			Assert(obj is float && Math.Abs((float)obj - 3.14f) < 0.01f, "float value should be ~3.14");
			OMCCC.LogMessage("[PASS] Scalar float test");
		}

		private static void TestScalarBool()
		{
			var (flag, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(bool), "true");
			Assert(flag && (bool)obj, "bool 'true' should parse");
			var (flag2, obj2, _) = EventArgumentParser.TryParseWithDetails(typeof(bool), "yes");
			Assert(flag2 && (bool)obj2, "bool 'yes' should parse");
			var (flag3, obj3, _) = EventArgumentParser.TryParseWithDetails(typeof(bool), "false");
			Assert(flag3 && !(bool)obj3, "bool 'false' should parse");
			var (flag4, obj4, _) = EventArgumentParser.TryParseWithDetails(typeof(bool), "0");
			Assert(flag4 && !(bool)obj4, "bool '0' should parse as false");
			OMCCC.LogMessage("[PASS] Scalar bool test");
		}

		private static void TestScalarString()
		{
			var (flag, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(string), "hello");
			Assert(flag && (string)obj == "hello", "string parsing should succeed");
			OMCCC.LogMessage("[PASS] Scalar string test");
		}

		private static void TestScalarChar()
		{
			var (flag, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(char), "A");
			Assert(flag && (char)obj == 'A', "char parsing should succeed");
			OMCCC.LogMessage("[PASS] Scalar char test");
		}

		private static void TestScalarEnum()
		{
			var (flag, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(DayOfWeek), "Monday");
			Assert(flag && (DayOfWeek)obj == DayOfWeek.Monday, "enum parsing should succeed");
			var (flag2, obj2, _) = EventArgumentParser.TryParseWithDetails(typeof(DayOfWeek), "monday");
			Assert(flag2 && (DayOfWeek)obj2 == DayOfWeek.Monday, "enum parsing should be case-insensitive");
			OMCCC.LogMessage("[PASS] Scalar enum test");
		}

		private static void TestArrayInt()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(int[]), "1 2 3");
			Assert(condition, "int array parsing should succeed");
			Assert(obj is int[] array && array.Length == 3 && array[0] == 1 && array[1] == 2 && array[2] == 3, "int array should be [1,2,3]");
			OMCCC.LogMessage("[PASS] Array int test");
		}

		private static void TestArrayString()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(string[]), "hello world test");
			Assert(condition, "string array parsing should succeed");
			Assert(obj is string[] array && array.Length == 3 && array[0] == "hello" && array[1] == "world" && array[2] == "test", "string array should be correct");
			OMCCC.LogMessage("[PASS] Array string test");
		}

		private static void TestArrayEnum()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(DayOfWeek[]), "Monday Wednesday Friday");
			Assert(condition, "enum array parsing should succeed");
			Assert(obj is DayOfWeek[] array && array.Length == 3 && array[0] == DayOfWeek.Monday && array[1] == DayOfWeek.Wednesday, "enum array should be correct");
			OMCCC.LogMessage("[PASS] Array enum test");
		}

		private static void TestListInt()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(List<int>), "10 20 30");
			Assert(condition, "List<int> parsing should succeed");
			Assert(obj is List<int> list && list.Count == 3 && list[0] == 10 && list[1] == 20, "List<int> should contain correct values");
			OMCCC.LogMessage("[PASS] Collection List<int> test");
		}

		private static void TestHashSetInt()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(HashSet<int>), "5 10 15");
			Assert(condition, "HashSet<int> parsing should succeed");
			Assert(obj is HashSet<int> hashSet && hashSet.Count == 3 && hashSet.Contains(5) && hashSet.Contains(10), "HashSet<int> should contain correct values");
			OMCCC.LogMessage("[PASS] Collection HashSet<int> test");
		}

		private static void TestIEnumerableInt()
		{
			var (condition, obj, _) = EventArgumentParser.TryParseWithDetails(typeof(IEnumerable<int>), "7 8 9");
			Assert(condition, "IEnumerable<int> parsing should succeed");
			Assert(obj != null, "IEnumerable<int> should not be null");
			List<int> list = ((IEnumerable<int>)obj).ToList();
			Assert(list.Count == 3 && list[0] == 7 && list[1] == 8, "IEnumerable<int> should contain correct values");
			OMCCC.LogMessage("[PASS] Collection IEnumerable<int> test");
		}

		private static void TestScalarIntError()
		{
			var (flag, _, text) = EventArgumentParser.TryParseWithDetails(typeof(int), "abc");
			Assert(!flag, "int parsing of 'abc' should fail");
			Assert(text != null && !string.IsNullOrEmpty(text), "error message should be provided");
			OMCCC.LogMessage("[PASS] Scalar int error test (error: " + text + ")");
		}

		private static void TestArrayIntError()
		{
			var (flag, _, text) = EventArgumentParser.TryParseWithDetails(typeof(int[]), "1 2 abc 4");
			Assert(!flag, "int array parsing with invalid element should fail");
			Assert(text?.Contains("position") ?? false, "error should indicate position");
			OMCCC.LogMessage("[PASS] Array int error test (error: " + text + ")");
		}

		private static void TestEnumError()
		{
			var (flag, _, text) = EventArgumentParser.TryParseWithDetails(typeof(DayOfWeek), "InvalidDay");
			Assert(!flag, "enum parsing of invalid value should fail");
			Assert(text?.Contains("Expected one of") ?? false, "error should list valid options");
			OMCCC.LogMessage("[PASS] Enum error test (error: " + text + ")");
		}

		private static void Assert(bool condition, string message)
		{
			if (!condition)
			{
				throw new Exception("Assertion failed: " + message);
			}
		}
	}
}
namespace OutwardModsCommunicatorChatControl.Managers
{
	public class PathsManager
	{
		private static PathsManager _instance;

		public string configPath = "";

		public string xmlFilePath = "";

		public static PathsManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new PathsManager();
				}
				return _instance;
			}
		}

		private PathsManager()
		{
			configPath = Path.Combine(PathsManager.ConfigPath, "Chat_Commands_Template");
			xmlFilePath = Path.Combine(configPath, "MyDocument.xml");
		}
	}
}
namespace OutwardModsCommunicatorChatControl.Events
{
	public static class EventBusPublisher
	{
		public const string Event_AddCommand = "ChatCommandsManager@AddChatCommand";

		public const string Event_RemoveCommand = "ChatCommandsManager@RemoveChatCommand";

		public const string ChatCommands_Listener = "gymmed.chat_commands_manager_*";

		public static void SendCommands()
		{
			ListEventsPublisher.SendListEventsCommand();
			GetEventPublisher.SendGetEventCommand();
			PublishEventPublisher.SendPublishCommand();
		}
	}
	public static class EventBusRegister
	{
		public static void RegisterEvents()
		{
		}
	}
	public static class EventBusSubscriber
	{
		public const string Event_AddedChatCommand = "ChatCommandsManager@AddChatCommand_After";

		public const string Event_RemovedChatCommand = "ChatCommandsManager@RemoveChatCommand_After";

		public static void AddSubscribers()
		{
			EventBus.Subscribe("gymmed.chat_commands_manager_*", "ChatCommandsManager@AddChatCommand_After", (Action<EventPayload>)AddedChatCommand);
			EventBus.Subscribe("gymmed.chat_commands_manager_*", "ChatCommandsManager@RemoveChatCommand_After", (Action<EventPayload>)RemovedChatCommand);
		}

		public static void AddedChatCommand(EventPayload payload)
		{
			if (payload != null)
			{
				(string, Type) tuple = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandName);
				payload.Get<string>(tuple.Item1, (string)null);
				OMCCC.LogMessage("Added command " + tuple.Item1);
			}
		}

		public static void RemovedChatCommand(EventPayload payload)
		{
			if (payload != null)
			{
				(string, Type) tuple = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandName);
				payload.Get<string>(tuple.Item1, (string)null);
				OMCCC.LogMessage("Removed command " + tuple.Item1);
			}
		}
	}
}
namespace OutwardModsCommunicatorChatControl.Events.Publishers
{
	public static class GetEventPublisher
	{
		public static void SendGetEventCommand()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_009f: Expected O, but got Unknown
			Action<Character, Dictionary<string, string>> value = TriggerFunction;
			EventPayload val = new EventPayload { };
			string item;
			((Dictionary<string, object>)val)[item] = "event";
			string item2 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandParameters).key;
			((Dictionary<string, object>)val)[item2] = new Dictionary<string, (string, string)>
			{
				{
					"mod",
					("Mod namespace (optional if searching all mods).", null)
				},
				{
					"event",
					("Event name to look up.", null)
				}
			};
			string item3 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandAction).key;
			((Dictionary<string, object>)val)[item3] = value;
			string item4 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandDescription).key;
			((Dictionary<string, object>)val)[item4] = "Gets detailed information about a specific event, including proper type information for collections (HashSet, List, arrays), enums, and other supported types.";
			EventPayload val2 = val;
			EventBus.Publish("gymmed.chat_commands_manager_*", "ChatCommandsManager@AddChatCommand", val2);
		}

		public static void TriggerFunction(Character caller, Dictionary<string, string> arguments)
		{
			object obj;
			if (caller == null)
			{
				obj = null;
			}
			else
			{
				CharacterUI characterUI = caller.CharacterUI;
				obj = ((characterUI != null) ? characterUI.ChatPanel : null);
			}
			ChatPanel val = (ChatPanel)obj;
			if ((Object)(object)val == (Object)null)
			{
				OMCCC.LogMessage("GetEventPublisher@TriggerFunction: No chat panel found");
				return;
			}
			arguments.TryGetValue("mod", out var value);
			arguments.TryGetValue("event", out var value2);
			if (string.IsNullOrEmpty(value2))
			{
				EventBusHelpers.SendMissingParams(val);
				return;
			}
			EventDefinition eventDef;
			string foundNamespace;
			if (!string.IsNullOrEmpty(value))
			{
				if (!EventBusHelpers.TryGetEvent(value, value2, out eventDef))
				{
					EventBusHelpers.SendEventNotFound(val, value, value2);
					return;
				}
				foundNamespace = value;
			}
			else if (!EventBusHelpers.TryFindEvent(value2, out foundNamespace, out eventDef))
			{
				ChatHelpers.SendChatLog(val, "Event '" + value2 + "' not found in any mod", ChatLogStatus.Error);
				return;
			}
			EventBusHelpers.SendEventInfo(val, foundNamespace, value2, eventDef);
		}
	}
	public static class ListEventsPublisher
	{
		public static void SendListEventsCommand()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0073: Expected O, but got Unknown
			Action<Character, Dictionary<string, string>> value = TriggerFunction;
			EventPayload val = new EventPayload { };
			string item;
			((Dictionary<string, object>)val)[item] = "events";
			string item2 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandParameters).key;
			((Dictionary<string, object>)val)[item2] = new Dictionary<string, (string, string)>();
			string item3 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandAction).key;
			((Dictionary<string, object>)val)[item3] = value;
			string item4 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandDescription).key;
			((Dictionary<string, object>)val)[item4] = "Lists all registered events from OutwardModsCommunicator.";
			EventPayload val2 = val;
			EventBus.Publish("gymmed.chat_commands_manager_*", "ChatCommandsManager@AddChatCommand", val2);
		}

		public static void TriggerFunction(Character caller, Dictionary<string, string> arguments)
		{
			object obj;
			if (caller == null)
			{
				obj = null;
			}
			else
			{
				CharacterUI characterUI = caller.CharacterUI;
				obj = ((characterUI != null) ? characterUI.ChatPanel : null);
			}
			ChatPanel val = (ChatPanel)obj;
			if ((Object)(object)val == (Object)null)
			{
				OMCCC.LogMessage("ListEventsPublisher@TriggerFunction: No chat panel found");
				return;
			}
			IReadOnlyDictionary<string, Dictionary<string, EventDefinition>> registeredEvents = EventBusHelpers.GetRegisteredEvents();
			if (registeredEvents == null || registeredEvents.Count == 0)
			{
				ChatHelpers.SendChatLog(val, "0 events registered");
				return;
			}
			int num = registeredEvents.Values.Sum((Dictionary<string, EventDefinition> modEvents) => modEvents.Count);
			ChatHelpers.SendChatLog(val, $"{num} events registered", ChatLogStatus.Success);
			foreach (KeyValuePair<string, Dictionary<string, EventDefinition>> item in registeredEvents)
			{
				ChatHelpers.SendChatLog(val, "Mod: " + item.Key);
				foreach (KeyValuePair<string, EventDefinition> item2 in item.Value)
				{
					string key = item2.Key;
					string text = (string.IsNullOrEmpty(item2.Value.Description) ? "(no description)" : item2.Value.Description);
					ChatHelpers.SendChatLog(val, "  - " + key + ": " + text);
				}
			}
		}
	}
	public static class PublishEventPublisher
	{
		public static void SendPublishCommand()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00ba: Expected O, but got Unknown
			Action<Character, Dictionary<string, string>> value = TriggerFunction;
			EventPayload val = new EventPayload { };
			string item;
			((Dictionary<string, object>)val)[item] = "publish";
			string item2 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandParameters).key;
			((Dictionary<string, object>)val)[item2] = new Dictionary<string, (string, string)>
			{
				{
					"mod",
					("Mod namespace (optional if searching all mods).", null)
				},
				{
					"event",
					("Event name.", null)
				}
			};
			string item3 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandAction).key;
			((Dictionary<string, object>)val)[item3] = value;
			string item4 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandDescription).key;
			((Dictionary<string, object>)val)[item4] = "Publishes an event to OutwardModsCommunicator with proper type casting for collections (HashSet, List, arrays), enums, and other types. Usage: /publish [mod] event [--param=value...]";
			string item5 = ChatCommandsManagerParamsHelper.Get(ChatCommandsManagerParams.CommandRequiresDebugMode).key;
			((Dictionary<string, object>)val)[item5] = true;
			EventPayload val2 = val;
			EventBus.Publish("gymmed.chat_commands_manager_*", "ChatCommandsManager@AddChatCommand", val2);
		}

		public static void TriggerFunction(Character caller, Dictionary<string, string> arguments)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			object obj;
			if (caller == null)
			{
				obj = null;
			}
			else
			{
				CharacterUI characterUI = caller.CharacterUI;
				obj = ((characterUI != null) ? characterUI.ChatPanel : null);
			}
			ChatPanel val = (ChatPanel)obj;
			if ((Object)(object)val == (Object)null)
			{
				OMCCC.LogMessage("PublishEventPublisher@TriggerFunction: No chat panel found");
				return;
			}
			arguments.TryGetValue("mod", out var value);
			arguments.TryGetValue("event", out var value2);
			if (string.IsNullOrEmpty(value2))
			{
				SendUsageError(val);
				return;
			}
			EventDefinition eventDef;
			string foundNamespace;
			if (!string.IsNullOrEmpty(value))
			{
				if (!EventBusHelpers.TryGetEvent(value, value2, out eventDef))
				{
					ChatHelpers.SendChatLog(val, "Event '" + value2 + "' not found in mod '" + value + "'", ChatLogStatus.Error);
					return;
				}
				foundNamespace = value;
			}
			else if (!EventBusHelpers.TryFindEvent(value2, out foundNamespace, out eventDef))
			{
				ChatHelpers.SendChatLog(val, "Event '" + value2 + "' not found in any mod", ChatLogStatus.Error);
				return;
			}
			EventPayload val2 = new EventPayload();
			List<string> list = new List<string>();
			EventSchema schema = eventDef.Schema;
			Dictionary<string, Type>.KeyCollection source = ((schema == null) ? null : schema.Fields?.Keys) ?? new Dictionary<string, Type>().Keys;
			foreach (KeyValuePair<string, string> argument in arguments)
			{
				string key = argument.Key;
				string value3 = argument.Value;
				if (key == "mod" || key == "event")
				{
					continue;
				}
				if (source.Contains(key))
				{
					Type type = eventDef.Schema.Fields[key];
					var (flag, value4, text) = EventArgumentParser.TryParseWithDetails(type, value3);
					if (flag)
					{
						((Dictionary<string, object>)(object)val2)[key] = value4;
						continue;
					}
					list.Add("Parameter '" + key + "' (" + type.Name + "): " + (text ?? "Unknown error"));
				}
				else
				{
					object obj2 = TryAutoDetectAndParse(value3);
					if (obj2 != null)
					{
						((Dictionary<string, object>)(object)val2)[key] = obj2;
						ChatHelpers.SendChatLog(val, "Dynamic parameter '" + key + "' auto-detected as " + obj2.GetType().Name);
					}
				}
			}
			if (list.Count > 0)
			{
				foreach (string item in list)
				{
					ChatHelpers.SendChatLog(val, item, ChatLogStatus.Error);
				}
				return;
			}
			EventBus.Publish(foundNamespace, value2, val2);
			ChatHelpers.SendChatLog(val, "Published event '" + foundNamespace + "." + value2 + "'", ChatLogStatus.Success);
		}

		private static object TryAutoDetectAndParse(string valueString)
		{
			if (string.IsNullOrWhiteSpace(valueString))
			{
				return null;
			}
			valueString = valueString.Trim();
			string[] array = valueString.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length > 1)
			{
				if (array.All((string p) => int.TryParse(p, out var _)))
				{
					int[] array2 = new int[array.Length];
					for (int i = 0; i < array.Length; i++)
					{
						int.TryParse(array[i], out array2[i]);
					}
					return array2;
				}
				return array;
			}
			if (int.TryParse(valueString, out var result))
			{
				return result;
			}
			if (bool.TryParse(valueString, out var result2))
			{
				return result2;
			}
			return valueString;
		}

		private static void SendUsageError(ChatPanel panel)
		{
			ChatHelpers.SendChatLog(panel, "Missing --event parameter. Usage: /publish <mod> <event> [--param=value...]", ChatLogStatus.Warning);
		}
	}
}