Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of thunderstoreinterface v1.0.0
ThunderstoreInterface.dll
Decompiled a day agousing 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(); } } } }