using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using Fusion;
using HarmonyLib;
using LycansColorCustomizer.Patches;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LycansColorCustomizer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("LycansColorCustomizer")]
[assembly: AssemblyTitle("LycansColorCustomizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 LycansColorCustomizer
{
public struct HairColorInfo
{
public string Name;
public Color32 TargetColor;
public string HexColor;
public HairColorInfo(string name, byte r, byte g, byte b, string hex)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
Name = name;
TargetColor = new Color32(r, g, b, byte.MaxValue);
HexColor = hex;
}
}
public struct PantsColorInfo
{
public string Name;
public Color32 TargetColor;
public string HexColor;
public PantsColorInfo(string name, byte r, byte g, byte b, string hex)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
Name = name;
TargetColor = new Color32(r, g, b, byte.MaxValue);
HexColor = hex;
}
}
public struct SkinColorInfo
{
public string Name;
public Color32 TargetColor;
public string HexColor;
public SkinColorInfo(string name, byte r, byte g, byte b, string hex)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
Name = name;
TargetColor = new Color32(r, g, b, byte.MaxValue);
HexColor = hex;
}
}
public enum CustomizerCategory
{
Hair,
Pants,
Skin
}
public static class AppearanceManager
{
public const string PREFS_HAIR_KEY = "CUSTOM_HAIR_COLOR_INDEX";
public const string PREFS_PANTS_KEY = "CUSTOM_PANTS_COLOR_INDEX";
public const string PREFS_SKIN_KEY = "CUSTOM_SKIN_COLOR_INDEX";
public static readonly HairColorInfo[] HairColors = new HairColorInfo[12]
{
new HairColorInfo("Natural Brown", 90, 68, 40, "8A5A36"),
new HairColorInfo("Blonde", 240, 210, 110, "F5D76E"),
new HairColorInfo("Jet Black", 40, 40, 45, "2C2C2E"),
new HairColorInfo("Ginger / Auburn", 210, 85, 30, "D35400"),
new HairColorInfo("Platinum / Silver", 225, 225, 235, "ECEFF1"),
new HairColorInfo("Crimson Red", 210, 35, 45, "E74C3C"),
new HairColorInfo("Midnight Blue", 45, 95, 225, "2980B9"),
new HairColorInfo("Emerald Green", 40, 195, 80, "27AE60"),
new HairColorInfo("Pastel Pink", 245, 95, 175, "FD79A8"),
new HairColorInfo("Royal Purple", 165, 55, 225, "8E44AD"),
new HairColorInfo("Electric Cyan", 45, 225, 225, "00CEC9"),
new HairColorInfo("Sunset Orange", 245, 135, 35, "E67E22")
};
public static readonly PantsColorInfo[] PantsColors = new PantsColorInfo[12]
{
new PantsColorInfo("Rustic Khaki", 109, 99, 86, "A89982"),
new PantsColorInfo("Midnight Black", 35, 35, 38, "2A2A2E"),
new PantsColorInfo("Denim Blue", 45, 75, 140, "345995"),
new PantsColorInfo("Forest Green", 35, 85, 45, "277A3E"),
new PantsColorInfo("Crimson Red", 130, 30, 35, "9E2A2B"),
new PantsColorInfo("Bleached Linen", 220, 220, 225, "E0E0E6"),
new PantsColorInfo("Leather Brown", 65, 40, 25, "4E311F"),
new PantsColorInfo("Royal Purple", 85, 40, 120, "6A2E8E"),
new PantsColorInfo("Golden Amber", 150, 105, 30, "C28B23"),
new PantsColorInfo("Slate Gray", 95, 100, 110, "6B7280"),
new PantsColorInfo("Teal Cyan", 30, 115, 125, "1E7B85"),
new PantsColorInfo("Rose Pink", 150, 65, 100, "A84E72")
};
public static readonly SkinColorInfo[] SkinColors = new SkinColorInfo[12]
{
new SkinColorInfo("Fair Peach", 235, 185, 155, "EBB99B"),
new SkinColorInfo("Rosy Porcelain", 245, 195, 180, "F5C3B4"),
new SkinColorInfo("Warm Beige", 225, 175, 140, "E1AF8C"),
new SkinColorInfo("Golden Peach", 225, 160, 125, "E1A07D"),
new SkinColorInfo("Olive Tan", 195, 150, 115, "C39673"),
new SkinColorInfo("Golden Bronze", 185, 135, 95, "B9875F"),
new SkinColorInfo("Warm Chestnut", 155, 105, 75, "9B694B"),
new SkinColorInfo("Mocha Espresso", 110, 75, 55, "6E4B37"),
new SkinColorInfo("Deep Ebony", 75, 50, 38, "4B3226"),
new SkinColorInfo("Ghostly Pale", 210, 205, 205, "D2CDCD"),
new SkinColorInfo("Orcish Olive", 140, 160, 115, "8CA073"),
new SkinColorInfo("Sunburnt Ruddy", 215, 135, 120, "D78778")
};
private static readonly Dictionary<string, Texture2D> TextureCache = new Dictionary<string, Texture2D>();
private static readonly Dictionary<PlayerRef, int> PlayerHairColors = new Dictionary<PlayerRef, int>();
private static readonly Dictionary<PlayerRef, int> PlayerPantsColors = new Dictionary<PlayerRef, int>();
private static readonly Dictionary<PlayerRef, int> PlayerSkinColors = new Dictionary<PlayerRef, int>();
public static CustomizerCategory CurrentCategory { get; private set; } = CustomizerCategory.Hair;
public static void CycleCategory()
{
CurrentCategory = (CustomizerCategory)((int)(CurrentCategory + 1) % 3);
}
public static void SetCategory(CustomizerCategory category)
{
CurrentCategory = category;
}
public static void CycleCurrentValue(int delta = 1)
{
switch (CurrentCategory)
{
case CustomizerCategory.Hair:
ChangeHair(delta);
break;
case CustomizerCategory.Pants:
ChangePants(delta);
break;
case CustomizerCategory.Skin:
ChangeSkin(delta);
break;
}
}
public static int GetSavedHair()
{
return PlayerPrefs.GetInt("CUSTOM_HAIR_COLOR_INDEX", 0);
}
public static void SetSavedHair(int index)
{
PlayerPrefs.SetInt("CUSTOM_HAIR_COLOR_INDEX", index);
PlayerPrefs.Save();
}
public static int GetSavedPants()
{
return PlayerPrefs.GetInt("CUSTOM_PANTS_COLOR_INDEX", 0);
}
public static void SetSavedPants(int index)
{
PlayerPrefs.SetInt("CUSTOM_PANTS_COLOR_INDEX", index);
PlayerPrefs.Save();
}
public static int GetSavedSkin()
{
return PlayerPrefs.GetInt("CUSTOM_SKIN_COLOR_INDEX", 0);
}
public static void SetSavedSkin(int index)
{
PlayerPrefs.SetInt("CUSTOM_SKIN_COLOR_INDEX", index);
PlayerPrefs.Save();
}
public static int GetHairCount()
{
return HairColors.Length;
}
public static int GetPantsCount()
{
return PantsColors.Length;
}
public static int GetSkinCount()
{
return SkinColors.Length;
}
public static HairColorInfo GetHairInfo(int index)
{
if (index >= 0 && index < HairColors.Length)
{
return HairColors[index];
}
return HairColors[0];
}
public static PantsColorInfo GetPantsInfo(int index)
{
if (index >= 0 && index < PantsColors.Length)
{
return PantsColors[index];
}
return PantsColors[0];
}
public static SkinColorInfo GetSkinInfo(int index)
{
if (index >= 0 && index < SkinColors.Length)
{
return SkinColors[index];
}
return SkinColors[0];
}
public static int ExtractHair(string id)
{
if (string.IsNullOrEmpty(id))
{
return -1;
}
Match match = Regex.Match(id, "#hair=(\\d+)", RegexOptions.IgnoreCase);
if (match.Success && int.TryParse(match.Groups[1].Value, out var result))
{
return result;
}
return -1;
}
public static int ExtractPants(string id)
{
if (string.IsNullOrEmpty(id))
{
return -1;
}
Match match = Regex.Match(id, "#pants=(\\d+)", RegexOptions.IgnoreCase);
if (match.Success && int.TryParse(match.Groups[1].Value, out var result))
{
return result;
}
return -1;
}
public static int ExtractSkin(string id)
{
if (string.IsNullOrEmpty(id))
{
return -1;
}
Match match = Regex.Match(id, "#skin=(\\d+)", RegexOptions.IgnoreCase);
if (match.Success && int.TryParse(match.Groups[1].Value, out var result))
{
return result;
}
return -1;
}
public static string CleanAppearanceTags(string id)
{
if (string.IsNullOrEmpty(id))
{
return "";
}
return Regex.Replace(Regex.Replace(Regex.Replace(id, "#hair=\\d+", "", RegexOptions.IgnoreCase), "#pants=\\d+", "", RegexOptions.IgnoreCase), "#skin=\\d+", "", RegexOptions.IgnoreCase);
}
public static string BuildCustomId(string currentId, int hairIndex, int pantsIndex, int skinIndex)
{
string text = CleanAppearanceTags(currentId);
if (string.IsNullOrEmpty(text))
{
text = PlayerPrefs.GetString("STEAM_ID", Guid.NewGuid().ToString());
}
string text2 = $"#hair={hairIndex}#pants={pantsIndex}#skin={skinIndex}";
if (text.Length + text2.Length > 63)
{
text = text.Substring(0, Math.Max(0, 63 - text2.Length));
}
return text + text2;
}
public static int GetPlayerHair(PlayerController player)
{
//IL_0011: 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_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null)
{
return 0;
}
if (PlayerHairColors.TryGetValue(player.Ref, out var value))
{
return value;
}
int num = ExtractHair(((object)player.PlayerData.ID/*cast due to .constrained prefix*/).ToString());
if (num >= 0)
{
PlayerHairColors[player.Ref] = num;
return num;
}
if (((SimulationBehaviour)player).HasInputAuthority)
{
return GetSavedHair();
}
return 0;
}
public static int GetPlayerPants(PlayerController player)
{
//IL_0011: 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_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null)
{
return 0;
}
if (PlayerPantsColors.TryGetValue(player.Ref, out var value))
{
return value;
}
int num = ExtractPants(((object)player.PlayerData.ID/*cast due to .constrained prefix*/).ToString());
if (num >= 0)
{
PlayerPantsColors[player.Ref] = num;
return num;
}
if (((SimulationBehaviour)player).HasInputAuthority)
{
return GetSavedPants();
}
return 0;
}
public static int GetPlayerSkin(PlayerController player)
{
//IL_0011: 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_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null)
{
return 0;
}
if (PlayerSkinColors.TryGetValue(player.Ref, out var value))
{
return value;
}
int num = ExtractSkin(((object)player.PlayerData.ID/*cast due to .constrained prefix*/).ToString());
if (num >= 0)
{
PlayerSkinColors[player.Ref] = num;
return num;
}
if (((SimulationBehaviour)player).HasInputAuthority)
{
return GetSavedSkin();
}
return 0;
}
public static void ApplyAppearanceToPlayer(PlayerController player, int hairIndex, int pantsIndex, int skinIndex)
{
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null)
{
return;
}
hairIndex = Mathf.Clamp(hairIndex, 0, HairColors.Length - 1);
pantsIndex = Mathf.Clamp(pantsIndex, 0, PantsColors.Length - 1);
skinIndex = Mathf.Clamp(skinIndex, 0, SkinColors.Length - 1);
PlayerHairColors[player.Ref] = hairIndex;
PlayerPantsColors[player.Ref] = pantsIndex;
PlayerSkinColors[player.Ref] = skinIndex;
try
{
SkinnedMeshRenderer value = Traverse.Create((object)player).Field<SkinnedMeshRenderer>("villagerMeshRenderer").Value;
if ((Object)(object)value == (Object)null || (Object)(object)((Renderer)value).material == (Object)null)
{
return;
}
int num = player.Index;
try
{
Type type = AccessTools.TypeByName("LycansNewRoles.PlayerCustomRegistry");
if (type != null)
{
MethodInfo methodInfo = AccessTools.Method(type, "GetPlayer", new Type[1] { typeof(PlayerRef) }, (Type[])null);
if (methodInfo != null)
{
object obj = methodInfo.Invoke(null, new object[1] { player.Ref });
if (obj != null)
{
num = Traverse.Create(obj).Property<int>("ColorIndex", (object[])null).Value;
}
}
}
}
catch
{
}
Texture tintedTexture = GetTintedTexture(ColorManager.GetTexture(num), num, hairIndex, pantsIndex, skinIndex);
if ((Object)(object)tintedTexture != (Object)null)
{
((Renderer)value).material.mainTexture = tintedTexture;
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in ApplyAppearanceToPlayer for {player.Ref}: {arg}");
}
}
public static Texture GetTintedTexture(Texture baseTexture, int outfitIndex, int hairIndex, int pantsIndex, int skinIndex)
{
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_022c: Unknown result type (might be due to invalid IL or missing references)
//IL_0239: Unknown result type (might be due to invalid IL or missing references)
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)baseTexture == (Object)null)
{
return null;
}
if (hairIndex <= 0 && pantsIndex <= 0 && skinIndex <= 0)
{
return baseTexture;
}
string text = $"{outfitIndex}_h{hairIndex}_p{pantsIndex}_s{skinIndex}";
if (TextureCache.TryGetValue(text, out var value) && (Object)(object)value != (Object)null)
{
return (Texture)(object)value;
}
Texture2D val = MakeReadable((Texture2D)(object)((baseTexture is Texture2D) ? baseTexture : null));
if ((Object)(object)val == (Object)null)
{
return baseTexture;
}
Color32[] pixels = val.GetPixels32();
Color32[] basePixels = (Color32[])pixels.Clone();
int width = ((Texture)val).width;
int height = ((Texture)val).height;
float num = (float)width / 2048f;
float num2 = (float)height / 2048f;
if (hairIndex > 0 && hairIndex < HairColors.Length)
{
HairColorInfo hairColorInfo = HairColors[hairIndex];
byte r = hairColorInfo.TargetColor.r;
byte g = hairColorInfo.TargetColor.g;
byte b = hairColorInfo.TargetColor.b;
ApplyHairTintRegion(pixels, basePixels, width, (int)(0f * num), (int)(725f * num), (int)(497f * num2), (int)(1360f * num2), r, g, b);
ApplyHairTintRegion(pixels, basePixels, width, (int)(910f * num), (int)(1030f * num), (int)(1580f * num2), (int)(1700f * num2), r, g, b);
ApplyHairTintRegion(pixels, basePixels, width, (int)(100f * num), (int)(270f * num), (int)(1810f * num2), (int)(1890f * num2), r, g, b);
}
if (pantsIndex > 0 && pantsIndex < PantsColors.Length)
{
PantsColorInfo pantsColorInfo = PantsColors[pantsIndex];
byte r2 = pantsColorInfo.TargetColor.r;
byte g2 = pantsColorInfo.TargetColor.g;
byte b2 = pantsColorInfo.TargetColor.b;
ApplyPantsTintRegion(pixels, width, (int)(1300f * num), (int)(2025f * num), (int)(540f * num2), (int)(1285f * num2), r2, g2, b2);
}
if (skinIndex > 0 && skinIndex < SkinColors.Length)
{
SkinColorInfo skinColorInfo = SkinColors[skinIndex];
byte r3 = skinColorInfo.TargetColor.r;
byte g3 = skinColorInfo.TargetColor.g;
byte b3 = skinColorInfo.TargetColor.b;
ApplyFaceSkinTintRegion(pixels, basePixels, width, (int)(65f * num), (int)(775f * num), (int)(1455f * num2), (int)(1995f * num2), r3, g3, b3);
ApplyFaceSkinTintRegion(pixels, basePixels, width, (int)(810f * num), (int)(900f * num), (int)(1750f * num2), (int)(2000f * num2), r3, g3, b3);
ApplyFaceSkinTintRegion(pixels, basePixels, width, (int)(1115f * num), (int)(1190f * num), (int)(1325f * num2), (int)(1395f * num2), r3, g3, b3);
ApplyBodySkinTintRegion(pixels, basePixels, width, (int)(260f * num), (int)(680f * num), (int)(60f * num2), (int)(485f * num2), r3, g3, b3);
ApplyBodySkinTintRegion(pixels, basePixels, width, (int)(1530f * num), (int)(2015f * num), (int)(160f * num2), (int)(515f * num2), r3, g3, b3);
}
val.SetPixels32(pixels);
val.Apply(false, false);
((Object)val).name = "Tinted_" + text;
TextureCache[text] = val;
return (Texture)(object)val;
}
private static void ApplyHairTintRegion(Color32[] pixels, Color32[] basePixels, int width, int minX, int maxX, int minY, int maxY, byte tr, byte tg, byte tb)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: 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_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: 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)
minX = Mathf.Clamp(minX, 0, width - 1);
maxX = Mathf.Clamp(maxX, 0, width - 1);
minY = Mathf.Clamp(minY, 0, pixels.Length / width - 1);
maxY = Mathf.Clamp(maxY, 0, pixels.Length / width - 1);
for (int i = minY; i <= maxY; i++)
{
int num = i * width;
for (int j = minX; j <= maxX; j++)
{
int num2 = num + j;
Color32 val = basePixels[num2];
if ((Math.Abs(val.r - val.g) >= 5 || Math.Abs(val.g - val.b) >= 5 || val.r <= 160) && (val.r <= 190 || val.g <= 130) && val.r >= 20 && val.r <= 155 && val.g >= 15 && val.g <= 125 && val.b >= 10 && val.b <= 85)
{
float num3 = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 75f;
Color32 val2 = pixels[num2];
val2.r = (byte)Mathf.Clamp((int)((float)(int)tr * num3), 0, 255);
val2.g = (byte)Mathf.Clamp((int)((float)(int)tg * num3), 0, 255);
val2.b = (byte)Mathf.Clamp((int)((float)(int)tb * num3), 0, 255);
pixels[num2] = val2;
}
}
}
}
private static void ApplyPantsTintRegion(Color32[] pixels, int width, int minX, int maxX, int minY, int maxY, byte tr, byte tg, byte tb)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
minX = Mathf.Clamp(minX, 0, width - 1);
maxX = Mathf.Clamp(maxX, 0, width - 1);
minY = Mathf.Clamp(minY, 0, pixels.Length / width - 1);
maxY = Mathf.Clamp(maxY, 0, pixels.Length / width - 1);
for (int i = minY; i <= maxY; i++)
{
int num = i * width;
for (int j = minX; j <= maxX; j++)
{
int num2 = num + j;
Color32 val = pixels[num2];
if (Math.Abs(val.r - val.g) >= 5 || Math.Abs(val.g - val.b) >= 5 || val.r <= 155)
{
float num3 = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 75f;
val.r = (byte)Mathf.Clamp((int)((float)(int)tr * num3), 0, 255);
val.g = (byte)Mathf.Clamp((int)((float)(int)tg * num3), 0, 255);
val.b = (byte)Mathf.Clamp((int)((float)(int)tb * num3), 0, 255);
pixels[num2] = val;
}
}
}
}
private static void ApplyFaceSkinTintRegion(Color32[] pixels, Color32[] basePixels, int width, int minX, int maxX, int minY, int maxY, byte tr, byte tg, byte tb)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: 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_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
minX = Mathf.Clamp(minX, 0, width - 1);
maxX = Mathf.Clamp(maxX, 0, width - 1);
minY = Mathf.Clamp(minY, 0, pixels.Length / width - 1);
maxY = Mathf.Clamp(maxY, 0, pixels.Length / width - 1);
for (int i = minY; i <= maxY; i++)
{
int num = i * width;
for (int j = minX; j <= maxX; j++)
{
int num2 = num + j;
Color32 val = basePixels[num2];
if ((Math.Abs(val.r - val.g) >= 5 || Math.Abs(val.g - val.b) >= 5 || val.r <= 155) && (val.r <= 240 || val.g <= 240 || val.b <= 240 || Math.Abs(val.r - val.b) >= 15) && (val.r >= 100 || val.g >= 100 || val.b >= 100) && (val.r > 155 || val.g > 125 || val.b > 85) && val.r > 170 && val.g > 115 && val.r >= val.g && val.g >= val.b)
{
float num3 = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 205f;
Color32 val2 = pixels[num2];
val2.r = (byte)Mathf.Clamp((int)((float)(int)tr * num3), 0, 255);
val2.g = (byte)Mathf.Clamp((int)((float)(int)tg * num3), 0, 255);
val2.b = (byte)Mathf.Clamp((int)((float)(int)tb * num3), 0, 255);
pixels[num2] = val2;
}
}
}
}
private static void ApplyBodySkinTintRegion(Color32[] pixels, Color32[] basePixels, int width, int minX, int maxX, int minY, int maxY, byte tr, byte tg, byte tb)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
minX = Mathf.Clamp(minX, 0, width - 1);
maxX = Mathf.Clamp(maxX, 0, width - 1);
minY = Mathf.Clamp(minY, 0, pixels.Length / width - 1);
maxY = Mathf.Clamp(maxY, 0, pixels.Length / width - 1);
for (int i = minY; i <= maxY; i++)
{
int num = i * width;
for (int j = minX; j <= maxX; j++)
{
int num2 = num + j;
Color32 val = basePixels[num2];
if ((Math.Abs(val.r - val.g) >= 6 || Math.Abs(val.g - val.b) >= 6 || val.r <= 155) && val.r > 160 && val.g > 115 && val.b > 75 && val.r >= val.g && val.g >= val.b)
{
float num3 = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 210f;
Color32 val2 = pixels[num2];
val2.r = (byte)Mathf.Clamp((int)((float)(int)tr * num3), 0, 255);
val2.g = (byte)Mathf.Clamp((int)((float)(int)tg * num3), 0, 255);
val2.b = (byte)Mathf.Clamp((int)((float)(int)tb * num3), 0, 255);
pixels[num2] = val2;
}
}
}
}
private static Texture2D MakeReadable(Texture2D source)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
if ((Object)(object)source == (Object)null)
{
return null;
}
RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
Graphics.Blit((Texture)(object)source, temporary);
RenderTexture active = RenderTexture.active;
RenderTexture.active = temporary;
Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, false);
val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
val.Apply(false, false);
RenderTexture.active = active;
RenderTexture.ReleaseTemporary(temporary);
return val;
}
public static void ChangeHair(int delta)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
PlayerController local = PlayerController.Local;
if ((Object)(object)local == (Object)null)
{
return;
}
int num = HairColors.Length;
int num2 = (GetPlayerHair(local) + delta) % num;
if (num2 < 0)
{
num2 += num;
}
SetSavedHair(num2);
int playerPants = GetPlayerPants(local);
int playerSkin = GetPlayerSkin(local);
ApplyAppearanceToPlayer(local, num2, playerPants, playerSkin);
try
{
string text = BuildCustomId(((object)local.PlayerData.ID/*cast due to .constrained prefix*/).ToString(), num2, playerPants, playerSkin);
string text2 = ((object)local.PlayerData.Username/*cast due to .constrained prefix*/).ToString();
NetworkPlayerData val = default(NetworkPlayerData);
((NetworkPlayerData)(ref val))..ctor(text, text2);
Traverse.Create((object)local).Method("Rpc_DefinePlayerData", new object[1] { val }).GetValue();
Plugin.Logger.LogInfo((object)$"Changed and synchronized hair tint to: {HairColors[num2].Name} (Index: {num2})");
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error syncing hair change over network: {arg}");
}
}
public static void ChangePants(int delta)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
PlayerController local = PlayerController.Local;
if ((Object)(object)local == (Object)null)
{
return;
}
int num = PantsColors.Length;
int num2 = (GetPlayerPants(local) + delta) % num;
if (num2 < 0)
{
num2 += num;
}
SetSavedPants(num2);
int playerHair = GetPlayerHair(local);
int playerSkin = GetPlayerSkin(local);
ApplyAppearanceToPlayer(local, playerHair, num2, playerSkin);
try
{
string text = BuildCustomId(((object)local.PlayerData.ID/*cast due to .constrained prefix*/).ToString(), playerHair, num2, playerSkin);
string text2 = ((object)local.PlayerData.Username/*cast due to .constrained prefix*/).ToString();
NetworkPlayerData val = default(NetworkPlayerData);
((NetworkPlayerData)(ref val))..ctor(text, text2);
Traverse.Create((object)local).Method("Rpc_DefinePlayerData", new object[1] { val }).GetValue();
Plugin.Logger.LogInfo((object)$"Changed and synchronized pants color to: {PantsColors[num2].Name} (Index: {num2})");
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error syncing pants change over network: {arg}");
}
}
public static void ChangeSkin(int delta)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
PlayerController local = PlayerController.Local;
if ((Object)(object)local == (Object)null)
{
return;
}
int num = SkinColors.Length;
int num2 = (GetPlayerSkin(local) + delta) % num;
if (num2 < 0)
{
num2 += num;
}
SetSavedSkin(num2);
int playerHair = GetPlayerHair(local);
int playerPants = GetPlayerPants(local);
ApplyAppearanceToPlayer(local, playerHair, playerPants, num2);
try
{
string text = BuildCustomId(((object)local.PlayerData.ID/*cast due to .constrained prefix*/).ToString(), playerHair, playerPants, num2);
string text2 = ((object)local.PlayerData.Username/*cast due to .constrained prefix*/).ToString();
NetworkPlayerData val = default(NetworkPlayerData);
((NetworkPlayerData)(ref val))..ctor(text, text2);
Traverse.Create((object)local).Method("Rpc_DefinePlayerData", new object[1] { val }).GetValue();
Plugin.Logger.LogInfo((object)$"Changed and synchronized skin color to: {SkinColors[num2].Name} (Index: {num2})");
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error syncing skin change over network: {arg}");
}
}
}
public static class HairTintManager
{
public static int GetSavedHair()
{
return AppearanceManager.GetSavedHair();
}
public static void SetSavedHair(int index)
{
AppearanceManager.SetSavedHair(index);
}
public static int GetHairCount()
{
return AppearanceManager.GetHairCount();
}
public static HairColorInfo GetHairInfo(int index)
{
return AppearanceManager.GetHairInfo(index);
}
public static int ExtractHair(string id)
{
return AppearanceManager.ExtractHair(id);
}
public static string RemoveHairTag(string id)
{
return AppearanceManager.CleanAppearanceTags(id);
}
public static string BuildCustomIdWithHair(string currentId, int hairIndex)
{
return AppearanceManager.BuildCustomId(currentId, hairIndex, AppearanceManager.GetSavedPants(), AppearanceManager.GetSavedSkin());
}
public static int GetPlayerHair(PlayerController player)
{
return AppearanceManager.GetPlayerHair(player);
}
public static void ApplyHairToPlayer(PlayerController player, int hairIndex)
{
AppearanceManager.ApplyAppearanceToPlayer(player, hairIndex, AppearanceManager.GetPlayerPants(player), AppearanceManager.GetPlayerSkin(player));
}
public static Texture GetTintedTexture(Texture baseTexture, int outfitIndex, int hairIndex)
{
return AppearanceManager.GetTintedTexture(baseTexture, outfitIndex, hairIndex, 0, 0);
}
public static void ChangeHair(int delta)
{
AppearanceManager.ChangeHair(delta);
}
}
public static class CustomizerHUD
{
private static GameObject _hudRoot;
private static TextMeshProUGUI _hudText;
private static Image _hudBg;
public static void EnsureInitialized(GameUI gameUI)
{
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Expected O, but got Unknown
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
//IL_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_hudRoot != (Object)null || (Object)(object)gameUI == (Object)null)
{
return;
}
try
{
TextMeshProUGUI value = Traverse.Create((object)gameUI).Field<TextMeshProUGUI>("pgmShortcutSkinText").Value;
if ((Object)(object)value == (Object)null)
{
return;
}
Transform val = ((Component)gameUI).transform.Find("Canvas");
if ((Object)(object)val == (Object)null)
{
Canvas componentInChildren = ((Component)gameUI).GetComponentInChildren<Canvas>(true);
if ((Object)(object)componentInChildren != (Object)null)
{
val = ((Component)componentInChildren).transform;
}
}
if ((Object)(object)val == (Object)null && (Object)(object)value != (Object)null)
{
val = ((TMP_Text)value).transform.parent;
}
if ((Object)(object)val == (Object)null)
{
val = ((Component)gameUI).transform;
}
_hudRoot = new GameObject("LycansColorCustomizerHUD", new Type[1] { typeof(RectTransform) });
_hudRoot.transform.SetParent(val, false);
_hudRoot.transform.SetAsLastSibling();
RectTransform component = _hudRoot.GetComponent<RectTransform>();
component.anchorMin = new Vector2(1f, 0.5f);
component.anchorMax = new Vector2(1f, 0.5f);
component.pivot = new Vector2(1f, 0.5f);
component.anchoredPosition = new Vector2(-40f, 0f);
component.sizeDelta = new Vector2(460f, 240f);
GameObject val2 = new GameObject("Background", new Type[3]
{
typeof(RectTransform),
typeof(CanvasRenderer),
typeof(Image)
});
val2.transform.SetParent(_hudRoot.transform, false);
RectTransform component2 = val2.GetComponent<RectTransform>();
component2.anchorMin = Vector2.zero;
component2.anchorMax = Vector2.one;
component2.sizeDelta = Vector2.zero;
component2.anchoredPosition = Vector2.zero;
_hudBg = val2.GetComponent<Image>();
((Graphic)_hudBg).color = new Color(0.04f, 0.05f, 0.08f, 0.85f);
GameObject val3 = Object.Instantiate<GameObject>(((Component)value).gameObject, _hudRoot.transform);
((Object)val3).name = "HUDText";
Component[] components = val3.GetComponents<Component>();
foreach (Component val4 in components)
{
if ((Object)(object)val4 != (Object)null && !(val4 is Transform) && !(val4 is RectTransform) && !(val4 is CanvasRenderer) && !(val4 is TextMeshProUGUI))
{
Object.Destroy((Object)(object)val4);
}
}
RectTransform component3 = val3.GetComponent<RectTransform>();
component3.anchorMin = Vector2.zero;
component3.anchorMax = Vector2.one;
component3.offsetMin = new Vector2(22f, 16f);
component3.offsetMax = new Vector2(-22f, -16f);
component3.anchoredPosition = Vector2.zero;
_hudText = val3.GetComponent<TextMeshProUGUI>();
if ((Object)(object)_hudText != (Object)null)
{
((Behaviour)_hudText).enabled = true;
((TMP_Text)_hudText).fontSize = 20f;
((TMP_Text)_hudText).alignment = (TextAlignmentOptions)257;
((TMP_Text)_hudText).richText = true;
((TMP_Text)_hudText).enableWordWrapping = true;
}
_hudRoot.SetActive(false);
Plugin.Logger.LogInfo((object)"CustomizerHUD successfully created on native GameUI Canvas!");
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error initializing CustomizerHUD: {arg}");
}
}
public static void SetVisible(bool visible, GameUI gameUI = null)
{
if ((Object)(object)_hudRoot == (Object)null && visible)
{
if ((Object)(object)gameUI == (Object)null && (Object)(object)GameManager.Instance != (Object)null)
{
gameUI = GameManager.Instance.gameUI;
}
EnsureInitialized(gameUI);
}
if ((Object)(object)_hudRoot != (Object)null)
{
_hudRoot.SetActive(visible);
if (visible)
{
UpdateText();
}
}
}
public static void UpdateText()
{
if ((Object)(object)_hudRoot == (Object)null || !_hudRoot.activeSelf || (Object)(object)_hudText == (Object)null)
{
return;
}
try
{
PlayerController local = PlayerController.Local;
int playerHair = AppearanceManager.GetPlayerHair(local);
int hairCount = AppearanceManager.GetHairCount();
HairColorInfo hairInfo = AppearanceManager.GetHairInfo(playerHair);
int playerPants = AppearanceManager.GetPlayerPants(local);
int pantsCount = AppearanceManager.GetPantsCount();
PantsColorInfo pantsInfo = AppearanceManager.GetPantsInfo(playerPants);
int playerSkin = AppearanceManager.GetPlayerSkin(local);
int skinCount = AppearanceManager.GetSkinCount();
SkinColorInfo skinInfo = AppearanceManager.GetSkinInfo(playerSkin);
CustomizerCategory currentCategory = AppearanceManager.CurrentCategory;
string text = ((currentCategory == CustomizerCategory.Hair) ? "<color=#FFFF00>▶ </color>" : " ");
string text2 = ((currentCategory == CustomizerCategory.Pants) ? "<color=#FFFF00>▶ </color>" : " ");
string text3 = ((currentCategory == CustomizerCategory.Skin) ? "<color=#FFFF00>▶ </color>" : " ");
string text4 = "<b><size=22><color=#FFFFFF>CHARACTER CUSTOMIZATION</color></size></b>\n" + $"<size=15><color=#DDDDDD>[C] Mode: <color=#FFFF00>{currentCategory}</color> | [X] Loop Color</color></size>\n\n" + $"{text}<b>Hair [{playerHair + 1}/{hairCount}]:</b> <color=#{hairInfo.HexColor}>{hairInfo.Name}</color>\n" + $"{text2}<b>Pants [{playerPants + 1}/{pantsCount}]:</b> <color=#{pantsInfo.HexColor}>{pantsInfo.Name}</color>\n" + $"{text3}<b>Skin [{playerSkin + 1}/{skinCount}]:</b> <color=#{skinInfo.HexColor}>{skinInfo.Name}</color>";
((TMP_Text)_hudText).text = text4;
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error updating CustomizerHUD text: {arg}");
}
}
}
[BepInPlugin("com.dev.lycanscolorcustomizer", "Lycans Color Customizer", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
public static Plugin Instance { get; private set; }
private void Awake()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
Instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Lycans Color Customizer v1.1.0 is initializing...");
try
{
Harmony val = new Harmony("com.dev.lycanscolorcustomizer");
val.PatchAll();
TryHookLycansNewRoles(val);
Logger.LogInfo((object)"Harmony patches applied successfully!");
}
catch (Exception arg)
{
Logger.LogError((object)$"Failed to apply Harmony patches: {arg}");
}
}
private void TryHookLycansNewRoles(Harmony harmony)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Expected O, but got Unknown
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
try
{
Type type = AccessTools.TypeByName("LycansNewRoles.PlayerCustom");
if (type != null)
{
MethodInfo methodInfo = AccessTools.Method(type, "UpdateColor", (Type[])null, (Type[])null);
if (methodInfo != null)
{
MethodInfo methodInfo2 = AccessTools.Method(typeof(PlayerControllerPatch), "OnLycansNewRolesUpdateColor", (Type[])null, (Type[])null);
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)"Successfully hooked LycansNewRoles.PlayerCustom.UpdateColor for seamless co-existence!");
}
}
Type type2 = AccessTools.TypeByName("LycansNewRoles.UICustomizationComponent");
if (type2 != null)
{
MethodInfo methodInfo3 = AccessTools.Method(type2, "Show", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(LycansNewRolesPatch), "OnCustomizationShow", (Type[])null, (Type[])null));
harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
MethodInfo methodInfo4 = AccessTools.Method(type2, "Hide", (Type[])null, (Type[])null);
if (methodInfo4 != null)
{
HarmonyMethod val2 = new HarmonyMethod(AccessTools.Method(typeof(LycansNewRolesPatch), "OnCustomizationHide", (Type[])null, (Type[])null));
harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
Logger.LogInfo((object)"Successfully hooked LycansNewRoles.UICustomizationComponent (Show/Hide) for mirror HUD sync!");
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("LycansNewRoles inter-mod check: " + ex.Message));
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.dev.lycanscolorcustomizer";
public const string PLUGIN_NAME = "Lycans Color Customizer";
public const string PLUGIN_VERSION = "1.1.0";
}
}
namespace LycansColorCustomizer.Patches
{
[HarmonyPatch(typeof(GameUI))]
public static class GameUIPatch
{
public static bool IsShortcutSkinActive { get; private set; }
[HarmonyPatch("ShowPregameShortcutSkin")]
[HarmonyPostfix]
public static void ShowPregameShortcutSkin_Postfix(GameUI __instance, bool active)
{
IsShortcutSkinActive = active;
CustomizerHUD.SetVisible(active, __instance);
if (active)
{
UpdateShortcutText(__instance);
}
}
public static void UpdateShortcutText(GameUI ui = null)
{
if ((Object)(object)ui == (Object)null)
{
if ((Object)(object)GameManager.Instance == (Object)null || (Object)(object)GameManager.Instance.gameUI == (Object)null)
{
return;
}
ui = GameManager.Instance.gameUI;
}
try
{
TextMeshProUGUI value = Traverse.Create((object)ui).Field<TextMeshProUGUI>("pgmShortcutSkinText").Value;
if ((Object)(object)value != (Object)null)
{
CustomizerCategory currentCategory = AppearanceManager.CurrentCategory;
((TMP_Text)value).text = "[Left Click / Right Click] Change Hat\n" + $"[C] Mode: <color=#FFFF00>{currentCategory}</color> | [X] Loop Color";
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in UpdateShortcutText: {arg}");
}
CustomizerHUD.UpdateText();
}
}
public static class LycansNewRolesPatch
{
public static void OnCustomizationShow()
{
try
{
CustomizerHUD.SetVisible(visible: true);
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in OnCustomizationShow: {arg}");
}
}
public static void OnCustomizationHide()
{
try
{
CustomizerHUD.SetVisible(visible: false);
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in OnCustomizationHide: {arg}");
}
}
}
[HarmonyPatch(typeof(PlayerController))]
public static class PlayerControllerPatch
{
[HarmonyPatch("Rpc_DefinePlayerData")]
[HarmonyPrefix]
public static void Rpc_DefinePlayerData_Prefix(PlayerController __instance, ref NetworkPlayerData networkPlayerData)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
try
{
if (((SimulationBehaviour)__instance).HasInputAuthority)
{
string text = ((object)networkPlayerData.ID/*cast due to .constrained prefix*/).ToString();
if (!text.Contains("#hair=") || !text.Contains("#pants=") || !text.Contains("#skin="))
{
int savedHair = AppearanceManager.GetSavedHair();
int savedPants = AppearanceManager.GetSavedPants();
int savedSkin = AppearanceManager.GetSavedSkin();
string text2 = AppearanceManager.BuildCustomId(text, savedHair, savedPants, savedSkin);
networkPlayerData = new NetworkPlayerData(text2, ((object)networkPlayerData.Username/*cast due to .constrained prefix*/).ToString());
Plugin.Logger.LogInfo((object)$"Injected custom appearance: Hair #{savedHair}, Pants #{savedPants}, Skin #{savedSkin} into PlayerData ID: {text2}");
}
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in Rpc_DefinePlayerData_Prefix: {arg}");
}
}
[HarmonyPatch("OnPlayerDataChanged")]
[HarmonyPostfix]
[HarmonyPriority(0)]
public static void OnPlayerDataChanged_Postfix(Changed<PlayerController> changed)
{
try
{
PlayerController behaviour = changed.Behaviour;
if (!((Object)(object)behaviour == (Object)null))
{
int playerHair = AppearanceManager.GetPlayerHair(behaviour);
int playerPants = AppearanceManager.GetPlayerPants(behaviour);
int playerSkin = AppearanceManager.GetPlayerSkin(behaviour);
AppearanceManager.ApplyAppearanceToPlayer(behaviour, playerHair, playerPants, playerSkin);
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in OnPlayerDataChanged_Postfix: {arg}");
}
}
[HarmonyPatch("UpdateModel")]
[HarmonyPostfix]
[HarmonyPriority(0)]
public static void UpdateModel_Postfix(PlayerController __instance, bool isWolf)
{
try
{
if (!isWolf)
{
int playerHair = AppearanceManager.GetPlayerHair(__instance);
int playerPants = AppearanceManager.GetPlayerPants(__instance);
int playerSkin = AppearanceManager.GetPlayerSkin(__instance);
AppearanceManager.ApplyAppearanceToPlayer(__instance, playerHair, playerPants, playerSkin);
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in UpdateModel_Postfix: {arg}");
}
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
public static void Update_Postfix(PlayerController __instance)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
try
{
if (((SimulationBehaviour)__instance).HasInputAuthority && (int)GameManager.LocalGameState == 1 && !((Object)(object)GameManager.Instance == (Object)null) && !((Object)(object)GameManager.Instance.gameUI == (Object)null) && !GameManager.Instance.gameUI.IsGameSettingMenuOpen && !GameManager.Instance.gameUI.IsSettingMenuOpen && (PreviewCameraPatch.IsMirrorActive || GameUIPatch.IsShortcutSkinActive))
{
if (Input.GetKeyDown((KeyCode)99))
{
AppearanceManager.CycleCategory();
GameUIPatch.UpdateShortcutText(GameManager.Instance.gameUI);
}
else if (Input.GetKeyDown((KeyCode)120) || Input.GetKeyDown((KeyCode)98))
{
AppearanceManager.CycleCurrentValue();
GameUIPatch.UpdateShortcutText(GameManager.Instance.gameUI);
}
else if (Input.mouseScrollDelta.y > 0.1f)
{
AppearanceManager.CycleCurrentValue();
GameUIPatch.UpdateShortcutText(GameManager.Instance.gameUI);
}
else if (Input.mouseScrollDelta.y < -0.1f)
{
AppearanceManager.CycleCurrentValue(-1);
GameUIPatch.UpdateShortcutText(GameManager.Instance.gameUI);
}
else if (Input.GetKeyDown((KeyCode)104))
{
AppearanceManager.SetCategory(CustomizerCategory.Hair);
AppearanceManager.ChangeHair(1);
GameUIPatch.UpdateShortcutText(GameManager.Instance.gameUI);
}
else if (Input.GetKeyDown((KeyCode)112))
{
AppearanceManager.SetCategory(CustomizerCategory.Pants);
AppearanceManager.ChangePants(1);
GameUIPatch.UpdateShortcutText(GameManager.Instance.gameUI);
}
else if (Input.GetKeyDown((KeyCode)107))
{
AppearanceManager.SetCategory(CustomizerCategory.Skin);
AppearanceManager.ChangeSkin(1);
GameUIPatch.UpdateShortcutText(GameManager.Instance.gameUI);
}
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in PlayerController.Update hook: {arg}");
}
}
public static void OnLycansNewRolesUpdateColor(object __instance)
{
try
{
PlayerController value = Traverse.Create(__instance).Property<PlayerController>("PlayerController", (object[])null).Value;
if ((Object)(object)value != (Object)null)
{
int playerHair = AppearanceManager.GetPlayerHair(value);
int playerPants = AppearanceManager.GetPlayerPants(value);
int playerSkin = AppearanceManager.GetPlayerSkin(value);
AppearanceManager.ApplyAppearanceToPlayer(value, playerHair, playerPants, playerSkin);
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Error in OnLycansNewRolesUpdateColor: {arg}");
}
}
}
[HarmonyPatch(typeof(PreviewCamera))]
public static class PreviewCameraPatch
{
private static bool _mirrorExplicitlyActive;
public static PreviewCamera CurrentInstance { get; private set; }
public static bool IsMirrorActive
{
get
{
if ((!((Object)(object)CurrentInstance != (Object)null) || !CurrentInstance.IsPreviewCameraActive) && !_mirrorExplicitlyActive)
{
return GameUIPatch.IsShortcutSkinActive;
}
return true;
}
}
[HarmonyPatch("Awake")]
[HarmonyPostfix]
public static void Awake_Postfix(PreviewCamera __instance)
{
CurrentInstance = __instance;
}
[HarmonyPatch("DisplayPreviewCamera")]
[HarmonyPostfix]
public static void DisplayPreviewCamera_Postfix(PreviewCamera __instance, bool active)
{
CurrentInstance = __instance;
_mirrorExplicitlyActive = active;
if (active)
{
GameUIPatch.UpdateShortcutText();
}
}
[HarmonyPatch("DisableCamera")]
[HarmonyPostfix]
public static void DisableCamera_Postfix()
{
_mirrorExplicitlyActive = false;
CustomizerHUD.SetVisible(visible: false);
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
public static void Update_Postfix(PreviewCamera __instance)
{
CurrentInstance = __instance;
}
}
}