using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("PeakClearCosmetics")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PeakClearCosmetics")]
[assembly: AssemblyTitle("PeakClearCosmetics")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace PeakClearCosmeticsMod
{
[BepInPlugin("com.tmh.peak.clearcosmetics", "PeakClearCosmetics", "1.7.0")]
public class Plugin : BaseUnityPlugin
{
private ConfigEntry<bool> _verboseLogging;
private ConfigEntry<KeyboardShortcut> _hotkey;
private ConfigEntry<bool> _dryRun;
private ConfigEntry<bool> _showButton;
private ConfigEntry<float> _buttonX;
private ConfigEntry<float> _buttonY;
private ConfigEntry<string> _passportNameContains;
private ConfigEntry<bool> _compatMultiCosmetic;
private ConfigEntry<bool> _compatMoreCustomizations;
private ConfigEntry<int> _reassertFrames;
private const string ButtonText = "Clear Cosmetics";
private GameObject _btnRoot;
private Button _btn;
private TextMeshProUGUI _label;
private RectTransform _rt;
private bool _clearing;
private void Awake()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
_verboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", true, "If true, log details about scanning & detection.");
_hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Hotkey", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "Hotkey to clear cosmetics immediately.");
_dryRun = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "DryRun", false, "If true, do not modify anything; only log what would happen.");
_showButton = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowButton", true, "Draw on-screen button when passport UI is open.");
_buttonX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ButtonX", 20f, "Button X position from right.");
_buttonY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ButtonY", 20f, "Button Y position from bottom.");
_passportNameContains = ((BaseUnityPlugin)this).Config.Bind<string>("Detection", "PassportObjectNameContains", "Canvas_HUD", "Substring that identifies the passport UI Canvas/panel name.");
_compatMultiCosmetic = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "TargetMultiCosmetic", true, "Also clear Multi_Cosmetic state.");
_compatMoreCustomizations = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "TargetMoreCustomizations", true, "Also clear MoreCustomizations state.");
_reassertFrames = ((BaseUnityPlugin)this).Config.Bind<int>("Compatibility", "ReassertClearFrames", 5, "Defensively reassert cleared values for N frames.");
((BaseUnityPlugin)this).Config.Save();
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PCC] v1.7.0 (compat + targeted-panel-refresh) awake. DLL path: " + Assembly.GetExecutingAssembly().Location));
}
private void Start()
{
CreateButton();
((BaseUnityPlugin)this).Logger.LogInfo((object)"[PCC] UI created.");
}
private void Update()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
KeyboardShortcut value = _hotkey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
OnClickClear();
}
bool flag = _showButton.Value && IsPassportOpen();
if (Object.op_Implicit((Object)(object)_btnRoot) && _btnRoot.activeSelf != flag)
{
_btnRoot.SetActive(flag);
}
}
private bool IsPassportOpen()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)Cursor.lockState > 0)
{
return false;
}
string text = _passportNameContains.Value?.Trim();
if (string.IsNullOrEmpty(text))
{
return false;
}
text = text.ToLowerInvariant();
Canvas[] array = Resources.FindObjectsOfTypeAll<Canvas>();
Canvas[] array2 = array;
foreach (Canvas val in array2)
{
if (!Object.op_Implicit((Object)(object)val) || !((Behaviour)val).isActiveAndEnabled)
{
continue;
}
GameObject gameObject = ((Component)val).gameObject;
string name = ((Object)gameObject).name;
if (name.IndexOf("PCC_OverlayCanvas", StringComparison.OrdinalIgnoreCase) < 0 && name.ToLowerInvariant().Contains(text))
{
if (_verboseLogging.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PCC] Passport match: '" + name + "'"));
}
return true;
}
}
return false;
}
private void CreateButton()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Expected O, but got Unknown
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Expected O, but got Unknown
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)_btnRoot))
{
GameObject val = new GameObject("PCC_OverlayCanvas");
Object.DontDestroyOnLoad((Object)(object)val);
Canvas val2 = val.AddComponent<Canvas>();
val2.renderMode = (RenderMode)0;
val2.sortingOrder = 32767;
val.layer = 5;
val.AddComponent<CanvasScaler>();
val.AddComponent<GraphicRaycaster>();
_btnRoot = new GameObject("PCC_Button");
_btnRoot.transform.SetParent(val.transform, false);
_rt = _btnRoot.AddComponent<RectTransform>();
_rt.sizeDelta = new Vector2(220f, 44f);
_rt.anchorMin = new Vector2(1f, 0f);
_rt.anchorMax = new Vector2(1f, 0f);
_rt.pivot = new Vector2(1f, 0f);
_rt.anchoredPosition = new Vector2(0f - _buttonX.Value, _buttonY.Value);
Image val3 = _btnRoot.AddComponent<Image>();
((Graphic)val3).color = new Color(0f, 0f, 0f, 0.55f);
_btn = _btnRoot.AddComponent<Button>();
((UnityEvent)_btn.onClick).AddListener(new UnityAction(OnClickClear));
GameObject val4 = new GameObject("Label");
val4.transform.SetParent(_btnRoot.transform, false);
RectTransform val5 = val4.AddComponent<RectTransform>();
val5.anchorMin = Vector2.zero;
val5.anchorMax = Vector2.one;
val5.offsetMin = Vector2.zero;
val5.offsetMax = Vector2.zero;
_label = val4.AddComponent<TextMeshProUGUI>();
((TMP_Text)_label).text = "Clear Cosmetics";
((TMP_Text)_label).alignment = (TextAlignmentOptions)514;
((TMP_Text)_label).fontSize = 22f;
((Graphic)_label).raycastTarget = false;
_btnRoot.SetActive(false);
}
}
private void OnClickClear()
{
if (!_clearing)
{
((MonoBehaviour)this).StartCoroutine(ClearRoutine());
}
}
private IEnumerator ClearRoutine()
{
_clearing = true;
bool changed = false;
try
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[PCC] Clear → Photon props + PlayerPrefs (+ compat targets)");
int photonCleared = 0;
int prefsCleared = 0;
Player lp = PhotonNetwork.LocalPlayer;
if (lp != null)
{
List<object> keys = ((Dictionary<object, object>)(object)lp.CustomProperties)?.Keys?.Cast<object>().ToList();
if (keys != null && keys.Count > 0)
{
Hashtable toNull = new Hashtable();
foreach (object kObj in keys)
{
string k = kObj as string;
if (string.IsNullOrEmpty(k))
{
continue;
}
string kl = k.ToLowerInvariant();
int num;
if (!kl.Contains("hat") && !kl.Contains("eye") && !kl.Contains("mouth") && !kl.Contains("accessor") && !kl.Contains("cosmetic"))
{
switch (kl)
{
case "hats":
case "eyes":
case "sxdmulticosmetics":
goto IL_01f9;
}
if (!kl.StartsWith("mc_"))
{
num = (kl.Contains("morecustom") ? 1 : 0);
goto IL_01fa;
}
}
goto IL_01f9;
IL_01fa:
if (num != 0)
{
toNull[(object)k] = null;
if (_verboseLogging.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PCC] Will null Photon key: " + k));
}
}
continue;
IL_01f9:
num = 1;
goto IL_01fa;
}
if (((Dictionary<object, object>)(object)toNull).Count > 0)
{
photonCleared = ((Dictionary<object, object>)(object)toNull).Count;
changed = true;
if (!_dryRun.Value)
{
lp.SetCustomProperties(toNull, (Hashtable)null, (WebFlags)null);
}
}
}
}
List<string> keysToWipe = new List<string>
{
"hat", "hats", "eyes", "mouth", "accessory", "accessories", "acc", "accs", "glasses", "brows",
"eyebrows", "face", "cosmetics", "cosmetic_accessories", "cosmetic_hats", "cosmetic_mouths", "cosmetic_eyes", "SXDMultiCosmetics"
};
if (_compatMultiCosmetic.Value)
{
keysToWipe.AddRange(new string[9] { "MC_SelectedHats", "MC_SelectedEyes", "MC_SelectedMouths", "MC_SelectedAccessories", "MC_ActiveSet", "MC_LastEquipped", "MC_MultiSet", "MC_Serialized", "MC_State" });
}
if (_compatMoreCustomizations.Value)
{
keysToWipe.AddRange(new string[3] { "MoreCustomizations_Selected", "MoreCustomizations_Serialized", "MoreCustomizations_State" });
}
foreach (string j in keysToWipe)
{
if (PlayerPrefs.HasKey(j))
{
if (_verboseLogging.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PCC] Will blank PlayerPrefs key: " + j));
}
if (!_dryRun.Value)
{
PlayerPrefs.SetString(j, "");
}
prefsCleared++;
changed = true;
}
}
if (changed && !_dryRun.Value)
{
PlayerPrefs.Save();
}
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[PCC] Clear base complete. Photon nulled={photonCleared}, PlayerPrefs cleared={prefsCleared}");
if (!_dryRun.Value)
{
InvokeCompatRefresh();
}
}
catch (Exception ex)
{
Exception e = ex;
((BaseUnityPlugin)this).Logger.LogWarning((object)$"[PCC] ClearRoutine exception: {e}");
}
for (int i = 0; i < Mathf.Max(0, _reassertFrames.Value); i++)
{
ReassertClearedOnce();
yield return null;
}
GameObject panel = GetPassportPanelRoot();
if ((Object)(object)panel != (Object)null)
{
yield return ((MonoBehaviour)this).StartCoroutine(NudgePassportPanel(panel));
}
else
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"[PCC] Passport panel not found — running fallback layout rebuild.");
RefreshPassportLayoutFallback();
}
_clearing = false;
}
private void ReassertClearedOnce()
{
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Expected O, but got Unknown
try
{
string[] array = new string[25]
{
"hat", "hats", "eyes", "mouth", "accessory", "accessories", "glasses", "cosmetics", "cosmetic_accessories", "cosmetic_hats",
"cosmetic_mouths", "cosmetic_eyes", "SXDMultiCosmetics", "MC_SelectedHats", "MC_SelectedEyes", "MC_SelectedMouths", "MC_SelectedAccessories", "MC_ActiveSet", "MC_LastEquipped", "MC_MultiSet",
"MC_Serialized", "MC_State", "MoreCustomizations_Selected", "MoreCustomizations_Serialized", "MoreCustomizations_State"
};
string[] array2 = array;
foreach (string text in array2)
{
if (PlayerPrefs.HasKey(text))
{
PlayerPrefs.SetString(text, "");
}
}
PlayerPrefs.Save();
Player localPlayer = PhotonNetwork.LocalPlayer;
if (localPlayer == null)
{
return;
}
Hashtable val = new Hashtable();
foreach (object item in ((Dictionary<object, object>)(object)localPlayer.CustomProperties)?.Keys?.Cast<object>() ?? Array.Empty<object>())
{
string text2 = item as string;
if (string.IsNullOrEmpty(text2))
{
continue;
}
string text3 = text2.ToLowerInvariant();
if (!text3.Contains("hat") && !text3.Contains("eye") && !text3.Contains("mouth") && !text3.Contains("accessor") && !text3.Contains("cosmetic"))
{
switch (text3)
{
default:
if (!text3.StartsWith("mc_") && !text3.Contains("morecustom"))
{
continue;
}
break;
case "hats":
case "eyes":
case "sxdmulticosmetics":
break;
}
}
val[(object)text2] = null;
}
if (((Dictionary<object, object>)(object)val).Count > 0)
{
localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
}
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"[PCC] ReassertClearedOnce failed: {arg}");
}
}
private void InvokeCompatRefresh()
{
try
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
int num = 0;
Assembly[] array = assemblies;
foreach (Assembly assembly in array)
{
string text = assembly.GetName().Name ?? "";
if (text.IndexOf("multi", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("cosmetic", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("custom", StringComparison.OrdinalIgnoreCase) < 0)
{
continue;
}
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
string text2 = type.FullName ?? type.Name;
if (text2.IndexOf("multi", StringComparison.OrdinalIgnoreCase) < 0 && text2.IndexOf("cosmetic", StringComparison.OrdinalIgnoreCase) < 0 && text2.IndexOf("custom", StringComparison.OrdinalIgnoreCase) < 0)
{
continue;
}
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo[] array2 = methods;
foreach (MethodInfo methodInfo in array2)
{
string name = methodInfo.Name;
if ((name.IndexOf("Refresh", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Rebuild", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("UpdateUI", StringComparison.OrdinalIgnoreCase) < 0) || methodInfo.GetParameters().Length != 0)
{
continue;
}
try
{
object obj = null;
if (methodInfo.IsStatic)
{
goto IL_019d;
}
obj = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null, null);
if (obj != null)
{
goto IL_019d;
}
goto end_IL_0158;
IL_019d:
methodInfo.Invoke(obj, null);
num++;
end_IL_0158:;
}
catch
{
}
}
}
}
if (_verboseLogging.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[PCC] Compat refresh calls attempted: {num}");
}
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"[PCC] InvokeCompatRefresh failed: {arg}");
}
}
private GameObject GetPassportPanelRoot()
{
try
{
Canvas[] array = Resources.FindObjectsOfTypeAll<Canvas>();
string value = _passportNameContains.Value ?? string.Empty;
Canvas[] array2 = array;
foreach (Canvas val in array2)
{
if (!Object.op_Implicit((Object)(object)val) || !((Behaviour)val).enabled)
{
continue;
}
string name = ((Object)((Component)val).gameObject).name;
if (name.IndexOf(value, StringComparison.OrdinalIgnoreCase) < 0)
{
continue;
}
TextMeshProUGUI[] componentsInChildren = ((Component)val).GetComponentsInChildren<TextMeshProUGUI>(true);
TextMeshProUGUI[] array3 = componentsInChildren;
foreach (TextMeshProUGUI val2 in array3)
{
if (!Object.op_Implicit((Object)(object)val2))
{
continue;
}
string text = ((TMP_Text)val2).text ?? string.Empty;
if (text.IndexOf("Passport", StringComparison.OrdinalIgnoreCase) >= 0)
{
Transform transform = ((TMP_Text)val2).transform;
RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
RectTransform val4 = val3;
while (Object.op_Implicit((Object)(object)val4) && Object.op_Implicit((Object)(object)((Transform)val4).parent) && (Object)(object)((Transform)val4).parent != (Object)(object)((Component)val).transform)
{
Transform parent = ((Transform)val4).parent;
val4 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
}
GameObject val5 = (Object.op_Implicit((Object)(object)val4) ? ((Component)val4).gameObject : ((Component)val).gameObject);
if (_verboseLogging.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[PCC] Passport panel root: '" + ((Object)val5).name + "' under HUD '" + name + "'"));
}
return val5;
}
}
}
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"[PCC] GetPassportPanelRoot failed: {arg}");
}
return null;
}
private IEnumerator NudgePassportPanel(GameObject panel)
{
if (Object.op_Implicit((Object)(object)panel) && panel.activeSelf)
{
if (Object.op_Implicit((Object)(object)EventSystem.current))
{
EventSystem.current.SetSelectedGameObject((GameObject)null);
}
panel.SetActive(false);
yield return null;
panel.SetActive(true);
yield return null;
Canvas.ForceUpdateCanvases();
RectTransform[] componentsInChildren = panel.GetComponentsInChildren<RectTransform>(true);
foreach (RectTransform rt in componentsInChildren)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(rt);
}
Canvas.ForceUpdateCanvases();
if (_verboseLogging.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[PCC] NudgePassportPanel: toggled panel & rebuilt layout.");
}
}
}
private void RefreshPassportLayoutFallback()
{
try
{
Canvas.ForceUpdateCanvases();
Canvas[] array = Resources.FindObjectsOfTypeAll<Canvas>();
int num = 0;
Canvas[] array2 = array;
foreach (Canvas val in array2)
{
if (Object.op_Implicit((Object)(object)val))
{
RectTransform[] componentsInChildren = ((Component)val).GetComponentsInChildren<RectTransform>(true);
foreach (RectTransform val2 in componentsInChildren)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(val2);
num++;
}
}
}
Canvas.ForceUpdateCanvases();
if (_verboseLogging.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[PCC] Fallback layout rebuild complete, rects={num}.");
}
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"[PCC] RefreshPassportLayoutFallback error: {arg}");
}
}
}
}