Decompiled source of thunderstoreinterface v1.0.0

ThunderstoreInterface.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;

[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("ThunderstoreInterface")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+95393cf0a14f2eab6a0a26e964a880a7a6855e3f")]
[assembly: AssemblyProduct("ThunderstoreInterface")]
[assembly: AssemblyTitle("ThunderstoreInterface")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ThunderstoreInterface
{
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInPlugin("zzz.kina.ThunderstoreInterface", "ThunderstoreInterface", "1.0.0")]
	public class ThunderstoreInterface : BaseUnityPlugin
	{
		public class ThunderstoreInfo(string team, Manifest manifest, string GUID)
		{
			public string team = team;

			public Manifest manifest = manifest;

			public string GUID = GUID;

			public APIResponse packageData;
		}

		public class Manifest
		{
			[JsonProperty("name")]
			internal string Name { get; set; }

			[JsonProperty("version_number")]
			internal string VersionNumber { get; set; }

			[JsonProperty("website_url")]
			internal Uri WebsiteUrl { get; set; }

			[JsonProperty("description")]
			internal string Description { get; set; }

			[JsonProperty("dependencies")]
			internal List<string> Dependencies { get; set; }
		}

		public class APIResponse
		{
			[JsonProperty("namespace")]
			internal string Namespace { get; set; }

			[JsonProperty("name")]
			internal string Name { get; set; }

			[JsonProperty("full_name")]
			internal string FullName { get; set; }

			[JsonProperty("owner")]
			internal string Owner { get; set; }

			[JsonProperty("package_url")]
			internal string PackageUrl { get; set; }

			[JsonProperty("date_created")]
			internal string DateCreated { get; set; }

			[JsonProperty("date_updated")]
			internal string DateUpdated { get; set; }

			[JsonProperty("is_pinned")]
			internal bool IsPinned { get; set; }

			[JsonProperty("is_deprecated")]
			internal bool IsDeprecated { get; set; }

			[JsonProperty("total_downloads")]
			internal string TotalDownloads { get; set; }

			[JsonProperty("latest")]
			internal PackageVersionExperimental Latest { get; set; }

			[JsonProperty("community_listings")]
			internal List<PackageListingExperimental> CommumityListings { get; set; }
		}

		public class PackageVersionExperimental
		{
			[JsonProperty("namespace")]
			internal string Namespace { get; set; }

			[JsonProperty("name")]
			internal string Name { get; set; }

			[JsonProperty("full_name")]
			internal string FullName { get; set; }

			[JsonProperty("version_number")]
			internal string VersionNumber { get; set; }

			[JsonProperty("description")]
			internal string Description { get; set; }

			[JsonProperty("date_created")]
			internal string DateCreated { get; set; }

			[JsonProperty("icon")]
			internal string Icon { get; set; }

			[JsonProperty("dependencies")]
			internal List<string> Dependencies { get; set; }

			[JsonProperty("download_url")]
			internal string DownloadUrl { get; set; }

			[JsonProperty("downloads")]
			internal int Downloads { get; set; }

			[JsonProperty("website_url")]
			internal string WebsiteUrl { get; set; }

			[JsonProperty("is_active")]
			internal bool IsActive { get; set; }
		}

		public class PackageListingExperimental
		{
			[JsonProperty("has_nsfw_content")]
			internal bool HasNSFWContent { get; set; }

			[JsonProperty("categories")]
			internal List<string> Categories { get; set; }

			[JsonProperty("community")]
			internal string Community { get; set; }

			[JsonProperty("review_status")]
			internal string ReviewStatus { get; set; }
		}

		private const string PluginGUID = "zzz.kina.ThunderstoreInterface";

		private const string PluginAuthor = "kina";

		private const string PluginName = "ThunderstoreInterface";

		private const string PluginVersion = "1.0.0";

		private static int modCount;

		private static List<ThunderstoreInfo> cachedInfos = new List<ThunderstoreInfo>();

		public static List<ThunderstoreInfo> thunderstoreInfos = new List<ThunderstoreInfo>();

		public static Action finishedAllMods;

		public static Action containsAI;

		public static List<ThunderstoreInfo> aigenMods = new List<ThunderstoreInfo>();

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			GetThunderstoreInfos();
		}

		public static async void GetThunderstoreInfos()
		{
			modCount = Chainloader.PluginInfos.Values.Count;
			try
			{
				if (File.Exists(Path.Combine(Environment.CurrentDirectory, "ThunderstoreInfos.json")) && cachedInfos.Count == 0)
				{
					Log.Debug("json exists, loading");
					cachedInfos = JsonConvert.DeserializeObject<List<ThunderstoreInfo>>(await File.ReadAllTextAsync(Path.Combine(Environment.CurrentDirectory, "ThunderstoreInfos.json")));
				}
			}
			catch (Exception ex)
			{
				Exception e = ex;
				Log.Warning("failed to read cached json !");
				Log.Warning(e);
			}
			finishedAllMods = (Action)Delegate.Combine(finishedAllMods, (Action)delegate
			{
				foreach (ThunderstoreInfo thunderstoreInfo2 in thunderstoreInfos)
				{
					if (thunderstoreInfo2.packageData.CommumityListings[0].Categories.Contains("AI Generated"))
					{
						aigenMods.Add(thunderstoreInfo2);
					}
				}
				if (aigenMods.Count > 0)
				{
					containsAI?.Invoke();
				}
			});
			try
			{
				foreach (PluginInfo pluginInfo in Chainloader.PluginInfos.Values)
				{
					bool skipGUID = false;
					foreach (ThunderstoreInfo thunderstoreInfo in cachedInfos)
					{
						if (thunderstoreInfo.GUID != pluginInfo.Metadata.GUID)
						{
							continue;
						}
						thunderstoreInfos.Add(thunderstoreInfo);
						skipGUID = true;
						LowerModCount();
						break;
					}
					if (skipGUID)
					{
						continue;
					}
					string manifestPath = null;
					DirectoryInfo currentFolder = new DirectoryInfo(Path.GetDirectoryName(pluginInfo.Location));
					for (int count = 0; count < 10; count++)
					{
						if (currentFolder.FullName == Paths.PluginPath)
						{
							break;
						}
						if (currentFolder.Parent == null)
						{
							break;
						}
						string potentialManifestPath = Path.Combine(currentFolder.FullName, "manifest.json");
						if (File.Exists(potentialManifestPath))
						{
							manifestPath = potentialManifestPath;
							break;
						}
						currentFolder = currentFolder.Parent;
					}
					if (manifestPath != null)
					{
						Manifest thunderstoreManifestV1 = JsonConvert.DeserializeObject<Manifest>(await File.ReadAllTextAsync(manifestPath));
						string teamNameDelimiter = "-" + thunderstoreManifestV1.Name;
						string team = "|";
						string directoryName = new DirectoryInfo(Path.GetDirectoryName(manifestPath)).Name;
						if (directoryName.Contains(teamNameDelimiter))
						{
							team = directoryName.Split(new string[1] { teamNameDelimiter }, StringSplitOptions.RemoveEmptyEntries)[0];
						}
						if (team == "|")
						{
							Log.Warning("couldnt find team name for " + thunderstoreManifestV1.Name + " ,., likely a local mod ,..,");
							LowerModCount();
							continue;
						}
						GetThunderstoreInfoAsync("https://thunderstore.io/api/experimental/package/" + team + "/" + thunderstoreManifestV1.Name + "/", new ThunderstoreInfo(team, thunderstoreManifestV1, pluginInfo.Metadata.GUID));
						await Task.Delay(TimeSpan.FromSeconds(0.30000001192092896));
					}
					else
					{
						LowerModCount();
					}
				}
			}
			catch (Exception data)
			{
				Log.Warning("exception while getting thunderstore info .,., ");
				Log.Warning(data);
			}
		}

		private static async void GetThunderstoreInfoAsync(string url, ThunderstoreInfo tsInfo)
		{
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();
			UnityWebRequest uwr = UnityWebRequest.Get(url);
			try
			{
				AsyncOperation asyncOp = (AsyncOperation)(object)uwr.SendWebRequest();
				while (!asyncOp.isDone)
				{
					await Task.Delay(16);
				}
				if ((int)uwr.result != 1)
				{
					Log.Debug(uwr.error + ": " + url);
				}
				else
				{
					Log.Debug(uwr.downloadHandler.text);
					tsInfo.packageData = JsonConvert.DeserializeObject<APIResponse>(uwr.downloadHandler.text);
					thunderstoreInfos.Add(tsInfo);
					cachedInfos.Add(tsInfo);
				}
				LowerModCount();
			}
			finally
			{
				((IDisposable)uwr)?.Dispose();
			}
		}

		private static void LowerModCount()
		{
			modCount--;
			if (modCount == 0)
			{
				string contents = JsonConvert.SerializeObject((object)cachedInfos, (Formatting)1);
				File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "ThunderstoreInfos.json"), contents);
				finishedAllMods?.Invoke();
			}
		}
	}
}