Decompiled source of SlayerSkills v1.0.8

SlayerSkills.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
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.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SlayerSkills")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SlayerSkills")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9f8a1b6e-6d0e-4dab-bbd8-9ed433836544")]
[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]
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace neobotics.ValheimMods;

internal class DebugUtils
{
	public static void ObjectInspector(object o)
	{
		if (o == null)
		{
			Debug.Log((object)"Object is null");
			return;
		}
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		Type type = o.GetType();
		Debug.Log((object)(o.ToString() + " Type " + type.Name));
		PropertyInfo[] properties = type.GetProperties(bindingAttr);
		foreach (PropertyInfo propertyInfo in properties)
		{
			Debug.Log((object)$"{type.Name}.{propertyInfo.Name} = {propertyInfo.GetValue(o)}");
		}
		FieldInfo[] fields = type.GetFields(bindingAttr);
		foreach (FieldInfo field in fields)
		{
			FieldPrinter(o, type, field);
		}
	}

	public static void MethodInspector(object o)
	{
		if (o == null)
		{
			Debug.Log((object)"Object is null");
			return;
		}
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		Type type = o.GetType();
		Debug.Log((object)(o.ToString() + " Type " + type.Name));
		MethodInfo[] methods = type.GetMethods(bindingAttr);
		foreach (MethodInfo methodInfo in methods)
		{
			methodInfo.GetParameters();
			string arg = string.Join(", ", (from x in methodInfo.GetParameters()
				select x.ParameterType?.ToString() + " " + x.Name).ToArray());
			Debug.Log((object)$"{methodInfo.ReturnType} {methodInfo.Name} ({arg})");
		}
	}

	private static void ItemDataInspector(ItemData item)
	{
		ObjectInspector(item);
		ObjectInspector(item.m_shared);
	}

	private static void FieldPrinter(object o, Type t, FieldInfo field)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Expected O, but got Unknown
		try
		{
			if (field.FieldType == typeof(ItemData))
			{
				ItemData val = (ItemData)field.GetValue(o);
				if (val != null)
				{
					ItemDataInspector(val);
				}
				else
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
				}
			}
			else if (field.FieldType == typeof(Transform))
			{
				Transform val2 = (Transform)field.GetValue(o);
				if ((Object)(object)val2 != (Object)null)
				{
					Debug.Log((object)("\tTransform.parent = " + ((Object)val2.parent).name));
				}
				else
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
				}
			}
			else if (field.FieldType == typeof(EffectList))
			{
				EffectList val3 = (EffectList)field.GetValue(o);
				if (val3 != null)
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}:");
					EffectData[] effectPrefabs = val3.m_effectPrefabs;
					foreach (EffectData val4 in effectPrefabs)
					{
						Debug.Log((object)("\tEffectData.m_prefab = " + ((Object)val4.m_prefab).name));
					}
				}
				else
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
				}
			}
			else
			{
				Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}");
			}
		}
		catch (Exception)
		{
			Debug.Log((object)("Exception accessing " + t?.Name + "." + field?.Name));
		}
	}

	public static void GameObjectInspector(GameObject go)
	{
		Debug.Log((object)("\n\nInspecting GameObject " + ((Object)go).name));
		ObjectInspector(go);
		Component[] componentsInChildren = go.GetComponentsInChildren<Component>();
		foreach (Component val in componentsInChildren)
		{
			try
			{
				string obj = ((val != null) ? ((Object)val).name : null);
				object obj2;
				if (val == null)
				{
					obj2 = null;
				}
				else
				{
					Transform transform = val.transform;
					if (transform == null)
					{
						obj2 = null;
					}
					else
					{
						Transform parent = transform.parent;
						obj2 = ((parent != null) ? ((Object)parent).name : null);
					}
				}
				Debug.Log((object)("\n\nInspecting Component " + obj + " with parent " + (string?)obj2));
				ObjectInspector(val);
			}
			catch (Exception)
			{
			}
		}
	}

	public static void ComponentInspector(Component c)
	{
		Debug.Log((object)("\n\nInspecting Component " + ((Object)c).name));
		ObjectInspector(c);
	}

	public static void EffectsInspector(EffectList e)
	{
		EffectData[] effectPrefabs = e.m_effectPrefabs;
		Debug.Log((object)$"Effect list has effects {e.HasEffects()} count {effectPrefabs.Length}");
		EffectData[] array = effectPrefabs;
		foreach (EffectData val in array)
		{
			Debug.Log((object)$"Effect Data {val} prefab name {((Object)val.m_prefab).name} prefab GameObject name {((Object)val.m_prefab.gameObject).name}");
		}
	}

	public static void PrintInventory()
	{
		foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
		{
			Debug.Log((object)allItem.m_shared.m_name);
		}
	}

	public static void PrintAllObjects()
	{
		ZNetScene.instance.m_prefabs.ForEach(delegate(GameObject x)
		{
			Debug.Log((object)("GameObject " + ((Object)x).name));
		});
	}

	public static void PrintAllCharacters()
	{
		Character.GetAllCharacters().ForEach(delegate(Character x)
		{
			Debug.Log((object)("Character " + ((Object)x).name));
		});
	}
}
public class DelegatedConfigEntry<T> : DelegatedConfigEntryBase
{
	private ConfigEntry<T> _entry;

	private EventHandler rootHandler;

	private Action<object, EventArgs> clientDelegate;

	private Logging Log;

	public ConfigEntry<T> ConfigEntry
	{
		get
		{
			return _entry;
		}
		set
		{
			_entry = value;
			if (_entry != null && rootHandler != null)
			{
				_entry.SettingChanged += rootHandler;
			}
			Name = ((ConfigEntryBase)_entry).Definition.Key;
			Section = ((ConfigEntryBase)_entry).Definition.Section;
			ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
			Log.Trace("Set " + Section + " " + Name + " to serialized value " + ServerValue);
		}
	}

	public T Value
	{
		get
		{
			return _entry.Value;
		}
		set
		{
			_entry.Value = value;
		}
	}

	public DelegatedConfigEntry(bool useServerDelegate = false)
		: this((Action<object, EventArgs>)null, useServerDelegate)
	{
	}

	public DelegatedConfigEntry(Action<object, EventArgs> delegateHandler, bool useServerDelegate = false)
	{
		Log = Logging.GetLogger();
		Log.Trace("DelegatedConfigEntry");
		if (delegateHandler != null)
		{
			clientDelegate = delegateHandler;
		}
		if (useServerDelegate)
		{
			Log.Trace("Configuring server delegate");
			rootHandler = delegate(object s, EventArgs e)
			{
				ServerDelegate(s, e);
			};
			ServerConfiguration.ServerDelegatedEntries.Add(this);
		}
		else if (clientDelegate != null)
		{
			rootHandler = delegate(object s, EventArgs e)
			{
				clientDelegate(s, e);
			};
		}
	}

	private void ServerDelegate(object sender, EventArgs args)
	{
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		Logging.GetLogger().Trace("ServerDelegate");
		_entry.SettingChanged -= rootHandler;
		ZNet instance = ZNet.instance;
		bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : null);
		if (flag.HasValue)
		{
			if (flag == false)
			{
				if (ServerValue != null)
				{
					((ConfigEntryBase)_entry).SetSerializedValue(ServerValue);
				}
			}
			else
			{
				ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
				ServerConfiguration.Instance.SendConfigToAllClients(sender, (SettingChangedEventArgs)args);
			}
		}
		if (clientDelegate != null)
		{
			clientDelegate(sender, args);
		}
		_entry.SettingChanged += rootHandler;
	}

	public void EnableHandler(bool setActive)
	{
		if (setActive)
		{
			_entry.SettingChanged += rootHandler;
		}
		else
		{
			_entry.SettingChanged -= rootHandler;
		}
	}

	public bool IsKeyPressed()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}

	public bool IsKeyDown()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}

	public bool IsKeyReleased()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKeyUp(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}
}
public class DelegatedConfigEntryBase
{
	public string Name;

	public string Section;

	public string ServerValue;
}
internal class HarmonyHelper
{
	public enum PatchType
	{
		Prefix,
		Postfix,
		Transpiler,
		Finalizer
	}

	private static Dictionary<string, string> detectionSet = new Dictionary<string, string>();

	private static Dictionary<string, string> unpatchMods = new Dictionary<string, string>();

	public static void GetDetectionSet(Dictionary<string, string> harmonyIds)
	{
		Logging logger = Logging.GetLogger();
		foreach (KeyValuePair<string, string> harmonyId in harmonyIds)
		{
			if (Harmony.HasAnyPatches(harmonyId.Key))
			{
				logger.Debug("Detected " + harmonyId.Value + " from Harmony");
				if (!detectionSet.ContainsKey(harmonyId.Key))
				{
					detectionSet.Add(harmonyId.Key, harmonyId.Value);
				}
			}
			else if (Chainloader.PluginInfos.ContainsKey(harmonyId.Key))
			{
				logger.Debug("Detected " + harmonyId.Value + " from BepInEx");
				if (!detectionSet.ContainsKey(harmonyId.Key))
				{
					detectionSet.Add(harmonyId.Key, harmonyId.Value);
				}
			}
		}
	}

	public static void AddExclusion(string key)
	{
		if (detectionSet.ContainsKey(key))
		{
			unpatchMods.Add(key, detectionSet[key]);
		}
	}

	public static void UnpatchMods(Harmony harmony)
	{
		Logging logger = Logging.GetLogger();
		foreach (KeyValuePair<string, string> unpatchMod in unpatchMods)
		{
			logger.Warning("Not compatible with " + unpatchMod.Value);
			harmony.UnpatchAll(unpatchMod.Key);
			detectionSet.Remove(unpatchMod.Key);
			logger.Warning("Disabled " + unpatchMod.Value);
		}
	}

	public static bool IsModDetected(string key)
	{
		return detectionSet.ContainsKey(key);
	}

	public static bool IsModNameDetected(string value)
	{
		return detectionSet.ContainsValue(value);
	}

	public static bool TryGetDetectedModName(string key, out string mod)
	{
		return detectionSet.TryGetValue(key, out mod);
	}

	public static bool TryGetDetectedModKey(string value, out string key)
	{
		key = null;
		foreach (string key2 in detectionSet.Keys)
		{
			if (detectionSet[key2] == value)
			{
				key = key2;
				return true;
			}
		}
		return false;
	}

	public static string AddAnonymousPatch(string baseMethodName, PatchType patchType, string modName, string patchMethodName = null)
	{
		string text = null;
		int num = 0;
		Logging logger = Logging.GetLogger();
		foreach (MethodBase item in Harmony.GetAllPatchedMethods().ToList())
		{
			MethodBaseExtensions.HasMethodBody(item);
			Patches patchInfo = Harmony.GetPatchInfo(item);
			ReadOnlyCollection<Patch> readOnlyCollection = patchInfo.Prefixes;
			switch (patchType)
			{
			case PatchType.Postfix:
				readOnlyCollection = patchInfo.Postfixes;
				break;
			case PatchType.Prefix:
				readOnlyCollection = patchInfo.Prefixes;
				break;
			case PatchType.Transpiler:
				readOnlyCollection = patchInfo.Transpilers;
				break;
			case PatchType.Finalizer:
				readOnlyCollection = patchInfo.Finalizers;
				break;
			}
			foreach (Patch item2 in readOnlyCollection)
			{
				if (!item2.owner.StartsWith("harmony-auto") || !(item.Name == baseMethodName))
				{
					continue;
				}
				if (patchMethodName != null)
				{
					if (item2.PatchMethod.Name == patchMethodName)
					{
						num++;
						text = item2.owner;
					}
				}
				else
				{
					num++;
					text = item2.owner;
				}
			}
			if (num == 1)
			{
				detectionSet.Add(text, modName);
				logger.Info($"Added unique anonymous {baseMethodName} {patchType}: {text} as {modName}");
			}
			else if (num > 1)
			{
				text = null;
				logger.Warning($"Found multiple anonymous {baseMethodName} {patchType} entries. Can't identify correct patch to remove or modify.");
			}
		}
		if (num == 0)
		{
			logger.Info("No patch found for " + modName);
		}
		return text;
	}
}
public class Logging
{
	public enum LogLevels
	{
		Critical,
		Error,
		Warning,
		Info,
		Debug,
		Trace
	}

	private static Logging _logger;

	public LogLevels LogLevel { get; set; }

	public string ModName { get; set; }

	private Logging(LogLevels level, string name)
	{
		LogLevel = level;
		ModName = name;
	}

	public static Logging GetLogger(LogLevels level, string name)
	{
		if (_logger == null)
		{
			_logger = new Logging(level, name);
		}
		return _logger;
	}

	public static Logging GetLogger()
	{
		if (_logger == null)
		{
			return GetLogger(LogLevels.Info, Assembly.GetExecutingAssembly().FullName);
		}
		return _logger;
	}

	public void Trace(string msg)
	{
		if (LogLevel >= LogLevels.Trace)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Debug(string msg)
	{
		if (LogLevel >= LogLevels.Debug)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Info(string msg)
	{
		if (LogLevel >= LogLevels.Info)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Warning(string msg)
	{
		if (LogLevel >= LogLevels.Warning)
		{
			Debug.LogWarning((object)Message(msg));
		}
	}

	public void Error(string msg)
	{
		if (LogLevel >= LogLevels.Error)
		{
			Debug.LogWarning((object)Message(msg));
		}
	}

	public void Error(Exception e)
	{
		Error(e, stackTrace: false);
	}

	public void Error(Exception e, bool stackTrace)
	{
		if (LogLevel >= LogLevels.Error)
		{
			Debug.LogWarning((object)Message(e.Message));
			if (stackTrace)
			{
				Debug.LogWarning((object)e.StackTrace);
			}
		}
	}

	public void Critical(Exception e)
	{
		if (LogLevel >= LogLevels.Critical)
		{
			Debug.LogError((object)Message(e.Message));
			Debug.LogError((object)e.StackTrace);
		}
	}

	private string Message(string msg)
	{
		return ModName + ": " + msg;
	}
}
public class ServerConfiguration
{
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	private static class ZNet_OnNewConnection_Patch
	{
		private static void Postfix(ZNet __instance, ZNetPeer peer)
		{
			Log.Debug("ZNet OnNewConnection postfix");
			if (!__instance.IsServer())
			{
				try
				{
					Log.Debug("Client registered RPC_ClientConfigReceiver");
					peer.m_rpc.Register<ZPackage>("ClientConfigReceiver." + GetPluginGuid(), (Action<ZRpc, ZPackage>)RPC_ClientConfigReceiver);
					return;
				}
				catch (Exception)
				{
					Log.Warning("Failed to register RPC");
					return;
				}
			}
			try
			{
				SendConfigToClient(peer);
			}
			catch (Exception)
			{
				Log.Warning("Error sending server configuration to client");
			}
		}
	}

	public static List<DelegatedConfigEntryBase> ServerDelegatedEntries = new List<DelegatedConfigEntryBase>();

	private static ConfigFile LocalConfig;

	private static BaseUnityPlugin Mod;

	private static ServerConfiguration _instance;

	private static Logging Log;

	public static bool IsSetup = false;

	private const string NOT_CONFIGURED = "ServerConfiguration not initialized. Setup first.";

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

	private ServerConfiguration()
	{
	}

	public void Setup(ConfigFile config, BaseUnityPlugin modInstance)
	{
		LocalConfig = config;
		Log = Logging.GetLogger();
		Log.Trace("ServerConfiguration Setup");
		Mod = modInstance;
		IsSetup = true;
	}

	public static string GetPluginGuid()
	{
		return Mod.Info.Metadata.GUID;
	}

	public static void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package)
	{
		if (!IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
			return;
		}
		Log.Debug("ClientConfigReceiver");
		string section;
		string name;
		while (package.GetPos() < package.Size())
		{
			section = package.ReadString();
			name = package.ReadString();
			string text = package.ReadString();
			Log.Trace("Reading " + section + " " + name + " value " + text + " from ZPackage");
			DelegatedConfigEntryBase delegatedConfigEntryBase = ServerDelegatedEntries.Find((DelegatedConfigEntryBase e) => e.Name == name && e.Section == section);
			if (delegatedConfigEntryBase != null)
			{
				Log.Trace("Found DCEB on client and setting to server value " + text);
				delegatedConfigEntryBase.ServerValue = text;
			}
			ConfigEntryBase val = LocalConfig[section, name];
			if (val != null)
			{
				Log.Trace("Found local CEB and setting underlying config value " + text);
				val.SetSerializedValue(text);
			}
		}
	}

	internal static void WriteConfigEntries(ZPackage zpkg)
	{
		foreach (DelegatedConfigEntryBase serverDelegatedEntry in ServerDelegatedEntries)
		{
			Log.Trace("Writing " + serverDelegatedEntry.Section + " " + serverDelegatedEntry.Name + " value " + serverDelegatedEntry.ServerValue + " to ZPackage");
			zpkg.Write(serverDelegatedEntry.Section);
			zpkg.Write(serverDelegatedEntry.Name);
			zpkg.Write(serverDelegatedEntry.ServerValue);
		}
	}

	internal static void SendConfigToClient(ZNetPeer peer)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected O, but got Unknown
		if (!IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
			return;
		}
		Log.Debug("ServerSendConfigToClient");
		ZPackage val = new ZPackage();
		WriteConfigEntries(val);
		peer.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { val });
	}

	public void SendConfigToAllClients(object o, SettingChangedEventArgs e)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		if (!IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
		}
		else if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() > 0)
		{
			Log.Debug("SendConfigToAllClients");
			ZPackage zpkg = new ZPackage();
			WriteConfigEntries(zpkg);
			((MonoBehaviour)Mod).StartCoroutine(_instance.Co_BroadcastConfig(zpkg));
		}
	}

	private IEnumerator Co_BroadcastConfig(ZPackage zpkg)
	{
		Log.Debug("Co_BroadcastConfig");
		List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers();
		foreach (ZNetPeer item in connectedPeers)
		{
			if (item != ZNet.instance.GetServerPeer())
			{
				item.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { zpkg });
			}
			yield return null;
		}
	}
}
internal class Utils
{
	public static TEnum Guardrails<TEnum>(string value, TEnum enumDefault) where TEnum : struct
	{
		if (Enum.TryParse<TEnum>(value, ignoreCase: true, out var result))
		{
			return result;
		}
		return enumDefault;
	}

	public static int Guardrails(int value, int lbound, int ubound)
	{
		if (value < lbound)
		{
			return lbound;
		}
		if (value > ubound)
		{
			return ubound;
		}
		return value;
	}

	public static float Guardrails(float value, float lbound, float ubound)
	{
		if (value < lbound)
		{
			return lbound;
		}
		if (value > ubound)
		{
			return ubound;
		}
		return value;
	}

	public static string UnClonifiedName(string name)
	{
		if (name == null)
		{
			return null;
		}
		int num = name.IndexOf("(Clone)");
		if (num < 1)
		{
			return name;
		}
		return name.Substring(0, num);
	}

	public static void SetTranslator(int id, string idText)
	{
		typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Localization.instance, new object[2]
		{
			"skill_" + id,
			idText
		});
	}

	public static string GetTranslated(int id)
	{
		Logging.GetLogger().Debug(string.Format("Got translation for id {0} to {1}", id, Localization.instance.Localize("skill_" + id)));
		return Localization.instance.Localize("$skill_" + id);
	}

	public static Sprite GetPrefabIcon(string prefabName)
	{
		Sprite result = null;
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
		ItemDrop val = default(ItemDrop);
		if ((Object)(object)itemPrefab != (Object)null && itemPrefab.TryGetComponent<ItemDrop>(ref val))
		{
			result = val.m_itemData.GetIcon();
		}
		return result;
	}

	public static Player GetPlayerByZDOID(ZDOID zid)
	{
		//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)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			ZDOID zDOID = ((Character)allPlayer).GetZDOID();
			if (((ZDOID)(ref zDOID)).Equals(zid))
			{
				return allPlayer;
			}
		}
		return null;
	}

	public static Character GetCharacterByZDOID(string cid)
	{
		//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)
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			ZDOID zDOID = allCharacter.GetZDOID();
			if (((object)(ZDOID)(ref zDOID)).ToString().Equals(cid))
			{
				return allCharacter;
			}
		}
		return null;
	}

	public static Character GetCharacterByZDOID(ZDOID cid)
	{
		//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)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			ZDOID zDOID = allCharacter.GetZDOID();
			if (((ZDOID)(ref zDOID)).Equals(cid))
			{
				return allCharacter;
			}
		}
		return null;
	}

	public static ZNetPeer GetPeerByRPC(ZRpc rpc)
	{
		foreach (ZNetPeer peer in ZNet.instance.GetPeers())
		{
			if (peer.m_rpc == rpc)
			{
				return peer;
			}
		}
		return null;
	}

	public static List<GameObject> GetGameObjectsOfType(Type t)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		List<GameObject> list = new List<GameObject>();
		Object[] array = Object.FindObjectsOfType(t);
		foreach (Object val in array)
		{
			list.Add(((Component)val).gameObject);
		}
		return list;
	}

	public static GameObject GetClosestGameObjectOfType(Type t, Vector3 point, float radius)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return GetGameObjectsOfTypeInRangeByDistance(t, point, radius)?[0];
	}

	public static List<GameObject> GetGameObjectsOfTypeInRangeByDistance(Type t, Vector3 point, float radius)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>();
		List<GameObject> gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius);
		if (gameObjectsOfTypeInRange.Count > 0)
		{
			foreach (GameObject item in gameObjectsOfTypeInRange)
			{
				list.Add(new KeyValuePair<GameObject, float>(item, Vector3.Distance(item.transform.position, point)));
			}
			list.Sort((KeyValuePair<GameObject, float> pair1, KeyValuePair<GameObject, float> pair2) => pair1.Value.CompareTo(pair2.Value));
			return list.ConvertAll((KeyValuePair<GameObject, float> x) => x.Key);
		}
		return null;
	}

	public static List<GameObject> GetGameObjectsOfTypeInRange(Type t, Vector3 point, float radius)
	{
		//IL_0007: 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)
		return (from x in GetGameObjectsOfType(t)
			where Vector3.Distance(x.transform.position, point) < radius
			select x).ToList();
	}

	public static float GetPointDepth(Vector3 p)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		return ZoneSystem.instance.m_waterLevel - GetSolidHeight(p);
	}

	public static List<string> GetDelimitedStringAsList(string delimitedString, char delimiter)
	{
		List<string> list = new List<string>();
		string[] array = delimitedString.Split(new char[1] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
		foreach (string text in array)
		{
			list.Add(text.Trim());
		}
		return list;
	}

	public static float GetSolidHeight(Vector3 p)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		int solidRayMask = ZoneSystem.instance.m_solidRayMask;
		float result = 0f;
		p.y += 1000f;
		RaycastHit val = default(RaycastHit);
		if (Physics.Raycast(p, Vector3.down, ref val, 2000f, solidRayMask) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody))
		{
			result = ((RaycastHit)(ref val)).point.y;
		}
		return result;
	}

	public static Transform FindChild(Transform aParent, string aName)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		foreach (Transform item in aParent)
		{
			Transform val = item;
			if (((Object)val).name == aName)
			{
				return val;
			}
			Transform val2 = FindChild(val, aName);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return null;
	}

	public static Transform FindParent(Transform go)
	{
		while ((Object)(object)go.parent != (Object)null)
		{
			go = go.parent;
		}
		return go;
	}

	public static GameObject GetPrefabByHash(int prefabHash)
	{
		GameObject val = ObjectDB.instance.GetItemPrefab(prefabHash);
		Logging logger = Logging.GetLogger();
		if ((Object)(object)val != (Object)null)
		{
			logger.Debug("Found prefab in ObjectDB");
		}
		else
		{
			ZNetScene instance = ZNetScene.instance;
			val = ((instance != null) ? instance.GetPrefab(prefabHash) : null);
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found prefab in Scene");
			}
		}
		return val;
	}

	public static GameObject GetPrefab(string prefabName)
	{
		GameObject val = ObjectDB.instance.GetItemPrefab(prefabName);
		Logging logger = Logging.GetLogger();
		if ((Object)(object)val != (Object)null)
		{
			logger.Debug("Found " + prefabName + " in ObjectDB");
		}
		else
		{
			ZNetScene instance = ZNetScene.instance;
			val = ((instance != null) ? instance.GetPrefab(prefabName) : null);
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found " + prefabName + " in Scene");
			}
		}
		return val;
	}

	public static string SerializeFromDictionary<K, V>(string delimp, string delimc, IDictionary<K, V> dict)
	{
		if (dict == null)
		{
			return null;
		}
		IEnumerable<string> values = dict.Select(delegate(KeyValuePair<K, V> kvp)
		{
			KeyValuePair<K, V> keyValuePair = kvp;
			string? obj = keyValuePair.Key?.ToString();
			string text = delimc;
			keyValuePair = kvp;
			return obj + text + keyValuePair.Value;
		});
		return string.Join(delimp, values);
	}

	public static void DeserializeToDictionary<K, V>(string serializedString, string delimp, string delimc, ref IDictionary<K, V> dict)
	{
		if (dict == null)
		{
			return;
		}
		dict.Clear();
		string[] separator = new string[1] { delimp };
		string[] separator2 = new string[1] { delimc };
		string[] array = serializedString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			string[] array2 = array[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries);
			if (array2.Length == 2)
			{
				dict.Add(TypedValue<K>(array2[0]), TypedValue<V>(array2[1]));
			}
		}
	}

	public static T TypedValue<T>(object a)
	{
		return (T)Convert.ChangeType(a, typeof(T));
	}

	public static bool CopyComponentToGameObject(Component original, ref GameObject destination)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		Logging logger = Logging.GetLogger();
		Type type = ((object)original).GetType();
		logger.Debug($"Original Type is {type}");
		GameObject obj = destination;
		logger.Debug("Destination GameObject " + ((obj != null) ? ((Object)obj).name : null));
		Component val = destination.GetComponent(type);
		if ((Object)(object)val == (Object)null)
		{
			val = destination.AddComponent(type);
		}
		if ((Object)(object)val == (Object)null)
		{
			logger.Debug("Destination component is null");
			return false;
		}
		Component val2 = (Component)Activator.CreateInstance(type);
		if ((Object)(object)val2 == (Object)null)
		{
			logger.Debug("Destination component is null");
			return false;
		}
		if ((Object)(object)val2 == (Object)null)
		{
			logger.Debug("Boxed component is null");
			return false;
		}
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			fieldInfo.SetValue(val2, fieldInfo.GetValue(original));
		}
		val = val2;
		return true;
	}

	public static bool CopyObject(object original, object target)
	{
		Logging logger = Logging.GetLogger();
		Type type = original.GetType();
		Type type2 = target.GetType();
		if (type == null)
		{
			logger.Warning("Copy Object: Source object is null");
			Activator.CreateInstance(type);
			return false;
		}
		if (type2 == null)
		{
			logger.Warning("Copy Object: Destination object is null");
			return false;
		}
		if (type2 != type)
		{
			logger.Warning("Copy Object: Source and destination components are different types");
			return false;
		}
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			fieldInfo.SetValue(target, fieldInfo.GetValue(original));
		}
		return true;
	}
}
internal class Cfg
{
	public static DelegatedConfigEntry<Logging.LogLevels> debugLevel = null;

	public static DelegatedConfigEntry<int> trophyCap = null;

	public static DelegatedConfigEntry<int> damageCap = null;

	public static DelegatedConfigEntry<int> trophyDistance = null;

	public static DelegatedConfigEntry<bool> damagePhysical = null;

	public static DelegatedConfigEntry<bool> damageElemental = null;

	public static DelegatedConfigEntry<bool> damageOther = null;

	public static DelegatedConfigEntry<SlayerSkills.Points> assignPoints = null;

	public static DelegatedConfigEntry<bool> lowerSkillsOnDeath = null;

	public static DelegatedConfigEntry<bool> allowCheats = null;

	public static DelegatedConfigEntry<bool> useCreatureLevel = null;

	public static DelegatedConfigEntry<int> bossPoints = null;

	public static DelegatedConfigEntry<bool> tamesSlay = null;

	public static DelegatedConfigEntry<bool> tamesBuff = null;

	public static DelegatedConfigEntry<Color> skillColor = null;

	private static KeyCode[] keyModifiers = (KeyCode[])(object)new KeyCode[2]
	{
		(KeyCode)308,
		(KeyCode)304
	};

	public static KeyboardShortcut keyConfigItemDefault = new KeyboardShortcut((KeyCode)115, keyModifiers);

	public static void BepInExConfig(BaseUnityPlugin _instance)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Expected O, but got Unknown
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Expected O, but got Unknown
		//IL_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Expected O, but got Unknown
		debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(SlayerSkills.ChangeLogging);
		debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log");
		SlayerSkills.Log.LogLevel = debugLevel.Value;
		skillColor = new DelegatedConfigEntry<Color>(SlayerSkills.ChangeColor);
		skillColor.ConfigEntry = _instance.Config.Bind<Color>("Utility", "SkillTextColor", Color.cyan, "Sets the color for the Slayer Skill text in the Trophy panel.");
		trophyCap = new DelegatedConfigEntry<int>(useServerDelegate: true);
		trophyCap.ConfigEntry = _instance.Config.Bind<int>("Slayer Skills", "SkillCap", 100, new ConfigDescription("Sets the maximum Slayer level attainable. Every slayer point earned increases the percentage of the damage buff against a specific creature type.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200), Array.Empty<object>()));
		trophyDistance = new DelegatedConfigEntry<int>(useServerDelegate: true);
		trophyDistance.ConfigEntry = _instance.Config.Bind<int>("Slayer Skills", "TrophyDistance", 30, new ConfigDescription("Sets the maximum distance, in meters, that a player (in multiplayer) can be from the trophy drop to qualify for the trophy point.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 50), Array.Empty<object>()));
		lowerSkillsOnDeath = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		lowerSkillsOnDeath.ConfigEntry = _instance.Config.Bind<bool>("Slayer Skills", "LowerSkillsOnDeath", true, "If enabled, will lower slayer skills upon death (same % as standard skills)");
		allowCheats = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		allowCheats.ConfigEntry = _instance.Config.Bind<bool>("Slayer Skills", "AllowCheats", false, "If enabled, allows raising and resetting Slayer skills using 'raiseskill' and 'resetskill' commands from the console, If the creature name contains spaces, use an underscore (_) instead of a space, e.g. 'raiseskill Greydwarf_brute 3'. Note creature name is case sensitive!");
		damageCap = new DelegatedConfigEntry<int>(useServerDelegate: true);
		damageCap.ConfigEntry = _instance.Config.Bind<int>("Slayer Damage", "DamagePercent", 100, new ConfigDescription("Sets the maximum damage buff percent of your normal damage. The applied buff percentage is determined by your current Slayer level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		damagePhysical = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		damagePhysical.ConfigEntry = _instance.Config.Bind<bool>("Slayer Damage", "BuffPhysical", true, "If enabled, applies slayer bonus to physical damage (slash, blunt, pierce)");
		damageElemental = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		damageElemental.ConfigEntry = _instance.Config.Bind<bool>("Slayer Damage", "BuffElemental", false, "If enabled, applies slayer bonus to elemental damage (lightning, fire, frost)");
		damageOther = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		damageOther.ConfigEntry = _instance.Config.Bind<bool>("Slayer Damage", "BuffOther", false, "If enabled, applies slayer bonus to other damage (poison, spirit)");
		assignPoints = new DelegatedConfigEntry<SlayerSkills.Points>(useServerDelegate: true);
		assignPoints.ConfigEntry = _instance.Config.Bind<SlayerSkills.Points>("Slayer Points", "MultiplayerPoints", SlayerSkills.Points.Random, "Controls how slayer skills are awarded in multiplayer. Random grants skill points to one player in group. All grants a skill point to every player in group. Distribute grants a fraction of a skill point evenly to every player in group.");
		useCreatureLevel = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		useCreatureLevel.ConfigEntry = _instance.Config.Bind<bool>("Slayer Points", "UseCreatureLevel", false, "If enabled, adjusts the Slayer points awarded on trophy drop based on the level (number of 'Stars') of the creature slain");
		bossPoints = new DelegatedConfigEntry<int>(useServerDelegate: true);
		bossPoints.ConfigEntry = _instance.Config.Bind<int>("Slayer Points", "BossAdjustment", 3, new ConfigDescription("Adjusts Slayer points awarded to account for bosses. Equivalent to treating a boss as an 'X-Star' creature. Applies even if UseCreatureLevel is false (and adds if true).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
		tamesSlay = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		tamesSlay.ConfigEntry = _instance.Config.Bind<bool>("Tamed Creatures", "TamesCanSlay", true, "If enabled, trophy drops from creatures slain by your tamed creatires count toward your Slayer skill");
		tamesBuff = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		tamesBuff.ConfigEntry = _instance.Config.Bind<bool>("Tamed Creatures", "TamesGetBuff", false, "If enabled, your tamed creatures also recieve your Slayer buff");
	}
}
internal class CreatureInfo
{
	public string Name { get; }

	public bool Tamed { get; }

	public bool Tapped { get; }

	public bool Boss { get; }

	public int Level { get; }

	public bool DropsEnabled { get; }

	public CreatureInfo(string name, bool tamed, bool tapped, bool boss, int level, bool dropsEnabled)
	{
		Name = name;
		Tamed = tamed;
		Tapped = tapped;
		Boss = boss;
		Level = level;
		DropsEnabled = dropsEnabled;
	}
}
internal class CustomDataWrapper
{
	private Dictionary<string, string> playerData;

	private CustomDataWrapper instance;

	private Dictionary<string, string> Data { get; set; }

	public CustomDataWrapper(Dictionary<string, string> sourceData, string keyPrefix)
	{
		CustomDataWrapper customDataWrapper = this;
		playerData = sourceData;
		Data = new Dictionary<string, string>();
		sourceData.Keys.ToList().ForEach(delegate(string key)
		{
			if (key.StartsWith(keyPrefix))
			{
				customDataWrapper.Data.Add(key, sourceData[key]);
			}
		});
	}

	public void Add(string key, string value)
	{
		Data.Add(key, value);
		playerData.Add(key, value);
	}

	public bool Remove(string key)
	{
		return Data.Remove(key) & playerData.Remove(key);
	}

	public void Set(string key, string value)
	{
		if (Data.ContainsKey(key))
		{
			Data[key] = value;
		}
		else
		{
			Data.Add(key, value);
		}
		if (playerData.ContainsKey(key))
		{
			playerData[key] = value;
		}
		else
		{
			playerData.Add(key, value);
		}
	}

	public string Get(string key)
	{
		if (Data.ContainsKey(key))
		{
			return Data[key];
		}
		return null;
	}

	public bool ContainsKey(string key)
	{
		return Data.ContainsKey(key);
	}

	public void PreSaveSync()
	{
		foreach (KeyValuePair<string, string> datum in Data)
		{
			if (!playerData.ContainsKey(datum.Key))
			{
				playerData.Add(datum.Key, datum.Value);
			}
		}
	}
}
[BepInPlugin("neobotics.valheim_mod.slayerskills", "SlayerSkills", "1.0.8")]
[BepInProcess("valheim.exe")]
[BepInProcess("valheim_server.exe")]
public class SlayerSkills : BaseUnityPlugin
{
	public enum Points
	{
		Random,
		All,
		Distribute,
		KillingBlow
	}

	[HarmonyPatch(typeof(Localization), "SetLanguage")]
	private static class Localization_SetLanguage_Patch
	{
		[HarmonyPostfix]
		private static void Localization_SetLanguage_Postfix(Localization __instance)
		{
			BuildCreatureTrophyMap();
		}
	}

	[HarmonyPatch(typeof(Game), "Start")]
	private static class Game_Start_Patch
	{
		[HarmonyPostfix]
		private static void Game_Start_Patch_Postfix(Game __instance)
		{
			Log.Debug(" Game_Start_Patch_Postfix");
			ZRoutedRpc.instance.Register<string, float>("RaiseSlayerStat", (Action<long, string, float>)RPC_RaiseSlayerStat);
		}
	}

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	private static class ZNetScene_Awake_Patch
	{
		[HarmonyPostfix]
		private static void ZNetScene_Awake_Postfix(ZNetScene __instance)
		{
			Log.Debug("ZNetScene_Awake_Patch_Postfix");
			BuildCreatureTrophyMap();
		}
	}

	[HarmonyPatch(typeof(InventoryGui), "UpdateTrophyList")]
	private static class InventoryGui_UpdateTrophyList_Patch
	{
		[HarmonyPostfix]
		private static void InventoryGui_UpdateTrophyList_Postfix(InventoryGui __instance, List<GameObject> ___m_trophyList)
		{
			Log.Debug("InventoryGui_UpdateTrophyList_Patch_Postfix");
			if (___m_trophyList == null)
			{
				return;
			}
			foreach (GameObject ___m_trophy in ___m_trophyList)
			{
				Transform transform = ___m_trophy.transform;
				Transform obj = ((transform is RectTransform) ? transform : null);
				TMP_Text component = ((Component)obj.Find("description")).GetComponent<TMP_Text>();
				TMP_Text component2 = ((Component)obj.Find("name")).GetComponent<TMP_Text>();
				if (nameToTokenMap.TryGetValue(component2.text, out var value))
				{
					if (trophyCollection.TryGetValue(value, out var value2))
					{
						string text = ((value2 < (float)Cfg.trophyCap.Value) ? $"{FlooredLevel(value2)}/{Cfg.trophyCap.Value}" : "Slayer");
						component.richText = true;
						component.text = "<color=" + colorString + ">" + text + "</color>\n" + component.text;
					}
					else
					{
						Log.Debug("Can't find mapped token " + value + " in trophy collection");
					}
				}
				else
				{
					Log.Debug("Can't find localized name " + component2.text + " slayerSkill");
				}
			}
		}
	}

	[HarmonyPatch(typeof(CharacterDrop), "OnDeath")]
	private static class CharacterDrop_OnDeath_Patch
	{
		[HarmonyPrefix]
		private static void CharacterDrop_OnDeath_Prefix(CharacterDrop __instance, Character ___m_character)
		{
			Log.Debug("CharacterDrop_OnDeath_Patch_Prefix");
			bool tapped = false;
			ZNetView val = default(ZNetView);
			if (((Component)___m_character).TryGetComponent<ZNetView>(ref val))
			{
				ZDO zDO = val.GetZDO();
				if (zDO.IsValid() && zDO.GetBool(UNIQUE_ID, false))
				{
					tapped = true;
				}
			}
			if ((Object)(object)___m_character != (Object)null)
			{
				_tempCreatureInfo = new CreatureInfo(___m_character.m_name, ___m_character.IsTamed(), tapped, ___m_character.IsBoss(), ___m_character.GetLevel(), __instance.m_dropsEnabled);
			}
		}

		[HarmonyPostfix]
		private static void CharacterDrop_OnDeath_Postfix(CharacterDrop __instance, ref CreatureInfo __state)
		{
			Log.Debug("CharacterDrop_OnDeath_Patch_Postfix");
			_tempCreatureInfo = null;
		}
	}

	[HarmonyPatch(typeof(CharacterDrop), "DropItems")]
	private static class CharacterDrop_DropItems_Patch
	{
		[HarmonyPostfix]
		private static void CharacterDrop_DropItems_Postfix(List<KeyValuePair<GameObject, int>> drops, Vector3 centerPos, float dropArea, bool ___m_dropsEnabled)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("CharacterDrop_DropItems_Patch_Postfix");
			if (_tempCreatureInfo == null || _tempCreatureInfo.Tamed || !_tempCreatureInfo.DropsEnabled)
			{
				return;
			}
			if (_tempCreatureInfo.Tapped)
			{
				Log.Debug("Creature was tapped by a player");
				{
					ItemDrop val = default(ItemDrop);
					foreach (KeyValuePair<GameObject, int> drop in drops)
					{
						if ((Object)(object)drop.Key != (Object)null && drop.Key.TryGetComponent<ItemDrop>(ref val) && (int)val.m_itemData.m_shared.m_itemType == 13)
						{
							int num = ((!Cfg.useCreatureLevel.Value) ? 1 : _tempCreatureInfo.Level);
							if (_tempCreatureInfo.Boss)
							{
								num += Cfg.bossPoints.Value;
							}
							InitiateRaiseStat(val.m_itemData.m_shared.m_name, num, centerPos);
						}
					}
					return;
				}
			}
			Log.Debug("Character " + _tempCreatureInfo.Name + " was not hit by player");
		}
	}

	[HarmonyPatch(typeof(Ragdoll), "SaveLootList")]
	private static class Ragdoll_SaveLootList_Patch
	{
		[HarmonyPostfix]
		private static void Ragdoll_SaveLootList_Postfix(Ragdoll __instance, CharacterDrop characterDrop, ZNetView ___m_nview)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Invalid comparison between Unknown and I4
			Log.Debug("Ragdoll_SaveLootList_Patch_Postfix");
			Character character = characterDrop.m_character;
			ZNetView val = default(ZNetView);
			if (!((Object)(object)character != (Object)null) || character.IsTamed() || !((Component)character).TryGetComponent<ZNetView>(ref val))
			{
				return;
			}
			ZDO zDO = val.GetZDO();
			if (zDO.IsValid() && zDO.GetBool(UNIQUE_ID, false))
			{
				ZDO zDO2 = ___m_nview.GetZDO();
				Log.Debug("Creature was tapped by a player");
				int @int = zDO2.GetInt("drops", 0);
				ItemDrop val2 = default(ItemDrop);
				for (int i = 0; i < @int; i++)
				{
					int int2 = zDO2.GetInt("drop_hash" + i, 0);
					GameObject prefab = ZNetScene.instance.GetPrefab(int2);
					if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val2) && (int)val2.m_itemData.m_shared.m_itemType == 13)
					{
						int num = ((!Cfg.useCreatureLevel.Value) ? 1 : character.GetLevel());
						if (character.IsBoss())
						{
							num += Cfg.bossPoints.Value;
						}
						string text = $"{val2.m_itemData.m_shared.m_name}:{num}";
						Log.Debug("Setting ragdoll with " + text);
						if (zDO2.IsValid())
						{
							zDO2.Set(StringExtensionMethods.GetStableHashCode(UNIQUE_ID), text);
						}
					}
				}
			}
			else
			{
				Log.Debug("Character " + ((character != null) ? ((Object)character).name : null) + " was not hit by player");
			}
		}
	}

	[HarmonyPatch(typeof(Ragdoll), "SpawnLoot")]
	private static class Ragdoll_SpawnLoot_Patch
	{
		[HarmonyPostfix]
		private static void Ragdoll_SpawnLoot_Postfix(Ragdoll __instance, Vector3 center, ZNetView ___m_nview)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("Ragdoll_SpawnLoot_Patch_Postfix");
			string text = null;
			ZDO zDO = ___m_nview.GetZDO();
			if (zDO.IsValid())
			{
				text = zDO.GetString(StringExtensionMethods.GetStableHashCode(UNIQUE_ID), "");
			}
			if (!Utility.IsNullOrWhiteSpace(text))
			{
				string[] array = text.Split(new char[1] { ':' });
				string itemName = array[0];
				float amount = float.Parse(array[1]);
				Log.Debug("Ragdoll is spawning trophy");
				InitiateRaiseStat(itemName, amount, center);
			}
		}
	}

	[HarmonyPatch(typeof(Character), "Damage")]
	private static class Character_Damage_Patch
	{
		[HarmonyPrefix]
		private static void Character_Damage_Prefix(Character __instance, ref HitData hit, ZNetView ___m_nview)
		{
			Log.Debug("Character_Damage_Patch_Prefix");
			Collider hitCollider = hit.m_hitCollider;
			Character attacker = hit.GetAttacker();
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)attacker != (Object)null) || !((Object)(object)localPlayer != (Object)null) || __instance.IsPlayer())
			{
				return;
			}
			ZDO zDO = ((Component)attacker).GetComponent<ZNetView>().GetZDO();
			bool @bool = zDO.GetBool("tamed", false);
			bool flag = @bool && zDO.GetOwner() == localPlayer.GetPlayerID();
			if ((Object)(object)attacker == (Object)(object)localPlayer || (flag && Cfg.tamesBuff.Value))
			{
				object name;
				if (hitCollider == null)
				{
					name = null;
				}
				else
				{
					Transform transform = ((Component)hitCollider).transform;
					if (transform == null)
					{
						name = null;
					}
					else
					{
						Transform root = transform.root;
						name = ((root != null) ? ((Object)root).name : null);
					}
				}
				string text = Utils.UnClonifiedName((string)name);
				if (Utility.IsNullOrWhiteSpace(text))
				{
					Logging log = Log;
					object obj;
					if (hitCollider == null)
					{
						obj = null;
					}
					else
					{
						Transform transform2 = ((Component)hitCollider).transform;
						if (transform2 == null)
						{
							obj = null;
						}
						else
						{
							Transform root2 = transform2.root;
							obj = ((root2 != null) ? ((Object)root2).name : null);
						}
					}
					log.Info("Can't determine original name " + (string?)obj);
					return;
				}
				Log.Debug(((attacker != null) ? attacker.GetHoverName() : null) + " hit " + text);
				if (creatureTrophyMap.TryGetValue(text, out var value))
				{
					if (trophyCollection.TryGetValue(value, out var value2))
					{
						ApplySlayerBonus(ref hit, Mathf.Min(value2, (float)Cfg.trophyCap.Value));
					}
					else
					{
						Log.Debug("Can't find " + value + " in trophy collection");
					}
				}
				else
				{
					Log.Debug("Can't find hit original " + text + " slayerSkill");
				}
			}
			if (attacker.IsPlayer() || (@bool && Cfg.tamesSlay.Value))
			{
				Log.Debug("Player tapping original");
				ZDO zDO2 = ___m_nview.GetZDO();
				zDO2.Set(UNIQUE_ID, true);
				zDO2.SetOwner(attacker.GetOwner());
			}
		}
	}

	[HarmonyPatch(typeof(Player), "Save")]
	public static class Player_Save_Patch
	{
		[HarmonyPrefix]
		public static void Player_Save_Patch_Prefix(Player __instance, ZPackage pkg)
		{
			Log.Debug("Player_Save_Patch_Prefix");
			if (customData != null)
			{
				string text = Utils.SerializeFromDictionary(",", ":", trophyCollection);
				customData.Set(COLLECTION_ID, text);
				Log.Debug("Serializing and adding trophy collection " + text);
				customData.PreSaveSync();
			}
		}
	}

	[HarmonyPatch(typeof(Player), "OnSpawned")]
	public static class Player_OnSpawned_Patch
	{
		[HarmonyPostfix]
		public static void Player_OnSpawned_Patch_Postfix(Player __instance)
		{
			Log.Debug("Player_OnSpawned_Patch_Postfix");
			if (ZNet.m_world == null)
			{
				return;
			}
			customData = new CustomDataWrapper(__instance.m_customData, UNIQUE_ID);
			string text = customData.Get(COLLECTION_ID);
			if (text != null)
			{
				Utils.DeserializeToDictionary(text, ",", ":", ref trophyCollection);
				Log.Debug("Deserialized trophy string " + text);
			}
			if (trophyCollection.Count <= 0 || trophyCollection.Keys.First().StartsWith("$"))
			{
				return;
			}
			Log.Info("Remapping trophy collection to newer version");
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>
			{
				{ "Greydwarf Brute", "Greydwarf brute" },
				{ "Greydwarf Shamen", "Greydwarf shamen" },
				{ "Draugr Elite", "Drauger elite" }
			};
			List<string> list = new List<string>();
			foreach (string key2 in dictionary2.Keys)
			{
				if (trophyCollection.TryGetValue(key2, out var value))
				{
					string key = dictionary2[key2];
					if (trophyCollection.ContainsKey(key))
					{
						trophyCollection[key] += value;
					}
					else
					{
						trophyCollection.Add(key, value);
					}
					list.Add(key2);
				}
			}
			foreach (string item in list)
			{
				trophyCollection.Remove(item);
			}
			foreach (string key3 in trophyCollection.Keys)
			{
				Log.Debug("Remapping " + key3);
				if (nameToTokenMap.TryGetValue(key3, out var value2))
				{
					Log.Debug("Found " + key3 + " with new key " + value2 + " from name-to-token map");
					dictionary.Add(value2, trophyCollection[key3]);
				}
				else
				{
					Log.Debug("Couldn't find " + key3 + " in name-to-token map");
				}
			}
			trophyCollection = dictionary;
			text = Utils.SerializeFromDictionary(",", ":", trophyCollection);
			Log.Debug("New trophy string " + text);
		}
	}

	[HarmonyPatch(typeof(Skills), "LowerAllSkills")]
	private static class Skills_LowerAllSkills_Patch
	{
		[HarmonyPostfix]
		private static void Skills_LowerAllSkills_Postfix(Skills __instance, float factor)
		{
			Log.Debug("Skills_LowerAllSkills_Patch_Postfix");
			if (!Cfg.lowerSkillsOnDeath.Value)
			{
				return;
			}
			foreach (string item in trophyCollection.Keys.ToList())
			{
				if (trophyCollection[item] < (float)Cfg.trophyCap.Value)
				{
					float num = trophyCollection[item] * factor;
					trophyCollection[item] -= num;
				}
			}
		}
	}

	[HarmonyPatch(typeof(Skills), "CheatRaiseSkill")]
	private static class Skills_CheatRaiseSkill_Patch
	{
		private static bool Prefix(string name, float value)
		{
			Logging.GetLogger().Debug("Skills CheatRaiseSkill Prefix");
			if (Cfg.allowCheats.Value)
			{
				name = name.Replace('_', ' ');
				if (nameToTokenMap.TryGetValue(name, out var value2) && trophyCollection.TryGetValue(value2, out var value3))
				{
					value3 += value;
					value3 = Mathf.Clamp(value3, 0f, (float)Cfg.trophyCap.Value);
					trophyCollection[value2] = value3;
					Console.instance.Print($"Slayer skill {name} = {value3}");
					return false;
				}
			}
			else
			{
				Log.Debug("SlayerSkills cheats are not enabled");
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(Skills), "CheatResetSkill")]
	private static class Skills_CheatResetSkill_Patch
	{
		private static bool Prefix(string name)
		{
			Logging.GetLogger().Debug("Skills CheatResetSkill Prefix");
			if (Cfg.allowCheats.Value)
			{
				name = name.Replace('_', ' ');
				if (nameToTokenMap.TryGetValue(name, out var value) && trophyCollection.ContainsKey(value))
				{
					trophyCollection[value] = 0f;
					Console.instance.Print("Slayer skill " + name + " reset");
					return false;
				}
			}
			else
			{
				Log.Debug("SlayerSkills cheats are not enabled");
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(Terminal), "TryRunCommand")]
	private static class Try_Run_Command_Patch
	{
		private static void Prefix(Terminal __instance, ref string text)
		{
			if (text == null)
			{
				return;
			}
			string text2 = text.ToLower();
			if (!text2.StartsWith(LcMod))
			{
				return;
			}
			string text3 = text2.Substring(LcMod.Length + 1).Trim();
			Log.Debug(Mod + " Configuration command: " + text3);
			if (text3.Equals("config"))
			{
				((BaseUnityPlugin)_modInstance).Config.Reload();
				_modInstance.ConfigureMod();
				__instance.AddString("Reset configuration");
			}
			else
			{
				string[] array = text3.Split(new string[1] { "=" }, 2, StringSplitOptions.RemoveEmptyEntries);
				if (array.Length == 2)
				{
					string text4 = array[0].Trim();
					string text5 = array[1].Trim();
					bool flag = true;
					switch (text4)
					{
					case "loglevel":
					{
						if (Enum.TryParse<Logging.LogLevels>(text5, out var result5))
						{
							Cfg.debugLevel.Value = result5;
						}
						else
						{
							flag = false;
						}
						break;
					}
					case "skillcap":
					{
						if (int.TryParse(text5, out var result3))
						{
							Cfg.trophyCap.Value = Utils.Guardrails(result3, 1, 200);
						}
						else
						{
							flag = false;
						}
						break;
					}
					case "damagepercent":
					{
						if (int.TryParse(text5, out var result6))
						{
							Cfg.damageCap.Value = Utils.Guardrails(result6, 0, 100);
						}
						else
						{
							flag = false;
						}
						break;
					}
					case "trophydistance":
					{
						if (int.TryParse(text5, out var result2))
						{
							Cfg.trophyDistance.Value = Utils.Guardrails(result2, 5, 50);
						}
						else
						{
							flag = false;
						}
						break;
					}
					case "buffphysical":
						Cfg.damagePhysical.ConfigEntry.Value = text5.Equals("true");
						break;
					case "lowerskillsondeath":
						Cfg.lowerSkillsOnDeath.ConfigEntry.Value = text5.Equals("true");
						break;
					case "buffelemental":
						Cfg.damageElemental.ConfigEntry.Value = text5.Equals("true");
						break;
					case "buffother":
						Cfg.damageOther.ConfigEntry.Value = text5.Equals("true");
						break;
					case "multiplayerpoints":
					{
						if (Enum.TryParse<Points>(text5, out var result4))
						{
							Cfg.assignPoints.Value = result4;
						}
						else
						{
							flag = false;
						}
						break;
					}
					case "bossadjustment":
					{
						if (int.TryParse(text5, out var result))
						{
							Cfg.bossPoints.Value = Utils.Guardrails(result, 0, 10);
						}
						else
						{
							flag = false;
						}
						break;
					}
					case "usecreaturelevel":
						Cfg.useCreatureLevel.ConfigEntry.Value = text5.Equals("true");
						break;
					case "tamescanslay":
						Cfg.tamesSlay.ConfigEntry.Value = text5.Equals("true");
						break;
					case "tamesgetbuff":
						Cfg.tamesBuff.ConfigEntry.Value = text5.Equals("true");
						break;
					case "allowcheats":
						Cfg.allowCheats.ConfigEntry.Value = text5.Equals("true");
						break;
					default:
						flag = false;
						break;
					}
					if (flag)
					{
						__instance.AddString("Reset " + text4 + "=" + text5);
					}
					else
					{
						__instance.AddString("Not a valid setting");
					}
				}
				else
				{
					__instance.AddString("Not a valid command");
				}
			}
			text = "";
		}
	}

	private static SlayerSkills _modInstance;

	private const string MOD_VERSION = "1.0.8";

	private static string Mod = "SlayerSkills";

	private static string LcMod = Mod.ToLower();

	public static Logging Log;

	public static string UNIQUE_ID = Mod + "_1847_";

	public static string COLLECTION_ID = UNIQUE_ID + "_C";

	private static CustomDataWrapper customData = null;

	private static IDictionary<string, float> trophyCollection = new Dictionary<string, float>();

	private static IDictionary<string, string> creatureTrophyMap = new Dictionary<string, string>();

	private static IDictionary<string, string> nameToTokenMap = new Dictionary<string, string>();

	private static CreatureInfo _tempCreatureInfo = null;

	private static string colorString = "#00FFFF";

	private static Harmony harmony = null;

	public static SlayerSkills GetInstance()
	{
		return _modInstance;
	}

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		_modInstance = this;
		harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
		harmony.PatchAll(Assembly.GetExecutingAssembly());
		ConfigureMod();
		Log.Info("Awake");
	}

	private void ConfigureMod()
	{
		Log = Logging.GetLogger(Logging.LogLevels.Info, Mod);
		ServerConfiguration.Instance.Setup(((BaseUnityPlugin)this).Config, (BaseUnityPlugin)(object)_modInstance);
		Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance);
	}

	public static void ChangeLogging(object s, EventArgs e)
	{
		SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
		Log.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}");
		Log.LogLevel = Cfg.debugLevel.Value;
	}

	public static void ChangeColor(object s, EventArgs e)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
		Log.Debug($"ChangeColor {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}");
		colorString = "#" + ColorUtility.ToHtmlStringRGB(Cfg.skillColor.Value);
	}

	private void OnDestroy()
	{
		harmony.UnpatchSelf();
	}

	private static int GetVersionID(string versionString)
	{
		string[] array = versionString.Split(new char[1] { '.' });
		return int.Parse(array[0]) * 10000 + int.Parse(array[1]) * 1000 + int.Parse(array[2]);
	}

	private static bool OkToKey(Player player)
	{
		if (!Chat.instance.HasFocus() && !Console.IsVisible() && (Object)(object)TextViewer.instance != (Object)null && !TextViewer.instance.IsVisible() && !GameCamera.InFreeFly() && !Minimap.IsOpen() && !TextInput.IsVisible() && !StoreGui.IsVisible() && !((Character)player).InCutscene() && !((Character)player).InBed() && !((Character)player).IsTeleporting() && !((Character)player).IsDead())
		{
			return !((Character)player).InPlaceMode();
		}
		return false;
	}

	private static void KeypressEntryPoint()
	{
		_ = Player.m_localPlayer;
		Log.Debug("KeypressEntryPoint");
	}

	private static string GetTrophyDisplayName(string trophyName)
	{
		string text = Localization.instance.Localize(trophyName);
		if (!text.EndsWith(" trophy"))
		{
			return text;
		}
		return text.Substring(0, text.Length - 7);
	}

	private static void ApplySlayerBonus(ref HitData hitData, float skillLevel)
	{
		skillLevel = Mathf.Clamp(skillLevel, 0f, (float)Cfg.trophyCap.Value);
		float num = skillLevel / (float)Cfg.trophyCap.Value;
		float num2 = (float)Cfg.damageCap.Value / 100f * num;
		Log.Debug($"Before slayer Level {skillLevel} multiplier {num2} blunt {hitData.m_damage.m_blunt} slash {hitData.m_damage.m_slash} pierce {hitData.m_damage.m_pierce} fire {hitData.m_damage.m_fire} frost {hitData.m_damage.m_frost} lightning {hitData.m_damage.m_lightning} poison {hitData.m_damage.m_poison} spirit {hitData.m_damage.m_spirit}");
		if (Cfg.damagePhysical.Value)
		{
			hitData.m_damage.m_blunt += hitData.m_damage.m_blunt * num2;
			hitData.m_damage.m_slash += hitData.m_damage.m_slash * num2;
			hitData.m_damage.m_pierce += hitData.m_damage.m_pierce * num2;
		}
		if (Cfg.damageElemental.Value)
		{
			hitData.m_damage.m_fire += hitData.m_damage.m_fire * num2;
			hitData.m_damage.m_frost += hitData.m_damage.m_frost * num2;
			hitData.m_damage.m_lightning += hitData.m_damage.m_lightning * num2;
		}
		if (Cfg.damageOther.Value)
		{
			hitData.m_damage.m_spirit += hitData.m_damage.m_spirit * num2;
			hitData.m_damage.m_poison += hitData.m_damage.m_poison * num2;
		}
		Log.Debug($"After slayer Level {skillLevel} multiplier {num2} blunt {hitData.m_damage.m_blunt} slash {hitData.m_damage.m_slash} pierce {hitData.m_damage.m_pierce} fire {hitData.m_damage.m_fire} frost {hitData.m_damage.m_frost} lightning {hitData.m_damage.m_lightning} poison {hitData.m_damage.m_poison} spirit {hitData.m_damage.m_spirit}");
	}

	public static void BuildCreatureTrophyMap()
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Invalid comparison between Unknown and I4
		CharacterDrop val = default(CharacterDrop);
		ItemDrop val2 = default(ItemDrop);
		foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
		{
			Character component = (Character)(object)prefab.GetComponent<Humanoid>();
			if ((Object)(object)component == (Object)null)
			{
				component = prefab.GetComponent<Character>();
			}
			if (!((Object)(object)component != (Object)null) || !prefab.TryGetComponent<CharacterDrop>(ref val))
			{
				continue;
			}
			foreach (Drop drop in val.m_drops)
			{
				if ((Object)(object)drop.m_prefab != (Object)null && drop.m_prefab.TryGetComponent<ItemDrop>(ref val2) && (int)val2.m_itemData.m_shared.m_itemType == 13)
				{
					string name = val2.m_itemData.m_shared.m_name;
					string trophyDisplayName = GetTrophyDisplayName(name);
					if (!creatureTrophyMap.ContainsKey(((Object)component).name))
					{
						Log.Debug("Adding " + ((Object)component).name + " " + name + " to original trophy map");
						creatureTrophyMap.Add(((Object)component).name, name);
					}
					if (!nameToTokenMap.ContainsKey(trophyDisplayName))
					{
						Log.Debug("Adding " + trophyDisplayName + " " + name + " to name-to-token map");
						nameToTokenMap.Add(trophyDisplayName, name);
					}
				}
			}
		}
	}

	private static int FlooredLevel(float level)
	{
		return Mathf.FloorToInt(level);
	}

	private static void RaiseStat(string itemName, float amt)
	{
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		Log.Debug("RaiseStat");
		bool flag = false;
		string trophyDisplayName = GetTrophyDisplayName(itemName);
		Log.Debug(itemName + " translates to trophy name " + trophyDisplayName);
		if (!trophyCollection.ContainsKey(itemName))
		{
			trophyCollection.Add(itemName, amt);
			int num = FlooredLevel(amt);
			if (num >= 1)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, $"{trophyDisplayName} Slayer Level {num}", 0, (Sprite)null);
				flag = true;
			}
			Log.Debug("Adding " + trophyDisplayName + " to slayer collection");
		}
		else
		{
			int num2 = FlooredLevel(trophyCollection[itemName]);
			if (num2 < Cfg.trophyCap.Value)
			{
				trophyCollection[itemName] += amt;
				if (trophyCollection[itemName] > (float)Cfg.trophyCap.Value)
				{
					trophyCollection[itemName] = Cfg.trophyCap.Value;
				}
				int num3 = FlooredLevel(trophyCollection[itemName]);
				if (num3 > num2)
				{
					((Character)Player.m_localPlayer).Message((MessageType)1, $"{trophyDisplayName} Slayer Level {num3}", 0, (Sprite)null);
					flag = true;
				}
			}
			else
			{
				Log.Debug("Trophy cap reached");
			}
		}
		if (flag)
		{
			Player localPlayer = Player.m_localPlayer;
			Transform head = ((Character)localPlayer).m_head;
			localPlayer.m_skillLevelupEffects.Create(head.position, head.rotation, head, 1f, -1);
		}
	}

	private static void RPC_RaiseSlayerStat(long id, string itemName, float amt)
	{
		Log.Debug("RPC_RaiseSlayerStat");
		RaiseStat(itemName, amt);
	}

	private static List<Player> GetPlayersInRange(Vector3 point, float range, List<Player> allPlayers)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		List<Player> list = new List<Player>();
		foreach (Player allPlayer in allPlayers)
		{
			if (Vector3.Distance(((Component)allPlayer).transform.position, point) < range)
			{
				list.Add(allPlayer);
			}
		}
		return list;
	}

	private static void InitiateRaiseStat(string itemName, float amount, Vector3 center)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		Log.Debug("IntitiateRaiseStat");
		List<Player> allPlayers = Player.GetAllPlayers();
		int num = allPlayers.Count();
		if (num > 1 && Cfg.assignPoints.Value != Points.KillingBlow)
		{
			List<Player> playersInRange = GetPlayersInRange(center, Cfg.trophyDistance.Value, allPlayers);
			Log.Debug($"Players in range {playersInRange.Count}");
			if (playersInRange.Count < num)
			{
				Log.Info($"{num - playersInRange.Count} player(s) not in range of the dropped trophy.");
			}
			if (playersInRange.Count <= 0)
			{
				return;
			}
			if (Cfg.assignPoints.Value != 0)
			{
				if (Cfg.assignPoints.Value == Points.Distribute)
				{
					amount /= (float)playersInRange.Count;
				}
				{
					ZNetView val = default(ZNetView);
					foreach (Player item in playersInRange)
					{
						if (((Component)item).TryGetComponent<ZNetView>(ref val) && val.IsValid() && val.GetZDO().m_uid != ZDOID.None)
						{
							Log.Debug($"Invoking RPC on {val.GetZDO().GetOwner()} player {item.GetPlayerName()}");
							ZRoutedRpc.instance.InvokeRoutedRPC(val.GetZDO().GetOwner(), "RaiseSlayerStat", new object[2] { itemName, amount });
						}
					}
					return;
				}
			}
			int index = Random.Range(0, playersInRange.Count);
			ZNetView val2 = default(ZNetView);
			if (((Component)playersInRange[index]).TryGetComponent<ZNetView>(ref val2) && val2.IsValid() && val2.GetZDO().m_uid != ZDOID.None)
			{
				Log.Debug($"Invoking RPC on {val2.GetZDO().GetOwner()} random player {playersInRange[index].GetPlayerName()}");
				ZRoutedRpc.instance.InvokeRoutedRPC(val2.GetZDO().GetOwner(), "RaiseSlayerStat", new object[2] { itemName, amount });
			}
		}
		else
		{
			RaiseStat(itemName, amount);
		}
	}
}