using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.SceneStreaming;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using LabFusion;
using LabFusion.Data;
using LabFusion.Entities;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.SDK.Metadata;
using LabFusion.Utilities;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using RandomAvatar;
using RandomAvatar.Helper;
using RandomAvatar.Menu;
using RandomAvatar.Menu.Elements;
using RandomAvatar.Patches;
using RandomAvatar.Utilities;
using Semver;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "RandomAvatar", "1.3.0", "HAHOOS", "https://thunderstore.io/c/bonelab/p/HAHOOS/RandomAvatar")]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonColor(0, 255, 0, 255)]
[assembly: MelonAuthorColor(0, 255, 165, 0)]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion" })]
[assembly: AssemblyTitle("Lets you switch to a random avatar by pressing button, as well in other ways")]
[assembly: AssemblyDescription("Lets you switch to a random avatar by pressing button, as well in other ways")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HAHOOS")]
[assembly: AssemblyProduct("RandomAvatar")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: ComVisible(false)]
[assembly: Guid("6c044178-2021-4782-90bf-1dc7b0a93b08")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.3.0.0")]
[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 RandomAvatar
{
internal interface IFilterHandler
{
Func<AvatarCrate, bool> IsOnList { get; set; }
bool IsEmpty();
void SetupPage();
}
internal class FilterHandler<T, TConfig> : IFilterHandler where T : class where TConfig : class
{
public Func<T, TConfig> GetConfigItem;
public Func<T, string> GetSearchString;
public Func<T, string> FetchElementName;
public Func<T[]> GetItems;
public Page MainPage { get; internal set; }
public MelonPreferences_Category Category { get; internal set; }
public MelonPreferences_Entry<List<TConfig>> List { get; internal set; }
public bool UseSortMode { get; set; }
public ViewMode ViewMode { get; set; }
public SortDirection SortDirection { get; set; }
public SortMode SortMode { get; set; }
public string Search { get; set; }
public string Name { get; set; }
public Color Color { get; set; }
public Page Page { get; private set; }
public Func<AvatarCrate, bool> IsOnList { get; set; }
public FilterHandler(Page mainPage, MelonPreferences_Category category, string entryName)
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
MainPage = mainPage;
Category = category;
List = category.CreateEntry<List<TConfig>>(entryName, new List<TConfig>(), (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
UseSortMode = true;
SortDirection = SortDirection.Descending;
Search = string.Empty;
Name = entryName ?? "N/A";
Color = Color.white;
base..ctor();
}
public void SetupPage()
{
//IL_0040: 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)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
//IL_0297: Unknown result type (might be due to invalid IL or missing references)
if (Page == null)
{
Page val3 = (Page = MainPage.CreatePage(Name, Color, 10, true));
}
BlacklistWhitelist.CleanupPage(Page);
Page.CreateEnum("Sort Direction", Color.yellow, (Enum)SortDirection, (Action<Enum>)delegate(Enum val)
{
SortDirection = (SortDirection)(object)val;
SetupPage();
});
if (UseSortMode)
{
Page.CreateEnum("Sort Mode", Color.cyan, (Enum)SortMode, (Action<Enum>)delegate(Enum val)
{
SortMode = (SortMode)(object)val;
SetupPage();
});
}
Page.CreateEnum("View Mode", Color.magenta, (Enum)ViewMode, (Action<Enum>)delegate(Enum val)
{
ViewMode = (ViewMode)(object)val;
SetupPage();
});
Page.CreateString("Search", Color.cyan, Search, (Action<string>)delegate(string val)
{
Search = val;
SetupPage();
});
Page.CreateFunction("Add All", new Color(0f, 1f, 0f), (Action)delegate
{
GetItems().ForEach(delegate(T x)
{
ChangeList(x, remove: false);
});
SetupPage();
Category.SaveToFile(false);
});
Page.CreateFunction("Remove All", new Color(0f, 1f, 0f), (Action)delegate
{
GetItems().ForEach(delegate(T x)
{
ChangeList(x, remove: true);
});
SetupPage();
Category.SaveToFile(false);
});
Page.CreateFunction("Refresh", Color.yellow, (Action)delegate
{
SetupPage();
});
if (!UseSortMode)
{
Page.CreateBlank();
}
Page.CreateBlank();
Page.CreateLabel("Go to the next page to see all the " + Name.ToLower(), Color.white);
Page.CreateBlank();
bool flag = false;
T[] array = GetItems();
foreach (T item in array)
{
if (item == null)
{
return;
}
if (!DoesViewModeAllow(((MelonPreferences_Entry<List<?>>)(object)List).Value, GetConfigItem(item), ViewMode) || (!string.IsNullOrWhiteSpace(Search) && !GetSearchString(item).Contains(Search, StringComparison.InvariantCultureIgnoreCase)))
{
continue;
}
FunctionElement element = null;
flag = true;
element = Page.CreateFunction(FetchElementName?.Invoke(item), (Color)(OnList(item) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if (OnList(item))
{
ChangeList(item, remove: true);
((Element)element).ElementColor = Color.red;
if (ViewMode == ViewMode.On)
{
SetupPage();
}
}
else
{
ChangeList(item, remove: false);
((Element)element).ElementColor = new Color(0f, 1f, 0f);
if (ViewMode == ViewMode.Off)
{
SetupPage();
}
}
Category.SaveToFile(false);
});
}
if (!flag)
{
Page.CreateLabel("Nothing to show here :(", Color.white);
}
}
public bool IsEmpty()
{
if (((MelonPreferences_Entry<List<?>>)(object)List).Value != null)
{
return ((MelonPreferences_Entry<List<?>>)(object)List).Value.Count == 0;
}
return true;
}
private void ChangeList(T item, bool remove)
{
TConfig item2 = GetConfigItem(item);
if (remove)
{
((MelonPreferences_Entry<List<?>>)(object)List).Value.Remove(item2);
}
else
{
((MelonPreferences_Entry<List<?>>)(object)List).Value.Add(item2);
}
}
private bool OnList(T item)
{
TConfig item2 = GetConfigItem(item);
return ((MelonPreferences_Entry<List<?>>)(object)List).Value.Contains(item2);
}
private static bool DoesViewModeAllow(List<TConfig> values, TConfig value, ViewMode mode)
{
if (value == null)
{
return true;
}
if (mode == ViewMode.All)
{
return true;
}
if (values.Contains(value))
{
return mode == ViewMode.On;
}
return mode == ViewMode.Off;
}
}
internal static class BlacklistWhitelist
{
public static MelonPreferences_Entry<bool> IsWhitelist;
public static MelonPreferences_Entry<bool> Enabled;
private static bool mainPageSetup = false;
public static MelonPreferences_Category Category { get; private set; }
public static Page Page { get; internal set; }
public static bool IsSetup { get; private set; } = false;
internal static List<IFilterHandler> FilterHandlers { get; } = new List<IFilterHandler>();
public static FilterHandler<AvatarTag, string> TagsHandler { get; private set; }
public static FilterHandler<AvatarCrate, string> AvatarHandler { get; private set; }
public static FilterHandler<PalletRef, string> PalletHandler { get; private set; }
public static void Setup()
{
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
if (IsSetup)
{
return;
}
IsSetup = true;
Category = MelonPreferences.CreateCategory("RandomAvatar_BlacklistWhitelist");
Enabled = Category.CreateEntry<bool>("Enabled", false, "Enabled", "If true, whitelist/blacklist will be checked when changing into random avatar", false, false, (ValueValidator)null, (string)null);
IsWhitelist = Category.CreateEntry<bool>("IsWhitelist", false, "Is Whitelist", "If true, the avatar will be allowed if it has the tags, if false, it will be allowed only if it doesn't have the tag", false, false, (ValueValidator)null, (string)null);
TagsHandler = new FilterHandler<AvatarTag, string>(Page, Category, "Tags")
{
FetchElementName = (AvatarTag tag) => $"{tag.Tag} [{tag.Count}]",
GetConfigItem = (AvatarTag tag) => tag.Tag,
GetItems = GetAllTags,
GetSearchString = (AvatarTag tag) => tag.Tag,
Color = Color.cyan,
UseSortMode = true
};
TagsHandler.IsOnList = (AvatarCrate crate) => TagsHandler.List.Value.Any((string x) => ((Crate)crate).Tags.Contains(x));
FilterHandlers.Add(TagsHandler);
AvatarHandler = new FilterHandler<AvatarCrate, string>(Page, Category, "Avatars")
{
FetchElementName = (AvatarCrate av) => ((Scannable)av).Title ?? "",
GetConfigItem = (AvatarCrate av) => ((Scannable)av).Barcode.ID,
GetItems = GetAllAvatars,
GetSearchString = (AvatarCrate av) => ((Scannable)av).Title,
Color = Color.magenta,
UseSortMode = false
};
AvatarHandler.IsOnList = (AvatarCrate crate) => AvatarHandler.List.Value.Any((string x) => ((Scannable)crate).Barcode.ID == x);
FilterHandlers.Add(AvatarHandler);
PalletHandler = new FilterHandler<PalletRef, string>(Page, Category, "Pallets")
{
FetchElementName = (PalletRef pallet) => $"{((Scannable)pallet.Pallet).Title} [{pallet.Avatars.Count}]",
GetConfigItem = (PalletRef pallet) => ((Scannable)pallet.Pallet).Barcode.ID,
GetItems = GetAllPallets,
GetSearchString = (PalletRef pallet) => ((Scannable)pallet.Pallet).Title,
Color = Color.yellow,
UseSortMode = true
};
PalletHandler.IsOnList = (AvatarCrate crate) => PalletHandler.List.Value.Any((string x) => ((Scannable)((Crate)crate).Pallet).Barcode.ID == x);
FilterHandlers.Add(PalletHandler);
Category.SetFilePath(Path.Combine(MelonEnvironment.UserDataDirectory, "RandomAvatar.cfg"));
Category.SaveToFile(false);
}
public static AvatarTag[] GetAllTags()
{
if (!AssetWarehouse.ready)
{
return Array.Empty<AvatarTag>();
}
List<AvatarTag> tags = new List<AvatarTag>();
AssetWarehouse.Instance.GetCrates<AvatarCrate>((ICrateFilter<AvatarCrate>)null).ForEach(Action<AvatarCrate>.op_Implicit((Action<AvatarCrate>)delegate(AvatarCrate x)
{
((Crate)x).Tags.ForEach(Action<string>.op_Implicit((Action<string>)delegate(string y)
{
int num = tags.FindIndex((AvatarTag x) => x.Tag == y);
if (num != -1)
{
tags[num].Count++;
}
else
{
tags.Add(new AvatarTag(y, 1));
}
}));
}));
if (TagsHandler.SortMode == SortMode.Amount)
{
return ((TagsHandler.SortDirection == SortDirection.Ascending) ? tags.OrderBy((AvatarTag x) => x.Count) : tags.OrderByDescending((AvatarTag x) => x.Count)).ToArray();
}
return ((TagsHandler.SortDirection == SortDirection.Ascending) ? tags.OrderBy((AvatarTag x) => x.Tag) : tags.OrderByDescending((AvatarTag x) => x.Tag)).ToArray();
}
public static AvatarCrate[] GetAllAvatars()
{
if (!AssetWarehouse.ready)
{
return Array.Empty<AvatarCrate>();
}
List<AvatarCrate> crates = AssetWarehouse.Instance.GetCrates<AvatarCrate>((ICrateFilter<AvatarCrate>)null);
if (!Core.Entry_UseRedacted.Value)
{
crates.RemoveAll(Predicate<AvatarCrate>.op_Implicit((Func<AvatarCrate, bool>)((AvatarCrate x) => ((Scannable)x).Redacted)));
}
List<AvatarCrate> source = ((IEnumerable<AvatarCrate>)crates.ToArray()).ToList();
if (AvatarHandler.SortDirection != 0)
{
return source.OrderByDescending((AvatarCrate x) => ((Scannable)x).Title).ToArray();
}
return source.OrderBy((AvatarCrate x) => ((Scannable)x).Title).ToArray();
}
public static PalletRef[] GetAllPallets()
{
if (!AssetWarehouse.ready)
{
return Array.Empty<PalletRef>();
}
List<PalletRef> list = new List<PalletRef>();
Enumerator<Pallet> enumerator = AssetWarehouse.Instance.GetPallets().GetEnumerator();
while (enumerator.MoveNext())
{
PalletRef palletRef = new PalletRef(enumerator.Current);
if ((Object)(object)palletRef?.Pallet != (Object)null)
{
List<Crate> avatars = palletRef.Avatars;
if (avatars != null && avatars.Count > 0)
{
list.Add(palletRef);
}
}
}
if (PalletHandler.SortMode == SortMode.Alphabetical)
{
if (PalletHandler.SortDirection != 0)
{
return list.OrderByDescending((PalletRef x) => ((Scannable)x.Pallet).Title).ToArray();
}
return list.OrderBy((PalletRef x) => ((Scannable)x.Pallet).Title).ToArray();
}
if (PalletHandler.SortDirection != 0)
{
return list.OrderByDescending((PalletRef x) => x.Avatars.Count).ToArray();
}
return list.OrderBy((PalletRef x) => x.Avatars.Count).ToArray();
}
public static void CleanupPage(Page page)
{
page.IndexPages.ForEach(delegate(Page x)
{
x.RemoveAll();
Menu.DestroyPage(x);
});
page.RemoveAll();
}
public static void RemoveElement(Page page, Element element, bool removeSubPages = true, bool removeMainPage = false)
{
if (removeMainPage)
{
page.Remove((Element[])(object)new Element[1] { element });
}
else
{
page.Remove(element);
}
page.IndexPages.ForEach(delegate(Page subPage)
{
if (subPage != null)
{
IReadOnlyList<Element> elements = subPage.Elements;
if (elements != null && elements.Count > 0)
{
if (removeSubPages)
{
subPage.Remove((Element[])(object)new Element[1] { element });
}
else
{
subPage.Remove(element);
}
}
}
});
}
public static void SetupPage()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
if (IsSetup)
{
if (!mainPageSetup)
{
Page.CreateBoolPref("Enabled", Color.red, ref Enabled, Category);
Page.CreateBoolPref("Is Whitelist", Color.cyan, ref IsWhitelist, Category);
Page.CreateBlank();
mainPageSetup = true;
}
FilterHandlers.ForEach(delegate(IFilterHandler x)
{
x.SetupPage();
});
}
}
public static bool IsAvatarAllowed(AvatarCrate crate)
{
if ((Object)(object)crate == (Object)null)
{
return false;
}
if (!IsSetup)
{
return true;
}
if (!Enabled.Value)
{
return true;
}
if (FilterHandlers.Any((IFilterHandler x) => x.IsOnList(crate)))
{
return IsWhitelist.Value;
}
return !IsWhitelist.Value;
}
}
public class AvatarTag
{
public string Tag { get; set; }
public int Count { get; set; }
public AvatarTag(string tag, int count = 0)
{
Tag = tag;
Count = count;
base..ctor();
}
}
public enum SortMode
{
Amount,
Alphabetical
}
public enum SortDirection
{
Ascending,
Descending
}
public enum ViewMode
{
All,
On,
Off
}
internal class PalletRef
{
public Pallet Pallet { get; set; }
public List<Crate> Avatars => Pallet.Crates.FindAll(Predicate<Crate>.op_Implicit((Func<Crate, bool>)((Crate x) => ((MemberInfo)((Object)x).GetIl2CppType()).Name == "AvatarCrate")));
public PalletRef(Pallet pallet)
{
Pallet = pallet;
base..ctor();
}
}
public class Core : MelonMod
{
public const string Version = "1.3.0";
internal static MelonPreferences_Entry<bool> Entry_UseRedacted;
internal static MelonPreferences_Entry<bool> Entry_EffectWhenSwitching;
internal static MelonPreferences_Entry<bool> Entry_AllowRandomAvatarInYourLobbies;
internal static MelonPreferences_Entry<int> Entry_MinimumFusionDelay;
internal static MelonPreferences_Category Preferences_Category { get; private set; }
internal static Instance Logger { get; private set; }
internal static LevelInfo LevelInfo { get; private set; }
internal static Dictionary<DateTimeOffset, AvatarCrate> AvatarHistory { get; set; } = new Dictionary<DateTimeOffset, AvatarCrate>();
public static bool SwapOnDeath { get; internal set; } = false;
public static bool SwapOnLevelChange { get; internal set; } = false;
public static bool SwapOnNextLevelChange { get; internal set; } = false;
public static bool SwapOnDamaged { get; internal set; } = false;
internal static Thunderstore Thunderstore { get; set; }
private static bool FirstLoad { get; set; } = true;
public static void SwapAvatar(string barcode, bool usePCFC)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
if (!string.IsNullOrWhiteSpace(barcode) && AssetWarehouse.Instance.HasCrate(new Barcode(barcode)) && !((Object)(object)Player.RigManager == (Object)null))
{
if (usePCFC)
{
PullCordForceChange obj = ((GameObject)(((object)GameObject.Find("RandomAvatar")) ?? ((object)new GameObject("RandomAvatar")))).AddComponent<PullCordForceChange>();
obj.avatarCrate = new AvatarCrateReference(barcode);
obj.rigManager = Player.RigManager;
obj.ForceChange(((Component)obj.rigManager).gameObject);
}
else
{
Player.RigManager.SwapAvatarCrate(new Barcode(barcode), true, (Action<bool>)null);
}
}
}
public static Barcode RandomAvatar()
{
if (BlacklistWhitelist.Enabled.Value && BlacklistWhitelist.FilterHandlers.TrueForAll((IFilterHandler x) => x.IsEmpty()))
{
BLHelper.SendNotification("Failure", "When having blacklist/whitelist enabled, you need to have at least one tag, avatar and/or pallet selected!", showTitleOnPopup: true, 3f, (NotificationType)2);
Logger.Error("Cannot swap to random avatar. When having blacklist/whitelist enabled, you need to have at least one tag, avatar and/or pallet selected!");
return null;
}
Random random = new Random();
List<AvatarCrate> crates = AssetWarehouse.Instance.GetCrates<AvatarCrate>((ICrateFilter<AvatarCrate>)null);
crates.RemoveAll(Predicate<AvatarCrate>.op_Implicit((Func<AvatarCrate, bool>)delegate(AvatarCrate x)
{
if ((Object)(object)x == (Object)null)
{
return true;
}
if (!Entry_UseRedacted.Value && ((Scannable)x).Redacted)
{
return true;
}
return (!BlacklistWhitelist.IsAvatarAllowed(x)) ? true : false;
}));
AvatarCrate val = crates[random.Next(crates.Count)];
AvatarHistory.Add(DateTimeOffset.Now, val);
BoneMenu.SetupHistoryPage();
return ((Scannable)val).Barcode;
}
public static void SwapToRandom()
{
if (!AssetWarehouse.ready)
{
BLHelper.SendNotification("Failure", "Asset Warehouse is not ready and therefore the avatar cannot be switched", showTitleOnPopup: true, 2f, (NotificationType)2);
return;
}
if (!Fusion.IsAllowed())
{
BLHelper.SendNotification("Disallowed", "The host of this server has disabled the usage of RandomAvatar, cannot change you into a random avatar", showTitleOnPopup: true, 3.5f, (NotificationType)2);
return;
}
if ((double)BoneMenu.Cooldown > 1.5)
{
BLHelper.SendNotification("Cooldown", $"Wait {BoneMenu.Cooldown} more seconds", showTitleOnPopup: true, 1.5f, (NotificationType)1);
return;
}
Barcode val = RandomAvatar();
if (!(val == (Barcode)null))
{
if (Fusion.IsConnected())
{
BoneMenu.Cooldown = BoneMenu.MinimumDelay;
}
SwapAvatar(val.ID, Entry_EffectWhenSwitching.Value);
}
}
private void PatchFusion()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Expected O, but got Unknown
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Expected O, but got Unknown
((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(LocalRagdoll).GetMethod("Knockout", new Type[1] { typeof(float) }), (HarmonyMethod)null, new HarmonyMethod(typeof(LocalRagdollPatches).GetMethod("Postfix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(LocalRagdoll).GetMethod("Knockout", new Type[2]
{
typeof(float),
typeof(bool)
}), (HarmonyMethod)null, new HarmonyMethod(typeof(LocalRagdollPatches).GetMethod("Postfix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(FusionMod).GetMethod("OnMainSceneInitializeDelayed"), (HarmonyMethod)null, new HarmonyMethod(typeof(FusionPatches).GetMethod("Postfix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
public override void OnInitializeMelon()
{
Logger = ((MelonBase)this).LoggerInstance;
try
{
Thunderstore = new Thunderstore("RandomAvatar / 1.3.0 A BONELAB Code Mod");
Thunderstore.BL_FetchPackage("RandomAvatar", "HAHOOS", "1.3.0", ((MelonBase)this).LoggerInstance);
}
catch (Exception value)
{
((MelonBase)this).LoggerInstance.Error($"An unexpected error has occurred while trying to gather thunderstore package information, exception:\n{value}");
}
((MelonBase)this).LoggerInstance.Msg("Setting up preferences");
Preferences_Category = MelonPreferences.CreateCategory("RandomAvatar");
Entry_UseRedacted = Preferences_Category.CreateEntry<bool>("UseRedacted", false, "Use Redacted", "If true, when switching to random avatar the mod will also include redacted avatars", false, false, (ValueValidator)null, (string)null);
Entry_EffectWhenSwitching = Preferences_Category.CreateEntry<bool>("EffectWhenSwitching", true, "Effect When Switching", "If true, when switching to random avatar there will be an effect with the Pull Cord Device like when going into an area in a level that changes your avatar", false, false, (ValueValidator)null, (string)null);
Entry_AllowRandomAvatarInYourLobbies = Preferences_Category.CreateEntry<bool>("AllowRandomAvatarInYourLobbies", true, "Allow Random Avatar In Your Lobbies", "If true, random avatar will work for players when you create your lobby/server, if false they won't be able to use it on versions after 1.1.0", false, false, (ValueValidator)null, (string)null);
Entry_MinimumFusionDelay = Preferences_Category.CreateEntry<int>("MinimumFusionDelay", 20, "Minimum Fusion Delay", "The minimum delay value (in seconds) for all players using RandomAvatar on versions after 1.1.0", false, false, (ValueValidator)null, (string)null);
Preferences_Category.SetFilePath(Path.Combine(MelonEnvironment.UserDataDirectory, "RandomAvatar.cfg"));
Preferences_Category.SaveToFile(false);
if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
{
((MelonBase)this).LoggerInstance.Msg("Setting up Fusion");
PatchFusion();
Fusion.Setup();
}
else
{
((MelonBase)this).LoggerInstance.Warning("Fusion was not found");
}
((MelonBase)this).LoggerInstance.Msg("Creating BoneMenu");
BoneMenu.Setup();
((MelonBase)this).LoggerInstance.Msg("Setting up blacklist/whitelist");
BlacklistWhitelist.Setup();
((MelonBase)this).LoggerInstance.Msg("Adding hooks");
Hooking.OnLevelLoaded += delegate(LevelInfo info)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
LevelInfo = info;
if (!Fusion.IsConnected())
{
LevelLoaded();
}
};
((MelonBase)this).LoggerInstance.Msg("Initialized.");
}
internal static void LevelLoaded()
{
if (FirstLoad)
{
FirstLoad = false;
Thunderstore.BL_SendNotification();
}
if ((SwapOnLevelChange || SwapOnNextLevelChange) && !((Object)(object)PlayerRefs.Instance == (Object)null))
{
SwapOnNextLevelChange = false;
if (PlayerRefs.Instance.HasRefs)
{
SwapToRandom();
return;
}
PlayerRefs instance = PlayerRefs.Instance;
instance.OnRefsComplete += Action.op_Implicit((Action)SwapToRandom);
}
}
public override void OnFixedUpdate()
{
TimeUtilities.OnEarlyFixedUpdate();
}
public override void OnUpdate()
{
TimeUtilities.OnEarlyUpdate();
BoneMenu.Update();
}
}
}
namespace RandomAvatar.Utilities
{
public static class Fusion
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static ServerEvent <>9__10_0;
public static ServerEvent <>9__10_1;
public static ServerEvent <>9__10_2;
internal void <Internal_Setup>b__10_0()
{
ServerChanged?.Invoke();
}
internal void <Internal_Setup>b__10_1()
{
ServerChanged?.Invoke();
}
internal void <Internal_Setup>b__10_2()
{
ServerChanged?.Invoke();
}
}
internal const string Allow_MetadataKey = "RandomAvatar.Allow";
internal const string Delay_MetadataKey = "RandomAvatar.Delay";
internal const int FusionDelay = 20;
internal const int DefaultDelay = 5;
internal static Action ServerChanged;
internal static bool Internal_IsConnected()
{
return NetworkInfo.HasServer;
}
internal static bool Internal_IsMine(Component comp)
{
return (Object)(object)comp.GetComponentInParent<RigManager>() == (Object)(object)Player.RigManager;
}
internal static bool IsMine(Component comp)
{
if (IsConnected())
{
return Internal_IsMine(comp);
}
return true;
}
internal static void Internal_UpdateMetadata()
{
if (Core.Entry_AllowRandomAvatarInYourLobbies != null && NetworkInfo.IsHost && LocalPlayer.Metadata != null)
{
LocalPlayer.Metadata.Metadata.TrySetMetadata("RandomAvatar.Allow", Core.Entry_AllowRandomAvatarInYourLobbies.Value.ToString());
LocalPlayer.Metadata.Metadata.TrySetMetadata("RandomAvatar.Delay", Core.Entry_MinimumFusionDelay.Value.ToString());
}
}
internal static void UpdateMetadata()
{
if (IsConnected())
{
Internal_UpdateMetadata();
}
}
internal static void Internal_Setup()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_005c: 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
object obj = <>c.<>9__10_0;
if (obj == null)
{
ServerEvent val = delegate
{
ServerChanged?.Invoke();
};
<>c.<>9__10_0 = val;
obj = (object)val;
}
MultiplayerHooking.OnJoinedServer += (ServerEvent)obj;
object obj2 = <>c.<>9__10_1;
if (obj2 == null)
{
ServerEvent val2 = delegate
{
ServerChanged?.Invoke();
};
<>c.<>9__10_1 = val2;
obj2 = (object)val2;
}
MultiplayerHooking.OnStartedServer += (ServerEvent)obj2;
object obj3 = <>c.<>9__10_2;
if (obj3 == null)
{
ServerEvent val3 = delegate
{
ServerChanged?.Invoke();
};
<>c.<>9__10_2 = val3;
obj3 = (object)val3;
}
MultiplayerHooking.OnDisconnected += (ServerEvent)obj3;
}
internal static int Internal_GetMinimumDelay()
{
if (Core.Entry_MinimumFusionDelay == null)
{
return 5;
}
if (!NetworkInfo.HasServer)
{
return 5;
}
NetworkPlayer val = default(NetworkPlayer);
if (!NetworkPlayerManager.TryGetPlayer((byte)0, ref val))
{
return 5;
}
PlayerMetadata metadata = val.PlayerID.Metadata;
if (metadata != null)
{
NetworkMetadata metadata2 = metadata.Metadata;
if (metadata2 != null)
{
string s = default(string);
metadata2.TryGetMetadata("RandomAvatar.Delay", ref s);
if (0 == 0)
{
if (!int.TryParse(s, out var result))
{
return 20;
}
return result;
}
}
}
return 20;
}
internal static int GetMinimumDelay()
{
if (!IsConnected())
{
return 5;
}
return Internal_GetMinimumDelay();
}
internal static void Setup()
{
if (IsConnected())
{
Internal_Setup();
}
}
internal static bool Internal_IsAllowed()
{
NetworkPlayer val = default(NetworkPlayer);
if (!NetworkPlayerManager.TryGetPlayer((byte)0, ref val))
{
return true;
}
PlayerMetadata metadata = val.PlayerID.Metadata;
if (metadata != null)
{
NetworkMetadata metadata2 = metadata.Metadata;
if (metadata2 != null)
{
string value = default(string);
metadata2.TryGetMetadata("RandomAvatar.Allow", ref value);
if (0 == 0)
{
if (!bool.TryParse(value, out var result))
{
return true;
}
return result;
}
}
}
return true;
}
public static bool IsAllowed()
{
if (!IsConnected())
{
return true;
}
return Internal_IsAllowed();
}
internal static void Internal_EnsureSync()
{
if (NetworkInfo.IsHost)
{
if (IsAllowed() != Core.Entry_AllowRandomAvatarInYourLobbies.Value)
{
UpdateMetadata();
}
else if (GetMinimumDelay() != Core.Entry_MinimumFusionDelay.Value)
{
UpdateMetadata();
}
}
}
public static void EnsureSync()
{
if (IsConnected())
{
Internal_EnsureSync();
}
}
public static bool IsConnected()
{
if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
{
return Internal_IsConnected();
}
return false;
}
}
public class Thunderstore
{
public readonly string UserAgent;
private Package _fetchedPackage;
private bool _isLatestVersion;
private string _currentVersion;
public bool IsV1Deprecated { get; set; }
public Thunderstore(string userAgent)
{
UserAgent = userAgent;
}
public Thunderstore(string userAgent, bool isV1Deprecated)
: this(userAgent)
{
IsV1Deprecated = isV1Deprecated;
}
public Thunderstore()
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
if (executingAssembly != null)
{
AssemblyName name = executingAssembly.GetName();
if (name != null)
{
UserAgent = $"{name.Name} / {name.Version} C# Application";
}
}
}
public Thunderstore(bool isV1Deprecated)
{
IsV1Deprecated = isV1Deprecated;
Assembly executingAssembly = Assembly.GetExecutingAssembly();
if (executingAssembly != null)
{
AssemblyName name = executingAssembly.GetName();
if (name != null)
{
UserAgent = $"{name.Name} / {name.Version}";
}
}
}
public void BL_FetchPackage(string name, string author, string currentVersion, Instance logger = null)
{
if (_fetchedPackage != null)
{
return;
}
_currentVersion = currentVersion;
try
{
_fetchedPackage = GetPackage(author, name);
if (_fetchedPackage == null && logger != null)
{
logger.Warning("Could not find Thunderstore package for " + name);
}
if (string.IsNullOrWhiteSpace(_fetchedPackage.Latest?.Version) && logger != null)
{
logger.Warning("Latest version could not be found or the version is empty");
}
_isLatestVersion = _fetchedPackage.IsLatestVersion(currentVersion);
if (!_isLatestVersion)
{
if (logger != null)
{
logger.Warning($"A new version of {name} is available: v{_fetchedPackage.Latest.Version} while the current is v{currentVersion}. It is recommended that you update");
}
}
else if (SemVersion.Parse(currentVersion, false) == _fetchedPackage.Latest.SemanticVersion)
{
if (logger != null)
{
logger.Msg($"Latest version of {name} is installed! (v{currentVersion})");
}
}
else if (logger != null)
{
logger.Msg($"Beta release of {name} is installed (v{_fetchedPackage.Latest.Version} is newest, v{currentVersion} is installed)");
}
}
catch (ThunderstorePackageNotFoundException)
{
if (logger != null)
{
logger.Warning("Could not find Thunderstore package for " + name);
}
}
catch (Exception ex2)
{
if (logger != null)
{
logger.Error("An unexpected error has occurred while trying to check if " + name + " is the latest version", ex2);
}
}
}
public void BL_CreateMenuLabel(Page page, bool createBlankSpace = true)
{
//IL_0012: 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)
if (_fetchedPackage != null)
{
if (createBlankSpace)
{
((Element)page.CreateFunction("", Color.white, (Action)null)).SetProperty((ElementProperties)1);
}
((Element)page.CreateFunction("Current Version: v" + _currentVersion + ((_isLatestVersion || _fetchedPackage == null) ? string.Empty : "<br><color=#00FF00>(Update available!)</color>"), Color.white, (Action)null)).SetProperty((ElementProperties)1);
}
}
public void BL_SendNotification()
{
//IL_007d: 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)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: 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_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Expected O, but got Unknown
if (_fetchedPackage != null && !_isLatestVersion)
{
NotificationText message = default(NotificationText);
((NotificationText)(ref message))..ctor($"There is a new version of {_fetchedPackage.Name}. Go to Thunderstore and download the latest version which is <color=#00FF00>v{_fetchedPackage.Latest.Version}</color>", Color.white, true);
Notifier.Send(new Notification
{
Title = NotificationText.op_Implicit("Update!"),
Message = message,
PopupLength = 5f,
ShowTitleOnPopup = true,
Type = (NotificationType)1
});
}
}
public Package GetPackage(string @namespace, string name, string version = null)
{
Package package = SendRequest<Package>($"https://thunderstore.io/api/experimental/package/{@namespace}/{name}/{version ?? string.Empty}");
if (!IsV1Deprecated && package != null)
{
V1PackageMetrics packageMetrics = GetPackageMetrics(@namespace, name);
if (packageMetrics != null)
{
package.TotalDownloads = packageMetrics.Downloads;
package.RatingScore = packageMetrics.RatingScore;
}
}
return package;
}
private static bool IsTaskGood<T>(Task<T> task) where T : class
{
if (task != null && task.IsCompletedSuccessfully)
{
return task.Result != null;
}
return false;
}
public T SendRequest<T>(string url)
{
Task<HttpResponseMessage> async = new HttpClient(new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback = (HttpRequestMessage _, X509Certificate2? _, X509Chain? _, SslPolicyErrors _) => true
})
{
DefaultRequestHeaders =
{
{ "User-Agent", UserAgent },
{ "Accept", "application/json" }
}
}.GetAsync(url);
async.Wait();
HttpResponseMessage httpResponseMessage = async?.Result;
if (IsTaskGood(async))
{
if (!httpResponseMessage.IsSuccessStatusCode)
{
HandleHttpError(httpResponseMessage);
return default(T);
}
Task<string> task = httpResponseMessage.Content.ReadAsStringAsync();
task.Wait();
string text = task?.Result;
if (IsTaskGood(task))
{
return JsonConvert.DeserializeObject<T>(text);
}
}
return default(T);
}
private static void HandleHttpError(HttpResponseMessage result)
{
if (IsThunderstoreError(result, out var details))
{
if (IsPackageNotFound(result, details))
{
throw new ThunderstorePackageNotFoundException("Thunderstore could not find the package");
}
throw new ThunderstoreErrorException("Thunderstore API has thrown an unexpected error!", result);
}
result.EnsureSuccessStatusCode();
}
public V1PackageMetrics GetPackageMetrics(string @namespace, string name)
{
if (IsV1Deprecated)
{
return null;
}
return SendRequest<V1PackageMetrics>($"https://thunderstore.io/api/v1/package-metrics/{@namespace}/{name}/");
}
public bool IsLatestVersion(string @namespace, string name, string currentVersion)
{
SemVersion currentVersion2 = default(SemVersion);
if (SemVersion.TryParse(currentVersion, ref currentVersion2, false))
{
return IsLatestVersion(@namespace, name, currentVersion2);
}
return false;
}
public bool IsLatestVersion(string @namespace, string name, Version currentVersion)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
return IsLatestVersion(@namespace, name, new SemVersion(currentVersion));
}
public bool IsLatestVersion(string @namespace, string name, SemVersion currentVersion)
{
if (!IsV1Deprecated)
{
return GetPackageMetrics(@namespace, name)?.IsLatestVersion(currentVersion) ?? false;
}
return GetPackage(@namespace, name)?.IsLatestVersion(currentVersion) ?? false;
}
private static bool IsPackageNotFound(HttpResponseMessage response, string details = "")
{
if (response.StatusCode != HttpStatusCode.NotFound)
{
return false;
}
if (details != null && details.Length == 0)
{
details = GetDetails(response);
}
return string.Equals(details, "Not found.", StringComparison.OrdinalIgnoreCase);
}
private static bool IsThunderstoreError(HttpResponseMessage response, out string details)
{
details = GetDetails(response);
return !string.IsNullOrWhiteSpace(details);
}
private static string GetDetails(HttpResponseMessage response)
{
if (response.IsSuccessStatusCode)
{
return null;
}
Task<string> task = response.Content.ReadAsStringAsync();
task.Wait();
string result = task.Result;
if (string.IsNullOrWhiteSpace(result))
{
return null;
}
ThunderstoreErrorResponse thunderstoreErrorResponse;
try
{
thunderstoreErrorResponse = JsonConvert.DeserializeObject<ThunderstoreErrorResponse>(result);
}
catch (JsonException)
{
return null;
}
if (!string.IsNullOrWhiteSpace(thunderstoreErrorResponse?.Details))
{
return thunderstoreErrorResponse.Details;
}
return null;
}
}
public class Package
{
[JsonProperty("namespace")]
public string Namespace { get; internal set; }
[JsonProperty("name")]
public string Name { get; internal set; }
[JsonProperty("full_name")]
public string FullName { get; internal set; }
[JsonProperty("owner")]
public string Owner { get; internal set; }
[JsonProperty("package_url")]
public string PackageURL { get; internal set; }
[JsonProperty("date_created")]
public DateTime CreatedAt { get; internal set; }
[JsonProperty("date_updated")]
public DateTime UpdatedAt { get; internal set; }
[JsonProperty("rating_score")]
public int RatingScore { get; internal set; }
[JsonProperty("is_pinned")]
public bool IsPinned { get; internal set; }
[JsonProperty("is_deprecated")]
public bool IsDeprecated { get; internal set; }
[JsonProperty("total_downloads")]
public int TotalDownloads { get; internal set; }
[JsonProperty("latest")]
public PackageVersion Latest { get; internal set; }
[JsonProperty("community_listings")]
public PackageListing[] CommunityListings { get; internal set; }
public bool IsLatestVersion(string current)
{
if (string.IsNullOrWhiteSpace(current))
{
return false;
}
if (Latest == null || Latest.SemanticVersion == (SemVersion)null)
{
return false;
}
SemVersion val = default(SemVersion);
if (SemVersion.TryParse(current, ref val, false))
{
return val >= Latest.SemanticVersion;
}
return false;
}
public bool IsLatestVersion(SemVersion current)
{
if (current == (SemVersion)null)
{
return false;
}
if (Latest == null || Latest.SemanticVersion == (SemVersion)null)
{
return false;
}
return current >= Latest.SemanticVersion;
}
public bool IsLatestVersion(Version current)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
if (current == null)
{
return false;
}
if (Latest == null || Latest.SemanticVersion == (SemVersion)null)
{
return false;
}
return new SemVersion(current) >= Latest.SemanticVersion;
}
}
public class PackageVersion
{
[JsonProperty("namespace")]
public string Namespace { get; internal set; }
[JsonProperty("name")]
public string Name { get; internal set; }
[JsonProperty("version_number")]
public string Version
{
get
{
return ((object)SemanticVersion).ToString();
}
internal set
{
SemanticVersion = SemVersion.Parse(value, false);
}
}
[JsonIgnore]
public SemVersion SemanticVersion { get; internal set; }
[JsonProperty("full_name")]
public string FullName { get; internal set; }
[JsonProperty("description")]
public string Description { get; internal set; }
[JsonProperty("icon")]
public string Icon { get; internal set; }
[JsonProperty("dependencies")]
public List<string> Dependencies { get; internal set; }
[JsonProperty("download_url")]
public string DownloadURL { get; internal set; }
[JsonProperty("date_created")]
public DateTime CreatedAt { get; internal set; }
[JsonProperty("downloads")]
public int Downloads { get; internal set; }
[JsonProperty("website_url")]
public string WebsiteURL { get; internal set; }
[JsonProperty("is_active")]
public bool IsActive { get; internal set; }
}
public class PackageListing
{
public enum ReviewStatus
{
UNREVIEWED,
APPROVED,
REJECTED
}
[JsonProperty("has_nsfw_content")]
public bool HasNSFWContent { get; internal set; }
[JsonProperty("categories")]
public List<string> Categories { get; internal set; }
[JsonProperty("community")]
public string Community { get; internal set; }
[JsonProperty("review_status")]
public string ReviewStatusString
{
get
{
return ReviewStatusValue.ToString();
}
internal set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (string.Equals(value, "unreviewed", StringComparison.OrdinalIgnoreCase))
{
ReviewStatusValue = ReviewStatus.UNREVIEWED;
}
else if (string.Equals(value, "approved", StringComparison.OrdinalIgnoreCase))
{
ReviewStatusValue = ReviewStatus.APPROVED;
}
else if (string.Equals(value, "rejected", StringComparison.OrdinalIgnoreCase))
{
ReviewStatusValue = ReviewStatus.REJECTED;
}
}
}
[JsonIgnore]
public ReviewStatus ReviewStatusValue { get; internal set; }
}
public class V1PackageMetrics
{
[JsonProperty("downloads")]
public int Downloads { get; internal set; }
[JsonProperty("rating_score")]
public int RatingScore { get; internal set; }
[JsonProperty("latest_version")]
public string LatestVersion
{
get
{
return ((object)LatestSemanticVersion).ToString();
}
internal set
{
LatestSemanticVersion = SemVersion.Parse(value, false);
}
}
[JsonIgnore]
public SemVersion LatestSemanticVersion { get; internal set; }
public bool IsLatestVersion(string current)
{
if (string.IsNullOrWhiteSpace(current))
{
return false;
}
if (LatestSemanticVersion == (SemVersion)null)
{
return false;
}
SemVersion val = default(SemVersion);
if (SemVersion.TryParse(current, ref val, false))
{
return val >= LatestSemanticVersion;
}
return false;
}
public bool IsLatestVersion(SemVersion current)
{
if (current == (SemVersion)null)
{
return false;
}
if (LatestSemanticVersion == (SemVersion)null)
{
return false;
}
return current >= LatestSemanticVersion;
}
public bool IsLatestVersion(Version current)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
if (current == null)
{
return false;
}
if (LatestSemanticVersion == (SemVersion)null)
{
return false;
}
return new SemVersion(current) >= LatestSemanticVersion;
}
}
public class ThunderstoreErrorResponse
{
[JsonProperty("detail")]
public string Details { get; internal set; }
}
public class ThunderstoreErrorException : Exception
{
public string Details { get; }
public HttpStatusCode HttpStatusCode { get; }
public ThunderstoreErrorException()
{
}
public ThunderstoreErrorException(string message)
: base(message)
{
}
public ThunderstoreErrorException(string message, Exception innerException)
: base(message, innerException)
{
}
public ThunderstoreErrorException(string message, string details, HttpStatusCode httpStatusCode, Exception innerException)
: base(message, innerException)
{
Details = details;
HttpStatusCode = httpStatusCode;
}
public ThunderstoreErrorException(string message, HttpResponseMessage response)
: base(message)
{
if (response.IsSuccessStatusCode)
{
return;
}
HttpStatusCode = response.StatusCode;
Task<string> task = response.Content.ReadAsStringAsync();
task.Wait();
string result = task.Result;
if (string.IsNullOrWhiteSpace(result))
{
Details = string.Empty;
return;
}
ThunderstoreErrorResponse thunderstoreErrorResponse;
try
{
thunderstoreErrorResponse = JsonConvert.DeserializeObject<ThunderstoreErrorResponse>(result);
}
catch (JsonException)
{
Details = string.Empty;
return;
}
if (thunderstoreErrorResponse != null)
{
Details = thunderstoreErrorResponse.Details;
}
}
}
public class ThunderstorePackageNotFoundException : ThunderstoreErrorException
{
public string Namespace { get; }
public string Name { get; }
public string Version { get; }
public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string details, HttpStatusCode httpStatusCode, Exception innerException)
: base(message, details, httpStatusCode, innerException)
{
Namespace = @namespace;
Name = name;
}
public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string version, string details, HttpStatusCode httpStatusCode, Exception innerException)
: base(message, details, httpStatusCode, innerException)
{
Namespace = @namespace;
Name = name;
Version = version;
}
public ThunderstorePackageNotFoundException(string message, string @namespace, string name, HttpResponseMessage response)
: base(message, response)
{
Namespace = @namespace;
Name = name;
}
public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string version, HttpResponseMessage response)
: base(message, response)
{
Namespace = @namespace;
Name = name;
Version = version;
}
public ThunderstorePackageNotFoundException()
{
}
public ThunderstorePackageNotFoundException(string message)
: base(message)
{
}
public ThunderstorePackageNotFoundException(string message, Exception innerException)
: base(message, innerException)
{
}
public ThunderstorePackageNotFoundException(string message, string details, HttpStatusCode httpStatusCode, Exception innerException)
: base(message, details, httpStatusCode, innerException)
{
}
public ThunderstorePackageNotFoundException(string message, HttpResponseMessage response)
: base(message, response)
{
}
}
internal static class TimeUtilities
{
private static float _deltaTime = 1f;
private static float _fixedDeltaTime = 0.02f;
private static float _timeSinceStartup = 0f;
private static float _timeScale = 1f;
private static int _frameCount = 0;
public static float DeltaTime => _deltaTime;
public static float FixedDeltaTime => _fixedDeltaTime;
public static float TimeSinceStartup => _timeSinceStartup;
public static float TimeScale => _timeScale;
public static int FrameCount => _frameCount;
internal static void OnEarlyUpdate()
{
_timeScale = Time.timeScale;
_deltaTime = Time.deltaTime;
_timeSinceStartup += _deltaTime;
_frameCount++;
}
internal static void OnEarlyFixedUpdate()
{
_fixedDeltaTime = Time.fixedDeltaTime;
}
public static bool IsMatchingFrame(int interval)
{
return FrameCount % interval == 0;
}
public static bool IsMatchingFrame(int interval, int offset)
{
return (FrameCount + offset) % interval == 0;
}
}
}
namespace RandomAvatar.Patches
{
public static class FusionPatches
{
public static void Postfix()
{
if (Fusion.IsConnected())
{
Core.LevelLoaded();
}
}
}
public static class LocalRagdollPatches
{
public static void Postfix()
{
if (RigData.HasPlayer && Core.SwapOnDeath)
{
Core.SwapToRandom();
}
}
}
[HarmonyPatch(typeof(Player_Health))]
public static class PlayerHealthPatches
{
private static long _lastDamage = DateTimeOffset.Now.ToUnixTimeMilliseconds();
private const int _damageDelay = 250;
[HarmonyPatch("Death")]
[HarmonyPostfix]
public static void Postfix(Player_Health __instance)
{
if (Fusion.IsMine((Component)(object)__instance) && Core.SwapOnDeath)
{
PlayerHealthDecorator val = default(PlayerHealthDecorator);
if (Core.Entry_EffectWhenSwitching.Value && (Object)(object)PlayerMarkerPatches.Instance != (Object)null && (!((Component)PlayerMarkerPatches.Instance).TryGetComponent<PlayerHealthDecorator>(ref val) || !val._reloadLevelOnDeath))
{
Core.SwapOnNextLevelChange = true;
}
Core.SwapToRandom();
}
}
[HarmonyPatch("TAKEDAMAGE")]
[HarmonyPostfix]
public static void Postfix2(Player_Health __instance)
{
if (Fusion.IsMine((Component)(object)__instance) && Core.SwapOnDamaged)
{
if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - _lastDamage >= 250)
{
Core.SwapToRandom();
}
_lastDamage = DateTimeOffset.Now.ToUnixTimeMilliseconds();
}
}
}
[HarmonyPatch(typeof(PlayerMarker))]
public static class PlayerMarkerPatches
{
public static PlayerMarker Instance { get; private set; }
[HarmonyPatch("Awake")]
public static void Postfix(PlayerMarker __instance)
{
Instance = __instance;
}
}
}
namespace RandomAvatar.Menu
{
public static class BoneMenu
{
private static float elapsed = 0f;
private static IntElement DelayElement;
internal const int _rmd = 5;
internal static bool IsSetup = false;
internal static Action EverySecond;
internal static int Cooldown = 0;
internal static FunctionElement IsAllowedLabel;
internal static FunctionElement FusionDelayLabel;
private static float _generalElapsed;
private static float _lastDelay;
private static int _lastMinimumDelay;
public static Page AuthorPage { get; private set; }
public static Page ModPage { get; private set; }
public static Page SettingsPage { get; private set; }
public static Page RepeatingPage { get; private set; }
public static Page ChallengesPage { get; private set; }
public static Page FusionPage { get; private set; }
public static Page HistoryPage { get; private set; }
public static Page AvatarHistoryPage { get; private set; }
public static Page AvatarHistoryTagsPage { get; private set; }
public static Page BlacklistWhitelistPage { get; private set; }
internal static FunctionElement RemainingLabel { get; private set; }
public static int Delay { get; private set; } = 30;
public static int Remaining { get; private set; } = 0;
public static bool SwitchEvery { get; private set; } = false;
public static bool SwapOnStart { get; private set; } = true;
public static int MinimumDelay => Fusion.GetMinimumDelay();
private static int RepeatingMinimumDelay
{
get
{
int num = Fusion.GetMinimumDelay();
if (num < 5)
{
num = 5;
}
return num;
}
}
internal static FunctionElement CooldownLabel { get; private set; }
internal static void AssetWarehouseReady()
{
BlacklistWhitelist.SetupPage();
Hooking.OnWarehouseReady -= AssetWarehouseReady;
}
internal static void Setup()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: 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_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: 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_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0243: Unknown result type (might be due to invalid IL or missing references)
//IL_0323: Unknown result type (might be due to invalid IL or missing references)
//IL_039b: Unknown result type (might be due to invalid IL or missing references)
if (IsSetup)
{
return;
}
IsSetup = true;
AuthorPage = Page.Root.CreatePage("HAHOOS", Color.white, 0, true);
ModPage = AuthorPage.CreatePage("RandomAvatar", Color.magenta, 0, true);
SettingsPage = ModPage.CreatePage("Settings", Color.cyan, 4, true);
SettingsPage.CreateBoolPref("Use Redacted Avatars", Color.cyan, ref Core.Entry_UseRedacted);
SettingsPage.CreateBoolPref("Add effect when switching avatar", Color.magenta, ref Core.Entry_EffectWhenSwitching);
BlacklistWhitelistPage = ModPage.CreatePage("Blacklist/Whitelist", Color.magenta, 10, true);
BlacklistWhitelist.Page = BlacklistWhitelistPage;
if (!AssetWarehouse.ready)
{
Hooking.OnWarehouseReady += AssetWarehouseReady;
}
else
{
BlacklistWhitelist.SetupPage();
}
_lastMinimumDelay = MinimumDelay;
HistoryPage = ModPage.CreatePage("History", Color.yellow, 10, true);
AvatarHistoryPage = HistoryPage.CreatePage("Placeholder", Color.white, 0, false);
AvatarHistoryTagsPage = AvatarHistoryPage.CreatePage("Tags", Color.red, 0, false);
SetupHistoryPage();
RepeatingPage = ModPage.CreatePage("Repeating", Color.red, 4, true);
UpdateRepeating();
ChallengesPage = ModPage.CreatePage("Challenges", Color.yellow, 3, true);
ChallengesPage.CreateBool("Switch to random avatar on death", Color.cyan, false, (Action<bool>)delegate(bool v)
{
Core.SwapOnDeath = v;
});
ChallengesPage.CreateBool("Switch to random avatar on level change", Color.yellow, false, (Action<bool>)delegate(bool v)
{
Core.SwapOnLevelChange = v;
});
ChallengesPage.CreateBool("Switch to random avatar on damaged", Color.magenta, false, (Action<bool>)delegate(bool v)
{
Core.SwapOnDamaged = v;
});
if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
{
FusionPage = ModPage.CreatePage("Fusion", Color.cyan, 0, true);
SetupFusionPage();
Fusion.ServerChanged = (Action)Delegate.Combine(Fusion.ServerChanged, (Action)delegate
{
SetupFusionPage();
Cooldown = 0;
});
EverySecond = (Action)Delegate.Combine(EverySecond, new Action(UpdateLabels));
EverySecond = (Action)Delegate.Combine(EverySecond, new Action(Fusion.EnsureSync));
}
EverySecond = (Action)Delegate.Combine(EverySecond, new Action(CheckDelay));
ModPage.CreateFunction("Switch to random avatar", Color.white, (Action)Core.SwapToRandom);
if (HelperMethods.CheckIfAssemblyLoaded("labfusion"))
{
CooldownLabel = ModPage.CreateLabel(((Cooldown > 0) ? $"Cooldown: {Cooldown}" : "Ready to use") ?? "", Color.white);
}
Core.Thunderstore.BL_CreateMenuLabel(ModPage, createBlankSpace: false);
}
internal static void SetupTagsPage(AvatarCrate crate)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
BlacklistWhitelist.TagsHandler.SetupPage();
BlacklistWhitelist.CleanupPage(AvatarHistoryTagsPage);
if (((Crate)crate).Tags.Count <= 0)
{
AvatarHistoryTagsPage.CreateLabel("Nothing to show here :(", Color.white);
return;
}
Dictionary<string, int> tags = new Dictionary<string, int>();
((Crate)crate).Tags.ForEach(Action<string>.op_Implicit((Action<string>)delegate(string x)
{
if (!string.IsNullOrWhiteSpace(x))
{
int value = BlacklistWhitelist.GetAllTags().FirstOrDefault((AvatarTag y) => y.Tag == x)?.Count ?? 0;
tags.Add(x, value);
}
}));
tags = tags.OrderByDescending((KeyValuePair<string, int> x) => x.Value).ToDictionary((KeyValuePair<string, int> x) => x.Key, (KeyValuePair<string, int> x) => x.Value);
tags.ForEach(delegate(KeyValuePair<string, int> x)
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
FunctionElement element = null;
element = AvatarHistoryTagsPage.CreateFunction($"{x.Key} [{x.Value}]", (Color)(BlacklistWhitelist.TagsHandler.List.Value.Contains(x.Key) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
{
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
if (BlacklistWhitelist.TagsHandler.List.Value.Contains(x.Key))
{
BlacklistWhitelist.TagsHandler.List.Value.Remove(x.Key);
((Element)element).ElementColor = Color.red;
}
else
{
BlacklistWhitelist.TagsHandler.List.Value.Add(x.Key);
((Element)element).ElementColor = new Color(0f, 1f, 0f);
}
BlacklistWhitelist.Category.SaveToFile(false);
});
});
}
internal static void SetupPageForAvatar(DateTimeOffset offset, AvatarCrate crate)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: 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_011c: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
//IL_0283: Unknown result type (might be due to invalid IL or missing references)
//IL_026d: Unknown result type (might be due to invalid IL or missing references)
BlacklistWhitelist.PalletHandler.SetupPage();
AvatarHistoryPage.Name = ((Scannable)crate).Title;
AvatarHistoryPage.RemoveAll();
AvatarHistoryPage.CreateFunction(((Scannable)crate).Title, Color.white, (Action)null);
AvatarHistoryPage.CreateFunction(((Scannable)crate).Barcode.ID, Color.white, (Action)null);
AvatarHistoryPage.CreateFunction("Change into avatar", Color.cyan, (Action)delegate
{
Core.SwapAvatar(((Scannable)crate).Barcode.ID, Core.Entry_EffectWhenSwitching.Value);
});
FunctionElement palletElement = null;
palletElement = AvatarHistoryPage.CreateFunction(((Scannable)((Crate)crate).Pallet).Title + " [" + (BlacklistWhitelist.GetAllPallets().FirstOrDefault((PalletRef x) => ((Scannable)x.Pallet).Barcode == ((Scannable)((Crate)crate).Pallet).Barcode).Avatars.Count.ToString() ?? "0") + "]", (Color)(BlacklistWhitelist.PalletHandler.List.Value.Contains(((Scannable)((Crate)crate).Pallet).Barcode.ID) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
{
//IL_00a5: 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)
if (BlacklistWhitelist.PalletHandler.List.Value.Contains(((Scannable)((Crate)crate).Pallet).Barcode.ID))
{
BlacklistWhitelist.PalletHandler.List.Value.Remove(((Scannable)((Crate)crate).Pallet).Barcode.ID);
((Element)palletElement).ElementColor = Color.red;
}
else
{
BlacklistWhitelist.PalletHandler.List.Value.Add(((Scannable)((Crate)crate).Pallet).Barcode.ID);
((Element)palletElement).ElementColor = new Color(0f, 1f, 0f);
}
BlacklistWhitelist.Category.SaveToFile(false);
});
AvatarHistoryPage.CreateFunction($"Tags ({((Crate)crate).Tags.Count})", Color.red, (Action)delegate
{
SetupTagsPage(crate);
Menu.OpenPage(AvatarHistoryTagsPage);
});
AvatarHistoryPage.CreateFunction($"Time: {offset:T}", Color.white, (Action)null);
FunctionElement element = null;
element = AvatarHistoryPage.CreateFunction((!BlacklistWhitelist.AvatarHandler.List.Value.Contains(((Scannable)crate).Barcode.ID)) ? (BlacklistWhitelist.IsWhitelist.Value ? "Not Whitelisted" : "Not Blacklisted") : (BlacklistWhitelist.IsWhitelist.Value ? "Whitelisted" : "Blacklisted"), (Color)(BlacklistWhitelist.AvatarHandler.List.Value.Contains(((Scannable)crate).Barcode.ID) ? new Color(0f, 1f, 0f) : Color.red), (Action)delegate
{
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
if (BlacklistWhitelist.AvatarHandler.List.Value.Contains(((Scannable)crate).Barcode.ID))
{
BlacklistWhitelist.AvatarHandler.List.Value.Remove(((Scannable)crate).Barcode.ID);
((Element)element).ElementName = (BlacklistWhitelist.IsWhitelist.Value ? "Not Whitelisted" : "Not Blacklisted");
((Element)element).ElementColor = Color.red;
}
else
{
BlacklistWhitelist.AvatarHandler.List.Value.Add(((Scannable)crate).Barcode.ID);
((Element)element).ElementName = (BlacklistWhitelist.IsWhitelist.Value ? "Whitelisted" : "Blacklisted");
((Element)element).ElementColor = new Color(0f, 1f, 0f);
}
BlacklistWhitelist.Category.SaveToFile(false);
});
}
internal static void SetupHistoryPage()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
if (HistoryPage == null)
{
return;
}
BlacklistWhitelist.CleanupPage(HistoryPage);
((Element)HistoryPage.CreateFunction("Clear all", Color.red, (Action)delegate
{
Core.AvatarHistory.Clear();
SetupHistoryPage();
})).SetProperty((ElementProperties)1);
HistoryPage.CreateBlank();
if (Core.AvatarHistory.Count == 0)
{
HistoryPage.CreateLabel("Nothing to show here :(", Color.white);
return;
}
Core.AvatarHistory = Core.AvatarHistory.OrderByDescending((KeyValuePair<DateTimeOffset, AvatarCrate> x) => x.Key.ToUnixTimeMilliseconds()).ToDictionary((KeyValuePair<DateTimeOffset, AvatarCrate> x) => x.Key, (KeyValuePair<DateTimeOffset, AvatarCrate> x) => x.Value);
Core.AvatarHistory.ForEach(delegate(KeyValuePair<DateTimeOffset, AvatarCrate> y)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
AvatarCrate x2 = y.Value;
((Element)HistoryPage.CreateFunction(((Scannable)x2).Title, Color.yellow, (Action)delegate
{
SetupPageForAvatar(y.Key, x2);
Menu.OpenPage(AvatarHistoryPage);
})).SetProperty((ElementProperties)1);
});
}
internal static void UpdateRepeating()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: 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)
if (RepeatingPage == null)
{
return;
}
RepeatingPage.RemoveAll();
DelayElement = RepeatingPage.CreateInt("Change Delay", Color.yellow, Delay, 5, RepeatingMinimumDelay, 3600, (Action<int>)delegate(int v)
{
Delay = v;
});
RepeatingPage.CreateBool("Swap on start", Color.red, SwapOnStart, (Action<bool>)delegate(bool v)
{
SwapOnStart = v;
});
ToggleFunctionElement _switchEvery = RepeatingPage.CreateToggleFunction("Switch to random avatar every set seconds", Color.white, null);
_switchEvery.Started += delegate
{
if (!SwitchEvery)
{
if (Delay < RepeatingMinimumDelay)
{
Core.Logger.Error("Cannot use repeated avatar change, set delay is below minimum");
_switchEvery.Cancel();
}
else
{
Remaining = Delay;
_lastDelay = Delay;
SwitchEvery = true;
if (SwapOnStart)
{
Core.SwapToRandom();
}
}
}
};
_switchEvery.Cancelled += delegate
{
SwitchEvery = false;
};
if (SwitchEvery)
{
_switchEvery.Start();
}
FunctionElement obj = RepeatingPage.CreateFunction("Time until switch: N/A", Color.white, (Action)null);
((Element)obj).SetProperty((ElementProperties)1);
RemainingLabel = obj;
}
internal static void UpdateLabels()
{
if (IsAllowedLabel != null)
{
if (Fusion.IsConnected())
{
((Element)IsAllowedLabel).ElementName = "Is currently allowed: " + (Fusion.IsAllowed() ? "<color=#2EFF2E>Yes</color>" : "<color=#FF0000>No</color>");
((Element)FusionDelayLabel).ElementName = $"Minimum Delay: <color=#00FFFF>{MinimumDelay}{((MinimumDelay != RepeatingMinimumDelay) ? $" (Repeated {RepeatingMinimumDelay})" : "")}</color>";
}
else
{
((Element)IsAllowedLabel).ElementName = string.Empty;
((Element)FusionDelayLabel).ElementName = string.Empty;
}
}
}
internal static void CheckDelay()
{
if (DelayElement != null && Delay < RepeatingMinimumDelay)
{
Delay = RepeatingMinimumDelay;
DelayElement.Value = Delay;
}
}
internal static void SetupFusionPage()
{
//IL_0023: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
if (FusionPage != null && IsSetup)
{
FusionPage.RemoveAll();
FusionPage.CreateBoolPref("Allow Random Avatar", Color.cyan, ref Core.Entry_AllowRandomAvatarInYourLobbies, null, delegate
{
Fusion.UpdateMetadata();
});
FusionPage.CreateIntPref("Delay/Cooldown", Color.yellow, ref Core.Entry_MinimumFusionDelay, 5, 0, 3600, null, delegate
{
Fusion.UpdateMetadata();
});
Fusion.UpdateMetadata();
IsAllowedLabel = FusionPage.CreateLabel("Is currently allowed: " + (Fusion.IsAllowed() ? "<color=#2EFF2E>Yes</color>" : "<color=#FF0000>No</color>"), Color.white);
FusionDelayLabel = FusionPage.CreateLabel($"Minimum Delay/Cooldown: <color=#00FFFF>{MinimumDelay}{((MinimumDelay != RepeatingMinimumDelay) ? $" (Repeated {RepeatingMinimumDelay})" : "")}</color>", Color.white);
}
}
internal static void Update()
{
if (_lastMinimumDelay != RepeatingMinimumDelay)
{
UpdateRepeating();
_lastMinimumDelay = RepeatingMinimumDelay;
}
_generalElapsed += TimeUtilities.DeltaTime;
if (_generalElapsed >= 1f)
{
_generalElapsed = 0f;
if (CooldownLabel != null)
{
if (Fusion.IsConnected() && Cooldown > 0)
{
Cooldown--;
}
else if (!Fusion.IsConnected())
{
Cooldown = 0;
}
if (Fusion.IsConnected())
{
((Element)CooldownLabel).ElementName = ((Cooldown > 0) ? $"Cooldown: {Cooldown}" : "Ready to use") ?? "";
}
else
{
((Element)CooldownLabel).ElementName = string.Empty;
}
}
EverySecond?.Invoke();
}
if (RemainingLabel == null)
{
return;
}
if (SwitchEvery)
{
if (Fusion.IsAllowed())
{
if (_lastDelay == (float)Delay)
{
elapsed += TimeUtilities.DeltaTime;
if (elapsed >= 1f)
{
Remaining--;
elapsed = 0f;
}
if (Remaining <= 0)
{
Core.SwapToRandom();
Remaining = Delay;
}
}
else
{
_lastDelay = Delay;
Remaining = Delay;
elapsed = 0f;
}
}
else
{
_lastDelay = 0f;
Remaining = 0;
elapsed = 0f;
SwitchEvery = false;
}
if (!((Element)RemainingLabel).ElementName.EndsWith(Remaining.ToString()))
{
((Element)RemainingLabel).ElementName = $"Time until switch: {Remaining}";
}
}
else if (!((Element)RemainingLabel).ElementName.EndsWith("N/A"))
{
((Element)RemainingLabel).ElementName = "Time until switch: N/A";
}
}
}
}
namespace RandomAvatar.Menu.Elements
{
public class BlankElement
{
public readonly FunctionElement Element;
public BlankElement()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
Element = new FunctionElement(string.Empty, Color.white, (Action)null);
((Element)Element).SetProperty((ElementProperties)1);
}
}
public class ToggleFunctionElement
{
public readonly FunctionElement Element;
public Action<ToggleFunctionElement> Callback;
public Color OffColor;
public Color OnColor;
public bool IsRunning { get; private set; }
public event Action Started;
public event Action Cancelled;
public void Start()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
if (!IsRunning)
{
IsRunning = true;
((Element)Element).ElementColor = OnColor;
this.Started?.Invoke();
Callback?.Invoke(this);
}
}
public void Cancel()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
if (IsRunning)
{
IsRunning = false;
((Element)Element).ElementColor = OffColor;
this.Cancelled?.Invoke();
}
}
public ToggleFunctionElement(string name, Color offColor, Color onColor, Action<ToggleFunctionElement> callback)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: 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)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
Callback = callback;
OffColor = offColor;
OnColor = onColor;
Element = new FunctionElement(name, offColor, (Action)delegate
{
if (IsRunning)
{
Cancel();
}
else
{
Start();
}
});
}
public ToggleFunctionElement(string name, Color offColor, Action<ToggleFunctionElement> callback)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: 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_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
Callback = callback;
OffColor = offColor;
OnColor = Color.red;
Element = new FunctionElement(name, offColor, (Action)delegate
{
if (IsRunning)
{
Cancel();
}
else
{
Start();
}
});
}
}
}
namespace RandomAvatar.Helper
{
internal static class BLHelper
{
private static readonly MelonPreferences_Category prefs = Core.Preferences_Category;
internal static IntElement CreateIntPref(this Page page, string name, Color color, ref MelonPreferences_Entry<int> value, int increment, int minValue, int maxValue, MelonPreferences_Category category = null, Action<int> callback = null, string prefName = null, int prefDefaultValue = 0)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (category == null)
{
category = prefs;
}
if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
{
if (prefName == null)
{
prefName = name;
}
if (!category.HasEntry(prefName))
{
value = category.CreateEntry<int>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
}
}
MelonPreferences_Entry<int> val = value;
IntElement val2 = page.CreateInt(name, color, val.Value, increment, minValue, maxValue, (Action<int>)delegate(int x)
{
val.Value = x;
category.SaveToFile(false);
Action<int> action = callback;
if (action != null)
{
Extensions.InvokeActionSafe<int>(action, x);
}
});
if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
{
((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
}
return val2;
}
internal static FloatElement CreateFloatPref(this Page page, string name, Color color, ref MelonPreferences_Entry<float> value, float increment, float minValue, float maxValue, MelonPreferences_Category category = null, Action<float> callback = null, string prefName = null, float prefDefaultValue = 0f)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (category == null)
{
category = prefs;
}
if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
{
if (prefName == null)
{
prefName = name;
}
if (!category.HasEntry(prefName))
{
value = category.CreateEntry<float>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
}
}
MelonPreferences_Entry<float> val = value;
FloatElement val2 = page.CreateFloat(name, color, val.Value, increment, minValue, maxValue, (Action<float>)delegate(float x)
{
val.Value = x;
category.SaveToFile(false);
Action<float> action = callback;
if (action != null)
{
Extensions.InvokeActionSafe<float>(action, x);
}
});
if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
{
((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
}
return val2;
}
internal static BoolElement CreateBoolPref(this Page page, string name, Color color, ref MelonPreferences_Entry<bool> value, MelonPreferences_Category category = null, Action<bool> callback = null, string prefName = null, bool prefDefaultValue = false)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (category == null)
{
category = prefs;
}
if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
{
if (prefName == null)
{
prefName = name;
}
if (!category.HasEntry(prefName))
{
value = category.CreateEntry<bool>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
}
}
MelonPreferences_Entry<bool> val = value;
BoolElement val2 = page.CreateBool(name, color, val.Value, (Action<bool>)delegate(bool x)
{
val.Value = x;
category.SaveToFile(false);
Action<bool> action = callback;
if (action != null)
{
Extensions.InvokeActionSafe<bool>(action, x);
}
});
if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
{
((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
}
return val2;
}
internal static EnumElement CreateEnumPref<T>(this Page page, string name, Color color, ref MelonPreferences_Entry<T> value, MelonPreferences_Category category = null, Action<Enum> callback = null, string prefName = null, Enum prefDefaultValue = null) where T : Enum
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (category == null)
{
category = prefs;
}
if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
{
if (prefName == null)
{
prefName = name;
}
if (!category.HasEntry(prefName))
{
value = category.CreateEntry<T>(prefName, (T)prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
}
}
MelonPreferences_Entry<T> val = value;
EnumElement val2 = page.CreateEnum(name, color, (Enum)val.Value, (Action<Enum>)delegate(Enum x)
{
val.Value = (T)x;
category.SaveToFile(false);
Action<Enum> action = callback;
if (action != null)
{
Extensions.InvokeActionSafe<Enum>(action, x);
}
});
if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
{
((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
}
return val2;
}
internal static StringElement CreateStringPref(this Page page, string name, Color color, ref MelonPreferences_Entry<string> value, MelonPreferences_Category category = null, Action<string> callback = null, string prefName = null, string prefDefaultValue = null)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (category == null)
{
category = prefs;
}
if (value == null || !category.HasEntry(((MelonPreferences_Entry)value).Identifier))
{
if (prefName == null)
{
prefName = name;
}
if (!category.HasEntry(prefName))
{
value = category.CreateEntry<string>(prefName, prefDefaultValue, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
}
}
MelonPreferences_Entry<string> val = value;
StringElement val2 = page.CreateString(name, color, val.Value, (Action<string>)delegate(string x)
{
val.Value = x;
category.SaveToFile(false);
Action<string> action = callback;
if (action != null)
{
Extensions.InvokeActionSafe<string>(action, x);
}
});
val2.Value = value.Value;
if (!string.IsNullOrWhiteSpace(((MelonPreferences_Entry)value).Description))
{
((Element)val2).SetTooltip(((MelonPreferences_Entry)value).Description);
}
return val2;
}
public static FunctionElement CreateLabel(this Page page, string text, Color color)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Expected O, but got Unknown
FunctionElement val = new FunctionElement(text, color, (Action)null);
((Element)val).SetProperty((ElementProperties)1);
page.Add((Element)(object)val);
return val;
}
public static ToggleFunctionElement CreateToggleFunction(this Page page, string name, Color offColor, Color onColor, Action<ToggleFunctionElement> callback)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
ToggleFunctionElement toggleFunctionElement = new ToggleFunctionElement(name, offColor, onColor, callback);
page.Add((Element)(object)toggleFunctionElement.Element);
return toggleFunctionElement;
}
public static ToggleFunctionElement CreateToggleFunction(this Page page, string name, Color offColor, Action<ToggleFunctionElement> callback)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
ToggleFunctionElement toggleFunctionElement = new ToggleFunctionElement(name, offColor, callback);
page.Add((Element)(object)toggleFunctionElement.Element);
return toggleFunctionElement;
}
public static BlankElement CreateBlank(this Page page)
{
BlankElement blankElement = new BlankElement();
page.Add((Element)(object)blankElement.Element);
return blankElement;
}
internal static void SendNotification(string title, string message, bool showTitleOnPopup = false, float popupLength = 2f, NotificationType type = 0, Texture2D customIcon = null)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: 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)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
Notifier.Send(new Notification
{
Title = new NotificationText("RandomAvatar | " + title, Color.white, true),
Message = new NotificationText(message, Color.white, true),
ShowTitleOnPopup = showTitleOnPopup,
CustomIcon = customIcon,
PopupLength = popupLength,
Type = type
});
}
internal static void SendNotification(NotificationText title, NotificationText message, bool showTitleOnPopup = false, float popupLength = 2f, NotificationType type = 0, Texture2D customIcon = null)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
title.Text = "RandomAvatar | " + title.Text;
Notifier.Send(new Notification
{
Title = title,
Message = message,
ShowTitleOnPopup = showTitleOnPopup,
CustomIcon = customIcon,
PopupLength = popupLength,
Type = type
});
}
internal static void SendNotification(Notification notification)
{
Notifier.Send(notification);
}
}
public static class OtherHelpers
{
public static void ForEach<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, Action<KeyValuePair<TKey, TValue>> action)
{
foreach (KeyValuePair<TKey, TValue> item in dictionary)
{
action?.Invoke(item);
}
}
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (T item in enumerable)
{
action?.Invoke(item);
}
}
}
}