using 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.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HZ_PieceRemover")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HZ_PieceRemover")] [assembly: AssemblyTitle("HZ_PieceRemover")] [assembly: AssemblyVersion("1.0.0.0")] [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 PieceRemover { [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ZNetScene_Awake_RemovePieces { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { if (PieceRemoverPlugin.ExcludedPieces.Count != 0) { PieceRemovalUtil.RemoveFromPieceTables("ZNetScene.Awake"); } } private static void RemoveFromZNetScene(ZNetScene znetScene) { Dictionary value = Traverse.Create((object)znetScene).Field("m_namedPrefabs").GetValue>(); foreach (string item in PieceRemoverPlugin.ExcludedPieces.ToList()) { GameObject prefab = znetScene.GetPrefab(item); if (!((Object)(object)prefab == (Object)null)) { znetScene.m_prefabs.Remove(prefab); znetScene.m_nonNetViewPrefabs.Remove(prefab); value?.Remove(StringExtensionMethods.GetStableHashCode(item)); PieceRemoverPlugin.Log.LogInfo((object)("[PieceRemover] Prefab '" + item + "' removido do ZNetScene.")); } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] internal static class ObjectDB_Awake_RemovePieces { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { if (PieceRemoverPlugin.ExcludedPieces.Count != 0) { PieceRemovalUtil.RemoveFromPieceTables("ObjectDB.Awake"); } } } internal static class PieceRemovalUtil { internal static void RemoveFromPieceTables(string origin) { PieceTable[] array = Resources.FindObjectsOfTypeAll(); int num = 0; PieceTable[] array2 = array; foreach (PieceTable val in array2) { if (val.m_pieces != null) { int num2 = val.m_pieces.RemoveAll((GameObject go) => (Object)(object)go != (Object)null && PieceRemoverPlugin.ExcludedPieces.Contains(((Object)go).name)); if (num2 > 0) { num += num2; PieceRemoverPlugin.Log.LogInfo((object)$"[PieceRemover] ({origin}) Removida(s) {num2} peça(s) de '{((Object)val).name}'."); } } } if (num == 0) { PieceRemoverPlugin.Log.LogInfo((object)("[PieceRemover] (" + origin + ") Nenhuma peça da lista de exclusão encontrada nesta passada.")); } } } [BepInPlugin("arthur.piece_remover", "PieceRemover", "1.0.0")] public class PieceRemoverPlugin : BaseUnityPlugin { public const string PluginGUID = "arthur.piece_remover"; public const string PluginName = "PieceRemover"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static HashSet ExcludedPieces = new HashSet(StringComparer.OrdinalIgnoreCase); private const string ConfigFileName = "piece_remover_exclude.cfg"; private string _configFilePath; private void Awake() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; _configFilePath = Path.Combine(Paths.ConfigPath, "piece_remover_exclude.cfg"); EnsureConfigFile(); LoadExcludedList(); new Harmony("arthur.piece_remover").PatchAll(); Log.LogInfo((object)$"[PieceRemover] {ExcludedPieces.Count} peça(s) marcada(s) para remoção."); } private void EnsureConfigFile() { if (!File.Exists(_configFilePath)) { string contents = "# PieceRemover - lista de pecas a excluir\n# Um nome de PREFAB por linha (GameObject.name), NAO o nome traduzido que aparece no jogo.\n# Linhas comecando com # sao ignoradas. Linhas em branco tambem.\n#\n# Confirme o nome exato do prefab via dnSpy/ILSpy antes de listar aqui.\n# Se o nome estiver errado, o mod avisa no log (BepInEx/LogOutput.log) que nao encontrou.\n#\n# Exemplo:\n# piece_bush01\n# piece_bush02\n"; File.WriteAllText(_configFilePath, contents); Log.LogInfo((object)("[PieceRemover] Arquivo de config criado em: " + _configFilePath)); } } internal void LoadExcludedList() { ExcludedPieces.Clear(); if (!File.Exists(_configFilePath)) { Log.LogWarning((object)"[PieceRemover] Config nao encontrado, nenhuma peça sera removida."); return; } string[] array = File.ReadAllLines(_configFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text) && !text.StartsWith("#")) { ExcludedPieces.Add(text); } } } } }