using System; using System.Collections; 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using ProjectM; using ProjectM.Hybrid; using Stunlock.Core; using Unity.Collections; using Unity.Entities; using UnityEngine; using VRisingTextureReplacer.Helpers; using VRisingTextureReplacer.Replacer; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("VRisingTextureReplacer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9582431cdc624a37d51ac0f0a07a43ef85da2fcd")] [assembly: AssemblyProduct("My first plugin")] [assembly: AssemblyTitle("VRisingTextureReplacer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VRisingTextureReplacer { [BepInPlugin("VRisingTextureReplacer", "VRisingTextureReplacer", "1.0.0")] public class Plugin : BasePlugin { internal static ManualLogSource Logger; internal static ConfigEntry LoggingEnabledConfig; internal static Dictionary ReplacementTextures = new Dictionary(); internal static Harmony Harmony = new Harmony("VRisingTextureReplacer"); internal static bool LoggingEnabled => LoggingEnabledConfig?.Value ?? false; internal static void Info(string msg) { if (LoggingEnabled) { Logger.LogInfo((object)msg); } } internal static void Warning(string msg) { Logger.LogWarning((object)msg); } internal static void Error(string msg) { Logger.LogError((object)msg); } public override void Load() { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) Logger = ((BasePlugin)this).Log; LoggingEnabledConfig = ((BasePlugin)this).Config.Bind("Debug", "EnableInfoLogging", false, "Enable info-level logging. Useful for diagnosing issues; disable for cleaner logs."); string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Textures"); if (!Directory.Exists(text)) { Error("Textures folder not found: " + text); return; } string[] files = Directory.GetFiles(text, "*.png"); foreach (string text2 in files) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text2); bool flag = fileNameWithoutExtension.EndsWith("_n", StringComparison.OrdinalIgnoreCase); byte[] array = File.ReadAllBytes(text2); Texture2D val = (flag ? new Texture2D(2, 2, (TextureFormat)4, true, true) : new Texture2D(2, 2, (TextureFormat)4, true, false)); if (!ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(array))) { Error("Failed to load image: " + text2); continue; } val.Compress(true); ((Object)val).name = fileNameWithoutExtension; ((Object)val).hideFlags = (HideFlags)32; Object.DontDestroyOnLoad((Object)(object)val); ReplacementTextures[fileNameWithoutExtension] = val; Info($"Loaded: {fileNameWithoutExtension} ({((Texture)val).width}x{((Texture)val).height}) fmt={val.format}{(flag ? " [normal map]" : "")}"); } if (ReplacementTextures.Count == 0) { Warning("No replacement textures loaded — skipping patch."); return; } ClassInjector.RegisterTypeInIl2Cpp(); Harmony.PatchAll(); Info($"Patched — {ReplacementTextures.Count} replacement texture(s) ready."); } public override bool Unload() { foreach (Texture2D value in ReplacementTextures.Values) { Object.Destroy((Object)(object)value); } ReplacementTextures.Clear(); Harmony.UnpatchSelf(); Info("Unloaded."); return true; } } } namespace VRisingTextureReplacer.Replacer { internal static class TextureReplacer { private static int SwapMaterialTextures(Material material) { int num = 0; foreach (string item in (Il2CppArrayBase)(object)material.GetTexturePropertyNames()) { Texture texture = material.GetTexture(item); if (!((Object)(object)texture == (Object)null)) { string name = ((Object)texture).name; if (!string.IsNullOrEmpty(name) && Plugin.ReplacementTextures.TryGetValue(name, out var value) && ((Object)texture).GetInstanceID() != ((Object)value).GetInstanceID()) { material.SetTexture(item, (Texture)(object)value); Plugin.Info("[TextureReplacer] Swapped: " + name + " on " + item); num++; } } } return num; } public static int SwapTexturesForEntity(Entity entity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) GameObject forEntity = PlayerGameObject.GetForEntity(entity); if ((Object)(object)forEntity == (Object)null) { return 0; } int num = 0; foreach (SkinnedMeshRenderer componentsInChild in forEntity.GetComponentsInChildren(true)) { foreach (Material item in (Il2CppArrayBase)(object)((Renderer)componentsInChild).sharedMaterials) { if ((Object)(object)item != (Object)null) { num += SwapMaterialTextures(item); } } } foreach (MeshRenderer componentsInChild2 in forEntity.GetComponentsInChildren(true)) { foreach (Material item2 in (Il2CppArrayBase)(object)((Renderer)componentsInChild2).sharedMaterials) { if ((Object)(object)item2 != (Object)null) { num += SwapMaterialTextures(item2); } } } return num; } } } namespace VRisingTextureReplacer.Patches { [HarmonyPatch] internal static class BuffPollingPatch { private const int BUFF_VBLOODABILITYREPLACE = 1171608023; private static bool _bloodmendActive; [HarmonyPatch(typeof(AbilityRunScriptsSystem_Client), "OnUpdate")] [HarmonyPostfix] private static void OnUpdatePostfix(AbilityRunScriptsSystem_Client __instance) { bool flag = PlayerState.HasBuff(1171608023); if (flag && !_bloodmendActive) { ((MonoBehaviour)CoroutineHelper.Instance).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(HybridEquipmentSystemPatch.DelayedRescan(5f))); Plugin.Info("[BuffPollingPatch] Bloodmend added to player character."); } _bloodmendActive = flag; } } [HarmonyPatch] internal static class HybridEquipmentSystemPatch { [CompilerGenerated] private sealed class d__5 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float delay; private int 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; if (!PlayerState.EnsurePlayerCache()) { return false; } 5__1 = TextureReplacer.SwapTexturesForEntity(PlayerState.Character); if (5__1 > 0) { Plugin.Info($"[TextureReplacer] Delayed — {5__1}"); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static long _signature; private static bool _hasInitial; [HarmonyPatch(typeof(HybridEquipmentSystem), "OnUpdate")] [HarmonyPostfix] private static void OnUpdatePostfix(HybridEquipmentSystem __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_00df: Unknown result type (might be due to invalid IL or missing references) if (!PlayerState.EnsurePlayerCache()) { return; } EntityManager entityManager = PlayerState.GameWorld.EntityManager; if (!((EntityManager)(ref entityManager)).HasComponent(PlayerState.Character)) { return; } Equipment componentData = ((EntityManager)(ref entityManager)).GetComponentData(PlayerState.Character); long num = ComputeSignature(componentData); if (!_hasInitial) { _signature = num; _hasInitial = true; int num2 = TextureReplacer.SwapTexturesForEntity(PlayerState.Character); if (num2 > 0) { Plugin.Info($"[TextureReplacer] Initial — {num2}"); } ((MonoBehaviour)CoroutineHelper.Instance).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DelayedRescan(0.1f))); } else if (num != _signature) { _signature = num; int num3 = TextureReplacer.SwapTexturesForEntity(PlayerState.Character); if (num3 > 0) { Plugin.Info($"[TextureReplacer] Immediate — {num3}"); } ((MonoBehaviour)CoroutineHelper.Instance).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DelayedRescan(0.1f))); } } private static long ComputeSignature(Equipment e) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) long num = 17L; num = num * 31 + HashSlot(e.ArmorHeadgearSlot); num = num * 31 + HashSlot(e.ArmorChestSlot); num = num * 31 + HashSlot(e.WeaponSlot); num = num * 31 + HashSlot(e.ArmorFootgearSlot); num = num * 31 + HashSlot(e.ArmorLegsSlot); num = num * 31 + HashSlot(e.CloakSlot); num = num * 31 + HashSlot(e.ArmorGlovesSlot); num = num * 31 + HashSlot(e.ChestCosmeticSlot); num = num * 31 + HashSlot(e.FootgearCosmeticSlot); num = num * 31 + HashSlot(e.LegsCosmeticSlot); num = num * 31 + HashSlot(e.CloakCosmeticSlot); return num * 31 + HashSlot(e.GlovesCosmeticSlot); } private static long HashSlot(EquipmentSlot s) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) long num = ((PrefabGUID)(ref s.SlotId)).GuidHash; num = (num << 8) | s.TransmogIndex; return (num << 1) | (s.HideEquipment ? 1 : 0); } [IteratorStateMachine(typeof(d__5))] internal static IEnumerator DelayedRescan(float delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__5(0) { delay = delay }; } } } namespace VRisingTextureReplacer.Helpers { public class CoroutineHelper : MonoBehaviour { private static CoroutineHelper _instance; public static CoroutineHelper Instance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("VRisingTextureReplacer_CoroutineHelper"); Object.DontDestroyOnLoad((Object)(object)val); _instance = ((Il2CppObjectBase)val.AddComponent(Il2CppType.Of())).Cast(); } return _instance; } } } public static class PlayerGameObject { private static World _clientWorld; private static HybridModelSystem _hybridModelSystem; public static GameObject GetForEntity(Entity entity) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (_clientWorld == null || !_clientWorld.IsCreated) { _clientWorld = null; Enumerator enumerator = World.All.GetEnumerator(); while (enumerator.MoveNext()) { World current = enumerator.Current; if (current.IsCreated && current.Name == "Client_0") { _clientWorld = current; break; } } if (_clientWorld == null) { return null; } _hybridModelSystem = null; } if (_hybridModelSystem == null) { _hybridModelSystem = _clientWorld.GetExistingSystemManaged(); if (_hybridModelSystem == null) { return null; } } Dictionary entityToGameObjectMap = _hybridModelSystem.GetEntityToGameObjectMap(); if (entityToGameObjectMap == null) { return null; } GameObject val = default(GameObject); return entityToGameObjectMap.TryGetValue(entity, ref val) ? val : null; } } internal static class PlayerState { private static EntityQuery _playerQuery; public static World GameWorld { get; private set; } public static Entity Character { get; private set; } = Entity.Null; public static bool EnsurePlayerCache() { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) if (GameWorld == null || !GameWorld.IsCreated) { GameWorld = null; Character = Entity.Null; Enumerator enumerator = World.All.GetEnumerator(); while (enumerator.MoveNext()) { World current = enumerator.Current; if (!current.IsCreated || current.Name.Contains("Loading")) { continue; } try { EntityManager entityManager = current.EntityManager; EntityQuery playerQuery = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); if (((EntityQuery)(ref playerQuery)).CalculateEntityCount() > 0) { GameWorld = current; _playerQuery = playerQuery; break; } } catch { } } if (GameWorld == null) { return false; } } EntityManager entityManager2 = GameWorld.EntityManager; if (Character == Entity.Null || !((EntityManager)(ref entityManager2)).Exists(Character)) { NativeArray val = ((EntityQuery)(ref _playerQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Character = ((val.Length > 0) ? val[0] : Entity.Null); val.Dispose(); if (Character == Entity.Null) { return false; } } return true; } public static bool HasBuff(int buffGuidHash) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!EnsurePlayerCache()) { return false; } EntityManager entityManager = GameWorld.EntityManager; if (!((EntityManager)(ref entityManager)).HasBuffer(Character)) { return false; } DynamicBuffer buffer = ((EntityManager)(ref entityManager)).GetBuffer(Character, false); for (int i = 0; i < buffer.Length; i++) { BuffBuffer val = buffer[i]; if (((PrefabGUID)(ref val.PrefabGuid)).GuidHash == buffGuidHash) { return true; } } return false; } public static bool HasComponent() where T : struct { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!EnsurePlayerCache()) { return false; } EntityManager entityManager = GameWorld.EntityManager; return ((EntityManager)(ref entityManager)).HasComponent(Character); } public static T GetComponent() where T : struct { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = GameWorld.EntityManager; return ((EntityManager)(ref entityManager)).GetComponentData(Character); } } }