using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using Zorro.Core;
using Zorro.Core.Serizalization;
[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("BobaHats")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+13bde32de102c984b19d0f35157b9132f071e3c0")]
[assembly: AssemblyProduct("BobaHats")]
[assembly: AssemblyTitle("BobaHats")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 BobaHats
{
internal static class BobaHatsPatches
{
private const int Spacer1 = -1535012113;
private const int Spacer2 = 1512782925;
private static ManualLogSource Logger => Plugin.Instance.Logger;
[HarmonyPatch(typeof(SyncPersistentPlayerDataPackage), "SerializeData")]
[HarmonyPostfix]
public static void SyncPersistentPlayerDataPackageSerializeData(SyncPersistentPlayerDataPackage __instance, BinarySerializer binarySerializer)
{
binarySerializer.WriteInt(0);
binarySerializer.WriteInt(-1535012113);
binarySerializer.WriteInt(1512782925);
PersistentPlayerDataService service = GameHandler.GetService<PersistentPlayerDataService>();
if (service == null)
{
Logger.LogError((object)"PersistentPlayerDataService is null, cannot set hat.");
return;
}
int actorNumber = __instance.ActorNumber;
PersistentPlayerData playerData = service.GetPlayerData(actorNumber);
Player val = default(Player);
if (playerData == null && PhotonNetwork.TryGetPlayer(actorNumber, ref val))
{
playerData = service.GetPlayerData(val);
}
if (playerData == null)
{
Logger.LogError((object)$"Player data for actor number {actorNumber} is null, cannot set hat.");
return;
}
Customization customizationSingleton = Plugin.GetCustomizationSingleton();
if ((Object)(object)customizationSingleton == (Object)null)
{
Logger.LogError((object)"Customization component not instantiated yet!");
return;
}
CustomizationOption[] hats = customizationSingleton.hats;
if (hats == null)
{
Logger.LogError((object)"No hats found in character customization, cannot set hat.");
return;
}
int currentHat = playerData.customizationData.currentHat;
if (currentHat < 0 || currentHat >= hats.Length)
{
Logger.LogWarning((object)$"Invalid hat index {currentHat} for player #{actorNumber}, custom hats may not be loaded yet!");
Plugin.BroadcastPluginEvent("OnLoadHats");
}
hats = customizationSingleton.hats;
if (currentHat < 0 || currentHat >= hats.Length)
{
Logger.LogError((object)$"Invalid hat index {currentHat} for player #{actorNumber}, custom hat may be missing!");
return;
}
CustomizationOption obj = hats[currentHat];
string text = ((obj != null) ? ((Object)obj).name : null) ?? "";
string text2 = JsonConvert.SerializeObject((object)new
{
hat = text
}, (Formatting)0);
binarySerializer.WriteString(text2, Encoding.UTF8);
Logger.LogDebug((object)$"Serialized hat for player #{actorNumber}: '{text}'");
}
[HarmonyPatch(typeof(SyncPersistentPlayerDataPackage), "DeserializeData")]
[HarmonyPostfix]
public static void SyncPersistentPlayerDataPackageDeserializeData(SyncPersistentPlayerDataPackage __instance, BinaryDeserializer binaryDeserializer)
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
if (binaryDeserializer.ReadInt() != 0)
{
Logger.LogError((object)"Missing 1st spacer trailer in SyncPersistentPlayerDataPackage.DeserializeData.");
return;
}
if (binaryDeserializer.ReadInt() != -1535012113)
{
Logger.LogError((object)"Missing 1st spacer trailer in SyncPersistentPlayerDataPackage.DeserializeData.");
return;
}
if (binaryDeserializer.ReadInt() != 1512782925)
{
Logger.LogError((object)"Missing 2nd spacer trailer in SyncPersistentPlayerDataPackage.DeserializeData.");
return;
}
try
{
using StringReader stringReader = new StringReader(binaryDeserializer.ReadString(Encoding.UTF8));
JsonTextReader val = new JsonTextReader((TextReader)stringReader);
try
{
JObject val2 = (JObject)JToken.ReadFrom((JsonReader)(object)val);
string name = ((object)val2["hat"])?.ToString() ?? string.Empty;
if (string.IsNullOrEmpty(name))
{
Logger.LogError((object)"Hat name is null or empty, cannot set hat.");
return;
}
Logger.LogDebug((object)$"Attempting to deserialize hat for player #{__instance.ActorNumber} to '{name}'");
Customization customizationSingleton = Plugin.GetCustomizationSingleton();
if ((Object)(object)customizationSingleton == (Object)null)
{
Logger.LogError((object)"Customization component not instantiated yet!");
return;
}
CustomizationOption[] hats = customizationSingleton.hats;
if (hats == null)
{
Logger.LogError((object)"No hats found in character customization, cannot set hat.");
return;
}
int num = Array.FindIndex(hats, (CustomizationOption hat) => ((Object)hat).name == name);
if (num >= 0)
{
__instance.Data.customizationData.currentHat = num;
Logger.LogDebug((object)$"Deserialized hat for player #{__instance.ActorNumber} from '{name}' to #{num}");
}
else
{
Logger.LogError((object)$"Hat '{name}' not found in customization hats, cannot set hat for player #{__instance.ActorNumber}");
}
}
finally
{
((IDisposable)val)?.Dispose();
}
}
catch (Exception ex)
{
Logger.LogError((object)$"Failed to deserialize hat for player #{__instance.ActorNumber} from JSON: {ex.Message}\n{ex.StackTrace}");
}
}
[HarmonyPatch(typeof(PersistentPlayerDataService), "OnSyncReceived")]
[HarmonyFinalizer]
public static Exception? PersistentPlayerDataServiceOnSyncReceivedFinalizer(PersistentPlayerDataService __instance, SyncPersistentPlayerDataPackage package, Exception? __exception)
{
if (__exception != null)
{
Logger.LogWarning((object)("PersistentPlayerDataService.OnSyncReceived threw an exception\n" + __exception.GetType().FullName + ": " + __exception.Message + "\n" + __exception.StackTrace));
}
return null;
}
[HarmonyPatch(typeof(CharacterCustomization), "OnPlayerDataChange")]
[HarmonyPostfix]
public static void CharacterCustomizationOnPlayerDataChangePostfix(CharacterCustomization __instance, PersistentPlayerData playerData)
{
Logger.LogDebug((object)$"CharacterCustomization.OnPlayerDataChange called with hat index {playerData.customizationData.currentHat}");
Plugin.BroadcastPluginEvent("OnAddHatsForCharacter", __instance._character);
}
[HarmonyPatch(typeof(CharacterCustomization), "OnPlayerDataChange")]
[HarmonyFinalizer]
public static Exception? CharacterCustomizationOnPlayerDataChangeFinalizer(CharacterCustomization __instance, Exception? __exception, PersistentPlayerData playerData)
{
if (__exception == null)
{
return null;
}
Logger.LogWarning((object)("CharacterCustomization.OnPlayerDataChange threw an exception\n" + __exception.GetType().FullName + ": " + __exception.Message + "\n" + __exception.StackTrace));
return null;
}
[HarmonyPatch(typeof(PersistentPlayerDataService), "OnSyncReceived")]
[HarmonyPostfix]
public static void PersistentPlayerDataServiceOnSyncReceivedPostfix(PersistentPlayerDataService __instance, SyncPersistentPlayerDataPackage package)
{
Logger.LogDebug((object)"PersistentPlayerDataService.OnSyncReceived");
}
[HarmonyPatch(typeof(PersistentPlayerDataService), "SetPlayerData")]
[HarmonyPostfix]
public static void PersistentPlayerDataServiceSetPlayerDataPostfix(PersistentPlayerDataService __instance, Player player, PersistentPlayerData playerData)
{
Logger.LogDebug((object)"PersistentPlayerDataService.SetPlayerData");
}
[HarmonyPatch(typeof(PersistentPlayerDataService), "GetPlayerData", new Type[] { typeof(Player) })]
[HarmonyPrefix]
public static void PersistentPlayerDataServiceGetPlayerDataPrefix(PersistentPlayerDataService __instance, Player player)
{
Logger.LogDebug((object)"PersistentPlayerDataService.SetPlayerData(Player)");
}
[HarmonyPatch(typeof(PersistentPlayerDataService), "GetPlayerData", new Type[] { typeof(int) })]
[HarmonyPrefix]
public static void PersistentPlayerDataServiceGetPlayerDataPrefix(PersistentPlayerDataService __instance, int actorNumber)
{
Logger.LogDebug((object)"PersistentPlayerDataService.SetPlayerData(int)");
}
[HarmonyPatch(typeof(CharacterCustomization), "OnPlayerDataChange")]
[HarmonyPrefix]
public static void CharacterCustomizationOnPlayerDataChangePrefix(CharacterCustomization __instance, PersistentPlayerData playerData)
{
Logger.LogDebug((object)"CharacterCustomization.OnPlayerDataChange(int)");
int currentHat = playerData.customizationData.currentHat;
Renderer[] playerHats = __instance.refs.playerHats;
if (playerHats != null && playerHats.Length != 0)
{
for (int i = 0; i < playerHats.Length; i++)
{
((Component)playerHats[i]).gameObject.SetActive(i == currentHat);
}
}
}
[HarmonyPatch(typeof(CharacterCustomization), "SetCustomizationForRef")]
[HarmonyPrefix]
public static void CharacterCustomizationSetCustomizationForRefPrefix(CustomizationRefs refs)
{
Logger.LogDebug((object)"CharacterCustomization.SetCustomizationForRef");
}
[HarmonyPatch(typeof(Character), "Awake")]
[HarmonyPostfix]
public static void CharacterAwakePostfix(Character __instance)
{
Plugin.BroadcastPluginEvent("OnAddHatsForCharacter", __instance);
}
[HarmonyPatch(typeof(Character), "Start")]
[HarmonyPostfix]
public static void CharacterStartPostfix(Character __instance)
{
Plugin.BroadcastPluginEvent("OnAddHatsForCharacter", __instance);
}
[HarmonyPatch(typeof(PlayerHandler), "RegisterCharacter")]
[HarmonyPostfix]
public static void PlayerHandlerRegisterCharacterPostfix(PlayerHandler __instance, Character character)
{
if ((Object)(object)character == (Object)null)
{
Logger.LogError((object)"PlayerHandler.RegisterCharacter called with null character, cannot add hats.");
return;
}
Logger.LogDebug((object)$"PlayerHandler.RegisterCharacter called for {character.characterName} ({((MonoBehaviourPun)character).photonView.ViewID})");
Plugin.BroadcastPluginEvent("OnAddHatsForCharacter", character);
}
[HarmonyPatch(typeof(CharacterCustomization), "Start")]
[HarmonyPrefix]
public static void CharacterCustomizationStartPrefix(CharacterCustomization __instance)
{
Logger.LogDebug((object)"CharacterCustomization.Start called");
Plugin.BroadcastPluginEvent("OnLoadHats");
Character character = __instance._character;
if (!((Object)(object)character == (Object)null))
{
Plugin.BroadcastPluginEvent("OnAddHatsForCharacter", character);
}
}
[HarmonyPatch(typeof(PlayerCustomizationDummy), "UpdateDummy")]
[HarmonyPrefix]
public static void PlayerCustomizationDummyUpdateDummyPrefix(PlayerCustomizationDummy __instance)
{
Logger.LogDebug((object)"PlayerCustomizationDummy.UpdateDummy patch called");
FixPlayerCustomizationData(__instance);
}
private static void FixPlayerCustomizationData(PlayerCustomizationDummy customizationDummy)
{
try
{
Plugin.BroadcastPluginEvent("OnLoadHats");
Character localCharacter = Character.localCharacter;
if ((Object)(object)localCharacter != (Object)null)
{
Plugin.BroadcastPluginEvent("OnAddHatsForCharacter", localCharacter);
}
PersistentPlayerDataService service = GameHandler.GetService<PersistentPlayerDataService>();
bool flag = false;
Customization customizationSingleton = Plugin.GetCustomizationSingleton();
if ((Object)(object)customizationSingleton != (Object)null)
{
PersistentPlayerData playerData = service.GetPlayerData(PhotonNetwork.LocalPlayer);
CharacterCustomizationData customizationData = playerData.customizationData;
if (customizationData.currentSkin < 0 || customizationData.currentSkin > customizationSingleton.skins.Length)
{
customizationData.currentSkin = 0;
flag = true;
}
if (customizationData.currentOutfit < 0 || customizationData.currentOutfit > customizationSingleton.fits.Length)
{
customizationData.currentOutfit = 0;
flag = true;
}
if (customizationData.currentHat < 0 || customizationData.currentHat > customizationSingleton.hats.Length)
{
customizationData.currentHat = 0;
flag = true;
}
if (customizationData.currentEyes < 0 || customizationData.currentEyes > customizationSingleton.eyes.Length)
{
customizationData.currentEyes = 0;
flag = true;
}
if (customizationData.currentAccessory < 0 || customizationData.currentAccessory > customizationSingleton.accessories.Length)
{
customizationData.currentAccessory = 0;
flag = true;
}
if (customizationData.currentMouth < 0 || customizationData.currentMouth > customizationSingleton.mouths.Length)
{
customizationData.currentMouth = 0;
flag = true;
}
if (flag)
{
service.SetPlayerData(PhotonNetwork.LocalPlayer, playerData);
}
}
}
catch (Exception ex)
{
Logger.LogError((object)("PlayerCustomizationDummy.UpdateDummy patch threw an exception\n" + ex.GetType().FullName + "\n" + ex.Message + "\n" + ex.StackTrace));
}
}
[HarmonyPatch(typeof(PlayerCustomizationDummy), "UpdateDummy")]
[HarmonyFinalizer]
public static Exception? PlayerCustomizationDummyUpdateDummyFinalizer(PlayerCustomizationDummy __instance, Exception? __exception)
{
if (__exception == null)
{
return null;
}
if (__exception is IndexOutOfRangeException)
{
Logger.LogWarning((object)("PlayerCustomizationDummy.UpdateDummy threw an exception\n" + __exception.GetType().FullName + ": " + __exception.Message + "\n" + __exception.StackTrace));
return null;
}
return __exception;
}
}
[BepInPlugin("BobaHats", "BobaHats", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <LoadHatsFromBundle>d__14 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public Plugin <>4__this;
private AssetBundleCreateRequest <createRequest>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadHatsFromBundle>d__14(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<createRequest>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_026b: Unknown result type (might be due to invalid IL or missing references)
//IL_025f: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Expected O, but got Unknown
int num = <>1__state;
Plugin plugin = <>4__this;
bool flag;
switch (num)
{
default:
return false;
case 0:
{
<>1__state = -1;
plugin.Logger.LogInfo((object)"Loading hats from bundle.");
string text = Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().Location).LocalPath), "bobacustomhats");
if (!File.Exists(text))
{
plugin.Logger.LogError((object)("AssetBundle not found at " + text + ". Please ensure the file exists."));
return false;
}
plugin.Logger.LogDebug((object)("Path to AssetBundle: " + text));
<createRequest>5__2 = AssetBundle.LoadFromFileAsync(text);
<>2__current = <createRequest>5__2;
<>1__state = 1;
return true;
}
case 1:
{
<>1__state = -1;
AssetBundle assetBundle = <createRequest>5__2.assetBundle;
plugin.Logger.LogInfo((object)"AssetBundle loaded.");
assetBundle.GetAllAssetNames();
Object[] array = assetBundle.LoadAllAssets();
Object[] array2 = array;
foreach (Object val in array2)
{
plugin.Logger.LogDebug((object)$"Asset: {val.name} ({((object)val).GetType()})");
}
plugin.Hats = (from x in array
where (x is GameObject || x is Texture2D) ? true : false
group x by x.name into x
where x.Count() == 2
select new Hat(x.Key, x.OfType<GameObject>().First(), x.OfType<Texture2D>().First())).ToArray();
plugin.HatNames = new HashSet<string>(plugin.Hats.Select((Hat h) => h.Name));
plugin.Logger.LogInfo((object)$"AssetBundle contains {plugin.Hats.Length} hats.");
goto IL_021b;
}
case 2:
{
<>1__state = -1;
if (Application.exitCancellationToken.IsCancellationRequested)
{
return false;
}
goto IL_021b;
}
IL_021b:
flag = false;
try
{
plugin.OnLoadHats();
}
catch (Exception ex)
{
plugin.Logger.LogError((object)("Failed to load hats: " + ex.Message + "\n" + ex.StackTrace));
flag = true;
}
<>2__current = (object)(flag ? new WaitForSecondsRealtime(12f) : new WaitForSecondsRealtime(3f));
<>1__state = 2;
return true;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static readonly Lazy<Shader> LazyCharacterShader = new Lazy<Shader>((Func<Shader>)(() => Shader.Find("W/Character")));
[NonSerialized]
public Hat[]? Hats;
[NonSerialized]
public HashSet<string>? HatNames;
[NonSerialized]
public bool HatsInserted;
private const int HatInsertIndex = 23;
public static Shader CharacterShader => LazyCharacterShader.Value;
internal ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;
public static Plugin? Instance { get; private set; }
public void Awake()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Logger.LogInfo((object)"Plugin v1.0.0 is starting up.");
new Harmony("BobaHats").PatchAll(typeof(BobaHatsPatches));
((MonoBehaviour)this).StartCoroutine(LoadHatsFromBundle());
}
[IteratorStateMachine(typeof(<LoadHatsFromBundle>d__14))]
private IEnumerator LoadHatsFromBundle()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadHatsFromBundle>d__14(0)
{
<>4__this = this
};
}
internal static Customization? GetCustomizationSingleton()
{
return Singleton<Customization>.Instance;
}
internal static Character? GetCharacterByActorNumber(int actorNumber)
{
return ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)((Character ch) => (Object)(object)((MonoBehaviourPun)ch).photonView != (Object)null && ((MonoBehaviourPun)ch).photonView.Owner != null && ((MonoBehaviourPun)ch).photonView.Owner.ActorNumber == actorNumber));
}
internal static Character? GetLocalCharacter()
{
return Character.localCharacter ?? GetCharacterByActorNumber(PhotonNetwork.LocalPlayer.ActorNumber);
}
public void OnLoadHats()
{
Plugin instance = Instance;
if ((Object)(object)instance == (Object)null)
{
Logger.LogError((object)"Plugin instance not loaded yet, cannot instantiate hats!");
return;
}
if (instance.Hats == null || instance.Hats.Length == 0 || HatNames == null || HatNames.Count == 0)
{
Logger.LogError((object)"No hats loaded, skipping instantiation!");
return;
}
Customization customizationSingleton = GetCustomizationSingleton();
if ((Object)(object)customizationSingleton == (Object)null)
{
Logger.LogError((object)"Customization component not instantiated yet!");
return;
}
if (customizationSingleton.hats == null || customizationSingleton.hats.Length == 0)
{
Logger.LogError((object)"CustomizationOptions.hats is not populated yet, not adding hats!");
return;
}
if (!customizationSingleton.hats.Skip(23).Any((CustomizationOption x) => HatNames.Contains(((Object)x).name)))
{
Logger.LogDebug((object)"Adding hat CustomizationOptions.");
List<CustomizationOption> list = new List<CustomizationOption>(instance.Hats.Length);
Hat[] hats = instance.Hats;
for (int i = 0; i < hats.Length; i++)
{
Hat hat = hats[i];
CustomizationOption val = CreateHatOption(hat.Name, hat.Icon);
if ((Object)(object)val == (Object)null)
{
Logger.LogError((object)("Failed to create CustomizationOption for hat '" + hat.Name + "'."));
}
else
{
list.Add(val);
}
}
HatsInserted = true;
ArrayInsert(ref customizationSingleton.hats, 23, list);
Logger.LogDebug((object)"Completed adding hats to Customization Options.");
}
PlayerCustomizationDummy dummy = PassportManager.instance.dummy;
Transform val2 = TransformExtensions.FindChildRecursive(((Component)dummy).transform, "Hat");
if ((Object)(object)val2 == (Object)null)
{
Logger.LogError((object)"Dummy hat container not found, cannot instantiate hats for dummy.");
return;
}
if (!HatsInserted)
{
Logger.LogError((object)"HatsInserted is not set yet, not instantiating hats!");
return;
}
ref Renderer[] playerHats = ref dummy.refs.playerHats;
if (!playerHats.Skip(23).Any((Renderer x) => HatNames.Contains(((Object)x).name)))
{
Renderer val3 = playerHats.FirstOrDefault();
Renderer obj = playerHats[0];
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
MeshRenderer componentInChildren = ((Component)obj).GetComponentInChildren<MeshRenderer>(true);
obj2 = ((componentInChildren != null) ? ((Renderer)componentInChildren).material : null);
}
Material dummyHatMat = (Material)obj2;
Material obj3 = dummyHatMat;
Dictionary<string, float> dictionary = ((obj3 != null) ? obj3.GetPropertyNames((MaterialPropertyType)0).ToDictionary((string n) => n, (string n) => dummyHatMat.GetFloat(n)) : null);
if ((Object)(object)val3 == (Object)null)
{
Logger.LogDebug((object)"Dummy is missing hats - something is wrong, aborting...");
return;
}
int layer = ((Component)val3).gameObject.layer;
Logger.LogDebug((object)$"Instantiating hats for dummy as children of {val2}.");
List<Renderer> list2 = new List<Renderer>(instance.Hats.Length);
Hat[] hats = instance.Hats;
for (int i = 0; i < hats.Length; i++)
{
Hat hat2 = hats[i];
if ((Object)(object)hat2.Prefab == (Object)null)
{
Logger.LogError((object)("Hat prefab for '" + hat2.Name + "' is null, skipping instantiation for dummy."));
continue;
}
GameObject val4 = Object.Instantiate<GameObject>(hat2.Prefab, val2);
((Object)val4).name = hat2.Name;
GameObjectExtensions.SetLayerRecursivly(val4, layer);
MeshRenderer[] componentsInChildren = val4.GetComponentsInChildren<MeshRenderer>(true);
for (int j = 0; j < componentsInChildren.Length; j++)
{
Material material = ((Renderer)componentsInChildren[j]).material;
material.enableInstancing = true;
((Object)material).hideFlags = (HideFlags)32;
material.shader = CharacterShader;
if (dictionary == null)
{
continue;
}
foreach (KeyValuePair<string, float> item in dictionary)
{
material.SetFloat(item.Key, item.Value);
}
}
Renderer componentInChildren2 = val4.GetComponentInChildren<Renderer>();
((Component)componentInChildren2).gameObject.SetActive(false);
list2.Add(componentInChildren2);
}
ArrayInsert(ref playerHats, 23, list2);
Logger.LogDebug((object)"Completed adding hats to Passport dummy.");
}
Character localCharacter = GetLocalCharacter();
AddHatsForCharacter(localCharacter);
if (GameHandler.GetService<PersistentPlayerDataService>() == null)
{
Logger.LogError((object)"PersistentPlayerDataService is null, cannot set hat.");
}
}
private static void ArrayInsert<T>(ref T[]? array, int insertIndex, IReadOnlyList<T>? toAdd)
{
if (toAdd == null || toAdd.Count == 0)
{
return;
}
if (array == null || array.Length == 0)
{
array = toAdd.ToArray();
return;
}
if (insertIndex < 0 || insertIndex > array.Length)
{
throw new ArgumentOutOfRangeException("insertIndex", $"Insert index ({insertIndex}) is out of bounds.");
}
T[] array2 = new T[array.Length + toAdd.Count];
if (insertIndex == array.Length)
{
array.CopyTo(array2, 0);
for (int i = 0; i < toAdd.Count; i++)
{
array2[i + insertIndex] = toAdd[i];
}
}
else
{
Array.Copy(array, 0, array2, 0, insertIndex);
for (int j = 0; j < toAdd.Count; j++)
{
array2[j + insertIndex] = toAdd[j];
}
int destinationIndex = insertIndex + toAdd.Count;
int length = array.Length - insertIndex;
Array.Copy(array, insertIndex, array2, destinationIndex, length);
}
array = array2;
}
private static void ArrayAppend<T>(ref T[]? array, IReadOnlyList<T>? toAdd)
{
if (toAdd == null || toAdd.Count == 0)
{
return;
}
if (array == null || array.Length == 0)
{
array = toAdd.ToArray();
return;
}
T[] array2 = new T[array.Length + toAdd.Count];
array.CopyTo(array2, 0);
for (int i = 0; i < toAdd.Count; i++)
{
array2[i + array.Length] = toAdd[i];
}
array = array2;
}
private void AddHatsForCharacter(Character? character)
{
Plugin instance = Instance;
if ((Object)(object)instance == (Object)null || HatNames == null || instance.Hats == null || instance.Hats.Length == 0)
{
Logger.LogError((object)"Plugin instance or hats not loaded yet, cannot instantiate hats!");
return;
}
if (!HatsInserted)
{
Logger.LogError((object)"HatsInserted is not set yet, not instantiating hats!");
return;
}
if ((Object)(object)character == (Object)null)
{
Logger.LogError((object)"Local character not found, cannot instantiate hats!");
return;
}
CharacterRefs refs = character.refs;
if (refs == null)
{
Logger.LogError((object)$"Character #{((MonoBehaviourPun)character).photonView.Owner.ActorNumber} '{((Object)character).name}' is missing refs!");
return;
}
CharacterCustomization customization = refs.customization;
if ((Object)(object)customization == (Object)null)
{
Logger.LogError((object)$"Character #{((MonoBehaviourPun)character).photonView.Owner.ActorNumber} '{((Object)character).name}' is missing a customization component!");
return;
}
ref Renderer[] playerHats = ref customization.refs.playerHats;
if (playerHats == null)
{
Logger.LogError((object)$"Character #{((MonoBehaviourPun)character).photonView.Owner.ActorNumber} '{((Object)character).name}' is missing hats on the customization component!");
return;
}
if (playerHats.Skip(23).Any((Renderer x) => HatNames.Contains(((Object)x).name)))
{
Logger.LogDebug((object)$"Character #{((MonoBehaviourPun)character).photonView.Owner.ActorNumber} '{((Object)character).name}' already has hats, skipping.");
return;
}
Logger.LogDebug((object)$"Adding hats to Character #{((MonoBehaviourPun)character).photonView.Owner.ActorNumber} '{((Object)character).name}'");
Transform val = TransformExtensions.FindChildRecursive(((Component)customization).transform, "Hat");
Logger.LogDebug((object)$"Hats container found: {val} (inst #{((Object)val).GetInstanceID()})");
if ((Object)(object)val == (Object)null)
{
Logger.LogError((object)"Hats container not found, cannot instantiate hats.");
return;
}
Logger.LogDebug((object)$"Instantiating hats as children of {val} (inst #{((Object)val).GetInstanceID()})");
Renderer obj = playerHats[0];
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
MeshRenderer componentInChildren = ((Component)obj).GetComponentInChildren<MeshRenderer>(true);
obj2 = ((componentInChildren != null) ? ((Renderer)componentInChildren).material : null);
}
Material hatMat = (Material)obj2;
Material obj3 = hatMat;
Dictionary<string, float> dictionary = ((obj3 != null) ? obj3.GetPropertyNames((MaterialPropertyType)0).ToDictionary((string n) => n, (string n) => hatMat.GetFloat(n)) : null);
List<Renderer> list = new List<Renderer>(instance.Hats.Length);
Hat[] hats = instance.Hats;
for (int i = 0; i < hats.Length; i++)
{
Hat hat = hats[i];
if ((Object)(object)hat.Prefab == (Object)null)
{
Logger.LogError((object)("Hat prefab for '" + hat.Name + "' is null, skipping instantiation."));
continue;
}
GameObject val2 = Object.Instantiate<GameObject>(hat.Prefab, val);
((Object)val2).name = hat.Name;
MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>(true);
for (int j = 0; j < componentsInChildren.Length; j++)
{
Material material = ((Renderer)componentsInChildren[j]).material;
material.enableInstancing = true;
((Object)material).hideFlags = (HideFlags)32;
material.shader = CharacterShader;
if (dictionary == null)
{
continue;
}
foreach (KeyValuePair<string, float> item in dictionary)
{
material.SetFloat(item.Key, item.Value);
}
}
Renderer componentInChildren2 = val2.GetComponentInChildren<Renderer>();
((Component)componentInChildren2).gameObject.SetActive(false);
list.Add(componentInChildren2);
}
ArrayInsert(ref playerHats, 23, list);
Logger.LogDebug((object)$"Completed adding hats to Character #{((MonoBehaviourPun)character).photonView.Owner.ActorNumber} '{((Object)character).name}'");
}
public static CustomizationOption CreateHatOption(string hatName, Texture2D icon)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
CustomizationOption obj = ScriptableObject.CreateInstance<CustomizationOption>();
obj.color = Color.white;
((Object)obj).name = hatName;
obj.texture = (Texture)(object)icon;
obj.type = (Type)50;
obj.requiredAchievement = (ACHIEVEMENTTYPE)0;
return obj;
}
public static void OnAddHatsForCharacter(Character character)
{
if ((Object)(object)character == (Object)null)
{
Plugin? instance = Instance;
if (instance != null)
{
instance.Logger.LogError((object)"OnAddHatsForCharacter called for null character.");
}
return;
}
Plugin? instance2 = Instance;
if (instance2 != null)
{
instance2.Logger.LogDebug((object)$"OnAddHatsForCharacter called for character #{((MonoBehaviourPun)character).photonView.Owner.ActorNumber} '{((Object)character).name}'");
}
Instance?.AddHatsForCharacter(character);
}
public static void BroadcastPluginEvent(string message)
{
Plugin instance = Instance;
BaseUnityPlugin[] array = Resources.FindObjectsOfTypeAll<BaseUnityPlugin>();
foreach (BaseUnityPlugin val in array)
{
Type type = ((object)val).GetType();
MethodInfo method = type.GetMethod(message, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Any, Array.Empty<Type>(), null);
if (!(method == null))
{
if (instance != null)
{
instance.Logger.LogDebug((object)("Calling " + method.Name + " on plugin " + type.FullName));
}
method.Invoke(method.IsStatic ? null : val, Array.Empty<object>());
}
}
}
public static void BroadcastPluginEvent(string message, params object[] args)
{
string message2 = message;
object[] args2 = args;
if (args2 == null)
{
throw new ArgumentNullException("args");
}
Plugin instance = Instance;
BaseUnityPlugin[] array = Resources.FindObjectsOfTypeAll<BaseUnityPlugin>();
foreach (BaseUnityPlugin val in array)
{
Type type = ((object)val).GetType();
MethodInfo methodInfo = (MethodInfo)type.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MemberInfo m) => m.Name == message2 && m is MethodInfo mi && HasCompatibleParameters(mi, args2));
if (!(methodInfo == null))
{
if (instance != null)
{
instance.Logger.LogDebug((object)("Calling " + methodInfo.Name + " on plugin " + type.FullName));
}
methodInfo.Invoke(methodInfo.IsStatic ? null : val, args2);
}
}
}
private static bool HasCompatibleParameters(MethodInfo mi, object[] args)
{
ParameterInfo[] parameters = mi.GetParameters();
if (parameters.Length != args.Length)
{
return false;
}
for (int i = 0; i < args.Length; i++)
{
if (!IsCompatibleParameter(parameters[i].ParameterType, args[i]))
{
return false;
}
}
return true;
}
private static bool IsCompatibleParameter(Type paramType, object? arg)
{
if (arg == null)
{
if (paramType.IsValueType)
{
return Nullable.GetUnderlyingType(paramType) != null;
}
return true;
}
if (!paramType.IsInstanceOfType(arg))
{
if (paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return Nullable.GetUnderlyingType(paramType).IsInstanceOfType(arg);
}
return false;
}
return true;
}
}
public struct Hat
{
public string Name;
public GameObject Prefab;
public Texture2D Icon;
public Hat(string name, GameObject prefab, Texture2D icon)
{
Name = name;
Prefab = prefab;
Icon = icon;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "BobaHats";
public const string PLUGIN_NAME = "BobaHats";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
internal IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}