using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CC;
using CayplayMissions.CustomizationNew;
using Duckify.Core;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Duckify.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+d6c8c358d71e57c629525ea9f368fd92dc9e9aa1")]
[assembly: AssemblyProduct("Duckify.Plugin")]
[assembly: AssemblyTitle("Duckify.Plugin")]
[assembly: AssemblyVersion("0.1.0.0")]
[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 Duckify.Plugin
{
[BepInPlugin("com.github.kirby1997.duckify", "Duckify", "0.1.0")]
public sealed class Plugin : BasePlugin
{
public const string Id = "com.github.kirby1997.duckify";
public const string Name = "Duckify";
public const string Version = "0.1.0";
private readonly HashSet<string> _reported = new HashSet<string>();
internal static Plugin Instance { get; private set; }
internal ConfigEntry<bool> Enabled { get; private set; }
public override void Load()
{
//IL_0043: 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_0067: Expected O, but got Unknown
Instance = this;
Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Dress every visitor in the park mascot's duck suit. Turn off to give them their own clothes back; the change shows at once.");
Enabled.SettingChanged += OnEnabledChanged;
new Harmony("com.github.kirby1997.duckify").PatchAll(typeof(SuitHooks));
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Duckify");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.1.0");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded");
}
log.LogInfo(val);
}
private void OnEnabledChanged(object sender, EventArgs args)
{
try
{
SuitHooks.RedressVisitors();
}
catch (Exception e)
{
ReportOnce("redressing visitors", e);
}
}
internal void ReportOnce(string what, Exception e)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
if (_reported.Add(what))
{
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(9, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(what);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(e);
}
log.LogError(val);
}
}
}
[HarmonyPatch]
internal static class SuitHooks
{
private readonly struct Table
{
public readonly int? Piece;
public readonly int? Empty;
public Table(int? piece, int? empty)
{
Piece = piece;
Empty = empty;
}
}
internal struct Swap
{
public bool Done;
public string Original;
public byte OriginalMaterial;
public string Piece;
public string[] Names;
public byte[] Materials;
}
private static readonly Dictionary<IntPtr, Table> Tables = new Dictionary<IntPtr, Table>();
private static readonly Wardrobe Wardrobe = new Wardrobe();
private static int _purgeAt = 512;
private static int _swapsUnderway;
[HarmonyPrefix]
[HarmonyPatch(typeof(CharacterCustomization), "setApparel")]
private static void BeforeSetApparel(CharacterCustomization __instance, ref int selection, int slot, ref int materialSelection, out Swap __state)
{
__state = default(Swap);
try
{
if ((Object)(object)((Component)__instance).GetComponent<VisitorsOutfitOverride>() == (Object)null)
{
return;
}
bool flag = _swapsUnderway > 0;
if (!flag)
{
RecordPick(__instance, slot, selection, materialSelection);
}
if (!Plugin.Instance.Enabled.Value)
{
return;
}
List<scrObj_Apparel> apparelTables = __instance.ApparelTables;
if (apparelTables == null || slot < 0 || slot >= apparelTables.Count)
{
return;
}
scrObj_Apparel val = apparelTables[slot];
List<Apparel> val2 = ((val != null) ? val.Items : null);
if (val2 == null || selection < 0 || selection >= val2.Count)
{
return;
}
int? piece = Describe(val).Piece;
if (piece.HasValue && piece != selection)
{
Swap swap = new Swap
{
Done = true,
Original = val2[selection].Name,
OriginalMaterial = (byte)materialSelection,
Piece = val2[piece.Value].Name
};
if (!flag)
{
CC_CharacterData storedCharacterData = __instance.StoredCharacterData;
swap.Names = Copy((storedCharacterData != null) ? storedCharacterData.ApparelNames : null);
swap.Materials = Copy((storedCharacterData != null) ? storedCharacterData.ApparelMaterials : null);
}
__state = swap;
_swapsUnderway++;
selection = piece.Value;
materialSelection = 0;
}
}
catch (Exception e)
{
__state = default(Swap);
Plugin.Instance.ReportOnce("suit swap", e);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(CharacterCustomization), "setApparel")]
private static void AfterSetApparel(CharacterCustomization __instance, int slot, Swap __state)
{
if (!__state.Done)
{
return;
}
_swapsUnderway = Math.Max(0, _swapsUnderway - 1);
if (__state.Names == null)
{
return;
}
try
{
CC_CharacterData storedCharacterData = __instance.StoredCharacterData;
List<string> val = ((storedCharacterData != null) ? storedCharacterData.ApparelNames : null);
if (val != null)
{
for (int i = 0; i < val.Count; i++)
{
string text = ((i != slot) ? ((i < __state.Names.Length) ? __state.Names[i] : val[i]) : ((val[i] == __state.Piece) ? __state.Original : val[i]));
if (val[i] != text)
{
val[i] = text;
}
}
}
List<byte> val2 = ((storedCharacterData != null) ? storedCharacterData.ApparelMaterials : null);
if (val2 == null)
{
return;
}
for (int j = 0; j < val2.Count; j++)
{
byte b = ((j == slot) ? __state.OriginalMaterial : ((j < __state.Materials?.Length) ? __state.Materials[j] : val2[j]));
if (val2[j] != b)
{
val2[j] = b;
}
}
}
catch (Exception e)
{
Plugin.Instance.ReportOnce("restoring a visitor's own outfit", e);
}
}
internal static void RedressVisitors()
{
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Expected O, but got Unknown
//IL_00da: 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)
List<long> list = new List<long>();
foreach (VisitorsOutfitOverride item in Object.FindObjectsByType<VisitorsOutfitOverride>((FindObjectsInactive)1, (FindObjectsSortMode)0))
{
try
{
CharacterCustomization component = ((Component)item).GetComponent<CharacterCustomization>();
if ((Object)(object)component == (Object)null)
{
continue;
}
long num = ((Il2CppObjectBase)component).Pointer.ToInt64();
list.Add(num);
IReadOnlyList<Pick> readOnlyList = Wardrobe.Outfit(num);
List<scrObj_Apparel> apparelTables = component.ApparelTables;
int num2 = 0;
while (apparelTables != null && num2 < apparelTables.Count)
{
if (!Wardrobe.Has(num, num2) && !((Object)(object)apparelTables[num2] == (Object)null))
{
int? empty = Describe(apparelTables[num2]).Empty;
if (empty.HasValue)
{
component.setApparel(empty.Value, num2, 0, true);
}
}
num2++;
}
foreach (Pick item2 in readOnlyList)
{
Pick current2 = item2;
component.setApparel(((Pick)(ref current2)).Selection, ((Pick)(ref current2)).Slot, ((Pick)(ref current2)).Material, true);
}
}
catch (Exception e)
{
Plugin.Instance.ReportOnce("redressing a visitor", e);
}
}
Wardrobe.KeepOnly((IEnumerable<long>)list);
ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Redressed ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" visitors.");
}
log.LogInfo(val);
}
private static void RecordPick(CharacterCustomization character, int slot, int selection, int material)
{
Wardrobe.Record(((Il2CppObjectBase)character).Pointer.ToInt64(), slot, selection, material);
if (Wardrobe.Count >= _purgeAt)
{
IEnumerable<long> enumerable = (from v in (IEnumerable<VisitorsOutfitOverride>)Object.FindObjectsByType<VisitorsOutfitOverride>((FindObjectsInactive)1, (FindObjectsSortMode)0)
select ((Component)v).GetComponent<CharacterCustomization>() into c
where (Object)(object)c != (Object)null
select ((Il2CppObjectBase)c).Pointer.ToInt64()).Append(((Il2CppObjectBase)character).Pointer.ToInt64());
Wardrobe.KeepOnly(enumerable);
_purgeAt = Math.Max(512, Wardrobe.Count * 2);
}
}
private static Table Describe(scrObj_Apparel table)
{
if (Tables.TryGetValue(((Il2CppObjectBase)table).Pointer, out var value))
{
return value;
}
List<Apparel> items = table.Items;
string[] array = new string[items?.Count ?? 0];
for (int i = 0; i < array.Length; i++)
{
array[i] = items[i].Name;
}
return Tables[((Il2CppObjectBase)table).Pointer] = new Table(MascotSuit.Pick((IReadOnlyList<string>)array), MascotSuit.EmptyIndex((IReadOnlyList<string>)array));
}
private static string[] Copy(List<string> list)
{
if (list == null)
{
return null;
}
string[] array = new string[list.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = list[i];
}
return array;
}
private static byte[] Copy(List<byte> list)
{
if (list == null)
{
return null;
}
byte[] array = new byte[list.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = list[i];
}
return array;
}
}
}