Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DvergrDiplomacy v0.2.1
DvergrDiplomacy.dll
Decompiled 2 months agousing 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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("DvergrDiplomacy")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DvergrDiplomacy")] [assembly: AssemblyTitle("DvergrDiplomacy")] [assembly: AssemblyVersion("1.0.0.0")] namespace Pix.DvergrDiplomacy; [BepInPlugin("Pix.DvergrDiplomacy", "DvergrDiplomacy", "0.2.1")] public sealed class DvergrDiplomacyTruceWedge : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__88_0; internal void <TryRegisterConsoleCommand>b__88_0(ConsoleEventArgs args) { //IL_0055: 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_006e: 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_0078: 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_007f: Expected O, but got Unknown //IL_0080: 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) try { if ((Object)(object)Player.m_localPlayer == (Object)null) { args.Context.AddString("No local player."); return; } if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null) { args.Context.AddString("Network not ready."); return; } Vector3 val = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f; ZPackage val2 = new ZPackage(); val2.Write(val); val2.Write(Quaternion.identity); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "DD_SpawnDverger_Test", new object[1] { val2 }); args.Context.AddString("Requested server spawn."); } catch (Exception ex) { args.Context.AddString("dd_spawn_dverger failed: " + ex.Message); } } } public const string PluginGuid = "Pix.DvergrDiplomacy"; public const string PluginName = "DvergrDiplomacy"; public const string PluginVersion = "0.2.1"; private const string BuildId = "DD_TRUCEWEDGE_0.2.0"; private const string RpcSpawnTest = "DD_SpawnDverger_Test"; private const string CmdSpawnDverger = "dd_spawn_dverger"; internal static DvergrDiplomacyTruceWedge Self; internal static ManualLogSource Log; private Harmony _harmony; private ConfigEntry<bool> _enabled; private ConfigEntry<float> _hostileSeconds; private ConfigEntry<int> _forgivenessFreeStrikes; private ConfigEntry<float> _forgivenessWindowSeconds; private ConfigEntry<float> _joinGraceSeconds; private ConfigEntry<float> _calmHoldSeconds; private ConfigEntry<float> _updateTargetHoldSeconds; private ConfigEntry<bool> _serverTriggerOnFindEnemy; private ConfigEntry<bool> _serverTriggerOnSetTarget; private ConfigEntry<bool> _showMessagesClient; private ConfigEntry<string> _warningPhrases; private ConfigEntry<bool> _spawnTestEnabled; private ConfigEntry<bool> _logEnabled; private ConfigEntry<float> _perAiLogEverySeconds; private ConfigEntry<bool> _traceAllAis; private ConfigEntry<bool> _clientSimWarning; private static MethodInfo MI_FindEnemy; private static MethodInfo MI_SetTarget; private static MethodInfo MI_UpdateAI; private static MethodInfo MI_CharacterDamage; private static MethodInfo MI_SetAlertedBool; private static MethodInfo MI_GetTargetCreature; private static FieldRef<MonsterAI, Character> FR_TargetCreature; private static bool FR_TargetCreatureOk; private static FieldInfo FI_Alerted; private static FieldInfo FI_Aggravated; private static FieldInfo FI_LastKnownTargetPos; private static FieldInfo FI_TargetStatic; private static FieldInfo FI_UpdateTargetTimer; private static readonly object _lock = new object(); private static readonly Dictionary<long, long> HostileUntilMsByPlayerId = new Dictionary<long, long>(); private static readonly Dictionary<long, long> JoinGraceUntilMsByPlayerId = new Dictionary<long, long>(); private static readonly Dictionary<long, int> StrikeCountByPlayerId = new Dictionary<long, int>(); private static readonly Dictionary<long, long> StrikeGraceUntilMsByPlayerId = new Dictionary<long, long>(); private static readonly HashSet<int> ActivatedAiIds = new HashSet<int>(); private static readonly Dictionary<int, long> CalmLockUntilMsByAiId = new Dictionary<int, long>(); private static readonly Dictionary<int, long> AiPlayerIdByAiId = new Dictionary<int, long>(); private static readonly Dictionary<int, float> NextLogAtByAiId = new Dictionary<int, float>(); private static readonly HashSet<int> ClientSimWarnedAiIds = new HashSet<int>(); private static bool _rpcsRegistered; private static bool _consoleRegistered; private string[] _phrases = new string[1] { "Hold your hand, outsider." }; private Random _rng = new Random(); private void Awake() { //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown Self = this; Log = ((BaseUnityPlugin)this).Logger; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable DvergrDiplomacy."); _hostileSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Diplomacy", "HostileSeconds", 180f, "How long they stay hostile after diplomacy breaks."); _forgivenessFreeStrikes = ((BaseUnityPlugin)this).Config.Bind<int>("Forgiveness", "FreeStrikes", 1, "Number of forgiven strikes before diplomacy breaks."); _forgivenessWindowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Forgiveness", "WindowSeconds", 30f, "Second strike within this window breaks diplomacy."); _joinGraceSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "JoinGraceSeconds", 15f, "Grace period after contact to prevent instant death."); _calmHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Wedge", "CalmHoldSeconds", 12f, "Hold calm this long (refreshes while hot)."); _updateTargetHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Wedge", "UpdateTargetHoldSeconds", 30f, "Clamp update target timer while holding calm."); _serverTriggerOnFindEnemy = ((BaseUnityPlugin)this).Config.Bind<bool>("ServerTriggers", "TriggerOnFindEnemy", true, "Server: treat FindEnemy->Player as contact (starts join grace)."); _serverTriggerOnSetTarget = ((BaseUnityPlugin)this).Config.Bind<bool>("ServerTriggers", "TriggerOnSetTarget", true, "Server: treat SetTarget(Player) as contact (starts join grace)."); _showMessagesClient = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "ShowMessages", true, "Client: show warning popup on forgiven strike."); _warningPhrases = ((BaseUnityPlugin)this).Config.Bind<string>("Client", "WarningPhrases", "Careful|Hold your hand, outsider.|Odin is watching.", "Pipe-separated list of warning phrases."); _spawnTestEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("SpawnTest", "Enabled", true, "Enable dd_spawn_dverger and server RPC spawn test."); _logEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "Log", false, "Enable extra logs (throttled)."); _perAiLogEverySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Logging", "PerAiLogEverySeconds", 1f, "Minimum seconds between logs per AI."); _traceAllAis = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "TraceAllAis", false, "Apply to all MonsterAI (debug)."); _clientSimWarning = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ClientSimWarning", true, "Client: warn once per AI if AI sim is client-side (only when Logging.Log=true)."); ParsePhrases(); ResolveHandles(); _harmony = new Harmony("Pix.DvergrDiplomacy"); ApplyPatches(); TryRegisterRpcs(); TryRegisterConsoleCommand(); Log.LogInfo((object)"[DD_TRUCEWEDGE_0.2.0] Loaded v0.2.1."); } private void Update() { try { if (EnabledNow()) { TryRegisterRpcs(); TryRegisterConsoleCommand(); } } catch { } } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } } private bool EnabledNow() { if (_enabled != null) { return _enabled.Value; } return false; } private bool LogsEnabled() { if (_logEnabled != null) { return _logEnabled.Value; } return false; } private void LogInfoExtra(string msg) { if (!LogsEnabled()) { return; } try { Log.LogInfo((object)msg); } catch { } } private void LogWarningExtra(string msg) { if (!LogsEnabled()) { return; } try { Log.LogWarning((object)msg); } catch { } } private void ParsePhrases() { try { string text = ((_warningPhrases != null) ? (_warningPhrases.Value ?? "") : ""); string[] array = text.Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries); List<string> list = new List<string>(); for (int i = 0; i < array.Length; i++) { string text2 = ((array[i] != null) ? array[i].Trim() : ""); if (text2.Length > 0) { list.Add(text2); } } if (list.Count > 0) { _phrases = list.ToArray(); } } catch { _phrases = new string[1] { "Hold your hand, outsider." }; } } private static void ResolveHandles() { try { FR_TargetCreature = AccessTools.FieldRefAccess<MonsterAI, Character>("m_targetCreature"); FR_TargetCreatureOk = true; } catch { FR_TargetCreatureOk = false; FR_TargetCreature = null; } Type typeFromHandle = typeof(MonsterAI); FI_Alerted = AccessTools.Field(typeFromHandle, "m_alerted"); FI_Aggravated = AccessTools.Field(typeFromHandle, "m_aggravated"); FI_LastKnownTargetPos = AccessTools.Field(typeFromHandle, "m_lastKnownTargetPos"); FI_TargetStatic = AccessTools.Field(typeFromHandle, "m_targetStatic"); FI_UpdateTargetTimer = AccessTools.Field(typeFromHandle, "m_updateTargetTimer"); MI_SetAlertedBool = AccessTools.Method(typeof(BaseAI), "SetAlerted", new Type[1] { typeof(bool) }, (Type[])null); MI_GetTargetCreature = AccessTools.Method(typeof(BaseAI), "GetTargetCreature", Type.EmptyTypes, (Type[])null); MI_FindEnemy = AccessTools.Method(typeof(BaseAI), "FindEnemy", Type.EmptyTypes, (Type[])null); MI_SetTarget = AccessTools.Method(typeof(MonsterAI), "SetTarget", new Type[1] { typeof(Character) }, (Type[])null); MI_UpdateAI = AccessTools.Method(typeof(MonsterAI), "UpdateAI", new Type[1] { typeof(float) }, (Type[])null); MI_CharacterDamage = ResolveCharacterDamageHitData(); } private static MethodInfo ResolveCharacterDamageHitData() { try { Type typeFromHandle = typeof(Character); MethodInfo[] methods = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo == null) && !(methodInfo.Name != "Damage")) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.Name == "HitData") { return methodInfo; } } } } catch { } return null; } private void ApplyPatches() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown if (MI_FindEnemy != null) { _harmony.Patch((MethodBase)MI_FindEnemy, (HarmonyMethod)null, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "FindEnemy_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (MI_SetTarget != null) { _harmony.Patch((MethodBase)MI_SetTarget, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "SetTarget_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (MI_UpdateAI != null) { _harmony.Patch((MethodBase)MI_UpdateAI, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "UpdateAI_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (MI_CharacterDamage != null) { _harmony.Patch((MethodBase)MI_CharacterDamage, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "CharacterDamage_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Self?.LogWarningExtra("[DD_TRUCEWEDGE_0.2.0] Could not resolve Character.Damage(HitData). Forgiveness will not detect attacks."); } } private static bool IsServer() { try { return (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); } catch { return false; } } private static long NowMs() { try { double num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : ((double)Time.realtimeSinceStartup)); if (num < 0.0) { num = 0.0; } return (long)(num * 1000.0); } catch { return (long)((double)Time.realtimeSinceStartup * 1000.0); } } private bool ShouldAct(Character owner) { if (!EnabledNow()) { return false; } if (_traceAllAis != null && _traceAllAis.Value) { return true; } return IsDverger(owner); } private static bool IsDverger(Character c) { if ((Object)(object)c == (Object)null) { return false; } try { string text = ((object)(Faction)(ref c.m_faction)).ToString(); if (!string.IsNullOrEmpty(text) && text.IndexOf("Dverger", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } catch { } try { string text2 = ((Object)c).name ?? ""; if (text2.IndexOf("dver", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } catch { } return false; } private static bool IsPlayerChar(Character c) { if ((Object)(object)c == (Object)null) { return false; } try { return c.IsPlayer(); } catch { return (Object)(object)((c is Player) ? c : null) != (Object)null; } } private static long GetStablePlayerId(Player p) { if ((Object)(object)p == (Object)null) { return 0L; } try { return p.GetPlayerID(); } catch { return 0L; } } private bool ShouldLog(int aiId) { if (_logEnabled == null || !_logEnabled.Value) { return false; } float num = Mathf.Max(0.1f, (_perAiLogEverySeconds != null) ? _perAiLogEverySeconds.Value : 1f); float time = Time.time; if (NextLogAtByAiId.TryGetValue(aiId, out var value) && time < value) { return false; } NextLogAtByAiId[aiId] = time + num; return true; } private void ClientMessage(string msg) { if (_showMessagesClient == null || !_showMessagesClient.Value) { return; } try { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, msg, 0, (Sprite)null, false); } } catch { } } private void PopupForgiven() { if (_phrases == null || _phrases.Length == 0) { ClientMessage("Hold your hand, outsider."); return; } int num = 0; try { num = _rng.Next(0, _phrases.Length); } catch { num = 0; } string msg = _phrases[num] ?? "Hold your hand, outsider."; ClientMessage(msg); } private bool IsHostileActive(long playerId, long nowMs) { if (playerId == 0L) { return false; } lock (_lock) { if (HostileUntilMsByPlayerId.TryGetValue(playerId, out var value)) { return nowMs < value; } } return false; } private void EnsureJoinGrace(long playerId, long nowMs, string reason) { if (playerId == 0L) { return; } long num = nowMs + (long)(Mathf.Max(0.1f, _joinGraceSeconds.Value) * 1000f); bool flag = false; lock (_lock) { if (!JoinGraceUntilMsByPlayerId.TryGetValue(playerId, out var value) || value < nowMs) { JoinGraceUntilMsByPlayerId[playerId] = num; flag = true; } } if (flag && IsServer()) { LogInfoExtra(string.Format("[{0}] JOIN-GRACE start playerId={1} untilMs={2} reason={3}", "DD_TRUCEWEDGE_0.2.0", playerId, num, reason)); } } private int GetStrikeCountResetIfExpired(long playerId, long nowMs) { if (playerId == 0L) { return 0; } lock (_lock) { StrikeGraceUntilMsByPlayerId.TryGetValue(playerId, out var value); if (value != 0L && nowMs > value) { StrikeCountByPlayerId[playerId] = 0; StrikeGraceUntilMsByPlayerId[playerId] = 0L; } StrikeCountByPlayerId.TryGetValue(playerId, out var value2); return value2; } } private void SetStrikeCount(long playerId, int strikes) { if (playerId == 0L) { return; } lock (_lock) { StrikeCountByPlayerId[playerId] = strikes; } } private void EnsureForgivenessWindow(long playerId, long nowMs) { if (playerId == 0L) { return; } long num = (long)(Mathf.Max(1f, _forgivenessWindowSeconds.Value) * 1000f); long value = nowMs + num; lock (_lock) { StrikeGraceUntilMsByPlayerId[playerId] = value; } } private void StartHostile(long playerId, long nowMs, string reason) { if (playerId != 0L) { long num = nowMs + (long)(Mathf.Max(1f, _hostileSeconds.Value) * 1000f); lock (_lock) { HostileUntilMsByPlayerId[playerId] = num; StrikeCountByPlayerId[playerId] = 0; StrikeGraceUntilMsByPlayerId[playerId] = 0L; JoinGraceUntilMsByPlayerId[playerId] = 0L; } if (IsServer()) { LogInfoExtra(string.Format("[{0}] HOSTILE START playerId={1} untilMs={2} reason={3}", "DD_TRUCEWEDGE_0.2.0", playerId, num, reason)); } } } private bool ShouldWedgeProtect(long playerId, long nowMs) { if (playerId == 0L) { return true; } return !IsHostileActive(playerId, nowMs); } private void ActivateOrRefreshWedge(int aiId, long playerId, long nowMs, string reason) { long num = nowMs + (long)(Mathf.Max(0.1f, _calmHoldSeconds.Value) * 1000f); lock (_lock) { ActivatedAiIds.Add(aiId); CalmLockUntilMsByAiId[aiId] = num; AiPlayerIdByAiId[aiId] = playerId; } if (IsServer() && ShouldLog(aiId)) { LogInfoExtra(string.Format("[{0}] WEDGE ENGAGE aiId={1} playerId={2} untilMs={3} reason={4}", "DD_TRUCEWEDGE_0.2.0", aiId, playerId, num, reason)); } } private void ReleaseWedge(int aiId, string reason) { lock (_lock) { ActivatedAiIds.Remove(aiId); CalmLockUntilMsByAiId.Remove(aiId); AiPlayerIdByAiId.Remove(aiId); } if (IsServer() && ShouldLog(aiId)) { LogInfoExtra(string.Format("[{0}] WEDGE RELEASE aiId={1} reason={2}", "DD_TRUCEWEDGE_0.2.0", aiId, reason)); } } private void ForceNeutral(MonsterAI ai) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) try { try { if (FI_Alerted != null) { FI_Alerted.SetValue(ai, false); } } catch { } try { if (FI_Aggravated != null) { FI_Aggravated.SetValue(ai, false); } } catch { } try { if (FI_LastKnownTargetPos != null) { FI_LastKnownTargetPos.SetValue(ai, Vector3.zero); } } catch { } try { if (FI_TargetStatic != null) { FI_TargetStatic.SetValue(ai, null); } } catch { } try { if (FI_UpdateTargetTimer != null) { FI_UpdateTargetTimer.SetValue(ai, Mathf.Max(0f, _updateTargetHoldSeconds.Value)); } } catch { } if (FR_TargetCreatureOk && FR_TargetCreature != null) { try { FR_TargetCreature.Invoke(ai) = null; } catch { } } try { if (MI_SetAlertedBool != null) { MI_SetAlertedBool.Invoke(ai, new object[1] { false }); } } catch { } } catch { } } private static Character GetTargetCreature(MonsterAI ai) { if ((Object)(object)ai == (Object)null) { return null; } if (FR_TargetCreatureOk && FR_TargetCreature != null) { try { return FR_TargetCreature.Invoke(ai); } catch { } } if (MI_GetTargetCreature != null) { try { object? obj2 = MI_GetTargetCreature.Invoke(ai, null); return (Character)((obj2 is Character) ? obj2 : null); } catch { } } return null; } public static void FindEnemy_Postfix(BaseAI __instance, ref Character __result) { try { if ((Object)(object)Self == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)__result == (Object)null || !Self.EnabledNow()) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if (!Self.ShouldAct(component) || !IsPlayerChar(__result)) { return; } Character obj = __result; Player val = (Player)(object)((obj is Player) ? obj : null); if (!((Object)(object)val == (Object)null)) { long nowMs = NowMs(); long stablePlayerId = GetStablePlayerId(val); if (IsServer() && Self._serverTriggerOnFindEnemy != null && Self._serverTriggerOnFindEnemy.Value) { Self.EnsureJoinGrace(stablePlayerId, nowMs, "FindEnemy"); } if (Self.ShouldWedgeProtect(stablePlayerId, nowMs)) { int instanceID = ((Object)__instance).GetInstanceID(); Self.ActivateOrRefreshWedge(instanceID, stablePlayerId, nowMs, "FindEnemy->Player"); __result = null; } } } catch { } } public static bool SetTarget_Prefix(MonsterAI __instance, Character attacker) { try { if ((Object)(object)Self == (Object)null) { return true; } if ((Object)(object)__instance == (Object)null || (Object)(object)attacker == (Object)null) { return true; } if (!Self.EnabledNow()) { return true; } Character component = ((Component)__instance).GetComponent<Character>(); if (!Self.ShouldAct(component)) { return true; } if (!IsPlayerChar(attacker)) { return true; } Player val = (Player)(object)((attacker is Player) ? attacker : null); if ((Object)(object)val == (Object)null) { return true; } long nowMs = NowMs(); long stablePlayerId = GetStablePlayerId(val); if (IsServer() && Self._serverTriggerOnSetTarget != null && Self._serverTriggerOnSetTarget.Value) { Self.EnsureJoinGrace(stablePlayerId, nowMs, "SetTarget"); } if (Self.ShouldWedgeProtect(stablePlayerId, nowMs)) { int instanceID = ((Object)__instance).GetInstanceID(); Self.ActivateOrRefreshWedge(instanceID, stablePlayerId, nowMs, "SetTarget->Player"); Self.ForceNeutral(__instance); return false; } return true; } catch { return true; } } public static void UpdateAI_Prefix(MonsterAI __instance, float dt) { //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)Self == (Object)null || (Object)(object)__instance == (Object)null || !Self.EnabledNow()) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if (!Self.ShouldAct(component)) { return; } int instanceID = ((Object)__instance).GetInstanceID(); if (!IsServer() && Self.LogsEnabled() && Self._clientSimWarning != null && Self._clientSimWarning.Value) { bool flag; lock (_lock) { flag = ClientSimWarnedAiIds.Add(instanceID); } if (flag) { Self.LogWarningExtra(string.Format("[{0}] CLIENT-SIM WARNING aiId={1} ownerGO='{2}'.", "DD_TRUCEWEDGE_0.2.0", instanceID, ((Object)(object)component != (Object)null && (Object)(object)((Component)component).gameObject != (Object)null) ? ((Object)((Component)component).gameObject).name : (((Object)(object)component != (Object)null) ? ((Object)component).name : "(null)"))); } } long num = NowMs(); Character targetCreature = GetTargetCreature(__instance); Player val = (Player)(object)((targetCreature is Player) ? targetCreature : null); if ((Object)(object)val != (Object)null) { long stablePlayerId = GetStablePlayerId(val); Self.EnsureJoinGrace(stablePlayerId, num, "UpdateAI(TargetPlayer)"); if (Self.ShouldWedgeProtect(stablePlayerId, num)) { Self.ActivateOrRefreshWedge(instanceID, stablePlayerId, num, "UpdateAI(SafetyNet)"); Self.ForceNeutral(__instance); return; } } bool flag2; long value; long value2; lock (_lock) { flag2 = ActivatedAiIds.Contains(instanceID); AiPlayerIdByAiId.TryGetValue(instanceID, out value); CalmLockUntilMsByAiId.TryGetValue(instanceID, out value2); } if (!flag2) { return; } if (!Self.ShouldWedgeProtect(value, num)) { Self.ReleaseWedge(instanceID, "HostileActive"); return; } bool flag3 = false; bool flag4 = false; Vector3 val2 = Vector3.zero; object obj = null; try { if (FI_Alerted != null) { flag3 = (bool)FI_Alerted.GetValue(__instance); } } catch { } try { if (FI_Aggravated != null) { flag4 = (bool)FI_Aggravated.GetValue(__instance); } } catch { } try { if (FI_LastKnownTargetPos != null) { val2 = (Vector3)FI_LastKnownTargetPos.GetValue(__instance); } } catch { } try { if (FI_TargetStatic != null) { obj = FI_TargetStatic.GetValue(__instance); } } catch { } bool flag5 = (Object)(object)targetCreature != (Object)null; if (flag3 || flag4 || obj != null || val2 != Vector3.zero || flag5) { long num2 = num + (long)(Mathf.Max(0.1f, Self._calmHoldSeconds.Value) * 1000f); lock (_lock) { CalmLockUntilMsByAiId[instanceID] = num2; } value2 = num2; } if (num < value2) { Self.ForceNeutral(__instance); } } catch { } } public static void CharacterDamage_Prefix(Character __instance, object hit) { try { if ((Object)(object)Self == (Object)null || !Self.EnabledNow() || (Object)(object)__instance == (Object)null || !IsDverger(__instance)) { return; } Character val = null; try { if (hit != null) { MethodInfo method = hit.GetType().GetMethod("GetAttacker", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { object? obj = method.Invoke(hit, null); val = (Character)((obj is Character) ? obj : null); } } } catch { val = null; } Player val2 = (Player)(object)((val is Player) ? val : null); if ((Object)(object)val2 == (Object)null) { return; } long nowMs = NowMs(); long stablePlayerId = GetStablePlayerId(val2); if (Self.IsHostileActive(stablePlayerId, nowMs)) { return; } int strikeCountResetIfExpired = Self.GetStrikeCountResetIfExpired(stablePlayerId, nowMs); int num = Mathf.Max(0, Self._forgivenessFreeStrikes.Value); int num2 = strikeCountResetIfExpired + 1; Self.EnsureForgivenessWindow(stablePlayerId, nowMs); Self.SetStrikeCount(stablePlayerId, num2); Self.EnsureJoinGrace(stablePlayerId, nowMs, "Strike"); if (num2 <= num) { if (!IsServer()) { if ((Object)(object)Player.m_localPlayer != (Object)null && GetStablePlayerId(Player.m_localPlayer) == stablePlayerId) { Self.PopupForgiven(); } } else { Self.LogInfoExtra(string.Format("[{0}] STRIKE FORGIVEN playerId={1} strike={2}/{3}", "DD_TRUCEWEDGE_0.2.0", stablePlayerId, num2, num)); } } else if (IsServer()) { Self.StartHostile(stablePlayerId, nowMs, "SecondStrike"); } else { Self.StartHostile(stablePlayerId, nowMs, "SecondStrike(client)"); } } catch { } } private void TryRegisterRpcs() { if (_rpcsRegistered || _spawnTestEnabled == null || !_spawnTestEnabled.Value) { return; } try { if (ZRoutedRpc.instance != null) { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ZRoutedRpc.instance.Register<ZPackage>("DD_SpawnDverger_Test", (Action<long, ZPackage>)RPC_ServerSpawnDvergerTest); LogInfoExtra("[DD_TRUCEWEDGE_0.2.0] Registered RPC DD_SpawnDverger_Test"); } _rpcsRegistered = true; } } catch { } } private void TryRegisterConsoleCommand() { //IL_0051: 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) //IL_0048: Expected O, but got Unknown if (_consoleRegistered || _spawnTestEnabled == null || !_spawnTestEnabled.Value) { return; } try { object obj = <>c.<>9__88_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0055: 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_006e: 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_0078: 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_007f: Expected O, but got Unknown //IL_0080: 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) try { if ((Object)(object)Player.m_localPlayer == (Object)null) { args.Context.AddString("No local player."); } else if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null) { args.Context.AddString("Network not ready."); } else { Vector3 val2 = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f; ZPackage val3 = new ZPackage(); val3.Write(val2); val3.Write(Quaternion.identity); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "DD_SpawnDverger_Test", new object[1] { val3 }); args.Context.AddString("Requested server spawn."); } } catch (Exception ex) { args.Context.AddString("dd_spawn_dverger failed: " + ex.Message); } }; <>c.<>9__88_0 = val; obj = (object)val; } new ConsoleCommand("dd_spawn_dverger", "Ask the server to spawn a Dverger near you.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); _consoleRegistered = true; LogInfoExtra("[DD_TRUCEWEDGE_0.2.0] Registered console command dd_spawn_dverger"); } catch { } } private static void RPC_ServerSpawnDvergerTest(long sender, ZPackage pkg) { //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_0037: 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_0039: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)Self == (Object)null) && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { Vector3 pos = pkg.ReadVector3(); Quaternion rot = pkg.ReadQuaternion(); SpawnDvergerServer(pos, rot, "RPC(sender=" + sender + ")"); } } catch { } } private static void SpawnDvergerServer(Vector3 pos, Quaternion rot, string reason) { //IL_0085: 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_00c9: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || (Object)(object)ZNetScene.instance == (Object)null) { return; } GameObject prefab = ZNetScene.instance.GetPrefab("Dverger"); if ((Object)(object)prefab == (Object)null) { prefab = ZNetScene.instance.GetPrefab("DvergerArbalest"); } if ((Object)(object)prefab == (Object)null) { Self?.LogWarningExtra("[DD_TRUCEWEDGE_0.2.0] Dverger prefab not found (" + reason + ")"); return; } GameObject val = Object.Instantiate<GameObject>(prefab, pos, rot); ZNetView component = val.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && !component.IsOwner()) { component.ClaimOwnership(); } Self?.LogInfoExtra(string.Format("[{0}] Server spawned Dverger ({1}) at {2}", "DD_TRUCEWEDGE_0.2.0", reason, pos)); } catch { } } }