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.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Splatform; using UnityEngine; using Visbending; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Visbending")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Visbending")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9ba5e1cb-d246-40ae-80e4-1d436066ca36")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] public static class HeightmapHelper { private delegate bool GetWorldHeightDelegate(Heightmap instance, Vector3 worldPos, out float height); private static VisbendingLogger.Context contextTerrain = VisbendingLogger.Context.Terrain; private static readonly GetWorldHeightDelegate _getWorldHeight = AccessTools.MethodDelegate(AccessTools.Method(typeof(Heightmap), "GetWorldHeight", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef> m_heightsField = AccessTools.FieldRefAccess>("m_heights"); public static bool GetPreciseHeight(Heightmap hmap, Vector3 worldPos, out float height) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) height = 0f; if ((Object)(object)hmap == (Object)null) { return false; } List list = m_heightsField.Invoke(hmap); if (list == null || list.Count == 0) { hmap.Regenerate(); } return _getWorldHeight(hmap, worldPos, out height); } public static bool GetHeight(Vector3 position, Heightmap hmap, out float h) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Vector3 val; if ((Object)(object)hmap != (Object)null) { if (GetPreciseHeight(hmap, position, out h)) { return h > 0f; } VisbendingLogger.Context context = contextTerrain; string[] array = new string[1]; val = position; array[0] = " position " + ((object)(Vector3)(ref val)).ToString() + " GetPreciseHeight failed"; VisbendingLogger.Log(context, array); } if (!ZoneSystem.instance.GetGroundHeight(position, ref h)) { VisbendingLogger.Context context2 = contextTerrain; string[] array2 = new string[1]; val = position; array2[0] = " position " + ((object)(Vector3)(ref val)).ToString() + " GetGroundHeight failed"; VisbendingLogger.Log(context2, array2); if (!ZoneSystem.instance.GetSolidHeight(position, ref h, 1000)) { VisbendingLogger.Context context3 = contextTerrain; string[] array3 = new string[1]; val = position; array3[0] = " position " + ((object)(Vector3)(ref val)).ToString() + " GetSolidHeight failed"; VisbendingLogger.Log(context3, array3); h = WorldGenerator.instance.GetHeight(position.x, position.z); } } return h > 0f; } } namespace Visbending; internal class AnchorType { private string anchorName; private string prefabName; private int radius; private int numberOfStones; private string colorKey; private List textKeys; private Dictionary zone2Anchor = new Dictionary(); private List anchors = new List(); private static VisbendingLogger.Context registerContext = VisbendingLogger.Context.Registration; public AnchorType(AnchorTypeBuilder builder) { anchorName = builder.anchorName; prefabName = builder.prefabName; radius = builder.radius; numberOfStones = builder.numberOfStones; } public void Init() { //IL_003e: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Log(registerContext, "AnchorType init 1"); Dictionary dictionary = new Dictionary(); foreach (Anchor value in zone2Anchor.Values) { dictionary[value.GetAnchorZone()] = value; VisbendingLogger.Log(registerContext, "AnchorType init 2"); value.Init(); VisbendingLogger.Log(registerContext, "AnchorType init 3"); anchors.Add(value); foreach (Vector2i spawnZone in value.GetSpawnZones()) { VisbendingLogger.Log(registerContext, "AnchorType init 4"); dictionary[spawnZone] = value; VisbendingLogger.Log(registerContext, "AnchorType init 5"); } } zone2Anchor = dictionary; } public List GetAnchors() { return anchors; } public Anchor GetAnchor(Vector2i zone) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return GeneralExtensions.GetValueSafe(zone2Anchor, zone); } public string GetAnchorName() { return anchorName; } public string GetPrefabName() { return prefabName; } public void SetColorKey(string colorKey) { this.colorKey = colorKey; } public string GetColorKey() { return colorKey; } public int GetRadius() { return radius; } public int GetNumberOfStones() { return numberOfStones; } public void SetTextKeys(List textKeys) { this.textKeys = textKeys; } public List GetTextKeys() { return textKeys; } public Anchor AddAnchor(Vector3 pos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Anchor anchor = new Anchor(this, pos); zone2Anchor.Add(anchor.GetAnchorZone(), anchor); return anchor; } public void serialize(ZPackage pkg) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Log(registerContext, anchorName + " " + prefabName + " " + radius + " " + numberOfStones); pkg.Write(anchorName); pkg.Write(prefabName); pkg.Write(radius); pkg.Write(numberOfStones); pkg.Write(anchors.Count); foreach (Anchor anchor in anchors) { pkg.Write(anchor.GetAnchorPosition()); pkg.Write(anchor.IsValid()); Dictionary dictionary = new Dictionary(); foreach (Group group in anchor.GetGroups()) { Candidate spawnedCandidate = group.GetSpawnedCandidate(); if (spawnedCandidate != null) { dictionary.Add(group.GetIndex(), spawnedCandidate.GetIndex()); } } pkg.Write(dictionary.Count); foreach (KeyValuePair item in dictionary) { pkg.Write(item.Key); pkg.Write(item.Value); } } } public static AnchorType Deserialize(ZPackage pkg) { //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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) string text = pkg.ReadString(); string text2 = pkg.ReadString(); int num = pkg.ReadInt(); int num2 = pkg.ReadInt(); VisbendingLogger.Log(registerContext, text + " " + text2 + " " + num + " " + num2); AnchorTypeBuilder anchorTypeBuilder = new AnchorTypeBuilder(); anchorTypeBuilder.AnchorName(text).PrefabName(text2).Radius(num) .NumberOfStones(num2); AnchorType anchorType = anchorTypeBuilder.Build(); if (!SpawnRegistry.GetStoneConfig(anchorType.GetAnchorName(), out var config)) { VisbendingLogger.Log(registerContext, "no config for anchor name " + anchorType.GetAnchorName()); return anchorType; } anchorType.SetColorKey(config.ColorEntry.Value); anchorType.SetTextKeys(config.TextKeys); int num3 = pkg.ReadInt(); VisbendingLogger.Log(registerContext, "number of anchors for " + anchorType.GetAnchorName() + " " + num3); for (int i = 0; i < num3; i++) { Vector3 pos = pkg.ReadVector3(); Anchor anchor = anchorType.AddAnchor(pos); anchor.Init(); pkg.ReadBool(); int num4 = pkg.ReadInt(); Dictionary dictionary = new Dictionary(); for (int j = 0; j < num4; j++) { dictionary.Add(pkg.ReadInt(), pkg.ReadInt()); } foreach (KeyValuePair item in dictionary) { anchor.GetGroup(item.Key).GetCandidate(item.Value).SetSpawned(spawned: true); } VisbendingLogger.Log(registerContext, "Anchor " + i + " read"); } return anchorType; } } internal class Anchor { private AnchorType type; private Vector3 position; private Vector2i zone; private Dictionary groups; private bool valid; private bool initialized; private int startGroupIndex = -1; private static VisbendingLogger.Context context = VisbendingLogger.Context.Registration; private HashSet spawnZones; private List textKeys; public Anchor(AnchorType type, Vector3 pos) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0022: Unknown result type (might be due to invalid IL or missing references) this.type = type; position = pos; zone = ZoneSystem.GetZone(pos); valid = true; initialized = false; } public void Init() { //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Log(context, "AnchorType init 1"); if (initialized) { return; } groups = new Dictionary(); float num = VisbendingMod.getMinimalRadius(); Random random = new Random((int)(position.x * 1000f + position.z) + type.GetAnchorName().GetHashCode()); int numberOfStones = type.GetNumberOfStones(); int radius = type.GetRadius(); textKeys = type.GetTextKeys(); int num2 = textKeys.Count; while (num2 > 1) { num2--; int index = random.Next(num2 + 1); string value = textKeys[index]; textKeys[index] = textKeys[num2]; textKeys[num2] = value; } VisbendingLogger.Log(context, "AnchorType init 2"); startGroupIndex = random.Next(numberOfStones); for (int i = 0; i < numberOfStones; i++) { VisbendingLogger.Log(context, "AnchorType init 3"); Group group = new GroupBuilder(this).Index(i).TextKey(GetTextKey(i)).Build(); groups.Add(group.GetIndex(), group); } Vector3 val = default(Vector3); Vector3 val2 = default(Vector3); foreach (Group value2 in groups.Values) { VisbendingLogger.Log(context, "AnchorType init 4"); float num3 = ((float)random.NextDouble() * 2f - 1f) * (360f / (float)numberOfStones / 3f); num3 = 0f; float num4 = ((float)value2.GetIndex() * (360f / (float)numberOfStones) + num3) * ((float)Math.PI / 180f); int num5 = 0; for (float num6 = radius; num6 >= num; num6 -= 5f) { ((Vector3)(ref val))..ctor(position.x + Mathf.Cos(num4) * num6, 0f, position.z + Mathf.Sin(num4) * num6); val = AdjustPosition(val, 5f); ((Vector3)(ref val2))..ctor(position.x - val.x, 0f, position.z - val.z); ((Vector3)(ref val2)).Normalize(); Quaternion orientation = Quaternion.LookRotation(val2, Vector3.up); ZoneSystem.GetZone(val); CandidateBuilder candidateBuilder = new CandidateBuilder(value2); value2.AddCandidate(candidateBuilder.Index(num5++).PlannedPos(val).Orientation(orientation) .Build()); } } initialized = true; spawnZones = new HashSet(); foreach (Candidate candidate in GetCandidates()) { spawnZones.Add(candidate.GetPlannedZone()); } VisbendingLogger.Log(context, "AnchorType init 5"); } private Vector3 AdjustPosition(Vector3 plannedPos, float safetyDistance) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if (safetyDistance > 15f) { safetyDistance = 15f; } Vector3 zonePos = ZoneSystem.GetZonePos(ZoneSystem.GetZone(plannedPos)); _ = zonePos + new Vector3(32f, 0f, 32f); _ = zonePos + new Vector3(64f, 0f, 0f); Vector3 val = zonePos + new Vector3(64f, 0f, 64f); _ = zonePos + new Vector3(0f, 0f, 64f); float num = plannedPos.x; float y = plannedPos.y; float num2 = plannedPos.z; if (num - zonePos.x < safetyDistance) { num = zonePos.x + safetyDistance; } if (val.x - num < safetyDistance) { num = val.x - safetyDistance; } if (num2 - zonePos.z < safetyDistance) { num2 = zonePos.z + safetyDistance; } if (val.z - num2 < safetyDistance) { num2 = val.z - safetyDistance; } ((Vector3)(ref plannedPos))..ctor(num, y, num2); return plannedPos; } public AnchorType GetParent() { return type; } public Vector2i GetAnchorZone() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return zone; } public HashSet GetCandidates() { HashSet hashSet = new HashSet(); foreach (Group value in groups.Values) { foreach (Candidate candidate in value.GetCandidates()) { hashSet.Add(candidate); } } return hashSet; } public Vector3 GetAnchorPosition() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return position; } public string GetAnchorName() { return type.GetAnchorName(); } public bool IsValid() { return valid; } public void SetValid(bool valid) { this.valid = valid; } public string GetPrefabName() { return type.GetPrefabName(); } public string GetColorKey() { return type.GetColorKey(); } public int GetRadius() { return type.GetRadius(); } public int GetNumberOfStones() { return type.GetNumberOfStones(); } private List GetTextKeys() { return type.GetTextKeys(); } public string GetTextKey(int groupidx) { int index = (startGroupIndex + groupidx) % textKeys.Count; VisbendingLogger.Log(VisbendingLogger.Context.Registration, "GetTextKey " + textKeys[index] + " " + groupidx + " " + startGroupIndex + " " + textKeys.Count); return textKeys[index]; } public Group GetGroup(int idx) { return GeneralExtensions.GetValueSafe(groups, idx); } public Dictionary.ValueCollection GetGroups() { return groups.Values; } public HashSet GetSpawnZones() { return spawnZones; } } internal class AnchorTypeBuilder { public string anchorName; public int radius; public int numberOfStones; public string prefabName; public string colorKey; public List textKeys; public AnchorTypeBuilder AnchorName(string anchorName) { this.anchorName = anchorName; return this; } public AnchorTypeBuilder Radius(int radius) { this.radius = radius; return this; } public AnchorTypeBuilder NumberOfStones(int numberOfStones) { this.numberOfStones = numberOfStones; return this; } public AnchorTypeBuilder PrefabName(string prefabName) { this.prefabName = prefabName; return this; } public AnchorTypeBuilder ColorKey(string colorKey) { this.colorKey = colorKey; return this; } public AnchorTypeBuilder TextKeys(List textKeys) { this.textKeys = textKeys; return this; } public AnchorType Build() { return new AnchorType(this); } } internal class GroupBuilder { public Anchor parent; public int index; public string textKey; public GroupBuilder(Anchor parent) { this.parent = parent; } public GroupBuilder Index(int index) { this.index = index; return this; } public GroupBuilder TextKey(string textKey) { this.textKey = textKey; return this; } public Group Build() { return new Group(this); } } internal class Group { private Anchor parent; private int index; private string textKey; private Dictionary candidates; public Group(GroupBuilder builder) { parent = builder.parent; index = builder.index; textKey = builder.textKey; candidates = new Dictionary(); } public Anchor GetParent() { return parent; } public int GetIndex() { return index; } public string GetTextKey() { return textKey; } public void AddCandidate(Candidate candidate) { candidates.Add(candidate.GetIndex(), candidate); } public Dictionary.ValueCollection GetCandidates() { return candidates.Values; } public Candidate GetCandidate(int idx) { return GeneralExtensions.GetValueSafe(candidates, idx); } public Candidate GetSpawnedCandidate() { foreach (Candidate value in candidates.Values) { if (value != null && value.IsSpawned()) { return value; } } return null; } } internal class CandidateBuilder { public Group parent; public int index; public Vector3 plannedPos; public Quaternion orientation; public CandidateBuilder(Group parent) { this.parent = parent; } public CandidateBuilder Index(int index) { this.index = index; return this; } public CandidateBuilder PlannedPos(Vector3 plannedPos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) this.plannedPos = plannedPos; return this; } public CandidateBuilder Orientation(Quaternion orientation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) this.orientation = orientation; return this; } public Candidate Build() { return new Candidate(this); } } internal class Candidate { private Group parent; private int index; private Vector3 plannedPos; private Vector2i plannedZone; private Quaternion orientation; private bool spawned; public Candidate(CandidateBuilder builder) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) parent = builder.parent; index = builder.index; plannedPos = builder.plannedPos; orientation = builder.orientation; plannedZone = ZoneSystem.GetZone(plannedPos); } public Group GetParent() { return parent; } public bool IsSpawned() { return spawned; } public void SetSpawned(bool spawned) { this.spawned = spawned; } public Vector3 GetPlannedPosition() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return plannedPos; } public Vector2i GetPlannedZone() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return plannedZone; } public Quaternion GetOrientation() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return orientation; } public int GetIndex() { return index; } } internal class JsonHelper { public static Dictionary ParseFullText(string filePath) { string text = File.ReadAllText(filePath); Dictionary dictionary = new Dictionary(); int i = 0; while (i < text.Length) { string text2 = ExtractNextString(text, ref i); if (text2 == null) { break; } for (; i < text.Length && text[i] != ':'; i++) { } i++; string text3 = ExtractNextString(text, ref i); if (text3 == null) { break; } dictionary[text2] = text3; for (; i < text.Length && text[i] != '"'; i++) { } } return dictionary; } private static string ExtractNextString(string text, ref int index) { while (index < text.Length && text[index] != '"') { index++; } if (index >= text.Length) { return null; } index++; StringBuilder stringBuilder = new StringBuilder(); bool flag = false; while (index < text.Length) { char c = text[index]; if (flag) { switch (c) { case '"': stringBuilder.Append('"'); break; case '\\': stringBuilder.Append('\\'); break; case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; default: stringBuilder.Append(c); break; } flag = false; } else { switch (c) { case '\\': flag = true; break; case '"': index++; return stringBuilder.ToString(); default: stringBuilder.Append(c); break; } } index++; } return stringBuilder.ToString(); } } internal class PrefabInfo { private static Dictionary deletable; public static bool IsDeletable(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return false; } if (prefab.GetComponent() == null && !((Object)prefab).name.ToLower().Contains("rock") && !((Object)prefab).name.ToLower().Contains("beech") && !((Object)prefab).name.ToLower().Contains("birch") && !((Object)prefab).name.ToLower().Contains("tree") && !((Object)prefab).name.ToLower().Contains("stub")) { return ((Object)prefab).name.ToLower().Contains("bush"); } return true; } public static bool GetDeletableObjectName(int hashCode, out string value) { value = ""; if (hashCode == 0) { return false; } if (deletable == null) { deletable = new Dictionary(); deletable.Add(-591983307, "Ashlands_rock1"); deletable.Add(-995267834, "Ashlands_rock2"); deletable.Add(-2113381525, "AshlandsBush1"); deletable.Add(-2113381524, "AshlandsBush2"); deletable.Add(870990425, "AshlandsTree1"); deletable.Add(870990427, "AshlandsTree3"); deletable.Add(870990428, "AshlandsTree4"); deletable.Add(870990429, "AshlandsTree5"); deletable.Add(870990430, "AshlandsTree6"); deletable.Add(1840491433, "AshlandsTree6_big"); deletable.Add(-174210823, "AshlandsTreeLog1"); deletable.Add(-1740294764, "AshlandsTreeLog2"); deletable.Add(-1552374362, "AshlandsTreeLogHalf1"); deletable.Add(1176508993, "AshlandsTreeLogHalf2"); deletable.Add(1910273542, "AshlandsTreeStump1"); deletable.Add(-1981409227, "AshlandsTreeStump2"); deletable.Add(747474128, "AshlandsTreeStump3"); deletable.Add(1321774774, "ashwood_decowall_tree"); deletable.Add(837895808, "beech_log"); deletable.Add(-624406308, "beech_log_half"); deletable.Add(1170585794, "Beech_Sapling"); deletable.Add(865557360, "Beech_small1"); deletable.Add(1268841887, "Beech_small2"); deletable.Add(747762302, "Beech_Stub"); deletable.Add(-493262268, "Beech1"); deletable.Add(1912302441, "BeechSeeds"); deletable.Add(-1664555947, "BigRock"); deletable.Add(-1411911791, "Birch_log"); deletable.Add(1868061717, "Birch_log_half"); deletable.Add(-646762577, "Birch_Sapling"); deletable.Add(-427486029, "Birch1"); deletable.Add(816500238, "Birch1_aut"); deletable.Add(-1993569970, "Birch2"); deletable.Add(-789472993, "Birch2_aut"); deletable.Add(-601117714, "BirchSeeds"); deletable.Add(-1425208488, "BirchStub"); deletable.Add(1998010392, "BlueberryBush"); deletable.Add(548904977, "Bush01"); deletable.Add(-1798873102, "Bush01_heath"); deletable.Add(-136568224, "Bush02_en"); deletable.Add(-150393364, "caverock_ice_pillar_wall"); deletable.Add(-2053541920, "caverock_ice_stalagmite"); deletable.Add(-1349061296, "caverock_ice_stalagmite_broken"); deletable.Add(1935032255, "caverock_ice_stalagmite_destruction"); deletable.Add(-494364525, "caverock_ice_stalagtite"); deletable.Add(-691410382, "caverock_ice_stalagtite_destruction"); deletable.Add(-15162285, "caverock_ice_stalagtite_falling"); deletable.Add(-481743960, "caverock_ice_wall_destruction"); deletable.Add(-107866523, "cliff_ashlandsflowrock_frac"); deletable.Add(940750515, "CloudberryBush"); deletable.Add(115692907, "FireworksRocket_Blue"); deletable.Add(1944157002, "FireworksRocket_Cyan"); deletable.Add(348302960, "FireworksRocket_Green"); deletable.Add(-232359017, "FireworksRocket_Purple"); deletable.Add(-1742513904, "FireworksRocket_Red"); deletable.Add(-1372515538, "FireworksRocket_White"); deletable.Add(-1287554715, "FireworksRocket_Yellow"); deletable.Add(1185163063, "FirTree"); deletable.Add(-1147276818, "FirTree_log"); deletable.Add(-755748398, "FirTree_log_half"); deletable.Add(1051479931, "FirTree_oldLog"); deletable.Add(-2139814576, "FirTree_Sapling"); deletable.Add(888684615, "FirTree_small"); deletable.Add(-367866354, "FirTree_small_dead"); deletable.Add(-2025597564, "FirTree_Stub"); deletable.Add(-1820912021, "FlametalRockstand"); deletable.Add(1243935330, "FlametalRockstand_frac"); deletable.Add(888919242, "fx_unstablelavarock_explosion"); deletable.Add(-2132038161, "HeathRockPillar"); deletable.Add(-328261538, "HeathRockPillar_frac"); deletable.Add(343637466, "ice_rock1"); deletable.Add(1448015437, "ice_rock1_frac"); deletable.Add(993449171, "lavabomb_rock1"); deletable.Add(2108016051, "LavaRock"); deletable.Add(2136704895, "lavarock_ashlands1"); deletable.Add(723343212, "MineRock_Copper"); deletable.Add(-922930389, "MineRock_Iron"); deletable.Add(-971628607, "MineRock_Meteorite"); deletable.Add(820355464, "MineRock_Obsidian"); deletable.Add(-1789907722, "MineRock_Stone"); deletable.Add(-1882492588, "MineRock_Tin"); deletable.Add(1457518369, "OakStub"); deletable.Add(1914820248, "Pickable_HardRockOffspring"); deletable.Add(1649351520, "Pickable_StoneRock"); deletable.Add(1603155848, "Pickable_SulfurRock"); deletable.Add(-1443700678, "piece_xmastree"); deletable.Add(1295600320, "PineTree"); deletable.Add(797319082, "Pinetree_01"); deletable.Add(364904293, "Pinetree_01_Stub"); deletable.Add(1111243907, "PineTree_log"); deletable.Add(1016303223, "PineTree_log_half"); deletable.Add(749341040, "PineTree_log_halfOLD"); deletable.Add(-1636733362, "PineTree_logOLD"); deletable.Add(-1134441643, "PineTree_Sapling"); deletable.Add(-1499803462, "Placeable_HardRock"); deletable.Add(-206628935, "projectile_lavaRock"); deletable.Add(1809630058, "RaspberryBush"); deletable.Add(1172889253, "Rock_3"); deletable.Add(1649426798, "Rock_3_frac"); deletable.Add(1576173780, "Rock_4"); deletable.Add(-2040381836, "Rock_4_plains"); deletable.Add(-1152709575, "Rock_7"); deletable.Add(112360646, "Rock_destructible"); deletable.Add(-447136041, "Rock_destructible_test"); deletable.Add(1499269640, "rock_mistlands1"); deletable.Add(33020421, "rock_mistlands1_frac"); deletable.Add(1499269639, "rock_mistlands2"); deletable.Add(1606082792, "rock1_mistlands"); deletable.Add(-1396233392, "rock1_mountain"); deletable.Add(-496513311, "rock1_mountain_frac"); deletable.Add(-1865631054, "rock2_heath"); deletable.Add(-1268964283, "rock2_heath_frac"); deletable.Add(-1397136109, "rock2_mountain"); deletable.Add(1422273664, "rock2_mountain_frac"); deletable.Add(-1473932452, "rock3_ice"); deletable.Add(-420778293, "rock3_ice_frac"); deletable.Add(-1398465710, "rock3_mountain"); deletable.Add(884909855, "rock3_mountain_frac"); deletable.Add(297427804, "rock3_silver"); deletable.Add(-990678761, "rock3_silver_frac"); deletable.Add(-820118935, "rock4_ashlands_frac"); deletable.Add(-2032417074, "rock4_bigrock_frac"); deletable.Add(-790658592, "rock4_coast"); deletable.Add(1039259597, "rock4_coast_frac"); deletable.Add(-1552092171, "rock4_copper"); deletable.Add(912150108, "rock4_copper_frac"); deletable.Add(1707947207, "rock4_forest"); deletable.Add(1082202028, "rock4_forest_frac"); deletable.Add(-1865985940, "rock4_heath"); deletable.Add(-1655434869, "rock4_heath_frac"); deletable.Add(1396764178, "RockDolmen_1"); deletable.Add(1800048705, "RockDolmen_2"); deletable.Add(233964764, "RockDolmen_3"); deletable.Add(571199914, "RockFinger"); deletable.Add(-171548199, "RockFinger_frac"); deletable.Add(414646403, "RockFingerBroken"); deletable.Add(1140737056, "RockFingerBroken_frac"); deletable.Add(1524190963, "rockformation1"); deletable.Add(-1854838197, "RockThumb"); deletable.Add(-233084190, "RockThumb_frac"); deletable.Add(926881886, "StoneRock"); deletable.Add(595427151, "stubbe"); deletable.Add(1515889972, "stubbe_spawner"); deletable.Add(2111235755, "SwampTree1"); deletable.Add(998340100, "SwampTree1_log"); deletable.Add(-142007914, "SwampTree1_Stub"); deletable.Add(1707951228, "SwampTree2"); deletable.Add(2052455688, "SwampTree2_darkland"); deletable.Add(270257971, "SwampTree2_log"); deletable.Add(-1209701263, "UnstableLavaRock"); deletable.Add(-1874176361, "UnstableLavaRock_explosion"); } value = GeneralExtensions.GetValueSafe(deletable, hashCode); return value != null; } } public static class RPCUtility { public enum RPCName { INIT_REGISTRY } private static VisbendingLogger.Context context = VisbendingLogger.Context.RPC; public static string GetCallName(RPCName rpcName) { VisbendingLogger.Log(context, "GetCallName" + rpcName); if (rpcName == RPCName.INIT_REGISTRY) { return "RPC_InitSpawnRegistry"; } throw new ArgumentException(rpcName.ToString()); } private static ZPackage SerializeAnchors() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown VisbendingLogger.Log(context, "Serialize Anchors"); int count = SpawnRegistry.anchorName2anchorType.Values.Count; ZPackage val = new ZPackage(); val.Write(count); foreach (AnchorType value in SpawnRegistry.anchorName2anchorType.Values) { value.serialize(val); } return val; } public static void RegisterClientRPC(ZNetPeer peer) { VisbendingLogger.Log(context, "RegisterClientRPC"); if (peer != null && !ZNet.instance.IsServer()) { peer.m_rpc.Register(GetCallName(RPCName.INIT_REGISTRY), (Action)InitRegistryForClient); } } public static void SyncToClient(ZNetPeer peer) { VisbendingLogger.Log(context, "SendServerInfoToClient " + peer.m_playerName); SyncToClient(peer, RPCName.INIT_REGISTRY); } private static void InitRegistryForClient(ZRpc rpc, ZPackage pkg) { VisbendingLogger.Log(context, "InitRegistryForClient"); SpawnRegistry.Clear(); int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { AnchorType anchorType = AnchorType.Deserialize(pkg); SpawnRegistry.anchorName2anchorType.Add(anchorType.GetAnchorName(), anchorType); } SpawnRegistry.Init(); } private static void SyncToClient(ZNetPeer peer, RPCName rpcName) { VisbendingLogger.Log(context, "SyncToClient " + rpcName); if (peer != null && peer.m_uid != 0L) { string callName = GetCallName(rpcName); if (rpcName != 0) { throw new ArgumentException(rpcName.ToString()); } peer.m_rpc.Invoke(callName, new object[1] { SerializeAnchors() }); } } } [HarmonyPatch(typeof(RuneStone), "Interact")] public class RuneStone_Interact_Patch { private static void Prefix(RuneStone __instance, Humanoid character, bool hold, bool alt) { if (!((Object)__instance).name.StartsWith(VisbendingMod.MOD_NAME)) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && component.IsValid()) { __instance.m_text = component.GetZDO().GetString(VisbendingMod.PARAM_TEXT_KEY, __instance.m_text); __instance.m_randomTexts?.Clear(); Player val = (Player)(object)((character is Player) ? character : null); if (!((Object)(object)val == (Object)null)) { TriggerCustomCompendiumEntry(val); } } } private static void TriggerCustomCompendiumEntry(Player player) { string topic = VisbendingMod.TEXTKEY_COMPENDIUM_BILLBOARDS_TOPIC; string tEXTKEY_COMPENDIUM_BILLBOARDS_TEXT = VisbendingMod.TEXTKEY_COMPENDIUM_BILLBOARDS_TEXT; string tEXTKEY_COMPENDIUM_BILLBOARDS_MESSAGE = VisbendingMod.TEXTKEY_COMPENDIUM_BILLBOARDS_MESSAGE; string text = Localization.instance.Localize(topic); Localization.instance.Localize(tEXTKEY_COMPENDIUM_BILLBOARDS_TEXT); string text2 = Localization.instance.Localize(tEXTKEY_COMPENDIUM_BILLBOARDS_MESSAGE); foreach (KeyValuePair knownText in player.GetKnownTexts()) { _ = knownText; if (player.GetKnownTexts().Any((KeyValuePair x) => x.Key == topic)) { return; } } player.AddKnownText(topic, tEXTKEY_COMPENDIUM_BILLBOARDS_TEXT); player.ShowTutorial(text, false); MessageHud.instance.ShowMessage((MessageType)1, text2, 0, (Sprite)null, false); } } [HarmonyPatch(typeof(Terminal), "TryRunCommand")] public static class Terminal_TryRunCommand_Patch { private static bool Prefix(string text) { if (text.ToLower() == "resetvis") { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { FieldInfo field = typeof(Player).GetField("m_knownTexts", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { Dictionary dictionary = (Dictionary)field.GetValue(localPlayer); List list = new List(); foreach (string key in dictionary.Keys) { if (key.Contains("Visbending") || key.Contains("$Visbending")) { list.Add(key); } } foreach (string item in list) { dictionary.Remove(item); } ((Character)localPlayer).Message((MessageType)2, $"Removed {list.Count} REAL entries from Dictionary.", 0, (Sprite)null); } } return false; } return true; } } internal class SpawnRegistry { private static VisbendingLogger.Context textContext = VisbendingLogger.Context.Text; private static VisbendingLogger.Context registerContext = VisbendingLogger.Context.Registration; private static readonly int GlobalConfigHash = (VisbendingMod.MOD_NAME + "_GlobalWorldData").GetHashCode(); public static Dictionary _stoneConfigs = new Dictionary(); public static Dictionary anchorName2anchorType = new Dictionary(); private static bool initialized = false; public static void Init() { if (initialized) { return; } VisbendingLogger.Log(registerContext, "SpawnRegistry init"); if (anchorName2anchorType == null || anchorName2anchorType.Count == 0) { if (anchorName2anchorType == null) { VisbendingLogger.Log(registerContext, "SpawnRegistry init, anchorName2anchorType is null"); } else { VisbendingLogger.Log(registerContext, "SpawnRegistry init, anchorName2anchorType.Count = 0"); } return; } foreach (KeyValuePair item in anchorName2anchorType) { StoneConfig stoneConfig = _stoneConfigs[item.Key]; item.Value.SetColorKey(stoneConfig.ColorEntry.Value); VisbendingLogger.Log(registerContext, "SpawnRegistry init 2"); item.Value.SetTextKeys(stoneConfig.TextKeys); VisbendingLogger.Log(registerContext, "SpawnRegistry init 3"); item.Value.Init(); VisbendingLogger.Log(registerContext, "SpawnRegistry init 4"); } initialized = true; } public static bool IsInitialized() { return initialized; } public static void RegisterStoneConfig(StoneConfig config) { VisbendingLogger.Log(registerContext, "Anchor = " + config.AnchorName + "Runestone = " + config.RunestonePrefabName + ", Number = " + config.CountEntry.Value + ", Radius = " + config.RadiusEntry.Value); if (!_stoneConfigs.ContainsKey(config.AnchorName)) { _stoneConfigs.Add(config.AnchorName, config); } } public static StoneConfig GetStoneConfigByTextKey(string textKey) { foreach (KeyValuePair stoneConfig in _stoneConfigs) { if (textKey.Contains(stoneConfig.Key)) { VisbendingLogger.Log(textContext, "Found config for textKey" + textKey); return stoneConfig.Value; } } VisbendingLogger.Log(textContext, "Non config found for textKey" + textKey); return null; } public static void RefreshRegisteredTexts(Dictionary translations) { VisbendingLogger.Log(textContext, "Refresh texts, size " + translations.Count); Dictionary> dictionary = new Dictionary>(); foreach (KeyValuePair translation in translations) { StoneConfig stoneConfigByTextKey = GetStoneConfigByTextKey(translation.Key); if (stoneConfigByTextKey != null) { VisbendingLogger.Log(textContext, "config for text key" + stoneConfigByTextKey.AnchorName); if (!dictionary.ContainsKey(stoneConfigByTextKey)) { dictionary.Add(stoneConfigByTextKey, new List()); } List valueSafe = GeneralExtensions.GetValueSafe>(dictionary, stoneConfigByTextKey); addKeyInternal(translation.Key, valueSafe); } else { VisbendingLogger.Log(textContext, "no config for text key " + translation.Key); } } foreach (KeyValuePair> item in dictionary) { VisbendingLogger.Log(textContext, "Refresh texts for " + item.Key.AnchorName + " " + item.Value.Count); refreshInternal(item.Key, item.Value); } } private static void addKeyInternal(string textKey, List list) { string item = "$" + textKey; if (!list.Contains(item)) { list.Add(item); VisbendingLogger.Log(textContext, " addKeyInternal, added " + textKey + " " + list.Count); } } private static void refreshInternal(StoneConfig config, List list) { if (list != null && list.Count > 0) { VisbendingLogger.Log(textContext, " refresh internal" + config.AnchorName + ", size " + list.Count); config.TextKeys = list; } else if (list == null) { VisbendingLogger.Log(textContext, " refresh internal" + config.AnchorName + ", list is null"); } else { VisbendingLogger.Log(textContext, " refresh internal" + config.AnchorName + ", list is empty"); } } public static void Clear() { VisbendingLogger.Log(registerContext, "SpawnRegistry clear"); anchorName2anchorType.Clear(); initialized = false; } public static bool GetStoneConfig(string name, out StoneConfig config) { config = GeneralExtensions.GetValueSafe(_stoneConfigs, name); return config != null; } public static void PrepareIfRelevantLocation(string context, ZoneLocation zonelocation, Vector3 pos) { //IL_013d: Unknown result type (might be due to invalid IL or missing references) if (!GetStoneConfig(zonelocation.m_prefabName, out var config)) { return; } if (!anchorName2anchorType.TryGetValue(config.AnchorName, out var value)) { int radius = config.RadiusEntry.Value; int num = config.CountEntry.Value; string uniqueIdentifier = VisbendingMod.MOD_NAME + "_" + config.AnchorName; ZDO val = ZDOUtility.FindMasterZDO(uniqueIdentifier); if (val != null) { radius = val.GetInt(VisbendingMod.PARAM_RADIUS, 0); num = val.GetInt(VisbendingMod.PARAM_NO_OF_STONES, 0); } else { ZDOUtility.WriteMasterZDO(uniqueIdentifier, radius, num); } value = new AnchorTypeBuilder().AnchorName(config.AnchorName).PrefabName(config.RunestonePrefabName).Radius(radius) .NumberOfStones(num) .TextKeys(config.TextKeys) .ColorKey(config.ColorEntry.Value) .Build(); anchorName2anchorType.Add(config.AnchorName, value); VisbendingLogger.Log(registerContext, context + "Relevant location" + zonelocation.m_prefabName + " " + radius + " " + num); } value.AddAnchor(pos); } public static void RemoveInvalidLocations(ZoneLocation zonelocation, Vector3 validPos) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Log(registerContext, "Remove invalid Locations " + zonelocation.m_prefabName); if (!anchorName2anchorType.TryGetValue(zonelocation.m_prefabName, out var value)) { return; } VisbendingLogger.Log(registerContext, " SpawnRegistry, relevant Invalid location" + zonelocation.m_prefabName); Vector2i zone = ZoneSystem.GetZone(validPos); foreach (Anchor anchor in value.GetAnchors()) { Vector2i anchorZone = anchor.GetAnchorZone(); if (((Vector2i)(ref anchorZone)).Equals(zone)) { VisbendingLogger.Log(registerContext, $" keeping valid Anchor Entry found in {0}", ((object)(Vector2i)(ref zone)).ToString()); } else { anchor.SetValid(valid: false); } } if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } Dictionary> zoneZDOsByAnchorName = ZDOUtility.GetZoneZDOsByAnchorName(value.GetAnchorName()); foreach (Anchor anchor2 in value.GetAnchors()) { List valueSafe = GeneralExtensions.GetValueSafe>(zoneZDOsByAnchorName, anchor2.GetAnchorZone()); if (!anchor2.IsValid()) { if (valueSafe != null && valueSafe.Count > 0) { VisbendingLogger.Log(registerContext, $"destroying {valueSafe.Count} ZDOs in {anchor2.GetAnchorZone()} "); ZDOUtility.DestroyZDOs(valueSafe); } else { VisbendingLogger.Log(registerContext, $"no ZDOs in zone {anchor2.GetAnchorZone()}"); } } else { int num = valueSafe?.Count ?? 0; VisbendingLogger.Log(registerContext, $"keeping {num} ZDOs in zone {anchor2.GetAnchorZone()}"); } } } public static bool IsValidAnchor(string anchorName, Vector2i zone) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) AnchorType anchorType = ((anchorName != null) ? anchorName2anchorType[anchorName] : null); if (anchorType != null) { Anchor anchor = anchorType.GetAnchor(zone); if (anchor != null) { return anchor.IsValid(); } } return false; } } public class StoneConfig { public string AnchorName; public string RunestonePrefabName; public List TextKeys; public ConfigEntry RadiusEntry; public ConfigEntry CountEntry; public ConfigEntry ColorEntry; } internal class Stuff { private static void CreateDebugSphere(Vector3 pos, float radius) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); obj.transform.position = pos; obj.transform.localScale = new Vector3(radius * 2f, radius * 2f, radius * 2f); Object.Destroy((Object)(object)obj.GetComponent()); Renderer component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { component.material.shader = Shader.Find("Standard"); component.material.SetInt("_SrcBlend", 5); component.material.SetInt("_DstBlend", 10); component.material.SetInt("_ZWrite", 0); component.material.DisableKeyword("_ALPHATEST_ON"); component.material.EnableKeyword("_ALPHABLEND_ON"); component.material.SetColor("_Color", new Color(1f, 0f, 0f, 0.3f)); } Object.Destroy((Object)(object)obj, 60f); } public static Vector3 ApplyPermanentGentleTerrain(Vector3 position, float delta) { //IL_001b: 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_002d: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = ZNetScene.instance.GetPrefab("raise"); if ((Object)(object)prefab == (Object)null) { return position; } Vector3 val = position; val.y += delta; TerrainModifier component = Object.Instantiate(prefab, val, Quaternion.identity).GetComponent(); if ((Object)(object)component != (Object)null) { component.m_level = true; component.m_levelRadius = 3.5f; component.m_smooth = true; component.m_smoothRadius = 6f; component.m_paintCleared = true; component.m_paintType = (PaintType)0; } return val; } public static bool IsStartAltarPlaced() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } foreach (LocationInstance location in ZoneSystem.instance.GetLocationList()) { if (location.m_location != null && location.m_location.m_prefabName == "StartTemple") { return true; } } return false; } private static Dictionary ParseSimpleJson(string json) { Dictionary dictionary = new Dictionary(); string[] array = json.Trim('{', '}', ' ', '\r', '\n').Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }, 2); if (array2.Length == 2) { string key = array2[0].Trim(' ', '"', '\r', '\n'); string value = array2[1].Trim(' ', '"', '\r', '\n'); dictionary[key] = value; } } return dictionary; } public static void PrintObjectsAround() { //IL_0022: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) if ((Object)(object)Player.m_localPlayer == (Object)null) { ZLog.Log((object)"no player"); return; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; List list = ZDOUtility.FindObjectsInRadius(position, 5f); Vector3 position2; if (list != null) { foreach (ZDO item in list) { if (item != null) { item.GetPosition(); string name = ((Object)ZNetScene.instance.GetPrefab(item.GetPrefab())).name; position2 = item.GetPosition(); ZLog.Log((object)(" nearby object : " + name + " " + ((object)(Vector3)(ref position2)).ToString())); } } } Collider[] array = Physics.OverlapSphere(position, 5f); for (int i = 0; i < array.Length; i++) { ZNetView componentInParent = ((Component)array[i]).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { ZDO zDO = componentInParent.GetZDO(); object obj; if (zDO == null) { obj = " unknown"; } else { position2 = zDO.GetPosition(); obj = ((object)(Vector3)(ref position2)).ToString(); } string text = (string)obj; string name2 = ((Object)((Component)componentInParent).gameObject).name; ZLog.Log((object)("Object found: " + name2 + " " + text)); } } } public static void MarkStonesOnMap() { //IL_00a7: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) ZNetView[] array = Object.FindObjectsByType((FindObjectsSortMode)0); List list = array.Where((ZNetView z) => z.GetZDO() != null && PrefabCreator.IsModObject(((Component)z).gameObject)).ToList(); if (list.Count == 0) { ZNetView[] array2 = array; foreach (ZNetView val in array2) { if ((Object)(object)((Component)val).gameObject != (Object)null) { ZLog.Log((object)("***" + ((Object)((Component)val).gameObject).name)); } } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "Keine Steine in der Nähe gefunden!", 0, (Sprite)null); } return; } foreach (ZNetView item in list) { Vector3 position = ((Component)item).transform.position; if ((Object)(object)Minimap.instance != (Object)null) { Minimap.instance.AddPin(position, (PinType)14, $"Stein: {position.x:F0}/{position.z:F0}", false, false, 0L, default(PlatformUserID)); } } Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Character)localPlayer2).Message((MessageType)2, $"{list.Count} Steine markiert!", 0, (Sprite)null); } } public static void DumpPrefabs() { if ((Object)(object)ZNetScene.instance == (Object)null) { return; } try { ZLog.Log((object)"start prefab export"); List prefabNames = ZNetScene.instance.GetPrefabNames(); ZLog.Log((object)"start prefab export, step 1"); prefabNames.Sort(); List list = new List(); bool flag = false; bool flag2 = false; foreach (string item2 in prefabNames) { if (!flag) { ZLog.Log((object)"start prefab export, step 2"); flag = true; } GameObject prefab = ZNetScene.instance.GetPrefab(item2); if (!flag2) { ZLog.Log((object)"start prefab export, step 3"); flag2 = true; } if ((Object)(object)prefab == (Object)null) { ZLog.Log((object)("prefab is null, name " + item2)); continue; } Renderer componentInChildren = prefab.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { string text = ""; Material sharedMaterial = componentInChildren.sharedMaterial; if ((Object)(object)sharedMaterial != (Object)null) { Shader shader = sharedMaterial.shader; text = ((!((Object)(object)shader != (Object)null)) ? "" : ((Object)shader).name); } string item = item2 + " " + StringExtensionMethods.GetStableHashCode(item2) + ", " + text; list.Add(item); } } File.WriteAllLines(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Valheim_PrefabsAndShaders.txt"), list); } catch (Exception ex) { ZLog.LogError((object)("Fehler beim Exportieren der Prefabs: " + ex.Message)); } } } internal class TransformUtility { public static void PrintFullTree(Transform transform) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Hierarchie-Analysis for: " + ((Object)transform).name); BuildTreeString(transform, stringBuilder, 0); Debug.Log((object)stringBuilder.ToString()); } private static void BuildTreeString(Transform current, StringBuilder sb, int indent) { string text = new string(' ', indent * 4); sb.AppendLine(text + "GameObject: [" + ((Object)current).name + "]"); Component[] components = ((Component)current).GetComponents(); foreach (Component val in components) { if (!((Object)(object)val == (Object)null)) { sb.AppendLine(text + " - Component: " + ((object)val).GetType().Name); } } for (int j = 0; j < current.childCount; j++) { BuildTreeString(current.GetChild(j), sb, indent + 1); } } } public static class VisbendingLogger { public enum Context { Extraction, Localization, Registration, RPC, Spawning, Terrain, Text, ZDO, ZNet, ZNetScene, ZNetView, ZoneSystem } private static HashSet contextSet; public static ConfigEntry ConfigLogContext; public static void Log(Context context, params string[] values) { initContext(); if (IsContexSet(context) && values != null && values.Length != 0) { if (values.Length > 1) { ZLog.Log((object)("[" + VisbendingMod.MOD_NAME + "]" + context.ToString() + " " + formatString(values))); } else { ZLog.Log((object)("[" + VisbendingMod.MOD_NAME + "]" + context.ToString() + " " + values[0])); } } } private static string formatString(string[] values) { string text = values[0]; for (int i = 0; i < values.Length - 1; i++) { text = text.Replace("{" + i + "}", values[i + 1]); } return text; } private static void initContext() { if (ConfigLogContext == null || contextSet != null) { return; } contextSet = new HashSet(); string[] array = ConfigLogContext.Value.Split(new char[1] { ',' }); ContextToHashSet(); Context[] values = EnumUtils.GetValues(); for (int i = 0; i < values.Length; i++) { Context item = values[i]; string[] array2 = array; foreach (string text in array2) { if (item.ToString().ToLower().Trim() .Equals(text.ToLower().Trim())) { contextSet.Add(item); } } } } private static bool IsContexSet(Context c) { return contextSet.Contains(c); } private static string FormatMessage(string context, string[] values) { try { if (values != null && values.Length != 0 && context.Contains("{0}")) { return string.Format(context, values); } } catch (FormatException) { return context + " | Extra-values: " + string.Join(", ", values); } if (values == null || values.Length == 0) { return context; } return context + " [" + string.Join(", ", values) + "]"; } private static HashSet ContextToHashSet() { HashSet hashSet = new HashSet(); Context[] values = EnumUtils.GetValues(); for (int i = 0; i < values.Length; i++) { Context context = values[i]; hashSet.Add(context.ToString()); } return hashSet; } public static string ContextToString(string separator) { StringBuilder stringBuilder = new StringBuilder(); HashSet hashSet = ContextToHashSet(); string value = ""; foreach (string item in hashSet) { stringBuilder.Append(value).Append(item.ToString()); value = separator; } return stringBuilder.ToString(); } } [HarmonyPatch(typeof(ZDOMan), "Load")] internal class ZDOMan_Load_Patch { private static void Postfix(BinaryReader reader, int version) { VisbendingLogger.Log(VisbendingLogger.Context.ZDO, "ZDOMan.Load" + ZDOMan.instance.NrOfObjects()); } } internal class ZDOUtility { private static VisbendingLogger.Context contextZDO = VisbendingLogger.Context.ZDO; private static readonly int GlobalConfigHash = (VisbendingMod.MOD_NAME + "_GlobalWorldData").GetHashCode(); private static readonly string MasterIdString = VisbendingMod.MOD_NAME + "_DataID"; public static bool CheckValidity(ZDO zdo) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0039: Unknown result type (might be due to invalid IL or missing references) Vector3 vec = zdo.GetVec3(VisbendingMod.PARAM_ANCHOR_POS, Vector3.zero); string @string = zdo.GetString(VisbendingMod.PARAM_ANCHOR_NAME, ""); if (vec == Vector3.zero) { return true; } Vector2i zone = ZoneSystem.GetZone(vec); return SpawnRegistry.IsValidAnchor(@string, zone); } public static void DestroyZDOs(List list) { if (list == null || list.Count == 0) { return; } foreach (ZDO item in list) { VisbendingLogger.Log(contextZDO, "destroying zdo " + item.GetPrefab()); item.SetOwner(ZDOMan.GetSessionID()); ZDOMan.instance.DestroyZDO(item); } } public static List FindObjectsInRadius(Vector3 position, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_007f: 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) List list = new List(); Vector2i zone = ZoneSystem.GetZone(position); MethodInfo method = typeof(ZDOMan).GetMethod("FindObjects", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2] { typeof(Vector2i), typeof(List) }, null); if (method == null) { return list; } Vector2i val = default(Vector2i); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { ((Vector2i)(ref val))..ctor(zone.x + i, zone.y + j); method.Invoke(ZDOMan.instance, new object[2] { val, list }); } } return list.Where((ZDO zdo) => Vector3.Distance(zdo.GetPosition(), position) <= radius).ToList(); } public static List FindObjects(Vector2i sector) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) List list = new List(); MethodInfo method = typeof(ZDOMan).GetMethod("FindObjects", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2] { typeof(Vector2i), typeof(List) }, null); if (method != null) { method.Invoke(ZDOMan.instance, new object[2] { sector, list }); } return list; } public static Dictionary> GetZoneZDOsByAnchorName(string anchorName) { //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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) Dictionary> dictionary = new Dictionary>(); ZDOMan instance = ZDOMan.instance; if (AccessTools.Field(typeof(ZDOMan), "m_objectsByID").GetValue(instance) is Dictionary dictionary2) { VisbendingLogger.Log(contextZDO, $"helping, {dictionary2.Count} ZDOs for {anchorName}..."); foreach (ZDO value2 in dictionary2.Values) { if (value2.GetString(VisbendingMod.PARAM_ANCHOR_NAME, "").Equals(anchorName)) { Vector2i zone = ZoneSystem.GetZone(value2.GetVec3(VisbendingMod.PARAM_ANCHOR_POS, Vector3.zero)); if (!dictionary.TryGetValue(zone, out var value)) { value = new List(); dictionary.Add(zone, value); } value.Add(value2); } } } VisbendingLogger.Log(contextZDO, $"returning, {dictionary.Count} ZDOs for {anchorName}..."); return dictionary; } public static ZDO FindMasterZDO(string uniqueIdentifier) { int hashCode = uniqueIdentifier.GetHashCode(); ZDOMan instance = ZDOMan.instance; ZDO result = null; if (AccessTools.Field(typeof(ZDOMan), "m_objectsByID").GetValue(instance) is Dictionary dictionary) { VisbendingLogger.Log(contextZDO, $"searching in {dictionary.Count} ZDOs for {uniqueIdentifier}..."); foreach (ZDO value in dictionary.Values) { if (value.GetInt(MasterIdString, 0) == hashCode) { result = value; break; } } } return result; } public static void WriteMasterZDO(string uniqueIdentifier, int radius, int noOfStones) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) int hashCode = uniqueIdentifier.GetHashCode(); VisbendingLogger.Log(contextZDO, "no Master-ZDO exists for " + uniqueIdentifier + ". creating new one for this world"); int hashCode2 = "LocationProxy".GetHashCode(); ZDOMan instance = ZDOMan.instance; ZDO val = instance.CreateNewZDO(Vector3.zero, hashCode2); VisbendingLogger.Log(contextZDO, " Master ZDO " + val.GetPrefab()); val.SetPrefab(hashCode2); val.Persistent = true; val.Set(MasterIdString, hashCode); val.Set(VisbendingMod.PARAM_RADIUS, radius); val.Set(VisbendingMod.PARAM_NO_OF_STONES, noOfStones); instance.AddToSector(val, new Vector2i(0, 0)); instance.ForceSendZDO(val.m_uid); VisbendingLogger.Log(contextZDO, "Master-ZDO successfully created and saved for " + uniqueIdentifier); } public static void CheckZDOMan(string context) { if (ZDOMan.instance == null) { VisbendingLogger.Log(VisbendingLogger.Context.ZDO, context + " ZDOMan is null"); return; } FieldInfo fieldInfo = AccessTools.Field(typeof(ZDOMan), "m_objectsByID"); if (fieldInfo == null) { VisbendingLogger.Log(VisbendingLogger.Context.ZDO, context + " ZDOMan, field is null"); } else { Dictionary dictionary = fieldInfo.GetValue(ZDOMan.instance) as Dictionary; VisbendingLogger.Log(VisbendingLogger.Context.ZDO, context + " ZDOMan, m_objectsByID count = " + dictionary.Count); } } public static void EnhanceZDO(Candidate candidate, ZDO zdo) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) Group parent = candidate.GetParent(); Anchor parent2 = parent.GetParent(); string textKey = parent.GetTextKey(); zdo.Persistent = true; zdo.Set(VisbendingMod.PARAM_TEXT_KEY, textKey); zdo.Set(VisbendingMod.PARAM_MSGHASH, StringExtensionMethods.GetStableHashCode(textKey)); zdo.Set(VisbendingMod.PARAM_ANCHOR_POS, parent2.GetAnchorPosition()); zdo.Set(VisbendingMod.PARAM_ANCHOR_NAME, parent2.GetAnchorName()); zdo.Set(VisbendingMod.PARAM_COLOR_KEY, parent2.GetColorKey()); zdo.Set(VisbendingMod.PARAM_GROUP_ID, parent.GetIndex()); zdo.Set(VisbendingMod.PARAM_INDEX, candidate.GetIndex()); VisbendingLogger.Log(VisbendingLogger.Context.ZDO, "data successfully written into StoneCandidate ZDO."); } } [HarmonyPatch(typeof(ZNetView), "Awake")] public class ZNetView_Awake_Patch { private static void Postfix(ZNetView __instance) { if (StoneSpawner.CurrentCandidate != null) { ZDO zDO = __instance.GetZDO(); if (zDO != null) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetView, "zdo !=null " + ((Object)((Component)__instance).gameObject).name); ZDOUtility.EnhanceZDO(StoneSpawner.CurrentCandidate, zDO); } else { VisbendingLogger.Log(VisbendingLogger.Context.ZNetView, "zdo ==null !! " + ((Object)((Component)__instance).gameObject).name); } } if (PrefabCreator.IsModObject(((Component)__instance).gameObject) && __instance.GetZDO() != null) { if (__instance.IsOwner() && !ZDOUtility.CheckValidity(__instance.GetZDO())) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetView, "destroying invalid stone " + ((Object)((Component)__instance).gameObject).name); __instance.Destroy(); } else { string @string = __instance.GetZDO().GetString("ColorKey", ""); StoneSpawner.ApplyVisualColor(((Component)__instance).gameObject, @string); } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class RegisterRPCPatch { private static void Postfix(ZNetPeer peer) { RPCUtility.RegisterClientRPC(peer); } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] public static class SyncOnJoin { private delegate ZNetPeer GetPeerDelegate(ZNet instance, ZRpc rpc); private static readonly GetPeerDelegate _GetPeerDelegate = AccessTools.MethodDelegate(AccessTools.Method(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null), (object)null, true); private static void Postfix(ZNet __instance, ZRpc rpc) { if (__instance.IsServer()) { ZNetPeer val = _GetPeerDelegate(__instance, rpc); if (val != null) { RPCUtility.SyncToClient(val); } } } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] public class ZNet_OnDestroy_Patch { private static void Postfix() { VisbendingLogger.Log(VisbendingLogger.Context.ZNet, "OnDestroy, clear registry"); SpawnRegistry.Clear(); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public class ZNetScene_Awake_Patch { private static readonly int GlobalConfigHash = (VisbendingMod.MOD_NAME + "_GlobalWorldData").GetHashCode(); [HarmonyPrefix] private static void Prefix(ZNetScene __instance) { if (PrefabCreator.GetAlternative() != null) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Awake, reserving alternative"); return; } VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Awake, reserving hashcodes"); foreach (StoneConfig value in SpawnRegistry._stoneConfigs.Values) { int hashCode = PrefabCreator.GetHashCode(value.RunestonePrefabName); Dictionary dictionary = (Dictionary)typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); if (!dictionary.ContainsKey(hashCode)) { dictionary.Add(hashCode, null); VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "ZNetScene, place holder " + hashCode); } } } } [HarmonyPatch(typeof(ZNetScene), "CreateObject", new Type[] { typeof(ZDO) })] public class ZNetScene_CreateObject_Fix_Patch { private static bool Prefix(ZNetScene __instance, ZDO zdo, ref GameObject __result) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) int prefab = zdo.GetPrefab(); GameObject prefab2 = __instance.GetPrefab(prefab); if (PrefabCreator.IsModObject(prefab2)) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "creating object"); if (!SpawnRegistry.IsInitialized()) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Spawn registry is not valid yet"); return false; } bool flag = ZDOUtility.CheckValidity(zdo); ZNetView val = __instance.FindInstance(zdo); if ((Object)(object)val != (Object)null) { __result = (flag ? ((Component)val).gameObject : null); if (flag) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "ZNetView existed and anchor zone is still valid"); __result = ((Component)val).gameObject; } else { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "ZNetView existed but meanwhile anchor zone became invalid"); val.Destroy(); __result = null; } return false; } if (!flag) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Object " + ((Object)prefab2).name + " NOT reanimated because anchor zone became invalid."); return false; } ZNetView.m_useInitZDO = true; ZNetView.m_initZDO = zdo; GameObject val2 = Object.Instantiate(prefab2, zdo.GetPosition(), zdo.GetRotation()); ((Object)val2).name = ((Object)prefab2).name; val2.SetActive(true); ZNetView component = val2.GetComponent(); if ((Object)(object)component != (Object)null) { __instance.AddInstance(zdo, component); __result = val2; VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Object " + ((Object)prefab2).name + " reanimated on zone reentry."); TerrainModifier component2 = val2.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = true; VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Poking height maps"); foreach (Heightmap allHeightmap in Heightmap.GetAllHeightmaps()) { if (allHeightmap.IsPointInside(zdo.GetPosition(), 25f)) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, " Poking " + ((Object)allHeightmap).name); allHeightmap.Poke(true); } } } else if (((Object)prefab2).name.ToLower().EndsWith("flatten")) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "flatten, no terrain modifier"); } ZNetView.m_useInitZDO = false; ZNetView.m_initZDO = null; return false; } VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Object " + ((Object)prefab2).name + " could not be reanimated."); ZNetView.m_useInitZDO = false; ZNetView.m_initZDO = null; } return true; } } [HarmonyPatch(typeof(ZNetScene), "Shutdown")] public class ZNetScene_Shutdown_Patch { private static void Prefix() { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) SpawnRegistry.Clear(); VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, "Prefix Shutdown"); ZNetView[] array = Object.FindObjectsByType((FindObjectsSortMode)0); int num = 0; ZNetView[] array2 = array; foreach (ZNetView val in array2) { if ((Object)(object)val != (Object)null && PrefabCreator.IsModObject(((Component)val).gameObject)) { Vector3 position; if (val.GetZDO() != null) { int @int = val.GetZDO().GetInt(VisbendingMod.PARAM_GROUP_ID, 0); int int2 = val.GetZDO().GetInt(VisbendingMod.PARAM_INDEX, 0); string[] array3 = new string[1]; string[] obj = new string[6] { "pos ", null, null, null, null, null }; position = ((Component)val).gameObject.transform.position; obj[1] = ((object)(Vector3)(ref position)).ToString(); obj[2] = " "; obj[3] = @int.ToString(); obj[4] = " "; obj[5] = int2.ToString(); array3[0] = string.Concat(obj); VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, array3); } else { string[] array4 = new string[1]; position = ((Component)val).gameObject.transform.position; array4[0] = "pos " + ((object)(Vector3)(ref position)).ToString(); VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, array4); } Object.DestroyImmediate((Object)(object)((Component)val).gameObject); num++; } } if (num > 0) { VisbendingLogger.Log(VisbendingLogger.Context.ZNetScene, $"Logout-Cleanup: {num} rune stones safely removed"); } } } public static class PrefabCreator { private static VisbendingLogger.Context context = VisbendingLogger.Context.Extraction; public static Dictionary extractedObjects = new Dictionary(); private static readonly object _lock = new object(); private static string alternative = null; public static void TryRegister(string source) { lock (_lock) { if (!((Object)(object)ZNetScene.instance != (Object)null)) { return; } foreach (GameObject value in extractedObjects.Values) { ExecuteRegistration(ZNetScene.instance, source, value); } } } public static void ExtractObjects(ZoneSystem __instance) { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown VisbendingLogger.Log(context, " Extracting objects"); foreach (StoneConfig config in SpawnRegistry._stoneConfigs.Values) { string text = VisbendingMod.MOD_NAME + config.RunestonePrefabName; if (extractedObjects.ContainsKey(text)) { extractedObjects.TryGetValue(text, out var value); VisbendingLogger.Log(context, " already extracted {0} , hashCode (object.getHashCode) {1}", ((Object)value).name, ((object)value).GetHashCode().ToString()); continue; } ZoneLocation val = __instance.m_locations.Find((ZoneLocation l) => l.m_prefabName == config.RunestonePrefabName); if (val != null) { val.m_prefab.LoadAsync(); val.m_prefab.WaitForLoadToComplete(); RuneStone componentInChildren = val.m_prefab.Asset.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { Material material = new Material(((Component)componentInChildren).GetComponentInChildren().sharedMaterial); ExtractObjectInternal(((Component)componentInChildren).gameObject, text, material); } } else { VisbendingLogger.Log(context, "Location {0} not found, searching for stone {1}", config.AnchorName, config.RunestonePrefabName); } } TryRegister("PrefabCreator.extractObjects"); } private static void ExtractObjectInternal(GameObject prefabToBe, string name, Material material) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(prefabToBe); ((Object)val).name = name; StringExtensionMethods.GetStableHashCode(((Object)val).name); if ((Object)(object)material != (Object)null) { val.GetComponentInChildren().material = material; } Object.DontDestroyOnLoad((Object)(object)val); val.SetActive(false); (val.GetComponent() ?? val.AddComponent()).m_persistent = true; TerrainModifier obj = val.AddComponent(); ((Behaviour)obj).enabled = false; obj.m_level = true; obj.m_levelRadius = 2.5f; obj.m_smooth = true; obj.m_smoothRadius = 6f; obj.m_paintCleared = true; obj.m_paintType = (PaintType)4; _ = val.layer; string text = LayerMask.LayerToName(val.layer); VisbendingLogger.Log(context, "Object {0} layer {layerID} ({1})", ((Object)val).name, text); extractedObjects.Add(name, val); } private static void ExtractSpecial(Transform current, string gameObjectName) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown Component[] components = ((Component)current).GetComponents(); foreach (Component val in components) { if ((Object)(object)val != (Object)null && ((Object)val.gameObject).name.Equals("gameObjectName")) { VisbendingLogger.Log(context, " ForceField found " + ((object)val).GetType().Name); GameObject val2 = Object.Instantiate(val.gameObject); ((Object)val2).name = VisbendingMod.MOD_NAME + "ForceField"; StringExtensionMethods.GetStableHashCode(((Object)val2).name); val2.GetComponentInChildren().material = new Material(val.gameObject.GetComponentInChildren().sharedMaterial); Object.DontDestroyOnLoad((Object)(object)val2); val2.SetActive(false); if (!extractedObjects.ContainsKey(((Object)val2).name)) { extractedObjects.Add(((Object)val2).name, val2); } } } for (int j = 0; j < current.childCount; j++) { ExtractSpecial(current.GetChild(j), gameObjectName); } } private static void ExecuteRegistration(ZNetScene scene, string source, GameObject prefab) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) ZNetView val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent(); } val.m_persistent = true; val.m_type = (ObjectType)2; val.m_syncInitialScale = true; Dictionary obj = (Dictionary)typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(scene); int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name); obj.Remove(stableHashCode); obj.Add(stableHashCode, prefab); if (!scene.m_prefabs.Contains(prefab)) { scene.m_prefabs.Add(prefab); } VisbendingLogger.Log(context, " (Caller = {0}), registration successful: {1}", source, ((Object)prefab).name); } public static string GetAlternative() { return alternative; } public static int GetHashCode(string candidatePrefabName) { if (alternative != null) { VisbendingLogger.Log(context, "alternativ GetHashCode"); return StringExtensionMethods.GetStableHashCode(alternative); } return StringExtensionMethods.GetStableHashCode(VisbendingMod.MOD_NAME + candidatePrefabName); } public static GameObject CreatePrefab(string candidatePrefabName) { if (alternative != null) { VisbendingLogger.Log(context, "alternativ CreatePrefab"); return ZNetScene.instance.GetPrefab(alternative); } return ZNetScene.instance.GetPrefab(VisbendingMod.MOD_NAME + candidatePrefabName); } public static bool IsModObject(GameObject prefab) { if (alternative != null) { if ((Object)(object)prefab != (Object)null) { return ((Object)prefab).name.Equals(alternative); } return false; } if ((Object)(object)prefab != (Object)null) { return ((Object)prefab).name.StartsWith(VisbendingMod.MOD_NAME); } return false; } } internal class StoneSpawner { private static VisbendingLogger.Context contextSpawn = VisbendingLogger.Context.Spawning; public static Candidate CurrentCandidate = null; private static Dictionary deletable = null; public static void SpawnStonesForAlreadyLoadedZones() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!SpawnRegistry.IsInitialized()) { return; } foreach (KeyValuePair item in SpawnRegistry.anchorName2anchorType) { foreach (Anchor anchor in item.Value.GetAnchors()) { if (!anchor.IsValid()) { continue; } foreach (Vector2i spawnZone in anchor.GetSpawnZones()) { if (ZoneSystem.instance.IsZoneLoaded(spawnZone)) { VisbendingLogger.Context context = contextSpawn; string[] array = new string[1]; Vector2i anchorZone = anchor.GetAnchorZone(); array[0] = "SpawnStonesForAlreadyLoadedZones, Zone " + ((object)(Vector2i)(ref anchorZone)).ToString(); VisbendingLogger.Log(context, array); SpawnStonesForZone(anchor.GetAnchorZone(), null, null); } } } } } public static void OnZoneGenerated(Vector2i zoneId, GameObject root, Heightmap hmap) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Log(contextSpawn, $"OnZoneGenerated, Zone {0}", ((object)(Vector2i)(ref zoneId)).ToString()); SpawnStonesForZone(zoneId, root, hmap); } private static bool IsValidPlacement(Vector3 position, Heightmap hmap, out float h) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) bool flag = HeightmapHelper.GetHeight(position, hmap, out h) && h > ZoneSystem.instance.m_waterLevel; if (!flag) { VisbendingLogger.Log(contextSpawn, $"StoneSpawner Placement invalid: height {0} (water level: {1})", h.ToString(), ZoneSystem.instance.m_waterLevel.ToString()); } else { foreach (LocationInstance location in ZoneSystem.instance.GetLocationList()) { float exteriorRadius = location.m_location.m_exteriorRadius; float num = 5f; float num2 = exteriorRadius + num; if (Vector3.Distance(position, location.m_position) < num2) { VisbendingLogger.Log(contextSpawn, $"StoneSpawner Placement invalid, too close to {0}", (location.m_location != null) ? location.m_location.m_name : " some location"); return false; } } } return flag; } private static void SpawnStonesForZone(Vector2i enteredZoneId, GameObject root, Heightmap hmap) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Context context = contextSpawn; string[] array = new string[1]; Vector2i val = enteredZoneId; array[0] = "StoneSpawner, entered zone id " + ((object)(Vector2i)(ref val)).ToString(); VisbendingLogger.Log(context, array); if (!SpawnRegistry.IsInitialized()) { if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) { return; } SpawnRegistry.Init(); } bool flag = false; foreach (KeyValuePair item in SpawnRegistry.anchorName2anchorType) { Anchor anchor = item.Value.GetAnchor(enteredZoneId); if (anchor == null) { continue; } flag = true; if (!anchor.IsValid()) { VisbendingLogger.Log(contextSpawn, "Error! anchor entry object for anchor zone " + anchor?.ToString() + " is invald, no spawn"); continue; } string prefabName = anchor.GetPrefabName(); int hashCode = PrefabCreator.GetHashCode(prefabName); GameObject val2 = PrefabCreator.CreatePrefab(prefabName); if (!Object.op_Implicit((Object)(object)val2)) { VisbendingLogger.Log(contextSpawn, "Error! StoneSpawner, failure, " + VisbendingMod.MOD_NAME + prefabName + "not found."); return; } HashSet hashSet = new HashSet(); Dictionary dictionary = new Dictionary(); foreach (Candidate candidate in anchor.GetCandidates()) { if (hashSet.Contains(candidate.GetPlannedZone())) { continue; } foreach (ZDO item2 in ZDOUtility.FindObjects(candidate.GetPlannedZone())) { if (item2.GetPrefab() == hashCode) { int @int = item2.GetInt(VisbendingMod.PARAM_GROUP_ID, 0); int int2 = item2.GetInt(VisbendingMod.PARAM_INDEX, 0); dictionary[@int] = int2; } } } foreach (KeyValuePair item3 in dictionary) { Group group = anchor.GetGroup(item3.Key); if (group != null) { VisbendingLogger.Log(contextSpawn, $"already spawned, setting group {0}, index {1} to spawned", item3.Key.ToString(), item3.Value.ToString()); group.GetCandidate(item3.Value)?.SetSpawned(spawned: true); } } foreach (Group group2 in anchor.GetGroups()) { if (group2.GetSpawnedCandidate() != null) { VisbendingLogger.Log(contextSpawn, $"Zone {0}, completed group {1} found --> continue", anchor.ToString(), group2.GetIndex().ToString()); continue; } string text = $"Stone_{anchor.GetAnchorPosition().x:0}_{anchor.GetAnchorPosition().z:0}_S{group2.GetIndex()}"; if (ZoneSystem.instance.GetGlobalKey(text)) { VisbendingLogger.Log(contextSpawn, "Zone " + anchor?.ToString() + ", global key found --> continue"); break; } foreach (Candidate candidate2 in group2.GetCandidates()) { float h; if (!((Vector2i)(ref enteredZoneId)).Equals(candidate2.GetPlannedZone())) { VisbendingLogger.Log(contextSpawn, "Zone " + anchor?.ToString() + ", stone zone id not entered zone id"); } else if (IsValidPlacement(candidate2.GetPlannedPosition() + new Vector3(0f, ZoneSystem.instance.GetGroundHeight(candidate2.GetPlannedPosition()), 0f), hmap, out h)) { if (GetSpawnedForGroup(candidate2, prefabName, hashCode, out var foundCandidate)) { foundCandidate.SetSpawned(spawned: true); break; } if (SpawnStone(candidate2, val2, h)) { hmap.Regenerate(); break; } } else { VisbendingLogger.Log(contextSpawn, "Warning! Visbending, Zone " + anchor?.ToString() + ", invalid placement"); } } } } if (!flag) { VisbendingLogger.Context context2 = contextSpawn; string[] array2 = new string[1]; val = enteredZoneId; array2[0] = "StoneSpawner, no Spawn, entered zone id " + ((object)(Vector2i)(ref val)).ToString() + " not connected to an anchor"; VisbendingLogger.Log(context2, array2); } } public static bool SpawnStone(Candidate candidate, GameObject prefab, float groundHeight) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) Vector3 val = candidate.GetPlannedPosition() + new Vector3(0f, groundHeight + 1f, 0f); CurrentCandidate = candidate; string anchorName = candidate.GetParent().GetParent().GetAnchorName(); VisbendingLogger.Log(contextSpawn, " Spawning stone " + anchorName); GameObject obj = Object.Instantiate(prefab, val, candidate.GetOrientation()); ((Object)obj).name = ((Object)prefab).name; TerrainModifier obj2 = obj.AddComponent(); ((Behaviour)obj2).enabled = true; obj2.m_level = true; obj2.m_levelRadius = 2.5f; obj2.m_smooth = true; obj2.m_smoothRadius = 6f; obj2.m_paintCleared = true; obj.SetActive(true); candidate.SetSpawned(spawned: true); foreach (Heightmap allHeightmap in Heightmap.GetAllHeightmaps()) { if (allHeightmap.IsPointInside(val, 10f)) { allHeightmap.Poke(true); } } CurrentCandidate = null; DestroyObjectsNearby(candidate, val, 10f); return true; } private static bool GetSpawnedForGroup(Candidate candidate, string prefabName, int myPrefabHash, out Candidate foundCandidate) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) foreach (ZDO item in ZDOUtility.FindObjects(candidate.GetPlannedZone())) { if (item.GetPrefab() == myPrefabHash) { Vector2i plannedZone = candidate.GetPlannedZone(); float xZDistance = getXZDistance(item.GetPosition(), candidate.GetPlannedPosition()); int @int = item.GetInt(VisbendingMod.PARAM_GROUP_ID, 0); if (@int == candidate.GetParent().GetIndex()) { VisbendingLogger.Log(contextSpawn, $"ZDO for {0} already exists in sector {1} with same group id{2} ", prefabName, ((object)(Vector2i)(ref plannedZone)).ToString(), @int.ToString()); foundCandidate = candidate.GetParent().GetCandidate(item.GetInt(VisbendingMod.PARAM_INDEX, 0)); return true; } if (xZDistance < 1f) { VisbendingLogger.Log(contextSpawn, $"ZDO for {0} already exists in sector {1}. Skip spawn.", prefabName, ((object)(Vector2i)(ref plannedZone)).ToString()); foundCandidate = candidate.GetParent().GetCandidate(item.GetInt(VisbendingMod.PARAM_INDEX, 0)); return true; } VisbendingLogger.Context context = contextSpawn; string[] obj = new string[7] { $"ZDO for {0} already exists in sector {1} but distance to great, pos zdo {2}, pos candidate {3}, group id zdo{4}, group id candidate{5}", prefabName, ((object)(Vector2i)(ref plannedZone)).ToString(), null, null, null, null }; Vector3 val = item.GetPosition(); obj[3] = ((object)(Vector3)(ref val)).ToString(); val = candidate.GetPlannedPosition(); obj[4] = ((object)(Vector3)(ref val)).ToString(); obj[5] = @int.ToString(); obj[6] = candidate.GetParent().GetIndex().ToString(); VisbendingLogger.Log(context, obj); } } foundCandidate = null; return false; } private static float getXZDistance(Vector3 pos1, Vector3 pos2) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Vector2 val = new Vector2(pos1.x, pos1.z); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(pos2.x, pos2.z); return Vector2.Distance(val, val2); } private static void DestroyObjectsNearby(Candidate candidate, Vector3 pos, float range) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) List list = ZDOUtility.FindObjectsInRadius(pos, range); VisbendingLogger.Log(contextSpawn, "found " + list.Count + " nearby Objects "); int num = 0; foreach (ZDO item in list) { GameObject prefab = ZNetScene.instance.GetPrefab(item.GetPrefab()); string value = null; bool flag = PrefabInfo.GetDeletableObjectName(item.GetPrefab(), out value) || PrefabInfo.IsDeletable(prefab); if (flag) { num++; item.SetOwner(ZDOMan.GetSessionID()); ZDOMan.instance.DestroyZDO(item); } VisbendingLogger.Log(contextSpawn, " nearby Object " + (((Object)(object)prefab != (Object)null) ? ((Object)prefab).name : value) + " " + item.GetPrefab() + " " + flag); } VisbendingLogger.Log(contextSpawn, "deleted " + num + " of " + list.Count); Collider[] array = Physics.OverlapSphere(pos, range); VisbendingLogger.Log(contextSpawn, "found hitcollider" + array.Length + " nearby Objects "); bool flag2 = true; Collider[] array2 = array; for (int i = 0; i < array2.Length; i++) { GameObject gameObject = ((Component)array2[i]).gameObject; if (!((Object)(object)gameObject != (Object)null) || !((Object)gameObject).name.ToLower().EndsWith("(clone)")) { continue; } int length = ((Object)gameObject).name.Length; string text = ((Object)gameObject).name.Substring(0, length - 7); int hashCode = text.GetHashCode(); string value2 = null; bool flag3 = PrefabInfo.GetDeletableObjectName(hashCode, out value2) || PrefabInfo.IsDeletable(gameObject); VisbendingLogger.Log(contextSpawn, " nearby Hitcollider " + ((Object)gameObject).name + " " + text + " " + flag3); if (flag3) { ZNetView component = gameObject.GetComponent(); if ((Object)(object)component != (Object)null && !flag2) { component.ClaimOwnership(); component.Destroy(); } } } } public static void ApplyVisualColor(GameObject obj, string hexColor) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) Color white = default(Color); if (!ColorUtility.TryParseHtmlString(hexColor, ref white)) { white = Color.white; } Color val = white * 1.5f; Light[] componentsInChildren = obj.GetComponentsInChildren(); foreach (Light obj2 in componentsInChildren) { obj2.color = white; obj2.intensity = 1.4f; } Renderer[] componentsInChildren2 = obj.GetComponentsInChildren(); foreach (Renderer val2 in componentsInChildren2) { Material[] materials = val2.materials; Material[] array = materials; foreach (Material val3 in array) { if (val3.HasProperty("_EmissionColor")) { val3.SetColor("_EmissionColor", val); val3.EnableKeyword("_EMISSION"); } } val2.materials = materials; } } } [HarmonyPatch(typeof(TextViewer), "ShowText")] public static class TextViewer_ShowText_Patch { public static void Postfix(TextViewer __instance, Style style, string textId) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Context context = VisbendingLogger.Context.Text; if ((int)style == 0 && textId.Contains(VisbendingMod.MOD_NAME)) { VisbendingLogger.Log(context, "TextViewer ShowText."); string text = Localization.instance.Localize(textId + "_rune"); if (string.IsNullOrEmpty(text)) { VisbendingLogger.Log(context, "TextView_Patch, Fallback " + textId + " | Text: " + text); text = Localization.instance.Localize(textId); } __instance.m_runeText.text = text; VisbendingLogger.Log(context, "TextView_Patch, runes set. Key: " + textId + " | Text: " + text); } } } [HarmonyPatch(typeof(Localization), "SetupLanguage")] public static class Localization_Patch { private static readonly Action AddWordDelegate = AccessTools.MethodDelegate>(AccessTools.Method(typeof(Localization), "AddWord", new Type[2] { typeof(string), typeof(string) }, (Type[])null), (object)null, true); [HarmonyPostfix] private static void Postfix(Localization __instance) { VisbendingLogger.Context context = VisbendingLogger.Context.Localization; VisbendingLogger.Log(context, "Start reading localization files"); bool flag = VisbendingMod.useEnglishForRuneTexts(); string directoryName = Path.GetDirectoryName(typeof(VisbendingMod).Assembly.Location); string text = Path.Combine(directoryName, "Languages"); if (!Directory.Exists(text)) { VisbendingLogger.Log(context, "languages folder does not exist, using mod folder"); text = directoryName; } string @string = PlayerPrefs.GetString("language"); string text2 = Path.Combine(text, @string + ".json"); string text3 = Path.Combine(text, "English.json"); VisbendingLogger.Log(context, text + " " + @string + ".json"); bool flag2 = flag && File.Exists(text3); VisbendingLogger.Log(context, "Use English for runes " + flag2); bool flag3 = "English".Equals(@string); if (!File.Exists(text2)) { VisbendingLogger.Log(context, text + " English.json"); text2 = Path.Combine(text, "English.json"); } else { VisbendingLogger.Log(context, text + " " + @string + ".json"); } if (File.Exists(text2)) { try { Dictionary dictionary = JsonHelper.ParseFullText(text2); foreach (KeyValuePair item in dictionary) { VisbendingLogger.Log(context, "key " + item.Key + " value " + item.Value); AddWordDelegate(__instance, item.Key, item.Value); if (flag3 || !flag2) { VisbendingLogger.Log(context, "key " + item.Key + "_rune value " + item.Value); AddWordDelegate(__instance, item.Key + "_rune", item.Value); } } SpawnRegistry.RefreshRegisteredTexts(dictionary); if (dictionary.TryGetValue("Visbending_config_desc", out var value)) { ConfigDescription description = ((ConfigEntryBase)VisbendingMod.ModDescription).Description; AccessTools.Field(typeof(ConfigDescription), "k__BackingField").SetValue(description, value); } } catch (Exception ex) { VisbendingLogger.Log(context, "Error!! Reading language file {0} ", ex.Message); } if (!(!flag3 && flag)) { return; } try { foreach (KeyValuePair item2 in JsonHelper.ParseFullText(text3)) { VisbendingLogger.Log(context, "key " + item2.Key + "_rune value " + item2.Value); AddWordDelegate(__instance, item2.Key + "_rune", item2.Value); } return; } catch (Exception ex2) { VisbendingLogger.Log(context, "Error!! Reading language file {0} ", ex2.Message); return; } } VisbendingLogger.Log(context, "no language file {0} found", text2); } private static Dictionary ReadJson(string jsonContent) { Dictionary dictionary = new Dictionary(); string pattern = "\"([^\"]+)\"\\s*:\\s*\"([^\"]+)\""; foreach (Match item in Regex.Matches(jsonContent, pattern)) { string value = item.Groups[1].Value; string text2 = (dictionary[value] = item.Groups[2].Value.Replace("\\n", "\n").Replace("\\r", "\r")); VisbendingLogger.Log(VisbendingLogger.Context.Localization, "Json : " + value + " " + text2); } return dictionary; } } [BepInPlugin("Goathedge.Visbending", "Visbending Mod", "1.1.0")] public class VisbendingMod : BaseUnityPlugin { public static ConfigEntry ModDescription; public static string MOD_NAME = "Visbending"; public static string HALDOR_LOCATION_NAME = "Vendor_BlackForest"; public static string HILDIR_LOCATION_NAME = "Hildir_camp"; public static string BOGWITCH_LOCATION_NAME = "BogWitch_Camp"; private static string START_TEMPLE = "StartTemple"; public static string TEXTKEY_COMPENDIUM_BILLBOARDS_TOPIC = "$" + MOD_NAME + "_Visbending_Topic"; public static string TEXTKEY_COMPENDIUM_BILLBOARDS_TEXT = "$" + MOD_NAME + "_Visbending_Text"; public static string TEXTKEY_COMPENDIUM_BILLBOARDS_MESSAGE = "$" + MOD_NAME + "_Visbending_Message"; public static string PARAM_RADIUS = "Radius"; public static string PARAM_NO_OF_STONES = "NoOfStones"; public static string PARAM_TEXT_KEY = "text"; public static string PARAM_MSGHASH = "msghash"; public static string PARAM_TOPIC = "topic"; public static string PARAM_ANCHOR_NAME = "AnchorName"; public static string PARAM_ANCHOR_POS = "AnchorPosition"; public static string PARAM_COLOR_KEY = "ColorKey"; public static string PARAM_GROUP_ID = "GroupId"; public static string PARAM_INDEX = "Index"; private static bool m_useEnglishForRuneTexts = false; private readonly Harmony harmony = new Harmony("Goathedge." + MOD_NAME); public static VisbendingMod Instance; private void Awake() { Instance = this; ModDescription = ((BaseUnityPlugin)this).Config.Bind("General", "Description", "Hint stones for special locations like trader camps", "You can set the default distance/radius and the default number of stones per location. These values are required for calculations. Changes to the configuration only affect new worlds. You can choose any color you like and change it at any time."); register(); ((BaseUnityPlugin)this).Config.Save(); harmony.PatchAll(); } private void register() { VisbendingLogger.ConfigLogContext = ((BaseUnityPlugin)this).Config.Bind("LogContext", "Context", " ", "LogContext, comma separated, possible values " + VisbendingLogger.ContextToString(",")); m_useEnglishForRuneTexts = ((BaseUnityPlugin)this).Config.Bind("Use English for rune text", "UseEnglishForRunes", false, "if a language file for the user language is present it will by default be used for rune texts. If some special letters do not work, switch to english.").Value; RegisterConfigurableLocation(BOGWITCH_LOCATION_NAME, "Runestone_Swamps", 350, 16, "#33FF33", new List { CreateTextKeyString(MOD_NAME, BOGWITCH_LOCATION_NAME, 1), CreateTextKeyString(MOD_NAME, BOGWITCH_LOCATION_NAME, 2) }); RegisterConfigurableLocation(HALDOR_LOCATION_NAME, "Runestone_BlackForest", 350, 16, "#009f9f", new List { CreateTextKeyString(MOD_NAME, HALDOR_LOCATION_NAME, 1), CreateTextKeyString(MOD_NAME, HALDOR_LOCATION_NAME, 2) }); RegisterConfigurableLocation(HILDIR_LOCATION_NAME, "Runestone_Meadows", 350, 16, "#FFFF00", new List { CreateTextKeyString(MOD_NAME, HILDIR_LOCATION_NAME, 1), CreateTextKeyString(MOD_NAME, HILDIR_LOCATION_NAME, 2) }); } private string CreateTextKeyString(string part1, string part2, int counter) { return "$" + part1 + "_" + part2 + "_" + counter; } private void RegisterConfigurableLocation(string targetPrefab, string stonePrefab, int defaultRadius, int defaultCount, string defaultColor, List textKeys) { int minimalRadius = getMinimalRadius(); int maximalRadius = getMaximalRadius(); int minimalNumber = getMinimalNumber(); int maximalNumber = getMaximalNumber(); ConfigEntry val = ((BaseUnityPlugin)this).Config.Bind(targetPrefab, PARAM_RADIUS, defaultRadius, getDistanceDescription()); ConfigEntry val2 = ((BaseUnityPlugin)this).Config.Bind(targetPrefab, PARAM_NO_OF_STONES, defaultCount, getNumberDescription()); ConfigEntry val3 = ((BaseUnityPlugin)this).Config.Bind(targetPrefab, PARAM_COLOR_KEY, defaultColor, getColorDescription()); if (val != null && val2 != null && val3 != null) { if (val.Value < minimalRadius) { val.Value = minimalRadius; } if (val.Value > maximalRadius) { val.Value = maximalRadius; } if (val2.Value < minimalNumber) { val2.Value = minimalNumber; } if (val2.Value > maximalNumber) { val2.Value = maximalNumber; } SpawnRegistry.RegisterStoneConfig(new StoneConfig { AnchorName = targetPrefab, RunestonePrefabName = stonePrefab, RadiusEntry = val, CountEntry = val2, ColorEntry = val3, TextKeys = textKeys }); } } public static int getMinimalRadius() { return 80; } public static int getMaximalRadius() { return 500; } public static int getMinimalNumber() { return 8; } public static int getMaximalNumber() { return 32; } public static string getDistanceDescription() { return "Distance (in meters) from central location the stones shall appear, allowed values " + getMinimalRadius() + " <= radius <=" + getMaximalRadius() + "."; } public static string getNumberDescription() { return "Number of stones placed around central location, allowed values " + getMinimalNumber() + " <= Number of stones <=" + getMaximalNumber() + "."; } public static string getColorDescription() { return "Color of the stone (Hex Code, for example #FF0000)."; } public static bool useEnglishForRuneTexts() { return m_useEnglishForRuneTexts; } } [HarmonyPatch(typeof(ZoneSystem), "Awake")] public class ZoneSystem_Awake_Patch { private static void Postfix(ZoneSystem __instance) { VisbendingLogger.Log(VisbendingLogger.Context.ZoneSystem, "Awake Patch"); } } [HarmonyPatch(typeof(ZoneSystem), "SetupLocations")] public static class ZoneSystem_SetupLocations_Patch { public static void Postfix(ZoneSystem __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) VisbendingLogger.Log(VisbendingLogger.Context.ZoneSystem, "SetupLocations"); PrefabCreator.ExtractObjects(__instance); PrefabCreator.TryRegister("SetupLocations"); foreach (LocationInstance value in __instance.m_locationInstances.Values) { ZoneLocation location = value.m_location; Vector3 position = value.m_position; SpawnRegistry.PrepareIfRelevantLocation("SetupLocations", location, position); } StoneSpawner.SpawnStonesForAlreadyLoadedZones(); } } [HarmonyPatch(typeof(ZoneSystem), "RegisterLocation")] public class ZoneSystem_RegisterLocation_Patch { private static void Postfix(ZoneLocation location, Vector3 pos, bool generated) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) VisbendingLogger.Log(VisbendingLogger.Context.ZoneSystem, "RegisterLocation"); SpawnRegistry.PrepareIfRelevantLocation("RegisterLocation", location, pos); } } [HarmonyPatch(typeof(ZoneSystem), "RemoveUnplacedLocations")] public static class ZoneSystem_RemoveUnplacedLocations_Patch { private static void Prefix(ZoneLocation location) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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) Vector3? val = null; foreach (KeyValuePair locationInstance in ZoneSystem.instance.m_locationInstances) { if (locationInstance.Value.m_location == location && locationInstance.Value.m_placed) { val = locationInstance.Value.m_position; break; } } if (val.HasValue) { VisbendingLogger.Log(VisbendingLogger.Context.ZoneSystem, $"Merchant {location.m_prefabName} fixed at {val.Value}. Cleaning up others."); ZoneSystem.GetZone(val.Value); SpawnRegistry.RemoveInvalidLocations(location, val.Value); } } } [HarmonyPatch(typeof(ZoneSystem), "SpawnZone")] public static class ZoneSystem_SpawnZone_Patch { private delegate bool IsZoneGeneratedDelegate(ZoneSystem instance, Vector2i zoneID); private static readonly IsZoneGeneratedDelegate _isZoneGeneratedDelegate = AccessTools.MethodDelegate(AccessTools.Method(typeof(ZoneSystem), "IsZoneGenerated", (Type[])null, (Type[])null), (object)null, true); private static void Postfix(Vector2i zoneID, GameObject root, bool __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_0135: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) Vector2i val; if (!_isZoneGeneratedDelegate(ZoneSystem.instance, zoneID)) { string[] array = new string[1]; string[] obj = new string[6] { "Warning, Zone ", null, null, null, null, null }; val = zoneID; obj[1] = ((object)(Vector2i)(ref val)).ToString(); obj[2] = "is not generated! __result"; obj[3] = __result.ToString(); obj[4] = ", root "; obj[5] = (((Object)(object)root != (Object)null) ? ((Object)root).name : ""); array[0] = string.Concat(obj); VisbendingLogger.Log(VisbendingLogger.Context.ZoneSystem, array); return; } if (!__result || (Object)(object)root == (Object)null) { string[] array2 = new string[1]; val = zoneID; array2[0] = "SpawnZone " + ((object)(Vector2i)(ref val)).ToString() + " waiting"; VisbendingLogger.Log(VisbendingLogger.Context.ZoneSystem, array2); return; } Heightmap componentInChildren = root.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { Vector3 worldPos = ZoneSystem.GetZonePos(zoneID) + new Vector3(32f, 0f, 32f); if (!HeightmapHelper.GetPreciseHeight(componentInChildren, worldPos, out var _)) { string[] array3 = new string[1]; val = zoneID; array3[0] = "Warning, SpawnZone " + ((object)(Vector2i)(ref val)).ToString() + ", hmap exist but not valid"; VisbendingLogger.Log(VisbendingLogger.Context.Terrain, array3); } StoneSpawner.OnZoneGenerated(zoneID, root, componentInChildren); } else { string[] array4 = new string[1]; val = zoneID; array4[0] = "Error!! SpawnZone " + ((object)(Vector2i)(ref val)).ToString() + " height map still null!!"; VisbendingLogger.Log(VisbendingLogger.Context.Terrain, array4); } } }