Decompiled source of Tribute v1.1.0

Muskiii.Tribute.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Steamworks;
using Tribute;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UIElements.Collections;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Muskiii.Tribute")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("Tribute")]
[assembly: AssemblyTitle("Muskiii.Tribute")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal class Netcommon
{
	public class T___00
	{
		public string status = "";

		public string message = "";

		public string posterImage = "";

		public string tipData = "";
	}

	private static readonly string randomId = Guid.NewGuid().ToString();

	public static readonly object RequestPosterResponseJson = new
	{
		status = "",
		message = "",
		posterImage = "",
		tipData = ""
	};

	public static readonly object RequestPaintingResponseJson = new
	{
		status = "",
		message = "",
		paintingData = new List<string>()
	};

	private static string GetLobbyName()
	{
		if (GameNetworkManager.Instance.disableSteam)
		{
			return "";
		}
		if (GameNetworkManager.Instance.steamLobbyName != null)
		{
			return GameNetworkManager.Instance.steamLobbyName + "`1`" + string.Join("x", GameNetworkManager.Instance.steamIdsInLobby.Select((SteamId s) => ((object)(SteamId)(ref s)).ToString()).ToArray());
		}
		return "";
	}

	private static string GetEncodedLobbyName()
	{
		string s;
		try
		{
			s = GetLobbyName();
		}
		catch (Exception ex)
		{
			s = "=n" + ex.Message;
		}
		return Convert.ToBase64String(Encoding.UTF8.GetBytes(s));
	}

	public static object RequestPosterRequestJson(string[] tags, int page)
	{
		return new
		{
			id = randomId,
			version = "1.1.0",
			tags = tags,
			page = page,
			config = new
			{
				log = (bool)((ConfigEntryBase)PluginConfig.LogAllowEntry).BoxedValue,
				showerror = (bool)((ConfigEntryBase)PluginConfig.ShowErrorEntry).BoxedValue,
				lobby = GetEncodedLobbyName(),
				nsfw = (bool)((ConfigEntryBase)PluginConfig.EnableNsfwEntry).BoxedValue
			}
		};
	}

	public static object RequestPaintingRequestJson(string[] tags, int page)
	{
		return new
		{
			id = randomId,
			version = "1.1.0",
			tags = tags,
			page = page,
			config = new
			{
				log = (bool)((ConfigEntryBase)PluginConfig.LogAllowEntry).BoxedValue,
				showerror = (bool)((ConfigEntryBase)PluginConfig.ShowErrorEntry).BoxedValue,
				lobby = GetEncodedLobbyName(),
				nsfw = (bool)((ConfigEntryBase)PluginConfig.EnableNsfwEntry).BoxedValue
			}
		};
	}
}
public abstract class TexturePatcher<T>
{
	public delegate void OnReadyHandler(TexturePatcher<T> patcher, Material[] materials, byte[][] data);

	private Task<bool>? loadingTask;

	private HttpClient httpClient = new HttpClient();

	protected static ManualLogSource Logger { get; set; }

	public abstract event OnReadyHandler OnReady;

	public TexturePatcher(ManualLogSource logger, params Material[] materials)
	{
		Logger = logger;
	}

	public abstract Task<bool> StartOrContinueLoading(Func<T> callback);

	protected async Task<string> postHttp(string url, object? data)
	{
		HttpContent postContent = new StringContent(JsonConvert.SerializeObject(data));
		Task<HttpResponseMessage> req = httpClient.PostAsync(url, postContent);
		return await (await req).Content.ReadAsStringAsync();
	}
}
public class PaintingCallback
{
	public Item? Item;

	public string Tags;

	public int Limit;
}
public class PaintingGet
{
	public static void LoadNewPaintings(string tags, int count)
	{
	}

	public static void LoadNextPaintings()
	{
	}
}
public class PosterCallback
{
	public Material Material;

	public string Tags;

	public int Limit;
}
namespace Tribute
{
	internal class Patches2
	{
		private class Cfg
		{
			public static bool enabled;

			public static bool enableNsfw;

			public static string posterTags;

			public static int posterLimit;

			public static bool paintingsEnabled;

			public static bool paintingsFromPosters;

			public static string paintingTags;

			public static int paintingLimit;

			public static bool oldEnabled;

			public static bool oldEnableNsfw;

			public static string oldPosterTags;

			public static int oldPosterLimit;

			public static bool oldPaintingsOn;

			public static bool oldPaintingsFromPosters;

			public static string oldPaintingTags;

			public static int oldPaintingLimit;
		}

		private static ManualLogSource Logger;

		private static TexturePatcherPoster? posterPatcher;

		private static TexturePatcherPainting? paintingPatcher;

		private static bool hasAttachedPoster;

		private static bool hasAttachedPainting;

		private static DateTime lastGenerateNewLevel;

		private static bool CheckForConfigUpdates()
		{
			Logger.LogDebug((object)"Cfg ");
			bool enabled = Cfg.enabled;
			bool enableNsfw = Cfg.enableNsfw;
			string posterTags = Cfg.posterTags;
			int posterLimit = Cfg.posterLimit;
			bool paintingsEnabled = Cfg.paintingsEnabled;
			bool oldPaintingsFromPosters = Cfg.oldPaintingsFromPosters;
			string paintingTags = Cfg.paintingTags;
			int paintingLimit = Cfg.paintingLimit;
			Cfg.oldEnabled = enabled;
			Cfg.oldEnableNsfw = enableNsfw;
			Cfg.oldPosterTags = posterTags;
			Cfg.oldPosterLimit = posterLimit;
			Cfg.oldPaintingsOn = paintingsEnabled;
			Cfg.oldPaintingsFromPosters = oldPaintingsFromPosters;
			Cfg.oldPaintingTags = paintingTags;
			Cfg.oldPaintingLimit = paintingLimit;
			Cfg.enabled = true;
			Cfg.enableNsfw = (bool)((ConfigEntryBase)PluginConfig.EnableNsfwEntry).BoxedValue;
			Cfg.posterTags = (string)((ConfigEntryBase)PluginConfig.TagsEntry).BoxedValue;
			Cfg.posterLimit = (int)((ConfigEntryBase)PluginConfig.LimitEntry).BoxedValue;
			Cfg.paintingsEnabled = (bool)((ConfigEntryBase)PluginConfig.PaintingsOnEntry).BoxedValue;
			Cfg.paintingsFromPosters = (bool)((ConfigEntryBase)PluginConfig.PaintingsFromPostersEntry).BoxedValue;
			Cfg.paintingTags = (string)((ConfigEntryBase)PluginConfig.PaintingTagsEntry).BoxedValue;
			Cfg.paintingLimit = (int)((ConfigEntryBase)PluginConfig.PaintingLimitEntry).BoxedValue;
			if (enabled != Cfg.enabled || posterTags != Cfg.posterTags || posterLimit != Cfg.posterLimit || paintingsEnabled != Cfg.paintingsEnabled || paintingTags != Cfg.paintingTags || paintingLimit != Cfg.paintingLimit)
			{
				return true;
			}
			return false;
		}

		private static void GetLatestData()
		{
			string value = Cfg.oldPosterTags ?? "";
			string value2 = Cfg.oldPaintingTags ?? "";
			bool flag = Cfg.oldPosterTags != null && Cfg.posterTags.Equals(value);
			bool flag2 = Cfg.oldPaintingTags != null && Cfg.paintingTags.Equals(value2);
			bool enabled = Cfg.enabled;
			bool paintingsEnabled = Cfg.paintingsEnabled;
			if (enabled)
			{
				StartLoadingPosterData();
			}
			if (paintingsEnabled)
			{
				Func<Task> func = async delegate
				{
					Task.Delay(1512);
					StartLoadingPaintingData();
				};
				func();
			}
		}

		private static void StartLoadingPosterData()
		{
			posterPatcher.StartOrContinueLoading(() => new PosterCallback
			{
				Material = null,
				Tags = Cfg.posterTags,
				Limit = Cfg.posterLimit
			});
		}

		private static void StartLoadingPaintingData()
		{
			string text = (Cfg.paintingsFromPosters ? Cfg.posterTags : Cfg.paintingTags);
			if (!paintingPatcher.HasEnoughPaintings(text, Cfg.paintingLimit))
			{
				paintingPatcher.StartGettingPaintings(text.Split(" "), Cfg.paintingLimit);
			}
		}

		public static void Init(ManualLogSource logger)
		{
			Logger = logger;
			posterPatcher = new TexturePatcherPoster(logger);
			paintingPatcher = new TexturePatcherPainting(logger);
			Boot();
			PluginConfig.CfgFile.SettingChanged += async delegate
			{
				if (!Cfg.posterTags.Equals((string)((ConfigEntryBase)PluginConfig.TagsEntry).BoxedValue))
				{
					posterPatcher.currentPage = 1;
				}
				Boot();
			};
		}

		private static void Boot()
		{
			CheckForConfigUpdates();
			GetLatestData();
			if (Cfg.enabled && !hasAttachedPoster)
			{
				posterPatcher.OnReady += async delegate(TexturePatcher<PosterCallback> patcher, Material[] materials, byte[][] data)
				{
					UpdateMaterialTexture(materials[0], data[0]);
					UpdateMaterialTexture(materials[1], data[1]);
				};
				hasAttachedPoster = true;
			}
			if (Cfg.paintingsEnabled && !hasAttachedPainting)
			{
				paintingPatcher.OnReady += async delegate
				{
				};
				hasAttachedPainting = true;
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void StartPatch()
		{
			CheckForConfigUpdates();
			StartLoadingPosterData();
		}

		[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
		[HarmonyPostfix]
		private static void GenerateNewLevelClientRpcPatch(int randomSeed)
		{
			DateTime utcNow = DateTime.UtcNow;
			_ = lastGenerateNewLevel;
			if (utcNow.Subtract(lastGenerateNewLevel).TotalMilliseconds > 500.0)
			{
				StartLoadingPosterData();
			}
			lastGenerateNewLevel = utcNow;
		}

		[HarmonyPatch(typeof(GrabbableObject), "SetScrapValue")]
		[HarmonyPostfix]
		private static void SetScrapValuePatch(GrabbableObject __instance)
		{
			try
			{
				CheckForConfigUpdates();
				if (Cfg.paintingsEnabled && __instance.itemProperties.itemName == "Painting")
				{
					paintingPatcher.GetNextPainting(__instance, (int)((NetworkBehaviour)__instance).NetworkObjectId);
				}
			}
			catch (Exception ex)
			{
				Logger.LogError((object)"ss");
				Logger.LogError((object)ex);
			}
		}

		private static void UpdateMaterialTexture(Material material, byte[] data)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, data);
			material.mainTexture = (Texture)(object)val;
		}
	}
	[BepInPlugin("Muskiii.Tribute", "Tribute", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static readonly List<string> PosterFiles = new List<string>();

		public static readonly List<string> TipFiles = new List<string>();

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Patches2.Init(((BaseUnityPlugin)this).Logger);
			Harmony val = new Harmony("Muskiii.Tribute");
			val.PatchAll(typeof(Patches2));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Tribute (1.1.0) is loaded!");
		}
	}
	internal class PluginConfig
	{
		private static readonly string POSTER_PAINTING_BASE_URL;

		public static readonly string POSTER_REQUEST_END;

		public static readonly string PAINTING_REQUEST_END;

		public static readonly string POSTER_REQUEST_URL;

		public static readonly string PAINTING_REQUEST_URL;

		public static ConfigEntry<string> TagsEntry;

		public static ConfigEntry<bool> EnableNsfwEntry;

		public static ConfigEntry<int> LimitEntry;

		public static ConfigEntry<bool> ShowErrorEntry;

		public static ConfigEntry<bool> SyncEntry;

		public static ConfigEntry<bool> LogAllowEntry;

		public static ConfigEntry<bool> PaintingsOnEntry;

		public static ConfigEntry<bool> PaintingsFromPostersEntry;

		public static ConfigEntry<string> PaintingTagsEntry;

		public static ConfigEntry<int> PaintingLimitEntry;

		public static BoolCheckBoxConfigItem EnableNsfw;

		public static TextInputFieldConfigItem Tags;

		public static IntInputFieldConfigItem Limit;

		public static BoolCheckBoxConfigItem ShowError;

		public static BoolCheckBoxConfigItem Sync;

		public static BoolCheckBoxConfigItem LogAllow;

		public static BoolCheckBoxConfigItem PaintingsOn;

		public static BoolCheckBoxConfigItem PaintingsFromPosters;

		public static TextInputFieldConfigItem PaintingTags;

		public static IntInputFieldConfigItem PaintingLimit;

		public static ConfigFile CfgFile { get; set; }

		static PluginConfig()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_01d7: Expected O, but got Unknown
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Expected O, but got Unknown
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Expected O, but got Unknown
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Expected O, but got Unknown
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Expected O, but got Unknown
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Expected O, but got Unknown
			//IL_027e: 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_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Expected O, but got Unknown
			//IL_02af: Expected O, but got Unknown
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Expected O, but got Unknown
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Expected O, but got Unknown
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Expected O, but got Unknown
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Expected O, but got Unknown
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Expected O, but got Unknown
			POSTER_PAINTING_BASE_URL = "https://musky.lol/tribute/v1/";
			POSTER_REQUEST_END = "request";
			PAINTING_REQUEST_END = "request_painting";
			POSTER_REQUEST_URL = POSTER_PAINTING_BASE_URL + POSTER_REQUEST_END;
			PAINTING_REQUEST_URL = POSTER_PAINTING_BASE_URL + PAINTING_REQUEST_END;
			CfgFile = new ConfigFile(Paths.ConfigPath + "\\Tribute.cfg", true);
			TagsEntry = CfgFile.Bind<string>("General", "Tags", "order:score rating:safe", "Tags to search for posters");
			EnableNsfwEntry = CfgFile.Bind<bool>("General", "Enable NSFW", !((string)((ConfigEntryBase)TagsEntry).BoxedValue).Contains("rating:s"), "Enable NSFW results from e621 - You must be at least 18 years old to enable NSFW results - By enabling this you agree you are at least 18 years old");
			LimitEntry = CfgFile.Bind<int>("General", "Count", 5, "How many sets of posters to generate");
			ShowErrorEntry = CfgFile.Bind<bool>("General", "Show Error", true, "Show error when tags dont have any posts");
			LogAllowEntry = CfgFile.Bind<bool>("Logging", "Allow", false, "Allow requests to be logged for debugging (see readme)");
			PaintingsOnEntry = CfgFile.Bind<bool>("Paintings", "Enable Paintings", true, "Enable paintings");
			PaintingsFromPostersEntry = CfgFile.Bind<bool>("Paintings", "Use poster tags for paintings", true, "Use poster tags for paintings");
			PaintingTagsEntry = CfgFile.Bind<string>("Paintings", "Paintings Tags", "order:score rating:safe", "Tags to search for paintings");
			PaintingLimitEntry = CfgFile.Bind<int>("Paintings", "Paintings Limit", 5, "How many sets of posters to generate");
			EnableNsfw = new BoolCheckBoxConfigItem(EnableNsfwEntry, new BoolCheckBoxOptions
			{
				RequiresRestart = false
			});
			Tags = new TextInputFieldConfigItem(TagsEntry, new TextInputFieldOptions
			{
				NumberOfLines = 1,
				RequiresRestart = false
			});
			ConfigEntry<int> limitEntry = LimitEntry;
			IntInputFieldOptions val = new IntInputFieldOptions();
			((BaseRangeOptions<int>)val).Min = 1;
			((BaseRangeOptions<int>)val).Max = 20;
			((BaseOptions)val).RequiresRestart = false;
			Limit = new IntInputFieldConfigItem(limitEntry, val);
			ShowError = new BoolCheckBoxConfigItem(ShowErrorEntry, new BoolCheckBoxOptions
			{
				RequiresRestart = false
			});
			LogAllow = new BoolCheckBoxConfigItem(LogAllowEntry, new BoolCheckBoxOptions
			{
				RequiresRestart = false
			});
			PaintingsOn = new BoolCheckBoxConfigItem(PaintingsOnEntry, new BoolCheckBoxOptions
			{
				RequiresRestart = false
			});
			PaintingsFromPosters = new BoolCheckBoxConfigItem(PaintingsFromPostersEntry, new BoolCheckBoxOptions
			{
				RequiresRestart = false
			});
			PaintingTags = new TextInputFieldConfigItem(PaintingTagsEntry, new TextInputFieldOptions
			{
				NumberOfLines = 1,
				RequiresRestart = false,
				CanModifyCallback = (CanModifyDelegate)(() => CanModifyResult.op_Implicit(!(bool)((ConfigEntryBase)PaintingsFromPostersEntry).BoxedValue))
			});
			ConfigEntry<int> paintingLimitEntry = PaintingLimitEntry;
			IntInputFieldOptions val2 = new IntInputFieldOptions();
			((BaseRangeOptions<int>)val2).Min = 1;
			((BaseRangeOptions<int>)val2).Max = 20;
			((BaseOptions)val2).RequiresRestart = false;
			PaintingLimit = new IntInputFieldConfigItem(paintingLimitEntry, val2);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)EnableNsfw);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)Tags);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)Limit);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)ShowError);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)LogAllow);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)PaintingsOn);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)PaintingsFromPosters);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)PaintingTags);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)PaintingLimit);
		}
	}
	public class TexturePatcherPainting : TexturePatcher<PaintingCallback>
	{
		private List<Item> items = new List<Item>();

		private List<Material> createdMaterials = new List<Material>();

		private Task<bool>? runningTask;

		private Task<bool>? otherRunningTask;

		private int currentPage = 1;

		private int currentPosterIndex = 0;

		private string currentTags = "";

		private List<byte[]> datas = new List<byte[]>();

		private Random rand = new Random();

		private int currentLimit = 1;

		private string[] lastPaintingDatas = Array.Empty<string>();

		public override event OnReadyHandler? OnReady;

		public TexturePatcherPainting(ManualLogSource logger, params Material[] materials)
			: base(logger, Array.Empty<Material>())
		{
		}

		private int GetNextPage(int limit)
		{
			if (createdMaterials.Count > limit)
			{
				createdMaterials = createdMaterials.Take(createdMaterials.Count - (createdMaterials.Count - limit)).ToList();
				currentPage = 1;
			}
			int result = currentPage;
			currentPage++;
			return result;
		}

		public bool HasEnoughPaintings(string tags, int count)
		{
			if (!tags.Equals(currentTags))
			{
				return false;
			}
			return datas.Count >= count;
		}

		public async Task<bool> StartGettingPaintings(string[] tags, int limit)
		{
			string[] tags2 = tags;
			datas.Clear();
			currentPage = 1;
			currentLimit = limit;
			currentTags = string.Join(" ", tags2);
			Func<int, Task> getWithPage = async delegate(int page)
			{
				var jsonResponse = JsonConvert.DeserializeAnonymousType(await postHttp(PluginConfig.PAINTING_REQUEST_URL, Netcommon.RequestPaintingRequestJson(tags2, page)), new
				{
					status = "",
					message = "",
					paintingData = new List<string>()
				});
				string[] paintingDatas = jsonResponse.paintingData.ToArray();
				if (jsonResponse.status == "ok")
				{
					string[] array = paintingDatas;
					foreach (string paintingData in array)
					{
						byte[] painting = Convert.FromBase64String(paintingData);
						datas.Add(painting);
					}
				}
			};
			await getWithPage(currentPage);
			while (datas.Count < limit)
			{
				await getWithPage(++currentPage);
			}
			return true;
		}

		public async Task<byte[]> DispensePainting()
		{
			return datas[rand.Next(datas.Count)];
		}

		public void GetNextPainting(GrabbableObject __instance, int seed)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			if (__instance.itemProperties.materialVariants.Length >= currentLimit)
			{
				return;
			}
			List<Material> list = new List<Material>(currentLimit);
			Random random = new Random(seed);
			Material[] array = (Material[])(object)new Material[currentLimit];
			List<int> list2 = new List<int>();
			list2.Clear();
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Material(__instance.itemProperties.materialVariants[0]);
				int num;
				do
				{
					num = random.Next(datas.Count);
				}
				while (list2.Contains(num));
				list2.Add(num);
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, datas[num]);
				array[i].mainTexture = (Texture)(object)val;
			}
			__instance.itemProperties.materialVariants = array;
		}

		private static void UpdateMaterialTexture(Material material, byte[] data)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, data);
			material.mainTexture = (Texture)(object)val;
		}

		public override async Task<bool> StartOrContinueLoading(Func<PaintingCallback> callback)
		{
			Func<PaintingCallback> callback2 = callback;
			if (callback2 == null)
			{
				return false;
			}
			if (runningTask != null)
			{
				PaintingCallback pageNTags = callback2();
				if ((Object)(object)pageNTags.Item != (Object)null)
				{
					items.Add(pageNTags.Item);
				}
				if (otherRunningTask == null)
				{
					otherRunningTask = Runner(items, pageNTags.Limit);
				}
				await otherRunningTask;
			}
			if (runningTask == null)
			{
				Func<Task<bool>> toRun = async delegate
				{
					PaintingCallback pageNTags2 = callback2();
					int limit = pageNTags2.Limit;
					string[] tags = pageNTags2.Tags.Split(" ");
					if ((Object)(object)pageNTags2.Item != (Object)null)
					{
						if (otherRunningTask == null)
						{
						}
						await otherRunningTask;
						items.Add(pageNTags2.Item);
						if (currentPosterIndex < createdMaterials.Count)
						{
							Item? item = pageNTags2.Item;
							Material[] array = new Material[1];
							List<Material> list = createdMaterials;
							TexturePatcherPainting texturePatcherPainting = this;
							int num = currentPosterIndex;
							texturePatcherPainting.currentPosterIndex = num + 1;
							array[0] = list[num];
							item.materialVariants = (Material[])(object)array;
							if (currentPosterIndex > createdMaterials.Count)
							{
								currentPosterIndex = 0;
							}
							return true;
						}
						return true;
					}
					int page = GetNextPage(limit);
					var jsonResponse = JsonConvert.DeserializeAnonymousType(await postHttp(PluginConfig.PAINTING_REQUEST_URL, Netcommon.RequestPaintingRequestJson(tags, page)), new
					{
						status = "",
						message = "",
						paintingData = new List<string>()
					});
					string[] paintingDatas = jsonResponse.paintingData.ToArray();
					if (jsonResponse.status == "ok")
					{
						lastPaintingDatas = paintingDatas;
						if (items.Count > 0)
						{
							otherRunningTask = Runner(items, limit);
							await otherRunningTask;
							items = new List<Item>();
						}
						return true;
					}
					return false;
				};
				runningTask = toRun();
			}
			return runningTask != null;
		}

		private async Task<bool> Runner(List<Item> items, int limit)
		{
			if (items.Count == 0)
			{
				return false;
			}
			Item it = items[0];
			Material commat = it.materialVariants[0];
			List<Material> mats = new List<Material>();
			List<byte[]> datas = new List<byte[]>();
			string[] array = lastPaintingDatas;
			foreach (string paintingData in array)
			{
				byte[] data = Convert.FromBase64String(paintingData);
				datas.Add(data);
			}
			for (int g = 0; g < datas.Count; g++)
			{
				if (createdMaterials.Count >= limit)
				{
					break;
				}
				Material newmat = new Material(commat);
				Texture2D texture = new Texture2D(2, 2);
				ImageConversion.LoadImage(texture, datas[g]);
				newmat.mainTexture = (Texture)(object)texture;
				createdMaterials.Add(newmat);
			}
			new HashSet<int>();
			foreach (Item item in items)
			{
				Random rand = new Random((int)DateTime.UtcNow.Ticks);
				List<Material> randomMats = new List<Material>();
				for (int i = 0; i < createdMaterials.Count; i++)
				{
					randomMats.Add(createdMaterials[rand.Next() % createdMaterials.Count]);
				}
				item.materialVariants = randomMats.ToArray();
			}
			if (OnReady != null)
			{
				OnReady(this, mats.ToArray(), datas.ToArray());
			}
			runningTask = null;
			otherRunningTask = null;
			return true;
		}
	}
	public class TexturePatcherPoster : TexturePatcher<PosterCallback>
	{
		public int currentPage = 0;

		private Task<bool> runningTask;

		private Dictionary<Task<bool>, int> idByTask = new Dictionary<Task<bool>, int>();

		private int currentTaskId = 0;

		private HashSet<int> canceledTaskIds = new HashSet<int>();

		public override event OnReadyHandler? OnReady;

		public TexturePatcherPoster(ManualLogSource logger, params Material[] materials)
			: base(logger, Array.Empty<Material>())
		{
		}

		public bool Cancel()
		{
			if (runningTask == null)
			{
				return false;
			}
			int item = DictionaryExtensions.Get<Task<bool>, int>((IDictionary<Task<bool>, int>)idByTask, runningTask, 0);
			canceledTaskIds.Add(item);
			runningTask = null;
			return true;
		}

		public override async Task<bool> StartOrContinueLoading(Func<PosterCallback> callback)
		{
			Func<PosterCallback> callback2 = callback;
			if (callback2 == null)
			{
				return false;
			}
			if (runningTask != null)
			{
				Cancel();
			}
			Func<int, Task<bool>> toRun = async delegate(int taskId)
			{
				PosterCallback pageNTags = callback2();
				int limit = pageNTags.Limit;
				string[] tags = pageNTags.Tags.Split(" ");
				TexturePatcherPoster texturePatcherPoster = this;
				int num = currentPage;
				texturePatcherPoster.currentPage = num + 1;
				int page = num;
				currentPage %= limit;
				if (currentPage < 0)
				{
					currentPage = 0;
				}
				var jsonResponse = JsonConvert.DeserializeAnonymousType(await postHttp(PluginConfig.POSTER_REQUEST_URL, Netcommon.RequestPosterRequestJson(tags, page)), new
				{
					status = "",
					message = "",
					posterImage = "",
					tipData = ""
				});
				if (jsonResponse.status == "ok")
				{
					if (canceledTaskIds.Contains(taskId))
					{
						return false;
					}
					byte[] posterData = Convert.FromBase64String(jsonResponse.posterImage);
					byte[] tipData = Convert.FromBase64String(jsonResponse.tipData);
					Material[] materials = ((Renderer)GameObject.Find("HangarShip/Plane.001").GetComponent<MeshRenderer>()).materials;
					if (OnReady != null)
					{
						OnReady(this, (Material[])(object)new Material[2]
						{
							materials[0],
							materials[1]
						}, new byte[2][] { posterData, tipData });
					}
					return true;
				}
				return false;
			};
			int taskId2 = currentTaskId++;
			runningTask = toRun(taskId2);
			idByTask.Add(runningTask, taskId2);
			return true;
		}
	}
	internal class Cacher
	{
		private static Dictionary<string, Dictionary<int, byte[]>> posterCache = new Dictionary<string, Dictionary<int, byte[]>>();

		private static Dictionary<string, Dictionary<int, byte[]>> tipCache = new Dictionary<string, Dictionary<int, byte[]>>();

		private static Dictionary<string, Dictionary<int, byte[]>> paintingCache = new Dictionary<string, Dictionary<int, byte[]>>();

		private static ManualLogSource Logger { get; set; }

		public static void Init(ManualLogSource logger)
		{
			Logger = logger;
		}

		public static void Clear()
		{
			posterCache.Clear();
			tipCache.Clear();
			paintingCache.Clear();
		}

		public static bool SetPoster(string tags, int page, byte[] posterData)
		{
			Dictionary<int, byte[]> dictionary = DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)posterCache, tags, (Dictionary<int, byte[]>)null);
			if (dictionary != null)
			{
				byte[] array = DictionaryExtensions.Get<int, byte[]>((IDictionary<int, byte[]>)dictionary, page, (byte[])null);
				if (array != null)
				{
					return true;
				}
				dictionary.Add(page, posterData);
			}
			else
			{
				posterCache.Add(tags, new Dictionary<int, byte[]>());
				DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)posterCache, tags, (Dictionary<int, byte[]>)null).Add(page, posterData);
			}
			return false;
		}

		public static bool SetTips(string tags, int page, byte[] tipsData)
		{
			Dictionary<int, byte[]> dictionary = DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)tipCache, tags, (Dictionary<int, byte[]>)null);
			if (dictionary != null)
			{
				byte[] array = DictionaryExtensions.Get<int, byte[]>((IDictionary<int, byte[]>)dictionary, page, (byte[])null);
				if (array != null)
				{
					return true;
				}
				dictionary.Add(page, tipsData);
			}
			else
			{
				tipCache.Add(tags, new Dictionary<int, byte[]>());
				DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)tipCache, tags, (Dictionary<int, byte[]>)null).Add(page, tipsData);
			}
			return false;
		}

		public static bool SetPainting(string tags, int page, byte[] paintingData)
		{
			Dictionary<int, byte[]> dictionary = DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)paintingCache, tags, (Dictionary<int, byte[]>)null);
			if (dictionary != null)
			{
				byte[] array = DictionaryExtensions.Get<int, byte[]>((IDictionary<int, byte[]>)dictionary, page, (byte[])null);
				if (array != null)
				{
					return true;
				}
				dictionary.Add(page, paintingData);
			}
			else
			{
				paintingCache.Add(tags, new Dictionary<int, byte[]>());
				DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)paintingCache, tags, (Dictionary<int, byte[]>)null).Add(page, paintingData);
			}
			return false;
		}

		public static byte[]? GetPoster(string tags, int page)
		{
			Dictionary<int, byte[]> dictionary = DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)posterCache, tags, (Dictionary<int, byte[]>)null);
			if (dictionary != null)
			{
				byte[] array = DictionaryExtensions.Get<int, byte[]>((IDictionary<int, byte[]>)dictionary, page, (byte[])null);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? GetTip(string tags, int page)
		{
			try
			{
				Dictionary<int, byte[]> dictionary = DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)tipCache, tags, (Dictionary<int, byte[]>)null);
				if (dictionary != null)
				{
					byte[] array = DictionaryExtensions.Get<int, byte[]>((IDictionary<int, byte[]>)dictionary, page, (byte[])null);
					if (array != null)
					{
						return array;
					}
				}
				return null;
			}
			catch (NullReferenceException ex)
			{
				Logger.LogError((object)ex);
			}
			return null;
		}

		public static byte[]? GetPainting(string tags, int page)
		{
			try
			{
				Dictionary<int, byte[]> dictionary = DictionaryExtensions.Get<string, Dictionary<int, byte[]>>((IDictionary<string, Dictionary<int, byte[]>>)paintingCache, tags, (Dictionary<int, byte[]>)null);
				if (dictionary != null)
				{
					byte[] array = DictionaryExtensions.Get<int, byte[]>((IDictionary<int, byte[]>)dictionary, page, (byte[])null);
					if (array != null)
					{
						return array;
					}
				}
			}
			catch (NullReferenceException ex)
			{
				Logger.LogError((object)ex);
			}
			return null;
		}
	}
	[BepInPlugin("Muskiii.Tribute", "Tribute", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Tribute : BaseUnityPlugin
	{
		public static Tribute Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Patch();
			Logger.LogInfo((object)"Muskiii.Tribute v1.1.0 has loaded!");
		}

		internal static void Patch()
		{
			//IL_000d: 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_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("Muskiii.Tribute");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Muskiii.Tribute";

		public const string PLUGIN_NAME = "Tribute";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}