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.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Steamworks;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using WhoDiedFirst.Helpers;
using WhoDiedFirst.Managers;
using WhoDiedFirst.NetcodePatcher;
using WhoDiedFirst.Patches;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WhoDiedFirst")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WhoDiedFirst")]
[assembly: AssemblyTitle("WhoDiedFirst")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: NetcodePatchedAssembly]
internal class <Module>
{
static <Module>()
{
}
}
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace WhoDiedFirst
{
public static class ConfigSettings
{
public static ConfigEntry<bool> isDebug;
public static ConfigEntry<bool> includeDisconnects;
public static ConfigEntry<bool> includeAbandoned;
public static ConfigEntry<bool> addWDFNote;
public static ConfigEntry<bool> overrideScoreboard;
public static ConfigEntry<bool> addDCToScoreboard;
public static ConfigEntry<bool> addDeathPlacementsToScoreboard;
public static ConfigEntry<int> deathPlacementWindow;
public static void BindConfigSettings()
{
isDebug = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<bool>("Overall", "Debug Messages", false, "Debug messages to console.");
includeDisconnects = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<bool>("DeathQualifiers", "includeDisconnects", true, "Should include those who disconnect in deathOrder");
includeAbandoned = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<bool>("DeathQualifiers", "includeAbandoned", true, "Should include those who are abandoned in deathOrder");
addWDFNote = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<bool>("DeathOverrides", "addWDFNote", true, "Adds a note on who died first to the end of round screen.");
overrideScoreboard = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<bool>("DeathOverrides", "overrideScoreboard", true, "Modifies the scoreboard to order each player based on when they died.");
addDCToScoreboard = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<bool>("DeathOverrides", "addDCToScoreboard", true, "Updates the scoreboard with a DC tag when someone DCs.");
addDeathPlacementsToScoreboard = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<bool>("DeathOverrides", "addDeathPlacementsToScoreboard", true, "Adds death placements alongside when someone dies. This is only for when two people die at the same time.");
deathPlacementWindow = ((BaseUnityPlugin)MainPlugin.Instance).Config.Bind<int>("DeathOverrides", "deathPlacementWindow", 300, "The window in which a number of people can die at the same time. The lowest value acceptable is 1. I'll probably do an override check because people don't read lmao.");
}
}
[BepInPlugin("lc.zapajax.whodiedfirst", "Who Died First", "0.1.1")]
public class MainPlugin : BaseUnityPlugin
{
private const string GUID = "lc.zapajax.whodiedfirst";
private const string NAME = "Who Died First";
private const string VERSION = "0.1.1";
private readonly Harmony harmony = new Harmony("lc.zapajax.whodiedfirst");
public static MainPlugin Instance;
public static LogHandler lh;
public GameObject netManagerPrefab;
public static List<SimplePlayer> deathOrder = new List<SimplePlayer>();
public static string wdfLastRound = "";
public static string planetName;
public static bool isOnPlanet = false;
public void Awake()
{
Instance = this;
lh = new LogHandler(((BaseUnityPlugin)this).Logger);
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
Type[] array = types;
foreach (Type type in array)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo[] array2 = methods;
foreach (MethodInfo methodInfo in array2)
{
object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
if (customAttributes.Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
ConfigSettings.BindConfigSettings();
lh.Log("Finished Binding Config File");
string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "netcode-wdf");
AssetBundle val = AssetBundle.LoadFromFile(text);
netManagerPrefab = val.LoadAsset<GameObject>("Assets/NetcodeObjs/NetcodeObj-WDF.prefab");
netManagerPrefab.AddComponent<NetcodeManager>();
harmony.PatchAll(typeof(ElevatorAnimationEventsPatch));
harmony.PatchAll(typeof(GameNetworkManagerPatch));
harmony.PatchAll(typeof(HUDManagerPatch));
harmony.PatchAll(typeof(PlayerControllerBPatch));
harmony.PatchAll(typeof(StartOfRoundPatch));
lh.Log("Finished Loading");
}
}
}
namespace WhoDiedFirst.Patches
{
[HarmonyPatch(typeof(ElevatorAnimationEvents))]
internal class ElevatorAnimationEventsPatch
{
[HarmonyPatch("ElevatorFullyRunning")]
[HarmonyPrefix]
private static void UpdateDeathOrderOnAbandoned(ElevatorAnimationEvents __instance)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Invalid comparison between Unknown and I4
if (!ConfigSettings.includeAbandoned.Value || GameNetworkManager.Instance.localPlayerController.isInElevator || MainPlugin.planetName == "71 Gordion" || (int)GameNetworkManager.Instance.localPlayerController.causeOfDeath != 10)
{
return;
}
ulong actualClientId = GameNetworkManager.Instance.localPlayerController.actualClientId;
long timeOfDeath = DateTimeOffset.Now.ToUnixTimeMilliseconds() / ConfigSettings.deathPlacementWindow.Value;
if (((NetworkBehaviour)StartOfRound.Instance).IsHost || ((NetworkBehaviour)StartOfRound.Instance).IsServer)
{
NetcodeManager.Instance.UpdateDeathOrderClientRpc(actualClientId, timeOfDeath);
return;
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Notifying Server");
}
Utilities.addToDeathOrder(actualClientId, timeOfDeath, cache: true);
NetcodeManager.Instance.UpdateDeathOrderServerRpc(actualClientId, timeOfDeath);
}
}
[HarmonyPatch(typeof(GameNetworkManager))]
internal class GameNetworkManagerPatch
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void AddToPrefabs(ref GameNetworkManager __instance)
{
((Component)__instance).GetComponent<NetworkManager>().AddNetworkPrefab(MainPlugin.Instance.netManagerPrefab);
}
}
[HarmonyPatch(typeof(HUDManager))]
internal class HUDManagerPatch
{
[HarmonyPatch("UpdateBoxesSpectateUI")]
[HarmonyPrefix]
public static bool UpdateBoxesSpectateUIPatcher(HUDManager __instance, ref Dictionary<Animator, PlayerControllerB> ___spectatingPlayerBoxes, ref float ___yOffsetAmount, ref int ___boxesAdded, ref GameObject ___spectatingPlayerBoxPrefab, ref Transform ___SpectateBoxesContainer)
{
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0539: Unknown result type (might be due to invalid IL or missing references)
//IL_0545: Unknown result type (might be due to invalid IL or missing references)
//IL_0289: Unknown result type (might be due to invalid IL or missing references)
//IL_0482: Unknown result type (might be due to invalid IL or missing references)
//IL_0304: Unknown result type (might be due to invalid IL or missing references)
//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
if (!ConfigSettings.overrideScoreboard.Value)
{
return true;
}
MethodInfo methodInfo = AccessTools.Method(typeof(HUDManager), "FillImageWithSteamProfile", (Type[])null, (Type[])null);
PlayerControllerB[] array = Utilities.orderPlayerScriptsByDeath(StartOfRound.Instance.allPlayerScripts);
PlayerControllerB playerScript;
for (int i = 0; i < array.Length; i++)
{
playerScript = array[i];
string text = Utilities.playerStatus(playerScript);
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(" -Name: " + playerScript.playerUsername + " - status: " + text);
}
if (text != "dead" && text != "disconnected")
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(" - Alive");
}
continue;
}
if (!___spectatingPlayerBoxes.Values.Contains(playerScript))
{
if (text == "disconnected" && !ConfigSettings.includeDisconnects.Value)
{
continue;
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(" - New Spectator");
}
GameObject val = Object.Instantiate<GameObject>(___spectatingPlayerBoxPrefab, ___SpectateBoxesContainer, false);
val.SetActive(true);
RectTransform component = val.GetComponent<RectTransform>();
component.anchoredPosition = new Vector2(component.anchoredPosition.x, ___yOffsetAmount);
___yOffsetAmount -= 70f;
___boxesAdded++;
___spectatingPlayerBoxes.Add(val.GetComponent<Animator>(), playerScript);
int num = Utilities.determineDeathPlacement(Utilities.indexOfIdInDeathOrder(playerScript.actualClientId));
string text2 = playerScript.playerUsername;
if (ConfigSettings.addDeathPlacementsToScoreboard.Value)
{
text2 = num + ": " + text2;
}
bool flag = false;
if (text == "disconnected" && ConfigSettings.addDCToScoreboard.Value)
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(" - is DC'd");
}
text2 += " [DC]";
flag = true;
}
((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).text = text2;
if (!GameNetworkManager.Instance.disableSteam && !flag)
{
RawImage component2 = val.GetComponent<RawImage>();
SteamId val2 = default(SteamId);
val2.Value = playerScript.playerSteamId;
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("playerScript.playerSteamId: " + playerScript.playerSteamId.GetType().ToString() + " - " + playerScript.playerSteamId);
}
methodInfo.Invoke(__instance, new object[3] { component2, val2, true });
}
continue;
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(" - Old Spectator");
}
Animator key = ___spectatingPlayerBoxes.FirstOrDefault((KeyValuePair<Animator, PlayerControllerB> x) => (Object)(object)x.Value == (Object)(object)playerScript).Key;
GameObject gameObject = ((Component)key).gameObject;
int num2 = Utilities.determineDeathPlacement(Utilities.indexOfIdInDeathOrder(playerScript.actualClientId));
string text3 = playerScript.playerUsername;
if (ConfigSettings.addDeathPlacementsToScoreboard.Value)
{
text3 = num2 + ": " + text3;
}
if (text == "disconnected" && ConfigSettings.includeDisconnects.Value && ConfigSettings.addDCToScoreboard.Value)
{
if (text3.IndexOf(" [DC]") == -1)
{
text3 += " [DC]";
}
}
else if (text == "disconnected" && !ConfigSettings.includeDisconnects.Value)
{
if (gameObject.activeSelf)
{
for (int j = 0; j < ___spectatingPlayerBoxes.Count; j++)
{
RectTransform component3 = ((Component)___spectatingPlayerBoxes.ElementAt(j).Key).gameObject.GetComponent<RectTransform>();
if (component3.anchoredPosition.y <= -70f * (float)___boxesAdded + 1f)
{
component3.anchoredPosition = new Vector2(component3.anchoredPosition.x, component3.anchoredPosition.y + 70f);
}
}
___yOffsetAmount += 70f;
}
___spectatingPlayerBoxes.Remove(key);
Object.Destroy((Object)(object)gameObject);
}
((TMP_Text)gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = text3;
if (!gameObject.activeSelf)
{
RectTransform component4 = gameObject.GetComponent<RectTransform>();
component4.anchoredPosition = new Vector2(component4.anchoredPosition.x, ___yOffsetAmount);
___boxesAdded++;
gameObject.SetActive(true);
___yOffsetAmount -= 70f;
}
}
return false;
}
[HarmonyPatch("SubmitChat_performed")]
[HarmonyPrefix]
private static bool lookForCmdStr(HUDManager __instance)
{
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0228: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_0243: Unknown result type (might be due to invalid IL or missing references)
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_024c: Unknown result type (might be due to invalid IL or missing references)
//IL_0253: Unknown result type (might be due to invalid IL or missing references)
//IL_0258: Unknown result type (might be due to invalid IL or missing references)
//IL_025d: Unknown result type (might be due to invalid IL or missing references)
//IL_0261: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
bool flag = false;
__instance.localPlayer = GameNetworkManager.Instance.localPlayerController;
string text = __instance.chatTextField.text.ToLower();
MethodInfo methodInfo = AccessTools.Method(typeof(HUDManager), "AddChatMessage", (Type[])null, (Type[])null);
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(text);
}
if (text == "/wdf")
{
flag = true;
string text2 = ((!(MainPlugin.wdfLastRound != "")) ? "No one died last round." : (MainPlugin.wdfLastRound + " died first last round."));
__instance.lastChatMessage = "";
methodInfo.Invoke(__instance, new object[2] { text2, "WDF" });
}
else if (text == "/status" && ConfigSettings.isDebug.Value)
{
flag = true;
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Planet: " + MainPlugin.planetName + " | IsOnPlanet: " + MainPlugin.isOnPlanet);
}
}
else if (text == "/kill" && ConfigSettings.isDebug.Value)
{
flag = true;
__instance.localPlayer.KillPlayer(default(Vector3), false, (CauseOfDeath)0, 0);
}
else if (text == "/ps" && ConfigSettings.isDebug.Value)
{
flag = true;
Utilities.printPlayerScripts();
}
else if (text == "/do" && ConfigSettings.isDebug.Value)
{
flag = true;
Utilities.printDeathOrder();
}
else if (text == "/lm" && ConfigSettings.isDebug.Value)
{
flag = true;
GameObject val = GameObject.FindGameObjectWithTag("MapPropsContainer");
GameObject prefabToSpawn = RoundManager.Instance.currentLevel.spawnableMapObjects[0].prefabToSpawn;
Vector3 position = ((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.position;
Vector3 forward = ((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.forward;
position += forward * 3f;
GameObject val2 = Object.Instantiate<GameObject>(prefabToSpawn, position, Quaternion.identity, val.transform);
val2.GetComponent<NetworkObject>().Spawn(true);
}
else if (text.StartsWith("/spawn ") && ConfigSettings.isDebug.Value)
{
flag = true;
text = text.Substring(7);
bool flag2 = false;
string text3 = "";
SelectableLevel currentLevel = RoundManager.Instance.currentLevel;
foreach (SpawnableEnemyWithRarity enemy in currentLevel.Enemies)
{
if (enemy.enemyType.enemyName.ToLower().Contains(text.ToLower()))
{
flag2 = true;
text3 = enemy.enemyType.enemyName;
SpawnEnemy(enemy, 1, inside: true);
MainPlugin.lh.Log("Spawned: " + enemy.enemyType.enemyName);
}
}
if (!flag2)
{
foreach (SpawnableEnemyWithRarity outsideEnemy in currentLevel.OutsideEnemies)
{
if (outsideEnemy.enemyType.enemyName.ToLower().Contains(text.ToLower()))
{
flag2 = true;
text3 = outsideEnemy.enemyType.enemyName;
SpawnEnemy(outsideEnemy, 1, inside: false);
MainPlugin.lh.Log("Spawned: " + outsideEnemy.enemyType.enemyName);
}
}
}
}
if (flag)
{
__instance.localPlayer.isTypingChat = false;
__instance.chatTextField.text = "";
EventSystem.current.SetSelectedGameObject((GameObject)null);
__instance.PingHUDElement(__instance.Chat, 2f, 1f, 0.2f);
((Behaviour)__instance.typingIndicator).enabled = false;
return false;
}
return true;
}
[HarmonyPatch("AddChatMessage")]
[HarmonyPostfix]
private static void ignoreLastCheckMessage(HUDManager __instance)
{
}
private static void SpawnEnemy(SpawnableEnemyWithRarity enemy, int amount, bool inside)
{
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if (inside)
{
RoundManager instance = RoundManager.Instance;
SelectableLevel currentLevel = RoundManager.Instance.currentLevel;
instance.SpawnEnemyOnServer(instance.allEnemyVents[Random.Range(0, instance.allEnemyVents.Length)].floorNode.position, instance.allEnemyVents[0].floorNode.eulerAngles.y, currentLevel.Enemies.IndexOf(enemy));
}
else
{
SelectableLevel currentLevel2 = RoundManager.Instance.currentLevel;
GameObject val = Object.Instantiate<GameObject>(currentLevel2.OutsideEnemies[currentLevel2.OutsideEnemies.IndexOf(enemy)].enemyType.enemyPrefab, GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length - 1)].transform.position, Quaternion.Euler(Vector3.zero));
val.gameObject.GetComponentInChildren<NetworkObject>().Spawn(true);
}
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class PlayerControllerBPatch
{
[HarmonyPatch("KillPlayer")]
[HarmonyPrefix]
private static void UpdateDeathOrderOnPlayerDeath(PlayerControllerB __instance)
{
if (!((NetworkBehaviour)__instance).IsOwner || __instance.isPlayerDead || !__instance.AllowPlayerDeath() || MainPlugin.planetName == "71 Gordion" || !MainPlugin.isOnPlanet)
{
return;
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Attempting Notification");
}
long timeOfDeath = DateTimeOffset.Now.ToUnixTimeMilliseconds() / ConfigSettings.deathPlacementWindow.Value;
if (((NetworkBehaviour)__instance).IsHost || ((NetworkBehaviour)__instance).IsServer)
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Notifying Client");
}
ulong actualClientId = __instance.actualClientId;
NetcodeManager.Instance.UpdateDeathOrderClientRpc(actualClientId, timeOfDeath);
}
else
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Notifying Server");
}
ulong actualClientId2 = __instance.actualClientId;
Utilities.addToDeathOrder(actualClientId2, timeOfDeath, cache: true);
NetcodeManager.Instance.UpdateDeathOrderServerRpc(actualClientId2, timeOfDeath);
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Going to the rest of the KillPlayer function");
}
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class StartOfRoundPatch
{
[HarmonyPatch("Start")]
[HarmonyPrefix]
private static void spawnNetManager(StartOfRound __instance)
{
if (((NetworkBehaviour)__instance).IsHost)
{
GameObject val = Object.Instantiate<GameObject>(MainPlugin.Instance.netManagerPrefab);
val.GetComponent<NetworkObject>().Spawn(false);
}
}
[HarmonyPatch("OnPlayerDC")]
[HarmonyPrefix]
private static void UpdateDeathOrderOnPlayerDC(StartOfRound __instance, ref int playerObjectNumber, ref ulong clientId)
{
if (!ConfigSettings.includeDisconnects.Value || !__instance.ClientPlayerList.ContainsKey(clientId) || ((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && clientId == GameNetworkManager.Instance.localPlayerController.actualClientId) || ((NetworkBehaviour)__instance).NetworkManager.ShutdownInProgress || (Object)(object)NetworkManager.Singleton == (Object)null || Utilities.isPlayerInDeathOrder(clientId) || MainPlugin.planetName == "71 Gordion" || !MainPlugin.isOnPlanet)
{
return;
}
long timeOfDeath = DateTimeOffset.Now.ToUnixTimeMilliseconds() / ConfigSettings.deathPlacementWindow.Value;
if (((NetworkBehaviour)__instance).IsHost || ((NetworkBehaviour)__instance).IsServer)
{
NetcodeManager.Instance.UpdateDeathOrderClientRpc(clientId, timeOfDeath);
return;
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Notifying Server");
}
Utilities.addToDeathOrder(clientId, timeOfDeath, cache: true);
NetcodeManager.Instance.UpdateDeathOrderServerRpc(clientId, timeOfDeath);
}
[HarmonyPatch("ResetStats")]
[HarmonyPostfix]
private static void clearDeathList(StartOfRound __instance)
{
MainPlugin.isOnPlanet = true;
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Planet Name: " + MainPlugin.planetName);
}
if (!(MainPlugin.planetName == "71 Gordion"))
{
MainPlugin.deathOrder.Clear();
}
}
[HarmonyPatch("WritePlayerNotes")]
[HarmonyPostfix]
private static void addFirstDeathToNotes(StartOfRound __instance, ref EndOfGameStats ___gameStats)
{
if (MainPlugin.planetName == "71 Gordion")
{
return;
}
List<SimplePlayer> deathOrder = MainPlugin.deathOrder;
if (deathOrder.Count == 0)
{
MainPlugin.wdfLastRound = "";
return;
}
List<SimplePlayer> list = new List<SimplePlayer>();
List<ulong> list2 = new List<ulong>();
for (int i = 0; i < deathOrder.Count; i++)
{
int num = Utilities.determineDeathPlacement(i);
if (num == 1)
{
list.Add(deathOrder[i]);
list2.Add(deathOrder[i].id);
}
if (num > 1)
{
break;
}
}
string text = list[0].name;
if (list.Count == 2)
{
text = text + " and " + list[1].name;
}
else if (list.Count > 2)
{
for (int j = 1; j < list.Count - 1; j++)
{
text = text + ", " + list[j].name;
}
if (list.Count > 1)
{
text = text + ", and " + list[list.Count - 1].name;
}
}
MainPlugin.wdfLastRound = text;
if (!ConfigSettings.addWDFNote.Value)
{
return;
}
for (int k = 0; k < __instance.allPlayerScripts.Length; k++)
{
string text2 = Utilities.playerStatus(__instance.allPlayerScripts[k]);
if (list2.Contains(__instance.allPlayerScripts[k].actualClientId) && text2 != "blank" && text2 != "na")
{
___gameStats.allPlayerStats[k].playerNotes.Add("Died First");
}
}
for (int l = 0; l < __instance.allPlayerScripts.Length; l++)
{
PlayerControllerB val = __instance.allPlayerScripts[l];
MainPlugin.lh.Log("Player: " + val.playerUsername);
List<string> playerNotes = ___gameStats.allPlayerStats[l].playerNotes;
for (int m = 0; m < playerNotes.Count; m++)
{
MainPlugin.lh.Log(" - " + playerNotes[m]);
}
}
}
[HarmonyPatch("ChangeLevel")]
[HarmonyPostfix]
private static void savePlanetNameOnChange(StartOfRound __instance)
{
MainPlugin.planetName = __instance.currentLevel.PlanetName;
}
[HarmonyPatch("EndOfGame")]
[HarmonyPostfix]
private static void LeftPlanet()
{
MainPlugin.isOnPlanet = true;
}
}
}
namespace WhoDiedFirst.Managers
{
internal class NetcodeManager : NetworkBehaviour
{
public static NetcodeManager Instance;
private void Awake()
{
Instance = this;
}
[ServerRpc(RequireOwnership = false)]
public void UpdateDeathOrderServerRpc(ulong id, long timeOfDeath)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: 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_0096: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
if (networkManager == null || !networkManager.IsListening)
{
return;
}
if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
{
ServerRpcParams val = default(ServerRpcParams);
FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3368827615u, val, (RpcDelivery)0);
BytePacker.WriteValueBitPacked(val2, id);
BytePacker.WriteValueBitPacked(val2, timeOfDeath);
((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3368827615u, val, (RpcDelivery)0);
}
if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Server to Client");
}
UpdateDeathOrderClientRpc(id, timeOfDeath);
}
}
[ClientRpc]
public void UpdateDeathOrderClientRpc(ulong id, long timeOfDeath)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: 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_0096: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
if (networkManager == null || !networkManager.IsListening)
{
return;
}
if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
{
ClientRpcParams val = default(ClientRpcParams);
FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(110921536u, val, (RpcDelivery)0);
BytePacker.WriteValueBitPacked(val2, id);
BytePacker.WriteValueBitPacked(val2, timeOfDeath);
((NetworkBehaviour)this).__endSendClientRpc(ref val2, 110921536u, val, (RpcDelivery)0);
}
if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Attempt add to Death Order");
}
Utilities.addToDeathOrder(id, timeOfDeath);
}
}
protected override void __initializeVariables()
{
((NetworkBehaviour)this).__initializeVariables();
}
[RuntimeInitializeOnLoadMethod]
internal static void InitializeRPCS_NetcodeManager()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
NetworkManager.__rpc_func_table.Add(3368827615u, new RpcReceiveHandler(__rpc_handler_3368827615));
NetworkManager.__rpc_func_table.Add(110921536u, new RpcReceiveHandler(__rpc_handler_110921536));
}
private static void __rpc_handler_3368827615(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
//IL_0023: 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_0043: 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)
NetworkManager networkManager = target.NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
ulong id = default(ulong);
ByteUnpacker.ReadValueBitPacked(reader, ref id);
long timeOfDeath = default(long);
ByteUnpacker.ReadValueBitPacked(reader, ref timeOfDeath);
target.__rpc_exec_stage = (__RpcExecStage)1;
((NetcodeManager)(object)target).UpdateDeathOrderServerRpc(id, timeOfDeath);
target.__rpc_exec_stage = (__RpcExecStage)0;
}
}
private static void __rpc_handler_110921536(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
//IL_0023: 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_0043: 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)
NetworkManager networkManager = target.NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
ulong id = default(ulong);
ByteUnpacker.ReadValueBitPacked(reader, ref id);
long timeOfDeath = default(long);
ByteUnpacker.ReadValueBitPacked(reader, ref timeOfDeath);
target.__rpc_exec_stage = (__RpcExecStage)2;
((NetcodeManager)(object)target).UpdateDeathOrderClientRpc(id, timeOfDeath);
target.__rpc_exec_stage = (__RpcExecStage)0;
}
}
protected internal override string __getTypeName()
{
return "NetcodeManager";
}
}
}
namespace WhoDiedFirst.Helpers
{
public class LogHandler
{
public ManualLogSource mls;
public LogHandler(ManualLogSource mls)
{
this.mls = mls;
}
public void Log(string msg)
{
long num = DateTimeOffset.Now.ToUnixTimeMilliseconds();
mls.LogInfo((object)(msg + " || " + num));
}
public void LogError(string msg)
{
long num = DateTimeOffset.Now.ToUnixTimeMilliseconds();
mls.LogError((object)(msg + " || " + num));
}
public void LogWarning(string msg)
{
long num = DateTimeOffset.Now.ToUnixTimeMilliseconds();
mls.LogWarning((object)(msg + " || " + num));
}
}
public class SimplePlayer
{
public ulong id { get; set; }
public string name { get; set; }
public long timeOfDeath { get; set; }
public PlayerControllerB playerScript { get; set; }
public bool isCached { get; set; }
public SimplePlayer(ulong id, string name, long timeOfDeath, PlayerControllerB playerScript, bool isCached = false)
{
this.id = id;
this.name = name;
this.timeOfDeath = timeOfDeath;
this.playerScript = playerScript;
this.isCached = isCached;
}
}
public class Utilities
{
public static int indexOfPlayerScript(ulong id, PlayerControllerB[] playerScripts)
{
for (int i = 0; i < playerScripts.Length; i++)
{
if (playerScripts[i].actualClientId == id)
{
return i;
}
}
return -1;
}
public static void addToDeathOrder(ulong id, long timeOfDeath, bool cache = false)
{
if (MainPlugin.planetName == "71 Gordion" || !MainPlugin.isOnPlanet)
{
return;
}
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
int num = indexOfPlayerScript(id, allPlayerScripts);
if (num < 0)
{
printPlayerScripts();
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.LogError("Something is wrong with the id. It returned: " + num + " - id: " + id);
}
return;
}
PlayerControllerB val = allPlayerScripts[num];
SimplePlayer item = new SimplePlayer(id, val.playerUsername, timeOfDeath, val, cache);
if (!isPlayerInDeathOrder(id))
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Add to Death Order");
}
int num2;
for (num2 = MainPlugin.deathOrder.Count - 1; num2 >= 0; num2--)
{
SimplePlayer simplePlayer = MainPlugin.deathOrder[num2];
if (simplePlayer.timeOfDeath <= timeOfDeath)
{
break;
}
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("On Insertion - idx: " + num2 + " - cahced: " + cache);
}
MainPlugin.deathOrder.Insert(num2 + 1, item);
}
else if (GameNetworkManager.Instance.localPlayerController.actualClientId == id && !cache)
{
for (int i = 0; i < MainPlugin.deathOrder.Count; i++)
{
if (MainPlugin.deathOrder[i].id == id)
{
MainPlugin.deathOrder[i].isCached = false;
}
}
}
printDeathOrder();
}
public static int indexOfIdInDeathOrder(ulong id)
{
List<SimplePlayer> deathOrder = MainPlugin.deathOrder;
for (int i = 0; i < deathOrder.Count; i++)
{
SimplePlayer simplePlayer = deathOrder[i];
if (simplePlayer.id == id)
{
return i;
}
}
return -1;
}
public static int determineDeathPlacement(int idx)
{
List<SimplePlayer> deathOrder = MainPlugin.deathOrder;
int num = 0;
long num2 = 0L;
for (int i = 0; i <= idx; i++)
{
SimplePlayer simplePlayer = deathOrder[i];
if (num2 == 0L || num2 != simplePlayer.timeOfDeath)
{
num2 = simplePlayer.timeOfDeath;
num++;
}
}
if (num == 0)
{
num = -1;
}
return num;
}
public static void printDeathOrder()
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Printing Death Order");
}
for (int i = 0; i < MainPlugin.deathOrder.Count; i++)
{
SimplePlayer simplePlayer = MainPlugin.deathOrder[i];
string text = "-Player: " + simplePlayer.name;
text = text + " -id: " + simplePlayer.id;
text = text + " -tod: " + simplePlayer.timeOfDeath;
if ((Object)(object)simplePlayer.playerScript != (Object)null)
{
text = text + " -status: " + playerStatus(simplePlayer.playerScript);
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(text);
}
}
}
public static void printPlayerScripts()
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Printing Player Scripts");
}
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
for (int i = 0; i < allPlayerScripts.Length; i++)
{
PlayerControllerB val = allPlayerScripts[i];
string text = "";
text = text + " -idx: " + i;
text = text + " -name: " + val.playerUsername;
text = text + " -id: " + val.actualClientId;
text = text + " -pId: " + val.playerClientId;
text = text + " -status: " + playerStatus(val);
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(text);
}
}
}
public static PlayerControllerB[] orderPlayerScriptsByDeath(PlayerControllerB[] playerScripts)
{
PlayerControllerB[] array = (PlayerControllerB[])(object)new PlayerControllerB[playerScripts.Length];
PlayerControllerB[] array2 = (PlayerControllerB[])playerScripts.Clone();
List<SimplePlayer> deathOrder = MainPlugin.deathOrder;
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Start of Ordering");
}
int i;
for (i = 0; i < deathOrder.Count; i++)
{
SimplePlayer simplePlayer = deathOrder[i];
int num = indexOfPlayerScript(simplePlayer.id, playerScripts);
array[i] = playerScripts[num];
array2[num] = null;
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("Midpoint of Ordering");
}
for (int j = 0; j < playerScripts.Length; j++)
{
if (!((Object)(object)array2[j] == (Object)null))
{
array[i] = array2[j];
i++;
}
}
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log("End of Ordering");
}
return array;
}
public static string playerStatus(PlayerControllerB playerScript)
{
if (playerScript.disconnectedMidGame)
{
return "disconnected";
}
if (playerScript.isPlayerDead && !playerScript.isPlayerControlled)
{
return "dead";
}
if (!playerScript.isPlayerDead && playerScript.isPlayerControlled)
{
return "living";
}
if (!playerScript.isPlayerDead && !playerScript.isPlayerControlled)
{
return "blank";
}
return "na";
}
public static void printInfo(PlayerControllerB playerScript)
{
if (ConfigSettings.isDebug.Value)
{
MainPlugin.lh.Log(playerScript.playerUsername + " Status: " + playerStatus(playerScript));
}
}
public static bool isPlayerInDeathOrder(ulong id)
{
List<SimplePlayer> deathOrder = MainPlugin.deathOrder;
for (int i = 0; i < deathOrder.Count; i++)
{
if (deathOrder[i].id == id)
{
return true;
}
}
return false;
}
}
}
namespace WhoDiedFirst.NetcodePatcher
{
[AttributeUsage(AttributeTargets.Module)]
internal class NetcodePatchedAssemblyAttribute : Attribute
{
}
}