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 CruiserSkinRevived v1.1.0
BepInEx/plugins/CruiserSkinRevived.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LethalNetworkAPI; using LethalNetworkAPI.Utils; using TerminalApi; using TerminalApi.Classes; using TerminalApi.Events; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("CruiserSkinRevived")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f2f73231a9be60d9edab16f2377085ae6fbe4a52")] [assembly: AssemblyProduct("CruiserSkinRevived")] [assembly: AssemblyTitle("CruiserSkinRevived")] [assembly: AssemblyVersion("1.0.0.0")] namespace CruiserSkinRevived.Main; [BepInPlugin("Fitrusielle.CruiserSkinRevived", "CruiserSkinRevived", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class CSR : BaseUnityPlugin { public enum SkinSelectionType { Terminal, Random } public static Dictionary<string, Skin> skins = new Dictionary<string, Skin>(); public static Material cruiserMaterial = null; public static Material cruiserDestroyedMaterial = null; public static ManualLogSource Log; private static LNetworkMessage<List<object>> configMessage = LNetworkMessage<List<object>>.Connect("CSR.Config", (Action<List<object>, ulong>)OnServerConfigMessageRecieved, (Action<List<object>>)OnClientConfigMessageRecieved, (Action<List<object>, ulong>)null); public static ConfigEntry<SkinSelectionType> skinSelectionType; public static ConfigEntry<bool> randomWithoutRepeat; public static ConfigEntry<bool> useOriginalSkin; public static ConfigEntry<bool> onlyHostCanChangeSkin; private void Awake() { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; cruiserMaterial = null; cruiserDestroyedMaterial = null; skinSelectionType = ((BaseUnityPlugin)this).Config.Bind<SkinSelectionType>("General", "SkinSelectionType", SkinSelectionType.Random, "If 'Random' - mod will select skin randomly.\nIf 'Terminal' - the player will have to set skin manually with command in terminal."); randomWithoutRepeat = ((BaseUnityPlugin)this).Config.Bind<bool>("Random", "NoRepeats", true, "If true, skins are chosen randomly without repeating twice."); useOriginalSkin = ((BaseUnityPlugin)this).Config.Bind<bool>("Random", "UseOriginalSkin", false, "If true, mod will use original skin in random like all other custom skins."); onlyHostCanChangeSkin = ((BaseUnityPlugin)this).Config.Bind<bool>("Terminal", "OnlyHostCanChangeSkin", false, "If true, only host will can change skin with terminal."); LoadSkins(Paths.PluginPath); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Skins count: " + skins.Count)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded skins: " + string.Join(", ", skins.Keys))); if (skins.Count == 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Not applying patch because skins count is 0."); } else { new Harmony("Fitrusielle.CruiserSkinRevived").PatchAll(typeof(Patch)); } Events.TerminalStarted += new TerminalEventHandler(initTerminalCommands); LNetworkUtils.OnNetworkStart += OnNetworkStart; ((BaseUnityPlugin)this).Logger.LogInfo((object)"CSR successfully Loaded."); } private void OnNetworkStart(bool isHost) { if (!isHost) { Log.LogInfo((object)"(Client) Requesting config from host."); configMessage.SendServer(new List<object>()); } } private static void OnServerConfigMessageRecieved(List<object> list, ulong client) { List<object> list2 = new List<object> { skinSelectionType.Value, randomWithoutRepeat.Value, useOriginalSkin.Value, onlyHostCanChangeSkin.Value }; Log.LogInfo((object)("(Server) Client requesting config. Sending: " + string.Join(", ", list2))); configMessage.SendClient(list2, client); } private static void OnClientConfigMessageRecieved(List<object> list) { skinSelectionType.Value = (SkinSelectionType)list[0]; randomWithoutRepeat.Value = (bool)list[1]; useOriginalSkin.Value = (bool)list[2]; onlyHostCanChangeSkin.Value = (bool)list[3]; Log.LogInfo((object)("(Client) Config is succesfully synchronized. Now client config is: " + string.Join(", ", skinSelectionType.Value, randomWithoutRepeat.Value, useOriginalSkin.Value, onlyHostCanChangeSkin.Value))); } private void LoadSkins(string path) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown string[] directories = Directory.GetDirectories(path); foreach (string path2 in directories) { LoadSkins(path2); } directories = Directory.GetFiles(path); foreach (string text in directories) { Skin skin = new Skin(); if (text.EndsWith("cruiser.png") || text.EndsWith("cruiser_example.png")) { Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, File.ReadAllBytes(text)); skin.defaultSkin = val; Texture2D val2 = new Texture2D(2, 2); ImageConversion.LoadImage(val2, File.ReadAllBytes(text.EndsWith("cruiser_example.png") ? text.Replace("example", "destroyed_example") : text.Replace(".png", "_destroyed.png"))); skin.destroyedSkin = val2; skin.name = (text.EndsWith("cruiser_example.png") ? "default" : text.Replace(path + "\\", "").Replace("_cruiser.png", "").ToLower()); } if ((Object)(object)skin.defaultSkin != (Object)null && (Object)(object)skin.destroyedSkin != (Object)null) { skins.Add(skin.name, skin); } } } private void initTerminalCommands(object sender, EventArgs e) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown TerminalKeyword val = TerminalApi.CreateTerminalKeyword("skin", true, (TerminalNode)null); foreach (KeyValuePair<string, Skin> skin in skins) { TerminalNode val2 = TerminalApi.CreateTerminalNode("", true, ""); TerminalKeyword val3 = TerminalApi.CreateTerminalKeyword(skin.Key, false, (TerminalNode)null); val = TerminalExtenstionMethods.AddCompatibleNoun(val, val3, val2); TerminalApi.AddTerminalKeyword(val3, new CommandInfo { TriggerNode = val2, DisplayTextSupplier = delegate { if ((Object)(object)cruiserMaterial == (Object)null) { return "Cannot set skin now.\n\n"; } if (LNetworkUtils.IsHostOrServer) { Patch.skinLocal = skin.Key; Patch.skinMessage.SendClients(Patch.skinLocal); } else { if (onlyHostCanChangeSkin.Value) { return "Only host can use this command."; } Patch.skinMessage.SendServer(skin.Key); } return "Skin is set to " + skin.Key + ".\n\n"; }, Category = "Skins", Description = "Set skin to " + skin.Key }); } TerminalApi.AddTerminalKeyword(val); TerminalApi.AddTerminalKeyword(TerminalApi.CreateTerminalKeyword("skins", "All available skins: " + string.Join(", ", skins.Keys) + ".\n\nTo set skin use 'skin {skin name}'.\n\n", true, "")); } } internal class Patch { public static string skinLocal = "default"; public static LNetworkMessage<string> skinMessage; private static Random random; [HarmonyPatch(typeof(StartOfRound), "StartGame")] [HarmonyPrefix] private static void StartGame(StartOfRound __instance) { if ((Object)(object)CSR.cruiserMaterial == (Object)null || (Object)(object)CSR.cruiserDestroyedMaterial == (Object)null) { VehicleController[] array = Object.FindObjectsByType<VehicleController>((FindObjectsSortMode)0); foreach (VehicleController val in array) { if (val.vehicleID == 0) { LoadCruiserMaterials(val); } } if ((Object)(object)CSR.cruiserMaterial == (Object)null || (Object)(object)CSR.cruiserDestroyedMaterial == (Object)null) { return; } } if (CSR.skinSelectionType.Value != CSR.SkinSelectionType.Terminal && LNetworkUtils.IsHostOrServer) { skinLocal = getRandomSkin(); CSR.Log.LogInfo((object)("(Server) skinLocal is " + skinLocal + ". Sending it to clients.")); skinMessage.SendClients(skinLocal); } } [HarmonyPatch(typeof(VehicleController), "Start")] [HarmonyPostfix] private static void Start(VehicleController __instance) { if (__instance.vehicleID == 0) { LoadCruiserMaterials(__instance); if (LNetworkUtils.IsHostOrServer) { CSR.Log.LogInfo((object)"(Server) VehicleController started. Sending skinLocal to clients."); skinMessage.SendClients(skinLocal); } else { CSR.Log.LogInfo((object)"(Client) VehicleController started. Sending ping to server."); skinMessage.SendServer("p"); } } } private static void LoadCruiserMaterials(VehicleController vc) { if ((Object)(object)CSR.cruiserMaterial != (Object)null && (Object)(object)CSR.cruiserMaterial != (Object)null) { return; } MeshRenderer componentInChildren = ((Component)vc).GetComponentInChildren<MeshRenderer>(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)null && ((Object)((Renderer)componentInChildren).sharedMaterial).name.StartsWith("TruckTexture")) { CSR.cruiserMaterial = ((Renderer)componentInChildren).sharedMaterial; CSR.Log.LogInfo((object)"(Client) Default cruiser material is loaded."); } GameObject[] array = Object.FindObjectsByType<GameObject>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (GameObject val in array) { if (((Object)val).name.Contains("MainBodyDestroyed") && ((Object)((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial).name.StartsWith("TruckTextureDestroyed")) { CSR.cruiserDestroyedMaterial = ((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial; CSR.Log.LogInfo((object)"(Client) Destroyed cruiser material is loaded."); } } if ((Object)(object)CSR.cruiserMaterial == (Object)null || (Object)(object)CSR.cruiserDestroyedMaterial == (Object)null) { CSR.Log.LogWarning((object)"(Client) For some reason one of cruiser materials failed to load. Skins will not work."); } } private static void OnSkinRecievedServer(string skin, ulong player) { if (skin == "p") { CSR.Log.LogInfo((object)("(Server) Recieved ping from client. Sending host skin back: " + skinLocal)); skinMessage.SendClient(skinLocal, player); } else { skinLocal = skin; skinMessage.SendClients(skinLocal, LNetworkUtils.AllConnectedClients); } } private static void OnSkinRecievedClient(string skin) { CSR.Log.LogInfo((object)("(Client) Recieved skin: " + skin)); skinLocal = skin; SetSkin(skinLocal); } private static void SetSkin(string name) { if ((Object)(object)CSR.cruiserMaterial == (Object)null || (Object)(object)CSR.cruiserDestroyedMaterial == (Object)null) { CSR.Log.LogError((object)"(Client) Cannot set cruiser skin. Cruiser material is not loaded."); return; } CSR.cruiserMaterial.mainTexture = (Texture)(object)CSR.skins[name].defaultSkin; CSR.cruiserDestroyedMaterial.mainTexture = (Texture)(object)CSR.skins[name].destroyedSkin; CSR.Log.LogInfo((object)("(Client) Cruiser skin set to " + name)); } private static string getRandomSkin() { if (CSR.skins.Count >= 3) { if (!CSR.randomWithoutRepeat.Value) { return CSR.skins.ElementAt(random.Next(0, CSR.skins.Count)).Key; } return getRandomSkinNoRepeatRecursive(); } return getFirstSkin(); } private static string getRandomSkinNoRepeatRecursive() { string key = CSR.skins.ElementAt(random.Next(0, CSR.skins.Count)).Key; if (key == skinLocal || (!CSR.useOriginalSkin.Value && key == "default")) { return getRandomSkinNoRepeatRecursive(); } return key; } private static string getFirstSkin() { string result = "default"; if (!CSR.useOriginalSkin.Value) { foreach (KeyValuePair<string, Skin> skin in CSR.skins) { if (skin.Key != "default") { return result = skin.Key; } } } return result; } static Patch() { Action<string> action = OnSkinRecievedClient; skinMessage = LNetworkMessage<string>.Connect("CSR.skinMessage", (Action<string, ulong>)OnSkinRecievedServer, action, (Action<string, ulong>)null); random = new Random(); } } public class Skin { public string name; public Texture2D defaultSkin; public Texture2D destroyedSkin; }