Decompiled source of Visbending v1.0.0

Visbending/Visbending.dll

Decompiled 8 hours ago
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<GetWorldHeightDelegate>(AccessTools.Method(typeof(Heightmap), "GetWorldHeight", (Type[])null, (Type[])null), (object)null, true);

	private static readonly FieldRef<Heightmap, List<float>> m_heightsField = AccessTools.FieldRefAccess<Heightmap, List<float>>("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<float> 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<string> textKeys;

	private Dictionary<Vector2i, Anchor> zone2Anchor = new Dictionary<Vector2i, Anchor>();

	private List<Anchor> anchors = new List<Anchor>();

	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<Vector2i, Anchor> dictionary = new Dictionary<Vector2i, Anchor>();
		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<Anchor> 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<Vector2i, Anchor>(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<string> textKeys)
	{
		this.textKeys = textKeys;
	}

	public List<string> 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<int, int> dictionary = new Dictionary<int, int>();
			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<int, int> 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<int, int> dictionary = new Dictionary<int, int>();
			for (int j = 0; j < num4; j++)
			{
				dictionary.Add(pkg.ReadInt(), pkg.ReadInt());
			}
			foreach (KeyValuePair<int, int> 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<int, Group> groups;

	private bool valid;

	private bool initialized;

	private int startGroupIndex = -1;

	private static VisbendingLogger.Context context = VisbendingLogger.Context.Registration;

	private HashSet<Vector2i> spawnZones;

	private List<string> 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<int, Group>();
		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<Vector2i>();
		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<Candidate> GetCandidates()
	{
		HashSet<Candidate> hashSet = new HashSet<Candidate>();
		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<string> 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<int, Group>(groups, idx);
	}

	public Dictionary<int, Group>.ValueCollection GetGroups()
	{
		return groups.Values;
	}

	public HashSet<Vector2i> GetSpawnZones()
	{
		return spawnZones;
	}
}
internal class AnchorTypeBuilder
{
	public string anchorName;

	public int radius;

	public int numberOfStones;

	public string prefabName;

	public string colorKey;

	public List<string> 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<string> 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<int, Candidate> candidates;

	public Group(GroupBuilder builder)
	{
		parent = builder.parent;
		index = builder.index;
		textKey = builder.textKey;
		candidates = new Dictionary<int, Candidate>();
	}

	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<int, Candidate>.ValueCollection GetCandidates()
	{
		return candidates.Values;
	}

	public Candidate GetCandidate(int idx)
	{
		return GeneralExtensions.GetValueSafe<int, Candidate>(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<string, string> ParseFullText(string filePath)
	{
		string text = File.ReadAllText(filePath);
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		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<int, string> deletable;

	public static bool IsDeletable(GameObject prefab)
	{
		if ((Object)(object)prefab == (Object)null)
		{
			return false;
		}
		if (prefab.GetComponent<ZoneVegetation>() == 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<int, string>();
			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<int, string>(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<ZPackage>(GetCallName(RPCName.INIT_REGISTRY), (Action<ZRpc, ZPackage>)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<ZNetView>();
		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<string, string> knownText in player.GetKnownTexts())
		{
			_ = knownText;
			if (player.GetKnownTexts().Any((KeyValuePair<string, string> 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<string, string> dictionary = (Dictionary<string, string>)field.GetValue(localPlayer);
					List<string> list = new List<string>();
					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<string, StoneConfig> _stoneConfigs = new Dictionary<string, StoneConfig>();

	public static Dictionary<string, AnchorType> anchorName2anchorType = new Dictionary<string, AnchorType>();

	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<string, AnchorType> 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<string, StoneConfig> 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<string, string> translations)
	{
		VisbendingLogger.Log(textContext, "Refresh texts, size " + translations.Count);
		Dictionary<StoneConfig, List<string>> dictionary = new Dictionary<StoneConfig, List<string>>();
		foreach (KeyValuePair<string, string> 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<string>());
				}
				List<string> valueSafe = GeneralExtensions.GetValueSafe<StoneConfig, List<string>>(dictionary, stoneConfigByTextKey);
				addKeyInternal(translation.Key, valueSafe);
			}
			else
			{
				VisbendingLogger.Log(textContext, "no config for text key " + translation.Key);
			}
		}
		foreach (KeyValuePair<StoneConfig, List<string>> 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<string> 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<string> 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<string, StoneConfig>(_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<Vector2i, List<ZDO>> zoneZDOsByAnchorName = ZDOUtility.GetZoneZDOsByAnchorName(value.GetAnchorName());
		foreach (Anchor anchor2 in value.GetAnchors())
		{
			List<ZDO> valueSafe = GeneralExtensions.GetValueSafe<Vector2i, List<ZDO>>(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<string> TextKeys;

	public ConfigEntry<int> RadiusEntry;

	public ConfigEntry<int> CountEntry;

	public ConfigEntry<string> 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<Collider>());
		Renderer component = obj.GetComponent<Renderer>();
		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<GameObject>(prefab, val, Quaternion.identity).GetComponent<TerrainModifier>();
		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<string, string> ParseSimpleJson(string json)
	{
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		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<ZDO> 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<ZNetView>();
			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<ZNetView>((FindObjectsSortMode)0);
		List<ZNetView> 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<string> prefabNames = ZNetScene.instance.GetPrefabNames();
			ZLog.Log((object)"start prefab export, step 1");
			prefabNames.Sort();
			List<string> list = new List<string>();
			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<Renderer>();
				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)) ? "<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<Component>();
		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<Context> contextSet;

	public static ConfigEntry<string> 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<Context>();
		string[] array = ConfigLogContext.Value.Split(new char[1] { ',' });
		ContextToHashSet();
		Context[] values = EnumUtils.GetValues<Context>();
		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<string> ContextToHashSet()
	{
		HashSet<string> hashSet = new HashSet<string>();
		Context[] values = EnumUtils.GetValues<Context>();
		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<string> 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<ZDO> 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<ZDO> 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<ZDO> list = new List<ZDO>();
		Vector2i zone = ZoneSystem.GetZone(position);
		MethodInfo method = typeof(ZDOMan).GetMethod("FindObjects", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(Vector2i),
			typeof(List<ZDO>)
		}, 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<ZDO> FindObjects(Vector2i sector)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		List<ZDO> list = new List<ZDO>();
		MethodInfo method = typeof(ZDOMan).GetMethod("FindObjects", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(Vector2i),
			typeof(List<ZDO>)
		}, null);
		if (method != null)
		{
			method.Invoke(ZDOMan.instance, new object[2] { sector, list });
		}
		return list;
	}

	public static Dictionary<Vector2i, List<ZDO>> 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<Vector2i, List<ZDO>> dictionary = new Dictionary<Vector2i, List<ZDO>>();
		ZDOMan instance = ZDOMan.instance;
		if (AccessTools.Field(typeof(ZDOMan), "m_objectsByID").GetValue(instance) is Dictionary<ZDOID, ZDO> 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<ZDO>();
						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<ZDOID, ZDO> 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<ZDOID, ZDO> dictionary = fieldInfo.GetValue(ZDOMan.instance) as Dictionary<ZDOID, ZDO>;
			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<GetPeerDelegate>(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<int, GameObject> dictionary = (Dictionary<int, GameObject>)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<GameObject>(prefab2, zdo.GetPosition(), zdo.GetRotation());
			((Object)val2).name = ((Object)prefab2).name;
			val2.SetActive(true);
			ZNetView component = val2.GetComponent<ZNetView>();
			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<TerrainModifier>();
				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<ZNetView>((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<string, GameObject> extractedObjects = new Dictionary<string, GameObject>();

	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<RuneStone>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Material material = new Material(((Component)componentInChildren).GetComponentInChildren<Renderer>().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<GameObject>(prefabToBe);
		((Object)val).name = name;
		StringExtensionMethods.GetStableHashCode(((Object)val).name);
		if ((Object)(object)material != (Object)null)
		{
			val.GetComponentInChildren<Renderer>().material = material;
		}
		Object.DontDestroyOnLoad((Object)(object)val);
		val.SetActive(false);
		(val.GetComponent<ZNetView>() ?? val.AddComponent<ZNetView>()).m_persistent = true;
		TerrainModifier obj = val.AddComponent<TerrainModifier>();
		((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<Component>();
		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<GameObject>(val.gameObject);
				((Object)val2).name = VisbendingMod.MOD_NAME + "ForceField";
				StringExtensionMethods.GetStableHashCode(((Object)val2).name);
				val2.GetComponentInChildren<Renderer>().material = new Material(val.gameObject.GetComponentInChildren<Renderer>().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<ZNetView>();
		if ((Object)(object)val == (Object)null)
		{
			val = prefab.AddComponent<ZNetView>();
		}
		val.m_persistent = true;
		val.m_type = (ObjectType)2;
		val.m_syncInitialScale = true;
		Dictionary<int, GameObject> obj = (Dictionary<int, GameObject>)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<int, string> 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<string, AnchorType> 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<string, AnchorType> 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<Vector2i> hashSet = new HashSet<Vector2i>();
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			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<int, int> 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<GameObject>(prefab, val, candidate.GetOrientation());
		((Object)obj).name = ((Object)prefab).name;
		TerrainModifier obj2 = obj.AddComponent<TerrainModifier>();
		((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<ZDO> 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<ZNetView>();
				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<Light>();
		foreach (Light obj2 in componentsInChildren)
		{
			obj2.color = white;
			obj2.intensity = 1.4f;
		}
		Renderer[] componentsInChildren2 = obj.GetComponentsInChildren<Renderer>();
		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 Locali