using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("GateOfOrethority")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8abdf42c92d4b9252e5276112f3a6a57b743df36")]
[assembly: AssemblyProduct("GateOfOrethority")]
[assembly: AssemblyTitle("GateOfOrethority")]
[assembly: AssemblyVersion("1.0.0.0")]
[HarmonyPatch(typeof(Character), "OnDeath")]
public class BossDeathTracker
{
private static void Postfix(Character __instance)
{
string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject);
GateOfOrethority.Log.LogInfo((object)("Boss died: prefab = " + prefabName));
if (1 == 0)
{
}
string text = prefabName switch
{
"Eikthyr" => "defeated_eikthyr",
"deer" => "defeated_eikthyr",
"gd_king" => "defeated_elder",
"Bonemass" => "defeated_bonemass",
"Dragon" => "defeated_moder",
"GoblinKing" => "defeated_yagluth",
"SeekerQueen" => "defeated_queen",
"Queen" => "defeated_queen",
"Fader" => "defeated_fader",
_ => null,
};
if (1 == 0)
{
}
string text2 = text;
if (text2 == null)
{
return;
}
foreach (Player allPlayer in Player.GetAllPlayers())
{
if (!allPlayer.m_customData.ContainsKey(text2))
{
allPlayer.m_customData[text2] = "true";
GateOfOrethority.Log.LogInfo((object)("Set player key '" + text2 + "' for " + allPlayer.GetPlayerName()));
}
}
}
}
public static class ConfigSync
{
[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
public class ServerSendConfig
{
private static void Postfix(ZNet __instance, ZNetPeer peer)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
if (!ZNet.instance.IsServer())
{
return;
}
ZPackage val = new ZPackage();
foreach (KeyValuePair<string, string> item in GateOfOrethority.ItemBossMap)
{
val.Write(item.Key);
val.Write(item.Value);
}
peer.m_rpc.Invoke("GateOfOrethority_ReceiveConfig", new object[1] { val });
}
}
[HarmonyPatch(typeof(ZNet), "Awake")]
public class ClientRegisterRPC
{
private static void Postfix(ZNet __instance)
{
if (!ZNet.instance.IsServer())
{
ZRoutedRpc.instance.Register<ZPackage>("GateOfOrethority_ReceiveConfig", (Action<long, ZPackage>)WrappedReceiveConfig);
}
}
private static void WrappedReceiveConfig(long sender, ZPackage pkg)
{
ReceiveConfig(pkg);
}
}
public static bool UseServerConfig = false;
public static Dictionary<string, string> ServerItemBossMap = new Dictionary<string, string>();
public static void ReceiveConfig(ZPackage pkg)
{
ServerItemBossMap.Clear();
while (pkg.GetPos() < pkg.Size())
{
string key = pkg.ReadString();
string value = pkg.ReadString();
ServerItemBossMap[key] = value;
}
UseServerConfig = GateOfOrethority.EnableServerOverride.Value;
}
}
public static class FlavorText
{
private static readonly Dictionary<string, string> itemMessages = new Dictionary<string, string>
{
{ "CopperOre", "The copper resists your passage, bound by roots older than stone." },
{ "TinOre", "The forge-born tin trembles, awaiting the Elder’s fall." },
{ "Copper", "The copper resists your passage, bound by roots older than stone." },
{ "Tin", "The forge-born tin trembles, awaiting the Elder’s fall." },
{ "Bronze", "Bronze and tin echo with ancient rites. The forest’s guardian still watches." },
{ "IronScrap", "Iron groans with the weight of decay. Bonemass’s curse clings to its core." },
{ "Iron", "Iron groans with the weight of decay. Bonemass’s curse clings to its core." },
{ "Ironpit", "The pit reeks of rot and resistance. The swamp’s champion must be vanquished." },
{ "SilverOre", "Silver shivers with frostbitten fury. The mountain’s dragon still reigns." },
{ "Silver", "The metal remembers the cold breath of Moder. You are not yet worthy." },
{ "BlackMetalScrap", "The scrap pulses with flame-forged pride. The plains demand tribute." },
{ "BlackMetal", "Black metal hums with scorched defiance. Yagluth’s embers burn too bright to pass." },
{ "MechanicalSpring", "Mechanical spring resists the warp, loyal to the Mistlands’ sovereign." },
{ "BronzeScrap", "The bronze scrap clinks with defiance. The Queen’s will must be broken." },
{ "DvergrNeedle", "The extractor trembles, bound by regal decree. The Queen’s dominion remains unbroken." },
{ "IronOre", "The Queen is curious to what you are going to do with this." },
{ "CharredCogwheel", "The cogwheel crackles with emerald flame. Fader’s wrath must be extinguished." },
{ "FlametalOre", "Fader says you spawned the wrong ore" },
{ "Flametal", "The Emerald Flame thinks you should try the New flametal" },
{ "FlametalOreNew", "The ore smolders with unspent vengeance. Fader’s dominion endures." },
{ "FlametalNew", "Flametal recoils from your grasp, forged in fire yet loyal to ash." }
};
public static string Get(string itemName)
{
string value;
return itemMessages.TryGetValue(itemName, out value) ? value : "The metal resists your passage. Its guardian still stands.";
}
}
[BepInPlugin("com.stayk.gateoforethority", "Gate of Ore-thority", "1.0.2")]
public class GateOfOrethority : BaseUnityPlugin
{
public static ManualLogSource Log;
public static ConfigEntry<bool> EnableServerOverride;
public static Dictionary<string, string> ItemBossMap = new Dictionary<string, string>();
public static readonly List<string> AllBossKeys = new List<string> { "defeated_eikthyr", "defeated_elder", "defeated_bonemass", "defeated_moder", "defeated_yagluth", "defeated_queen", "defeated_fader" };
private Dictionary<string, ConfigEntry<string>> RawConfigEntries = new Dictionary<string, ConfigEntry<string>>();
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
EnableServerOverride = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableServerOverride", false, "If true, clients will use server-enforced boss flags for teleport restrictions.");
RegisterItem("CopperOre", "defeated_elder");
RegisterItem("TinOre", "defeated_elder");
RegisterItem("Copper", "defeated_elder");
RegisterItem("Tin", "defeated_elder");
RegisterItem("Bronze", "defeated_elder");
RegisterItem("IronScrap", "defeated_bonemass");
RegisterItem("Iron", "defeated_bonemass");
RegisterItem("Ironpit", "defeated_bonemass");
RegisterItem("SilverOre", "defeated_moder");
RegisterItem("Silver", "defeated_moder");
RegisterItem("BlackMetalScrap", "defeated_yagluth");
RegisterItem("BlackMetal", "defeated_yagluth");
RegisterItem("MechanicalSpring", "defeated_queen");
RegisterItem("DvergrNeedle", "defeated_queen");
RegisterItem("IronOre", "defeated_queen");
RegisterItem("BronzeScrap", "defeated_queen");
RegisterItem("CharredCogwheel", "defeated_fader");
RegisterItem("FlametalOre", "defeated_fader");
RegisterItem("Flametal", "defeated_fader");
RegisterItem("FlametalNew", "defeated_fader");
RegisterItem("FlametalOreNew", "defeated_fader");
EnforceServerConfig();
Harmony.CreateAndPatchAll(typeof(GateOfOrethority).Assembly, (string)null);
Log.LogInfo((object)"Gate of Ore-thority initialized with server override and player key support.");
}
private void RegisterItem(string itemName, string defaultBossKey)
{
ConfigEntry<string> value = ((BaseUnityPlugin)this).Config.Bind<string>("TeleportRestrictions", itemName, defaultBossKey, "Boss flag required to teleport with " + itemName + ".");
RawConfigEntries[itemName] = value;
}
private void EnforceServerConfig()
{
bool flag = (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer();
bool value = EnableServerOverride.Value;
foreach (KeyValuePair<string, ConfigEntry<string>> rawConfigEntry in RawConfigEntries)
{
string key = rawConfigEntry.Key;
string text = rawConfigEntry.Value.Value;
if (!flag && value)
{
text = ((ConfigEntryBase)rawConfigEntry.Value).DefaultValue.ToString();
Log.LogInfo((object)("[Ore-thority] Overriding client config for '" + key + "' → '" + text + "'"));
}
ItemBossMap[key] = text;
}
if (!flag && value)
{
Log.LogInfo((object)"[Ore-thority] Server override is active. Client config values have been replaced.");
}
else
{
Log.LogInfo((object)"[Ore-thority] Using local config values.");
}
}
}
[HarmonyPatch(typeof(Terminal), "TryRunCommand")]
public class PlayerKeyConsolePatch
{
private static bool Prefix(Terminal __instance, string text)
{
if (!text.StartsWith("ore_"))
{
return true;
}
Player localPlayer = Player.m_localPlayer;
if ((Object)(object)localPlayer == (Object)null)
{
return true;
}
string[] array = text.Split(new char[1] { ' ' });
string text2 = array[0];
switch (text2)
{
case "ore_grantkey":
if (array.Length < 2)
{
return false;
}
localPlayer.m_customData[array[1]] = "true";
__instance.AddString("[Ore-thority] Granted key '" + array[1] + "' to " + localPlayer.GetPlayerName());
return false;
case "ore_revokekey":
if (array.Length < 2)
{
return false;
}
localPlayer.m_customData.Remove(array[1]);
__instance.AddString("[Ore-thority] Revoked key '" + array[1] + "' from " + localPlayer.GetPlayerName());
return false;
case "ore_listkeys":
__instance.AddString("[Ore-thority] Keys for " + localPlayer.GetPlayerName() + ":");
foreach (KeyValuePair<string, string> customDatum in localPlayer.m_customData)
{
__instance.AddString(" " + customDatum.Key + " = " + customDatum.Value);
}
return false;
case "ore_grantallkeys":
foreach (string allBossKey in GateOfOrethority.AllBossKeys)
{
localPlayer.m_customData[allBossKey] = "true";
}
__instance.AddString("[Ore-thority] Granted all progression keys to " + localPlayer.GetPlayerName());
return false;
case "ore_resetkeys":
foreach (string allBossKey2 in GateOfOrethority.AllBossKeys)
{
localPlayer.m_customData.Remove(allBossKey2);
}
__instance.AddString("[Ore-thority] Reset all progression keys for " + localPlayer.GetPlayerName());
return false;
default:
__instance.AddString("[Ore-thority] Unknown command: " + text2);
return false;
}
}
}
[HarmonyPatch(typeof(Player), "TeleportTo")]
public class TeleportBlocker
{
private static bool Prefix(Player __instance, Vector3 pos, Quaternion rot, bool distantTeleport)
{
Inventory inventory = ((Humanoid)__instance).GetInventory();
List<ItemData> allItems = inventory.GetAllItems();
foreach (KeyValuePair<string, string> item in GateOfOrethority.ItemBossMap)
{
string key = item.Key;
string text = ((ConfigSync.UseServerConfig && ConfigSync.ServerItemBossMap.ContainsKey(key)) ? ConfigSync.ServerItemBossMap[key] : item.Value);
foreach (ItemData item2 in allItems)
{
GameObject dropPrefab = item2.m_dropPrefab;
string text2 = ((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? item2.m_shared.m_name;
bool flag = __instance.m_customData.ContainsKey(text);
GateOfOrethority.Log.LogInfo((object)$"Teleport check: item='{text2}', requiredKey='{text}', playerHasKey={flag}");
if ((text2 == key || item2.m_shared.m_name == key) && !flag)
{
string text3 = FlavorText.Get(key);
if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)MessageHud.instance != (Object)null)
{
MessageHud.instance.ShowMessage((MessageType)2, text3, 0, (Sprite)null, false);
}
else
{
GateOfOrethority.Log.LogWarning((object)("[TeleportBlocker] Could not show message: " + text3));
}
return false;
}
}
}
return true;
}
}