Decompiled source of EditKeepsOwner v1.0.0

EditKeepsOwner.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EditKeepsOwner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EditKeepsOwner")]
[assembly: AssemblyTitle("EditKeepsOwner")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[BepInPlugin("six.editkeepsowner", "Edit Keeps Owner", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class EditKeepsOwner : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	private static FieldInfo HitPieceField;

	private static readonly FieldInfo[] CreatorFields = (from f in typeof(Piece).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
		where f.Name.IndexOf("creator", StringComparison.OrdinalIgnoreCase) >= 0 && f.Name.IndexOf("Percent", StringComparison.OrdinalIgnoreCase) < 0
		select f).ToArray();

	public static string PrefabName(string name)
	{
		int num = name.IndexOf("(");
		return ((num < 0) ? name : name.Substring(0, num)).Trim();
	}

	private void Awake()
	{
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Type type = AccessTools.TypeByName("ValheimPlus.AEM");
		MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "listenToHotKeysAndDoWork", (Type[])null, (Type[])null));
		HitPieceField = ((type == null) ? null : AccessTools.Field(type, "HitPiece"));
		if (methodInfo == null || HitPieceField == null)
		{
			Log.LogError((object)"V+ editing mode not found (ValheimPlus.AEM.listenToHotKeysAndDoWork / HitPiece). Patch not applied.");
		}
		else
		{
			new Harmony("six.editkeepsowner").Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(EditKeepsOwner), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
		}
		Log.LogInfo((object)("Creator fields on Piece: " + string.Join(", ", CreatorFields.Select((FieldInfo f) => f.Name))));
		CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new FixCreatorCommand());
	}

	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Expected O, but got Unknown
		MethodInfo methodInfo = AccessTools.Method(typeof(EditKeepsOwner), "AfterCopy", (Type[])null, (Type[])null);
		List<CodeInstruction> list = new List<CodeInstruction>();
		int num = 0;
		foreach (CodeInstruction instruction in instructions)
		{
			list.Add(instruction);
			if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodInfo { Name: "Instantiate" } methodInfo2 && methodInfo2.ReturnType == typeof(GameObject))
			{
				list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo));
				num++;
			}
		}
		if (num == 1)
		{
			Log.LogInfo((object)"Patched V+ editing mode: moved pieces keep their builder.");
		}
		else
		{
			Log.LogWarning((object)$"Expected 1 copy site in V+ editing mode, found {num}. V+ may have changed.");
		}
		return list;
	}

	public static GameObject AfterCopy(GameObject copy)
	{
		try
		{
			Piece val = (Object.op_Implicit((Object)(object)copy) ? copy.GetComponent<Piece>() : null);
			ZNetView val2 = (Object.op_Implicit((Object)(object)copy) ? copy.GetComponent<ZNetView>() : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2) || !val2.IsValid())
			{
				return copy;
			}
			if (!val2.IsOwner())
			{
				val2.ClaimOwnership();
			}
			object? value = HitPieceField.GetValue(null);
			Piece val3 = (Piece)((value is Piece) ? value : null);
			ZNetView val4 = (Object.op_Implicit((Object)(object)val3) ? ((Component)val3).GetComponent<ZNetView>() : null);
			if (Object.op_Implicit((Object)(object)val3) && val3.GetCreator() != 0L && Object.op_Implicit((Object)(object)val4) && val4.IsValid())
			{
				CopyCreatorData(val4.GetZDO(), val2.GetZDO());
				FieldInfo[] creatorFields = CreatorFields;
				foreach (FieldInfo fieldInfo in creatorFields)
				{
					fieldInfo.SetValue(val, fieldInfo.GetValue(val3));
				}
				Log.LogInfo((object)$"Kept builder {val.GetCreator()} on moved {PrefabName(((Object)copy).name)}.");
			}
			else if (GiveLocalCreator(val))
			{
				Log.LogInfo((object)("Original had no builder; gave moved " + PrefabName(((Object)copy).name) + " to you."));
			}
		}
		catch (Exception arg)
		{
			Log.LogWarning((object)$"Could not keep builder on moved piece: {arg}");
		}
		return copy;
	}

	private static void CopyCreatorData(ZDO from, ZDO to)
	{
		to.Set(ZDOVars.s_creator, from.GetLong(ZDOVars.s_creator, 0L));
		int num = from.GetInt(ZDOVars.s_creatorIndex, int.MinValue);
		if (num != int.MinValue)
		{
			to.Set(ZDOVars.s_creatorIndex, num, false);
		}
		else
		{
			long num2 = from.GetLong(ZDOVars.s_creatorIndex, long.MinValue);
			if (num2 != long.MinValue)
			{
				to.Set(ZDOVars.s_creatorIndex, num2);
			}
		}
		string text = from.GetString(ZDOVars.s_creatorName, (string)null);
		if (!string.IsNullOrEmpty(text))
		{
			to.Set(ZDOVars.s_creatorName, text);
		}
	}

	public static bool GiveLocalCreator(Piece piece)
	{
		//IL_001a: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)localPlayer))
		{
			return false;
		}
		PlatformUserID platformUserID = ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID;
		piece.SetCreator(localPlayer.GetPlayerID(), platformUserID);
		return true;
	}
}
public class FixCreatorCommand : ConsoleCommand
{
	public override string Name => "fixcreator";

	public override string Help => "fixcreator [radius=10] - give containers near you that have no builder to you";

	public override bool IsCheat => true;

	public override void Run(string[] args)
	{
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)localPlayer))
		{
			return;
		}
		float result = 10f;
		if (args.Length != 0)
		{
			float.TryParse(args[0], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
		}
		result = Mathf.Clamp(result, 1f, 50f);
		HashSet<string> hashSet = new HashSet<string>();
		foreach (GameObject item in ObjectDB.instance.m_items)
		{
			PieceTable val = ((!Object.op_Implicit((Object)(object)item)) ? null : item.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces);
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			foreach (GameObject item2 in val.m_pieces.Where((GameObject g) => Object.op_Implicit((Object)(object)g)))
			{
				hashSet.Add(((Object)item2).name);
			}
		}
		List<Piece> list = new List<Piece>();
		Piece.GetAllPiecesInRadius(((Component)localPlayer).transform.position, result, list);
		int num = 0;
		int num2 = 0;
		foreach (Piece item3 in list)
		{
			if (!Object.op_Implicit((Object)(object)item3) || item3.GetCreator() != 0L || !Object.op_Implicit((Object)(object)((Component)item3).GetComponentInChildren<Container>()))
			{
				continue;
			}
			if (!hashSet.Contains(EditKeepsOwner.PrefabName(((Object)((Component)item3).gameObject).name)))
			{
				num2++;
				continue;
			}
			ZNetView component = ((Component)item3).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
				}
				if (EditKeepsOwner.GiveLocalCreator(item3))
				{
					num++;
				}
			}
		}
		Console.instance.Print($"fixcreator: gave {num} container(s) within {result}m a builder; left {num2} world/dungeon container(s) alone.");
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}