Decompiled source of Weapon Neon Contour Mod v2.8.5

Weapon_Neon_Contour_Mod.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("svet")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("svet")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9c8e4050-348e-42e7-85e4-ce07be14488b")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ValheimWeaponContourMod;

[BepInPlugin("com.yourname.weaponcontour", "Weapon Neon Contour Mod", "2.8.5")]
public class WeaponContourPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Game), "Start")]
	private class Game_Start_Patch
	{
		private static void Postfix()
		{
			ZRoutedRpc.instance.Register<string>("RPC_WeaponContour_SyncString", (Action<long, string>)RPC_WeaponContour_SyncString);
		}
	}

	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	private class ZNet_OnNewConnection_Patch
	{
		private static void Postfix(ZNet __instance, ZNetPeer peer)
		{
			if (__instance.IsServer() && peer != null)
			{
				List<string> list = new List<string>();
				list.Add(ServerLockConfig.Value ? "LOCKED" : "UNLOCKED");
				string[] weaponCategories = WeaponCategories;
				foreach (string text in weaponCategories)
				{
					WeaponConfigSettings weaponConfigSettings = CategoryConfigs[text];
					list.Add(string.Format(CultureInfo.InvariantCulture, "{0};{1};{2};{3};{4};{5};{6};{7}", text, weaponConfigSettings.OutlineThickness, weaponConfigSettings.NeonIntensity, weaponConfigSettings.WaveSpeed, weaponConfigSettings.BaseAlpha, weaponConfigSettings.OffsetX, weaponConfigSettings.OffsetY, weaponConfigSettings.OffsetZ));
				}
				string text2 = string.Join("|", list.ToArray());
				ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "RPC_WeaponContour_SyncString", new object[1] { text2 });
				Debug.Log((object)("[WeaponContourMod] Сетевой пакет авторитарных настроек отправлен клиенту: " + peer.m_playerName));
			}
		}
	}

	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	private class ZNet_Disconnect_Patch
	{
		private static void Prefix()
		{
			IsConfigOverriddenByServer = false;
			IsConfigLockedByServer = false;
			ServerOverriddenValues.Clear();
			Debug.Log((object)"[WeaponContourMod] Отключение от сервера: управление конфигом возвращено игроку.");
		}
	}

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	private class ZNetScene_Patch
	{
		private static void Postfix(ZNetScene __instance)
		{
			if (__instance.m_prefabs.Count == 0)
			{
				return;
			}
			foreach (GameObject prefab in __instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				Component componentInChildren = prefab.GetComponentInChildren(typeof(ItemDrop));
				ItemDrop val = (ItemDrop)(object)((componentInChildren is ItemDrop) ? componentInChildren : null);
				if (!((Object)(object)val == (Object)null) && val.m_itemData != null)
				{
					SharedData shared = val.m_itemData.m_shared;
					string text = ((Object)prefab).name.ToLower();
					string text2 = DetermineCategory(shared, text);
					if (!string.IsNullOrEmpty(text2) && !text.Contains("hammer") && !text.Contains("hoe") && !text.Contains("cultivator") && !text.Contains("pickaxe") && !text.Contains("fishingrod"))
					{
						ApplyNeonOutline(prefab, text2);
					}
				}
			}
		}

		private static string DetermineCategory(SharedData shared, string nameLower)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Invalid comparison between Unknown and I4
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Invalid comparison between Unknown and I4
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Invalid comparison between Unknown and I4
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Invalid comparison between Unknown and I4
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Invalid comparison between Unknown and I4
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Invalid comparison between Unknown and I4
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Invalid comparison between Unknown and I4
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Invalid comparison between Unknown and I4
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Invalid comparison between Unknown and I4
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Invalid comparison between Unknown and I4
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Invalid comparison between Unknown and I4
			if ((int)shared.m_itemType == 5)
			{
				return null;
			}
			if ((int)shared.m_skillType == 9 || (int)shared.m_skillType == 10 || nameLower.Contains("staff") || nameLower.Contains("wand"))
			{
				return "Магия";
			}
			if (nameLower.Contains("crossbow"))
			{
				return "Арбалеты";
			}
			if ((int)shared.m_itemType == 4)
			{
				return "Луки";
			}
			if ((int)shared.m_skillType == 11 || nameLower.Contains("claw") || nameLower.Contains("fist"))
			{
				if ((int)shared.m_itemType == 14 || nameLower.Contains("ripper"))
				{
					return "Двуручные кулаки";
				}
				return "Кулаки";
			}
			if ((int)shared.m_itemType == 14)
			{
				if ((int)shared.m_skillType == 1 || nameLower.Contains("sword"))
				{
					return "Двуручные мечи";
				}
				if ((int)shared.m_skillType == 4 || nameLower.Contains("atgeir"))
				{
					return "Древковое";
				}
				if ((int)shared.m_skillType == 7 || nameLower.Contains("axe") || nameLower.Contains("battleaxe"))
				{
					return "Двуручные топоры";
				}
				if ((int)shared.m_skillType == 2 || nameLower.Contains("ripper") || nameLower.Contains("dagger") || nameLower.Contains("knife"))
				{
					return "Двуручные ножи";
				}
				return "Двуручные дубины";
			}
			if ((int)shared.m_itemType == 3)
			{
				if ((int)shared.m_skillType == 1 || nameLower.Contains("sword"))
				{
					return "Одноручные мечи";
				}
				if ((int)shared.m_skillType == 2 || nameLower.Contains("dagger") || nameLower.Contains("knife"))
				{
					return "Ножи";
				}
				if ((int)shared.m_skillType == 5 || nameLower.Contains("spear"))
				{
					return "Копья";
				}
				if ((int)shared.m_skillType == 7 || nameLower.Contains("axe"))
				{
					return "Топоры";
				}
				if ((int)shared.m_skillType == 3 || nameLower.Contains("club") || nameLower.Contains("mace"))
				{
					return "Дубины";
				}
			}
			return null;
		}

		private static void ApplyNeonOutline(GameObject prefab, string weaponCategory)
		{
			Component[] componentsInChildren = prefab.GetComponentsInChildren(typeof(Renderer), true);
			foreach (Component obj in componentsInChildren)
			{
				Renderer val = (Renderer)(object)((obj is Renderer) ? obj : null);
				if (!((Object)(object)val != (Object)null) || (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer)))
				{
					continue;
				}
				string name = ((Object)((Component)val).gameObject).name;
				if (!name.Contains("NeonOutline") && name.IndexOf("particle", StringComparison.OrdinalIgnoreCase) < 0 && (Object)(object)((Component)val).gameObject.GetComponent(typeof(WeaponOutlineController)) == (Object)null)
				{
					WeaponOutlineController weaponOutlineController = ((Component)val).gameObject.AddComponent(typeof(WeaponOutlineController)) as WeaponOutlineController;
					if ((Object)(object)weaponOutlineController != (Object)null)
					{
						weaponOutlineController.WeaponCategory = weaponCategory;
					}
				}
			}
		}
	}

	private readonly Harmony harmony = new Harmony("com.yourname.weaponcontour");

	public static Dictionary<string, WeaponConfigSettings> CategoryConfigs = new Dictionary<string, WeaponConfigSettings>();

	public static Dictionary<string, RuntimeConfigValues> ServerOverriddenValues = new Dictionary<string, RuntimeConfigValues>();

	public static bool IsConfigOverriddenByServer = false;

	public static ConfigEntry<bool> ServerLockConfig;

	public static bool IsConfigLockedByServer = false;

	private static readonly string[] WeaponCategories = new string[15]
	{
		"Топоры", "Двуручные топоры", "Дубины", "Двуручные дубины", "Одноручные мечи", "Двуручные мечи", "Копья", "Древковое", "Ножи", "Двуручные ножи",
		"Луки", "Арбалеты", "Магия", "Кулаки", "Двуручные кулаки"
	};

	private void Awake()
	{
		ServerLockConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Служебные", "LockConfiguration", true, "Если включено (true), сервер заблокирует и подчинит себе настройки всех подключенных клиентов.");
		string[] weaponCategories = WeaponCategories;
		foreach (string text in weaponCategories)
		{
			float num = 1.007f;
			float num2 = 0.7f;
			float num3 = 0.2f;
			float num4 = 0.15f;
			switch (text)
			{
			case "Топоры":
				num = 0.9896f;
				break;
			case "Двуручные топоры":
				num = 0.9915f;
				num2 = 0f;
				break;
			case "Дубины":
				num = 0.9986f;
				break;
			case "Двуручные дубины":
				num = 0.995f;
				break;
			case "Одноручные мечи":
				num = 1f;
				num2 = 0.7f;
				num3 = 0.1f;
				break;
			case "Двуручные мечи":
				num = 0.9929f;
				break;
			case "Копья":
				num = 0.995f;
				break;
			case "Древковое":
				num = 0.9919f;
				break;
			case "Ножи":
				num = 0.9929f;
				break;
			case "Двуручные ножи":
				num = 0.9935f;
				num2 = 0f;
				break;
			case "Луки":
				num = 0.997f;
				break;
			case "Арбалеты":
				num = 0.998f;
				break;
			case "Магия":
				num = 0.998f;
				break;
			case "Кулаки":
				num = 1.007f;
				break;
			case "Двуручные кулаки":
				num = 1.005f;
				num2 = 0f;
				break;
			}
			CategoryConfigs[text] = new WeaponConfigSettings
			{
				OutlineThickness = ((BaseUnityPlugin)this).Config.Bind<float>(text ?? "", "Thickness", num, "Толщина неоновой обводки для категории " + text + ".").Value,
				NeonIntensity = ((BaseUnityPlugin)this).Config.Bind<float>(text ?? "", "Intensity", num2, "Яркость свечения для категории " + text + ".").Value,
				WaveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>(text ?? "", "WaveSpeed", num3, "Скорость пульсации пламени для категории " + text + ".").Value,
				BaseAlpha = ((BaseUnityPlugin)this).Config.Bind<float>(text ?? "", "MaxAlpha", num4, "Прозрачность контура для категории " + text + ".").Value,
				OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>(text ?? "", "OffsetX", 0f, "Смещение контура по оси X (влево/вправо) для категории " + text + ".").Value,
				OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>(text ?? "", "OffsetY", 0f, "Смещение контура по оси Y (вверх/вниз) для категории " + text + ".").Value,
				OffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>(text ?? "", "OffsetZ", 0f, "Смещение контура по оси Z (вперед/назад) для категории " + text + ".").Value
			};
		}
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Мод контура оружия успешно обновлен до версии 2.8.5! Добавлена система Server Lockdown.");
	}

	private static void RPC_WeaponContour_SyncString(long sender, string configData)
	{
		if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
		{
			return;
		}
		try
		{
			if (string.IsNullOrEmpty(configData))
			{
				return;
			}
			string[] array = configData.Split(new char[1] { '|' });
			if (array.Length < 2)
			{
				return;
			}
			IsConfigLockedByServer = array[0] == "LOCKED";
			if (!IsConfigLockedByServer)
			{
				IsConfigOverriddenByServer = false;
				ServerOverriddenValues.Clear();
				Debug.Log((object)("[WeaponContourMod] Сервер разрешил использовать локальные клиентские конфиги. (Получено от сервера ID: " + sender + ")"));
				return;
			}
			ServerOverriddenValues.Clear();
			for (int i = 1; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ';' });
				if (array2.Length >= 8)
				{
					string key = array2[0];
					RuntimeConfigValues value = new RuntimeConfigValues
					{
						OutlineThickness = float.Parse(array2[1], CultureInfo.InvariantCulture),
						NeonIntensity = float.Parse(array2[2], CultureInfo.InvariantCulture),
						WaveSpeed = float.Parse(array2[3], CultureInfo.InvariantCulture),
						BaseAlpha = float.Parse(array2[4], CultureInfo.InvariantCulture),
						OffsetX = float.Parse(array2[5], CultureInfo.InvariantCulture),
						OffsetY = float.Parse(array2[6], CultureInfo.InvariantCulture),
						OffsetZ = float.Parse(array2[7], CultureInfo.InvariantCulture)
					};
					ServerOverriddenValues[key] = value;
				}
			}
			IsConfigOverriddenByServer = true;
			Debug.Log((object)"[WeaponContourMod] Конфигурация заблокирована сервером администратора! Локальные изменения игнорируются.");
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[WeaponContourMod] Критическая ошибка Server Sync: " + ex.Message));
		}
	}
}
public class WeaponConfigSettings
{
	public float OutlineThickness;

	public float NeonIntensity;

	public float WaveSpeed;

	public float BaseAlpha;

	public float OffsetX;

	public float OffsetY;

	public float OffsetZ;
}
public class RuntimeConfigValues
{
	public float OutlineThickness;

	public float NeonIntensity;

	public float WaveSpeed;

	public float BaseAlpha;

	public float OffsetX;

	public float OffsetY;

	public float OffsetZ;
}
public class WeaponOutlineController : MonoBehaviour
{
	public string WeaponCategory = "Одноручные мечи";

	private Renderer _baseRenderer;

	private Material _outlineMaterial;

	private GameObject _outlineObject;

	private ZNetView _nview;

	private ItemDrop _itemDrop;

	private Humanoid _cachedOwner;

	private float _nextCheckTime;

	private int _cachedQuality = -1;

	private bool _isStaticPrefab;

	private Renderer _actualVisualRenderer;

	private static readonly int ColorPropID = Shader.PropertyToID("_Color");

	private static readonly int EmissionColorPropID = Shader.PropertyToID("_EmissionColor");

	private static readonly int MainColorPropID = Shader.PropertyToID("_MainColor");

	private static readonly FieldRef<Humanoid, ItemData> LeftItemRef = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_leftItem");

	private void Awake()
	{
		ref Renderer baseRenderer = ref _baseRenderer;
		Component component = ((Component)this).GetComponent(typeof(Renderer));
		baseRenderer = (Renderer)(object)((component is Renderer) ? component : null);
		Transform root = ((Component)this).transform.root;
		ref ZNetView nview = ref _nview;
		Component obj = ((Component)this).GetComponentInParent(typeof(ZNetView)) ?? (Object.op_Implicit((Object)(object)root) ? ((Component)root).GetComponent(typeof(ZNetView)) : null);
		nview = (ZNetView)(object)((obj is ZNetView) ? obj : null);
		ref ItemDrop itemDrop = ref _itemDrop;
		Component obj2 = ((Component)this).GetComponentInParent(typeof(ItemDrop)) ?? (Object.op_Implicit((Object)(object)root) ? ((Component)root).GetComponentInChildren(typeof(ItemDrop)) : null);
		itemDrop = (ItemDrop)(object)((obj2 is ItemDrop) ? obj2 : null);
		ref Humanoid cachedOwner = ref _cachedOwner;
		Component obj3 = ((Component)this).GetComponentInParent(typeof(Humanoid)) ?? (Object.op_Implicit((Object)(object)root) ? ((Component)root).GetComponentInChildren(typeof(Humanoid)) : null);
		cachedOwner = (Humanoid)(object)((obj3 is Humanoid) ? obj3 : null);
		_isStaticPrefab = ((Object)(object)_itemDrop != (Object)null && (Object)(object)_cachedOwner == (Object)null) || (Object)(object)_nview == (Object)null;
		CreateOutlineMesh();
	}

	private void CreateOutlineMesh()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Expected O, but got Unknown
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_outlineObject != (Object)null)
		{
			return;
		}
		_outlineObject = new GameObject("NeonOutline");
		if (_isStaticPrefab)
		{
			_outlineObject.transform.SetParent(((Component)this).transform, false);
		}
		Renderer val3;
		if (_baseRenderer is MeshRenderer)
		{
			Component obj = _outlineObject.AddComponent(typeof(MeshFilter));
			MeshFilter val = (MeshFilter)(object)((obj is MeshFilter) ? obj : null);
			Component component = ((Component)this).GetComponent(typeof(MeshFilter));
			MeshFilter val2 = (MeshFilter)(object)((component is MeshFilter) ? component : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
			{
				val.sharedMesh = val2.sharedMesh;
			}
			Component obj2 = _outlineObject.AddComponent(typeof(MeshRenderer));
			val3 = (Renderer)(object)((obj2 is MeshRenderer) ? obj2 : null);
		}
		else
		{
			Renderer baseRenderer = _baseRenderer;
			SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((baseRenderer is SkinnedMeshRenderer) ? baseRenderer : null);
			if (val4 == null)
			{
				return;
			}
			Component obj3 = _outlineObject.AddComponent(typeof(SkinnedMeshRenderer));
			SkinnedMeshRenderer val5 = (SkinnedMeshRenderer)(object)((obj3 is SkinnedMeshRenderer) ? obj3 : null);
			if ((Object)(object)val5 != (Object)null)
			{
				val5.sharedMesh = val4.sharedMesh;
				val5.bones = val4.bones;
				val5.rootBone = val4.rootBone;
			}
			val3 = (Renderer)(object)val5;
		}
		Shader val6 = Shader.Find("Custom/Piece") ?? Shader.Find("Custom/Standard") ?? Shader.Find("Standard") ?? Shader.Find("Sprites/Default");
		_outlineMaterial = new Material(val6);
		_outlineMaterial.EnableKeyword("_EMISSION");
		_outlineMaterial.SetInt("_SrcBlend", 5);
		_outlineMaterial.SetInt("_DstBlend", 10);
		_outlineMaterial.SetInt("_ZWrite", 0);
		_outlineMaterial.SetInt("_Cull", 1);
		_outlineMaterial.renderQueue = 3000;
		if ((Object)(object)val3 != (Object)null)
		{
			val3.sharedMaterial = _outlineMaterial;
		}
		float num = 1.007f;
		float num2 = 0f;
		float num3 = 0f;
		float num4 = 0f;
		WeaponConfigSettings value2;
		if (WeaponContourPlugin.IsConfigOverriddenByServer && WeaponContourPlugin.ServerOverriddenValues.TryGetValue(WeaponCategory, out var value))
		{
			num = value.OutlineThickness;
			num2 = value.OffsetX;
			num3 = value.OffsetY;
			num4 = value.OffsetZ;
		}
		else if (WeaponContourPlugin.CategoryConfigs.TryGetValue(WeaponCategory, out value2))
		{
			num = value2.OutlineThickness;
			num2 = value2.OffsetX;
			num3 = value2.OffsetY;
			num4 = value2.OffsetZ;
		}
		_outlineObject.transform.localScale = Vector3.one * num;
		if (_isStaticPrefab)
		{
			_outlineObject.transform.localPosition = new Vector3(num2, num3, num4);
		}
		_outlineObject.SetActive(false);
	}

	private void Update()
	{
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_042d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0437: Unknown result type (might be due to invalid IL or missing references)
		//IL_0441: Unknown result type (might be due to invalid IL or missing references)
		//IL_044b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0474: Unknown result type (might be due to invalid IL or missing references)
		//IL_0498: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_outlineObject == (Object)null)
		{
			CreateOutlineMesh();
		}
		if ((Object)(object)_outlineObject == (Object)null || (Object)(object)_outlineMaterial == (Object)null)
		{
			return;
		}
		float time = Time.time;
		if (time >= _nextCheckTime)
		{
			_nextCheckTime = time + 0.5f;
			UpdateQualityAndOwner();
			FindActualVisualRenderer();
		}
		if (_cachedQuality < 5)
		{
			if (_outlineObject.activeSelf)
			{
				_outlineObject.SetActive(false);
			}
			return;
		}
		if (!_isStaticPrefab && (Object)(object)_cachedOwner != (Object)null)
		{
			if ((Object)(object)_actualVisualRenderer == (Object)null || !_actualVisualRenderer.enabled || !((Component)_actualVisualRenderer).gameObject.activeInHierarchy)
			{
				if (_outlineObject.activeSelf)
				{
					_outlineObject.SetActive(false);
				}
				return;
			}
			if (!_outlineObject.activeSelf)
			{
				_outlineObject.SetActive(true);
			}
			_outlineObject.transform.position = ((Component)_actualVisualRenderer).transform.position;
			_outlineObject.transform.rotation = ((Component)_actualVisualRenderer).transform.rotation;
		}
		else
		{
			if ((Object)(object)_baseRenderer == (Object)null || !_baseRenderer.enabled || !((Component)this).gameObject.activeInHierarchy)
			{
				if (_outlineObject.activeSelf)
				{
					_outlineObject.SetActive(false);
				}
				return;
			}
			if (!_outlineObject.activeSelf)
			{
				_outlineObject.SetActive(true);
			}
		}
		float num = 0.3f;
		float num2 = 0.15f;
		float num3 = 1.007f;
		float num4 = 0.9f;
		float num5 = 0f;
		float num6 = 0f;
		float num7 = 0f;
		WeaponConfigSettings value2;
		if (WeaponContourPlugin.IsConfigOverriddenByServer && WeaponContourPlugin.ServerOverriddenValues.TryGetValue(WeaponCategory, out var value))
		{
			num = value.WaveSpeed;
			num2 = value.BaseAlpha;
			num3 = value.OutlineThickness;
			num4 = value.NeonIntensity;
			num5 = value.OffsetX;
			num6 = value.OffsetY;
			num7 = value.OffsetZ;
		}
		else if (WeaponContourPlugin.CategoryConfigs.TryGetValue(WeaponCategory, out value2))
		{
			num = value2.WaveSpeed;
			num2 = value2.BaseAlpha;
			num3 = value2.OutlineThickness;
			num4 = value2.NeonIntensity;
			num5 = value2.OffsetX;
			num6 = value2.OffsetY;
			num7 = value2.OffsetZ;
		}
		if (!_isStaticPrefab && (Object)(object)_actualVisualRenderer != (Object)null)
		{
			_outlineObject.transform.Translate(new Vector3(num5, num6, num7), (Space)1);
		}
		Vector3 val = Vector3.one * num3;
		if (_outlineObject.transform.localScale != val)
		{
			_outlineObject.transform.localScale = val;
		}
		Color val2 = default(Color);
		Color val3 = default(Color);
		if (_cachedQuality <= 7)
		{
			((Color)(ref val2))..ctor(0f, 0.4f, 1f);
			((Color)(ref val3))..ctor(0f, 0.15f, 0.75f);
		}
		else if (_cachedQuality <= 10)
		{
			((Color)(ref val2))..ctor(0f, 0.85f, 1f);
			((Color)(ref val3))..ctor(0.45f, 0f, 1f);
		}
		else if (_cachedQuality <= 13)
		{
			((Color)(ref val2))..ctor(1f, 0f, 0.55f);
			((Color)(ref val3))..ctor(0.6f, 0f, 1f);
		}
		else
		{
			((Color)(ref val2))..ctor(1f, 0.35f, 0f);
			((Color)(ref val3))..ctor(1f, 0f, 0.1f);
		}
		float num8 = ((num > 0f) ? (time * num) : 0f);
		float num9 = ((num > 0f) ? ((Mathf.Sin(num8) + 1f) * 0.5f) : 0f);
		Color val4 = Color.Lerp(val2, val3, num9);
		float num10 = num2 * 0.4f;
		float a = ((num > 0f) ? Mathf.Lerp(num10, num2, Mathf.PingPong(time * (num * 2.5f), 1f)) : num2);
		val4.a = a;
		Color val5 = default(Color);
		((Color)(ref val5))..ctor(val4.r * num4, val4.g * num4, val4.b * num4, val4.a);
		if (_outlineMaterial.HasProperty(ColorPropID))
		{
			_outlineMaterial.SetColor(ColorPropID, val5);
		}
		if (_outlineMaterial.HasProperty(EmissionColorPropID))
		{
			_outlineMaterial.SetColor(EmissionColorPropID, val5);
		}
		if (_outlineMaterial.HasProperty(MainColorPropID))
		{
			_outlineMaterial.SetColor(MainColorPropID, val5);
		}
	}

	private void FindActualVisualRenderer()
	{
		if (_isStaticPrefab || (Object)(object)_cachedOwner == (Object)null)
		{
			return;
		}
		Component[] componentsInChildren = ((Component)((Component)_cachedOwner).transform.root).GetComponentsInChildren(typeof(Renderer), false);
		foreach (Component obj in componentsInChildren)
		{
			Renderer val = (Renderer)(object)((obj is Renderer) ? obj : null);
			if ((Object)(object)val != (Object)null && (val is MeshRenderer || val is SkinnedMeshRenderer) && !(((Object)((Component)val).gameObject).name == "NeonOutline") && !((Object)((Component)val).gameObject).name.Contains("particle") && (((Object)((Component)val).gameObject).name == ((Object)((Component)this).gameObject).name || ((Object)((Component)val).gameObject).name.Contains(((Object)((Component)this).gameObject).name)))
			{
				_actualVisualRenderer = val;
				break;
			}
		}
	}

	private void UpdateQualityAndOwner()
	{
		if ((Object)(object)_itemDrop != (Object)null && _itemDrop.m_itemData != null)
		{
			_cachedQuality = _itemDrop.m_itemData.m_quality;
			return;
		}
		Transform root = ((Component)this).transform.root;
		if ((Object)(object)_cachedOwner == (Object)null)
		{
			ref Humanoid cachedOwner = ref _cachedOwner;
			Component obj = ((Component)this).GetComponentInParent(typeof(Humanoid)) ?? (Object.op_Implicit((Object)(object)root) ? ((Component)root).GetComponentInChildren(typeof(Humanoid)) : null);
			cachedOwner = (Humanoid)(object)((obj is Humanoid) ? obj : null);
		}
		if ((Object)(object)_cachedOwner != (Object)null)
		{
			if (((Character)_cachedOwner).IsPlayer() && (Object)/*isinst with value type is only supported in some contexts*/ == (Object)(object)Player.m_localPlayer)
			{
				ItemData val = _cachedOwner.GetCurrentWeapon();
				string text = (((Object)(object)root != (Object)null) ? ((Object)root).name : "");
				if (val == null || text.IndexOf("shield", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)this).name.IndexOf("shield", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val = LeftItemRef.Invoke(_cachedOwner);
				}
				if (val != null)
				{
					_cachedQuality = val.m_quality;
					return;
				}
			}
			else
			{
				Component component = ((Component)_cachedOwner).GetComponent(typeof(ZNetView));
				ZNetView val2 = (ZNetView)(((object)((component is ZNetView) ? component : null)) ?? ((object)_nview));
				if ((Object)(object)val2 != (Object)null && val2.IsValid())
				{
					int num = val2.GetZDO().GetInt("RightItemQuality", 1);
					int cachedQuality = val2.GetZDO().GetInt("LeftItemQuality", 1);
					if ((((Object)(object)root != (Object)null) ? ((Object)root).name : "").IndexOf("shield", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)this).name.IndexOf("shield", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						_cachedQuality = cachedQuality;
					}
					else
					{
						_cachedQuality = ((num > 1) ? num : val2.GetZDO().GetInt("quality", 1));
					}
					return;
				}
			}
		}
		else if ((Object)(object)_nview != (Object)null && _nview.IsValid())
		{
			_cachedQuality = _nview.GetZDO().GetInt("quality", 1);
			return;
		}
		_cachedQuality = 1;
	}

	private void OnDestroy()
	{
		if ((Object)(object)_outlineObject != (Object)null)
		{
			Object.Destroy((Object)(object)_outlineObject);
		}
		if ((Object)(object)_outlineMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)_outlineMaterial);
		}
	}
}