using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Jotunn;
using Jotunn.Managers;
using PortalIndicator.Patches;
using PortalIndicator.RPC;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PortalIndicator")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PortalIndicator")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace PortalIndicator
{
internal static class Environment
{
internal static bool IsServer
{
get
{
if ((Object)(object)ZNet.instance != (Object)null)
{
return ZNet.instance.IsServer();
}
return false;
}
}
internal static long ServerPeerId => ZRoutedRpc.instance.GetServerPeerID();
internal static bool GameStarted { get; set; }
}
internal static class Log
{
public static bool IsDebug { get; set; }
public static void Debug(object message)
{
MethodBase? method = new StackTrace().GetFrame(1).GetMethod();
string name = method.DeclaringType.Name;
string name2 = method.Name;
Logger.LogDebug((object)$"[{name}.{name2}] {message}");
}
public static void Info(object message)
{
Logger.LogInfo(message);
}
public static void Warning(object message)
{
Logger.LogWarning(message);
}
public static void Error(object message)
{
Logger.LogError(message);
}
public static void Fatal(object message)
{
Logger.LogFatal(message);
}
}
[BepInPlugin("BugattiBoys.Valheim.PortalIndicator", "PortalIndicator", "0.0.5")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class PortalIndicator : BaseUnityPlugin
{
public const string PluginGUID = "BugattiBoys.Valheim.PortalIndicator";
public const string PluginName = "PortalIndicator";
public const string PluginVersion = "0.0.5";
private void Awake()
{
Log.IsDebug = true;
Logger.LogInfo((object)"PortalIndicator has landed");
MinimapManager.OnVanillaMapAvailable += MinimapManager_OnVanillaMapDataLoaded;
Log.Error("Show a fucking message");
Log.Info("Applying patches");
Patcher.Patch();
}
private static void MinimapManager_OnVanillaMapDataLoaded()
{
Log.Info("MiniMapManager.OnVanillaMapDataLoaded");
RequestUpdate();
}
public static void RequestUpdate()
{
Log.Info("Requesting Portal Update");
long sessionID = ZDOMan.GetSessionID();
string name = Game.instance.GetPlayerProfile().GetName();
SendToServer.SyncRequest($"{name} ({sessionID}) has joined the game");
}
public static void GameStarted()
{
Log.Info("Registering RPC handlers");
RPCManager.Register();
}
public static void UpdateFromPackage(ZPackage pkg)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Invalid comparison between Unknown and I4
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
if (Environment.IsServer)
{
return;
}
int num = pkg.ReadInt();
Log.Info($"Received {num} portals from server");
foreach (PinData pin in Minimap.instance.m_pins)
{
if ((int)pin.m_type == 6 && pin.m_name.StartsWith("_"))
{
Minimap.instance.DestroyPinMarker(pin);
}
}
if (num > 0)
{
for (int i = 0; i < num; i++)
{
ZPackage obj = pkg.ReadPackage();
string text = obj.ReadString();
Vector3 val = obj.ReadVector3();
Minimap.instance.AddPin(val, (PinType)6, "_" + text, false, false, 0L, "");
}
}
}
public static void ProcessSyncRequest()
{
Log.Info("Responding to sync request");
SendToClient.Resync(Package(), "I said so");
}
public static ZPackage Package()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
List<ZDO> portals = ZDOMan.instance.GetPortals();
ZPackage val = new ZPackage();
val.Write(portals.Count);
Log.Info($"Packaging {portals.Count} portals for client(s)");
foreach (ZDO item in portals)
{
val.Write(PackagePortal(item));
}
return val;
}
public static ZPackage PackagePortal(ZDO portal)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: 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_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
ZPackage val = new ZPackage();
val.Write(portal.GetString("tag", ""));
val.Write(portal.GetPosition());
return val;
}
}
}
namespace PortalIndicator.RPC
{
internal static class Client
{
public static void RequestSync(string reason)
{
Log.Debug("Asking server for a sync request, because: " + reason);
ZRoutedRpc.instance.InvokeRoutedRPC(Environment.ServerPeerId, "PortalIndicator_SyncPortalRequest", new object[1] { reason });
}
public static void ReceiveResync(long sender, ZPackage pkg)
{
PortalIndicator.UpdateFromPackage(pkg);
}
}
internal static class RPCManager
{
internal const string RPC_SYNCPORTAL = "PortalIndicator_SyncPortal";
internal const string RPC_RESYNC = "PortalIndicator_ResyncPortals";
internal const string RPC_SYNCREQUEST = "PortalIndicator_SyncPortalRequest";
internal const string RPC_ADDORUPDATEREQUEST = "PortalIndicator_AddOrUpdatePortalRequest";
internal const string RPC_REMOVEREQUEST = "PortalIndicator_RemovePortalRequest";
public static void Register()
{
ZRoutedRpc.instance.Register<string>("PortalIndicator_SyncPortalRequest", (Action<long, string>)Server.SyncRequest);
ZRoutedRpc.instance.Register<ZPackage>("PortalIndicator_ResyncPortals", (Action<long, ZPackage>)Client.ReceiveResync);
}
}
internal static class SendToClient
{
public static void Resync(ZPackage pkg, string reason)
{
Log.Info("Sending all portals to everybody, because: " + reason);
ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "PortalIndicator_ResyncPortals", new object[2] { pkg, reason });
}
}
internal static class SendToServer
{
public static void SyncRequest(string reason)
{
Log.Info("Asking server for a sync request, because: " + reason);
Log.Info($"Environment Peer ID: {Environment.ServerPeerId}");
ZRoutedRpc.instance.InvokeRoutedRPC(Environment.ServerPeerId, "PortalIndicator_SyncPortalRequest", new object[1] { reason });
}
}
internal static class Server
{
public static void SyncRequest(long sender, string reason)
{
Log.Debug($"Received sync request from `{sender}` because: {reason}");
PortalIndicator.ProcessSyncRequest();
}
public static void ResponseToSyncRequest(ZPackage pkg)
{
if (ZNet.instance.GetConnectedPeers().Count == 0)
{
Log.Info("Not sending resync package: nobody is connected");
}
Log.Debug("Sending all portals to everybody");
ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "PortalIndicator_ResyncPortals", new object[1] { pkg });
}
internal static void AddOrUpdateRequest(long sender, ZPackage pkg)
{
}
internal static void RemoveRequest(long sender, ZDOID portalId)
{
if (Environment.IsServer)
{
PortalIndicator.ProcessSyncRequest();
}
}
}
}
namespace PortalIndicator.Patches
{
[HarmonyPatch(typeof(Game), "Start")]
internal static class Game_Start
{
private static void Postfix()
{
Environment.GameStarted = true;
PortalIndicator.GameStarted();
}
}
[HarmonyPatch(typeof(Game), "ConnectPortals")]
internal static class Game_ConnectPortals
{
private static void Postfix()
{
PortalIndicator.RequestUpdate();
}
}
[HarmonyPatch(typeof(Minimap), "SetMapMode")]
internal static class Minimap_SetMapMode
{
private static void Prefix()
{
Log.Info("Map status changed, triggering resync");
PortalIndicator.RequestUpdate();
}
}
internal static class Patcher
{
private static readonly Harmony patcher = new Harmony("BugattiBoys.Valheim.PortalIndicator.harmony");
public static void Patch()
{
patcher.PatchAll(typeof(Game_Start));
patcher.PatchAll(typeof(Minimap_SetMapMode));
}
public static void Unpatch()
{
Harmony obj = patcher;
if (obj != null)
{
obj.UnpatchSelf();
}
}
}
[HarmonyPatch(typeof(Player), "PlacePiece")]
internal static class Player_PlacePiece
{
internal static void Postfix(Piece piece)
{
Log.Info("Piece placed!");
Log.Info(piece.m_name);
if (piece.m_name.Contains("$piece_portal"))
{
Log.Info("A portal has been placed!");
PortalIndicator.RequestUpdate();
}
}
}
[HarmonyPatch(typeof(WearNTear), "OnPlaced")]
internal static class WearNTear_OnPlaced
{
internal static void Prefix(WearNTear __instance)
{
Piece component = ((Component)__instance).GetComponent<Piece>();
ZNetView component2 = ((Component)__instance).GetComponent<ZNetView>();
if (component.m_name.Contains("$piece_portal") && Object.op_Implicit((Object)(object)component2))
{
Log.Info("A portal has been placed!");
PortalIndicator.RequestUpdate();
}
}
}
[HarmonyPatch(typeof(WearNTear), "Destroy")]
internal static class WearNTear_Destroy
{
private static void Postfix(WearNTear __instance)
{
Piece piece = __instance.m_piece;
if (Object.op_Implicit((Object)(object)piece) && Object.op_Implicit((Object)(object)piece.m_nview) && piece.m_name.Contains("$piece_portal") && piece.CanBeRemoved())
{
Log.Info("A portal has been destroyed");
PortalIndicator.RequestUpdate();
}
}
}
}