Please disclose if your mod was created primarily 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 ImperiumEvents v1.0.0
ImperiumEvents.dll
Decompiled 4 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("RavenwoodRandomRelics")] [assembly: AssemblyDescription("A Valheim mod that adds custom relics, statues, and decor.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("James Jones TV")] [assembly: AssemblyProduct("Ravenwood Random Relics Mod")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("2.2.2")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.2.0")] namespace ImperiumEvents; public class FinishRuneInteract : MonoBehaviour, Hoverable, Interactable { private Piece m_piece; private void Awake() { m_piece = ((Component)this).GetComponent<Piece>(); } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null || (Object)(object)ImperiumTriathlonManager.Instance == (Object)null) { return false; } ImperiumTriathlonManager.Instance.RequestFinish(val); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverText() { string text = (((Object)(object)m_piece != (Object)null) ? m_piece.m_name : "Finish Rune"); return text + "\n[<color=yellow><b>E</b></color>] Finish Race"; } public string GetHoverName() { return ((Object)(object)m_piece != (Object)null) ? m_piece.m_name : "Finish Rune"; } } public class HornInteract : MonoBehaviour, Hoverable, Interactable { private ZSFX m_sfx; private Piece m_piece; private ZNetView m_nview; private void Awake() { m_sfx = ((Component)this).GetComponent<ZSFX>(); m_piece = ((Component)this).GetComponent<Piece>(); m_nview = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)m_nview != (Object)null) { m_nview.Register("ImperiumHornSound", (Action<long>)RPC_PlayHorn); } } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null || (Object)(object)ImperiumTriathlonManager.Instance == (Object)null) { return false; } if (!ImperiumTriathlonManager.Instance.IsConfiguredAdmin(val)) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, "Only configured admin can start the race.", 0, (Sprite)null, false); } return false; } if ((Object)(object)m_nview != (Object)null) { m_nview.InvokeRPC(ZNetView.Everybody, "ImperiumHornSound", Array.Empty<object>()); } ImperiumTriathlonManager.Instance.RequestStartRace(val); return true; } private void RPC_PlayHorn(long sender) { if ((Object)(object)m_sfx != (Object)null) { m_sfx.Play(); } } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverText() { string text = (((Object)(object)m_piece != (Object)null) ? m_piece.m_name : "Horn"); return text + "\n[<color=yellow><b>E</b></color>] Start Imperium Triathlon"; } public string GetHoverName() { return ((Object)(object)m_piece != (Object)null) ? m_piece.m_name : "Horn"; } } [BepInPlugin("Imperium.Events", "Imperium Events", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ImperiumEvents : BaseUnityPlugin { public const string PluginGUID = "Imperium.Events"; public const string PluginName = "Imperium Events"; public const string PluginVersion = "1.0.0"; private AssetBundle relicsBundle; public static ConfigEntry<string> PlayerPreferredCategory; public static ManualLogSource ModLogger; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) ModLogger = ((BaseUnityPlugin)this).Logger; new Harmony("imperium.events.harmony").PatchAll(); PlayerPreferredCategory = ((BaseUnityPlugin)this).Config.Bind<string>("General", "CustomHammerTab", "ImperiumEvents", "Custom hammer tab category name"); ImperiumTriathlonManager.Initialize(((BaseUnityPlugin)this).Config); ((Component)this).gameObject.AddComponent<ImperiumTriathlonManager>(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string r) => r.ToLower().Contains("imperium")); if (string.IsNullOrEmpty(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not find embedded asset bundle resource containing 'imperium'."); return; } using (Stream stream = executingAssembly.GetManifestResourceStream(text)) { if (stream == null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Embedded asset bundle stream was null for '" + text + "'.")); return; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); relicsBundle = AssetBundle.LoadFromMemory(memoryStream.ToArray()); } if ((Object)(object)relicsBundle == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load AssetBundle from embedded resource!"); return; } PrefabManager.OnPrefabsRegistered -= RegisterNow; PrefabManager.OnPrefabsRegistered += RegisterNow; } private void RegisterNow() { if (!((Object)(object)relicsBundle == (Object)null)) { RelicRegistrar.RegisterAllRelics(relicsBundle); ImperiumTriathlonBootstrap.AttachTriathlonComponents(((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ImperiumEvents] Registration complete. Hammer tab: '" + PlayerPreferredCategory.Value + "'.")); } } } public static class ImperiumTriathlonBootstrap { public static void AttachTriathlonComponents(ManualLogSource logger) { AttachIfFound("Imperium_Horn", typeof(HornInteract), logger); AttachIfFound("Start_Rune", typeof(StartRuneInteract), logger); AttachIfFound("Finish_Rune", typeof(FinishRuneInteract), logger); AttachIfFound("Imperium_Scoreboard", typeof(RaceScoreboard), logger); AttachNightLight(logger); } private static void AttachIfFound(string prefabName, Type componentType, ManualLogSource logger) { GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName); if ((Object)(object)prefab == (Object)null) { if (logger != null) { logger.LogWarning((object)("[ImperiumEvents] Prefab not found for triathlon hookup: " + prefabName)); } } else if ((Object)(object)prefab.GetComponent(componentType) == (Object)null) { prefab.AddComponent(componentType); if (logger != null) { logger.LogInfo((object)("[ImperiumEvents] Attached " + componentType.Name + " to " + prefabName + ".")); } } } private static void AttachNightLight(ManualLogSource logger) { GameObject prefab = PrefabManager.Instance.GetPrefab("Imperium_Scoreboard"); if ((Object)(object)prefab == (Object)null) { if (logger != null) { logger.LogWarning((object)"[ImperiumEvents] Imperium_Scoreboard prefab not found."); } return; } Transform val = prefab.transform.Find("NightLight"); if ((Object)(object)val == (Object)null) { if (logger != null) { logger.LogWarning((object)"[ImperiumEvents] NightLight child not found on Imperium_Scoreboard."); } } else if ((Object)(object)((Component)val).GetComponent<ScoreboardEmissionNight>() == (Object)null) { ((Component)val).gameObject.AddComponent<ScoreboardEmissionNight>(); if (logger != null) { logger.LogInfo((object)"[ImperiumEvents] Attached ScoreboardEmissionNight to NightLight."); } } } } public class ImperiumTriathlonManager : MonoBehaviour { [Serializable] private struct EntrantState { public string PlayerName; public bool Registered; public bool Finished; public double StartTime; public double FinishTime; } [Serializable] private class RaceResultsFile { public string EventName; public string SavedAt; public List<RaceResultEntry> Results = new List<RaceResultEntry>(); } [Serializable] private class RaceResultEntry { public string PlayerName; public float TimeSeconds; public string TimeFormatted; } private static class MiniJson { public static string Serialize(RaceResultsFile file) { if (file == null) { return "{}"; } string text = "{\n"; text = text + " \"EventName\": " + Quote(file.EventName) + ",\n"; text = text + " \"SavedAt\": " + Quote(file.SavedAt) + ",\n"; text += " \"Results\": [\n"; for (int i = 0; i < file.Results.Count; i++) { RaceResultEntry raceResultEntry = file.Results[i]; text += " {\n"; text = text + " \"PlayerName\": " + Quote(raceResultEntry.PlayerName) + ",\n"; text = text + " \"TimeSeconds\": " + raceResultEntry.TimeSeconds.ToString(CultureInfo.InvariantCulture) + ",\n"; text = text + " \"TimeFormatted\": " + Quote(raceResultEntry.TimeFormatted) + "\n"; text += " }"; if (i < file.Results.Count - 1) { text += ","; } text += "\n"; } text += " ]\n"; return text + "}"; } private static string Quote(string value) { if (value == null) { return "\"\""; } return "\"" + value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") .Replace("\r", "\\r") .Replace("\t", "\\t") + "\""; } } [CompilerGenerated] private sealed class <RegisterRpcsWhenReady>d__21 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ImperiumTriathlonManager <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RegisterRpcsWhenReady>d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (ZRoutedRpc.instance == null || (Object)(object)ZNet.instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } if (!<>4__this.rpcsRegistered) { ZRoutedRpc.instance.Register<string>("ImperiumTriathlon_Register", (Action<long, string>)<>4__this.RPC_Register); ZRoutedRpc.instance.Register<string>("ImperiumTriathlon_Finish", (Action<long, string>)<>4__this.RPC_Finish); ZRoutedRpc.instance.Register<string>("ImperiumTriathlon_StartRace", (Action<long, string>)<>4__this.RPC_StartRace); ZRoutedRpc.instance.Register<string>("ImperiumTriathlon_AdminReset", (Action<long, string>)<>4__this.RPC_AdminReset); ZRoutedRpc.instance.Register<string>("ImperiumTriathlon_BoardText", (Action<long, string>)<>4__this.RPC_BoardText); ZRoutedRpc.instance.Register<string>("ImperiumTriathlon_CenterMessage", (Action<long, string>)<>4__this.RPC_CenterMessage); ZRoutedRpc.instance.Register<string>("ImperiumTriathlon_ResultsPopup", (Action<long, string>)<>4__this.RPC_ResultsPopup); <>4__this.rpcsRegistered = true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ServerStartRaceCountdown>d__38 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ImperiumTriathlonManager <>4__this; private int <seconds>5__1; private List<string> <keys>5__2; private int <i>5__3; private List<string>.Enumerator <>s__4; private string <key>5__5; private EntrantState <state>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ServerStartRaceCountdown>d__38(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <keys>5__2 = null; <>s__4 = default(List<string>.Enumerator); <key>5__5 = null; <state>5__6 = default(EntrantState); <>1__state = -2; } private bool MoveNext() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.registrationOpen = false; <>4__this.BroadcastBoardText(<>4__this.BuildBoardText()); <seconds>5__1 = Mathf.Max(1, Mathf.RoundToInt(CountdownSeconds.Value)); <i>5__3 = <seconds>5__1; break; case 1: <>1__state = -1; <i>5__3--; break; } if (<i>5__3 >= 1) { <>4__this.BroadcastCenterMessage("Imperium Triathlon starts in " + <i>5__3); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } <>4__this.raceStarted = true; <>4__this.raceEnded = false; <>4__this.raceStartServerTime = Time.realtimeSinceStartupAsDouble; <keys>5__2 = <>4__this.entrants.Keys.ToList(); <>s__4 = <keys>5__2.GetEnumerator(); try { while (<>s__4.MoveNext()) { <key>5__5 = <>s__4.Current; <state>5__6 = <>4__this.entrants[<key>5__5]; <state>5__6.StartTime = <>4__this.raceStartServerTime; <state>5__6.FinishTime = 0.0; <state>5__6.Finished = false; <>4__this.entrants[<key>5__5] = <state>5__6; <state>5__6 = default(EntrantState); <key>5__5 = null; } } finally { ((IDisposable)<>s__4).Dispose(); } <>s__4 = default(List<string>.Enumerator); <>4__this.BroadcastCenterMessage("GO!"); <>4__this.BroadcastBoardText(<>4__this.BuildBoardText()); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static ImperiumTriathlonManager Instance; private const string RpcRegister = "ImperiumTriathlon_Register"; private const string RpcFinish = "ImperiumTriathlon_Finish"; private const string RpcStartRace = "ImperiumTriathlon_StartRace"; private const string RpcAdminReset = "ImperiumTriathlon_AdminReset"; private const string RpcBoardText = "ImperiumTriathlon_BoardText"; private const string RpcCenterMessage = "ImperiumTriathlon_CenterMessage"; private const string RpcResultsPopup = "ImperiumTriathlon_ResultsPopup"; private static ConfigEntry<string> AdminPlayerNames; private static ConfigEntry<string> ResultsFileName; private static ConfigEntry<float> CountdownSeconds; private static ConfigEntry<bool> RequireConfiguredAdminForStartAndReset; private readonly Dictionary<string, EntrantState> entrants = new Dictionary<string, EntrantState>(StringComparer.OrdinalIgnoreCase); private readonly List<RaceScoreboard> localBoards = new List<RaceScoreboard>(); private bool registrationOpen = true; private bool raceStarted = false; private bool raceEnded = false; private double raceStartServerTime = 0.0; private bool rpcsRegistered = false; public static void Initialize(ConfigFile config) { AdminPlayerNames = config.Bind<string>("Imperium Triathlon", "AdminPlayerNames", "Caenos", "Comma separated player names allowed to start/reset the event. Example: Caenos,James"); ResultsFileName = config.Bind<string>("Imperium Triathlon", "ResultsFileName", "ImperiumTriathlonResults.json", "JSON file written into BepInEx/config."); CountdownSeconds = config.Bind<float>("Imperium Triathlon", "CountdownSeconds", 5f, "Countdown before the race starts."); RequireConfiguredAdminForStartAndReset = config.Bind<bool>("Imperium Triathlon", "RequireConfiguredAdminForStartAndReset", true, "If true, only names in AdminPlayerNames can start/reset the race."); } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)this); return; } Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); ((MonoBehaviour)this).StartCoroutine(RegisterRpcsWhenReady()); } [IteratorStateMachine(typeof(<RegisterRpcsWhenReady>d__21))] private IEnumerator RegisterRpcsWhenReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RegisterRpcsWhenReady>d__21(0) { <>4__this = this }; } public void ForceEndRace() { if (ZNet.instance.IsServer()) { EndRace(); } } public void RegisterLocalBoard(RaceScoreboard board) { if (!((Object)(object)board == (Object)null) && !localBoards.Contains(board)) { localBoards.Add(board); board.SetBoardText(BuildBoardText()); } } public void UnregisterLocalBoard(RaceScoreboard board) { if (!((Object)(object)board == (Object)null)) { localBoards.Remove(board); } } public bool IsRaceStarted() { return raceStarted; } public bool IsRaceEnded() { return raceEnded; } public bool IsRegistrationOpen() { return registrationOpen && !raceStarted && !raceEnded; } public bool IsConfiguredAdmin(Player player) { return (Object)(object)player != (Object)null && IsConfiguredAdmin(player.GetPlayerName()); } public bool IsConfiguredAdmin(string playerName) { if (!RequireConfiguredAdminForStartAndReset.Value) { return true; } if (string.IsNullOrWhiteSpace(playerName)) { return false; } string[] source = (from x in AdminPlayerNames.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select x.Trim() into x where !string.IsNullOrWhiteSpace(x) select x).ToArray(); return source.Any((string x) => string.Equals(x, playerName, StringComparison.OrdinalIgnoreCase)); } public void RequestRegister(Player player) { if (!((Object)(object)player == (Object)null) && ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null)) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ImperiumTriathlon_Register", new object[1] { player.GetPlayerName() }); } } public void RequestFinish(Player player) { if (!((Object)(object)player == (Object)null) && ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null)) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ImperiumTriathlon_Finish", new object[1] { player.GetPlayerName() }); } } public void RequestStartRace(Player player) { if (!((Object)(object)player == (Object)null) && ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null)) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ImperiumTriathlon_StartRace", new object[1] { player.GetPlayerName() }); } } public void RequestAdminReset(Player player) { if (!((Object)(object)player == (Object)null) && ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null)) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ImperiumTriathlon_AdminReset", new object[1] { player.GetPlayerName() }); } } private void RPC_Register(long sender, string playerName) { if (!ZNet.instance.IsServer()) { return; } if (raceStarted) { BroadcastCenterMessage("Race already started."); } else if (raceEnded) { BroadcastCenterMessage("Race ended. Admin must reset the event."); } else if (!string.IsNullOrWhiteSpace(playerName)) { if (!entrants.ContainsKey(playerName)) { entrants.Add(playerName, new EntrantState { PlayerName = playerName, Registered = true, Finished = false, StartTime = 0.0, FinishTime = 0.0 }); BroadcastCenterMessage(playerName + " joined the Imperium Triathlon."); } else { BroadcastCenterMessage(playerName + " is already registered."); } BroadcastBoardText(BuildBoardText()); } } private void RPC_Finish(long sender, string playerName) { if (!ZNet.instance.IsServer() || !raceStarted || raceEnded || string.IsNullOrWhiteSpace(playerName)) { return; } if (!entrants.TryGetValue(playerName, out var value)) { BroadcastCenterMessage(playerName + " is not registered."); return; } if (value.Finished) { BroadcastCenterMessage(playerName + " already finished."); return; } value.Finished = true; value.FinishTime = Time.realtimeSinceStartupAsDouble - raceStartServerTime; entrants[playerName] = value; BroadcastCenterMessage(playerName + " finished in " + FormatTime(value.FinishTime)); BroadcastBoardText(BuildBoardText()); if (entrants.Count > 0 && entrants.Values.All((EntrantState x) => x.Finished)) { EndRace(); } } private void RPC_StartRace(long sender, string playerName) { if (ZNet.instance.IsServer()) { if (raceStarted) { BroadcastCenterMessage("Race already started."); } else if (raceEnded) { BroadcastCenterMessage("Race ended. Admin must reset the event."); } else if (entrants.Count == 0) { BroadcastCenterMessage("No registered players."); } else if (!IsConfiguredAdmin(playerName)) { BroadcastCenterMessage("Only configured admin players can start the race."); } else { ((MonoBehaviour)this).StartCoroutine(ServerStartRaceCountdown()); } } } private void RPC_AdminReset(long sender, string playerName) { if (ZNet.instance.IsServer()) { if (!raceEnded) { BroadcastCenterMessage("Race is not in ended state."); return; } if (!IsConfiguredAdmin(playerName)) { BroadcastCenterMessage("Only configured admin players can reset the race."); return; } ResetRaceServer(); BroadcastCenterMessage("Imperium Triathlon reset. Registration is open."); BroadcastBoardText(BuildBoardText()); } } [IteratorStateMachine(typeof(<ServerStartRaceCountdown>d__38))] private IEnumerator ServerStartRaceCountdown() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ServerStartRaceCountdown>d__38(0) { <>4__this = this }; } private void EndRace() { raceStarted = false; raceEnded = true; registrationOpen = false; string text = BuildResultsPopupText(); BroadcastBoardText(BuildBoardText()); BroadcastResultsPopup(text); SaveResultsJson(); } private void ResetRaceServer() { entrants.Clear(); registrationOpen = true; raceStarted = false; raceEnded = false; raceStartServerTime = 0.0; } private void BroadcastBoardText(string text) { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ImperiumTriathlon_BoardText", new object[1] { text ?? string.Empty }); } } private void BroadcastCenterMessage(string text) { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ImperiumTriathlon_CenterMessage", new object[1] { text ?? string.Empty }); } } private void BroadcastResultsPopup(string text) { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ImperiumTriathlon_ResultsPopup", new object[1] { text ?? string.Empty }); } } private void RPC_BoardText(long sender, string text) { for (int num = localBoards.Count - 1; num >= 0; num--) { if ((Object)(object)localBoards[num] == (Object)null) { localBoards.RemoveAt(num); } else { localBoards[num].SetBoardText(text); } } } private void RPC_CenterMessage(long sender, string text) { if ((Object)(object)MessageHud.instance != (Object)null && !string.IsNullOrWhiteSpace(text)) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false); } } private void RPC_ResultsPopup(long sender, string text) { if ((Object)(object)MessageHud.instance != (Object)null && !string.IsNullOrWhiteSpace(text)) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false); } } private string BuildBoardText() { if (raceEnded) { List<EntrantState> list = entrants.Values.OrderBy((EntrantState x) => x.FinishTime).ToList(); string text = "IMPERIUM TRIATHLON\n\nRESULTS"; for (int i = 0; i < list.Count; i++) { text = text + "\n" + (i + 1) + ". " + list[i].PlayerName + " " + FormatTime(list[i].FinishTime); } return text + "\n\nAdmin touch Start Rune to reset"; } if (raceStarted) { List<EntrantState> list2 = (from x in entrants.Values where x.Finished orderby x.FinishTime select x).ToList(); List<EntrantState> list3 = (from x in entrants.Values where !x.Finished orderby x.PlayerName select x).ToList(); string text2 = "IMPERIUM TRIATHLON\n\nRACE LIVE"; if (list2.Count > 0) { text2 += "\n\nFINISHED"; for (int j = 0; j < list2.Count; j++) { text2 = text2 + "\n" + (j + 1) + ". " + list2[j].PlayerName + " " + FormatTime(list2[j].FinishTime); } } if (list3.Count > 0) { text2 += "\n\nRACING"; for (int k = 0; k < list3.Count; k++) { text2 = text2 + "\n- " + list3[k].PlayerName; } } return text2; } string text3 = "IMPERIUM TRIATHLON\n\nREGISTERED PLAYERS"; if (entrants.Count == 0) { text3 += "\n\nWaiting for racers..."; } else { int num = 1; foreach (EntrantState item in entrants.Values.OrderBy((EntrantState x) => x.PlayerName)) { text3 = text3 + "\n" + num + ". " + item.PlayerName; num++; } } text3 += "\n\nUse Start Rune to register"; return text3 + "\nUse Horn to start"; } private string BuildResultsPopupText() { List<EntrantState> list = entrants.Values.OrderBy((EntrantState x) => x.FinishTime).ToList(); string text = "IMPERIUM TRIATHLON RESULTS"; for (int i = 0; i < list.Count; i++) { text = text + "\n" + (i + 1) + ". " + list[i].PlayerName + " " + FormatTime(list[i].FinishTime); } return text; } private void SaveResultsJson() { try { RaceResultsFile file = new RaceResultsFile { EventName = "Imperium Triathlon", SavedAt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Results = (from x in entrants.Values orderby x.FinishTime select new RaceResultEntry { PlayerName = x.PlayerName, TimeSeconds = (float)x.FinishTime, TimeFormatted = FormatTime(x.FinishTime) }).ToList() }; string path = Path.Combine(Paths.ConfigPath, ResultsFileName.Value); string contents = MiniJson.Serialize(file); File.WriteAllText(path, contents); } catch (Exception ex) { Debug.LogError((object)("[Imperium Triathlon] Failed to save results JSON: " + ex)); } } private string FormatTime(double seconds) { return TimeSpan.FromSeconds(seconds).ToString("mm\\:ss\\.ff"); } } public class PlacementWatcher : MonoBehaviour { public List<GameObject> RegisterList; private void Start() { if (RegisterList != null && !RegisterList.Contains(((Component)this).gameObject)) { RegisterList.Add(((Component)this).gameObject); } } private void OnDestroy() { if (RegisterList != null) { RegisterList.Remove(((Component)this).gameObject); } } } public class RaceScoreboard : MonoBehaviour { private TMP_Text scoreText; private void Awake() { Transform val = ((Component)this).transform.Find("ScoreText"); if ((Object)(object)val != (Object)null) { scoreText = ((Component)val).GetComponent<TMP_Text>(); } if ((Object)(object)scoreText == (Object)null) { scoreText = ((Component)this).GetComponentInChildren<TMP_Text>(true); } if ((Object)(object)scoreText != (Object)null && string.IsNullOrWhiteSpace(scoreText.text)) { scoreText.text = "IMPERIUM TRIATHLON\n\nWaiting for race..."; } } private void OnEnable() { if ((Object)(object)ImperiumTriathlonManager.Instance != (Object)null) { ImperiumTriathlonManager.Instance.RegisterLocalBoard(this); } } private void Start() { if ((Object)(object)ImperiumTriathlonManager.Instance != (Object)null) { ImperiumTriathlonManager.Instance.RegisterLocalBoard(this); } } private void OnDisable() { if ((Object)(object)ImperiumTriathlonManager.Instance != (Object)null) { ImperiumTriathlonManager.Instance.UnregisterLocalBoard(this); } } public void SetBoardText(string text) { if ((Object)(object)scoreText != (Object)null) { scoreText.text = text; } } } public static class RelicConfigManager { private static string configPath = Path.Combine(Paths.ConfigPath, "ImperiumEvents.cfg"); public static void SaveConfig(string key, string value) { File.AppendAllText(configPath, key + "=" + value + "\n"); } public static string LoadConfig(string key) { if (!File.Exists(configPath)) { return null; } string[] array = File.ReadAllLines(configPath); foreach (string text in array) { if (text.StartsWith(key + "=")) { return text.Substring(key.Length + 1); } } return null; } } public class RelicRegistration { public string PrefabName; public string DisplayName; public RequirementConfig[] Requirements; public string Description; public int Comfort; public bool IsWerewolf; public bool IsHorn; public RelicRegistration(string prefab, string display, RequirementConfig[] reqs, string desc, int comfort = 0, bool isWerewolf = false, bool isHorn = false) { PrefabName = prefab; DisplayName = display; Requirements = reqs; Description = desc; Comfort = comfort; IsWerewolf = isWerewolf; IsHorn = isHorn; } } public static class RelicRegistrar { private static readonly List<GameObject> placedWerewolves = new List<GameObject>(); private static bool wasAlreadyRegistered = false; public static readonly List<RelicRegistration> AllRegistrations = new List<RelicRegistration> { new RelicRegistration("Start_Gate", "Start Gate", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("RoundLog", 10, 0, true), new RequirementConfig("FineWood", 5, 0, true) }, "Imperium event Start Gate."), new RelicRegistration("Finish_Gate", "Finish Gate", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("RoundLog", 10, 0, true), new RequirementConfig("FineWood", 5, 0, true) }, "Imperium event Start Gate."), new RelicRegistration("Welcome_Banner", "Welcome Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Imperium event banner."), new RelicRegistration("Imperium_Standing_Banner", "Imperium Standing Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Imperium event banner."), new RelicRegistration("Imperium_Hanging_Banner", "Imperium Hanging Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 3, 0, true) }, "Imperium event banner."), new RelicRegistration("Arrow_Left", "Left Arrow Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 3, 0, true) }, "Imperium event banner."), new RelicRegistration("Arrow_Right", "Right Arrow Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 3, 0, true) }, "Imperium event banner."), new RelicRegistration("Arrow_Straight", "Straight Arrow Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Imperium event banner."), new RelicRegistration("Safe_Zone", "Safe Zone Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Imperium event banner."), new RelicRegistration("Danger_Other", "Other kind of danger Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Imperium event banner."), new RelicRegistration("Danger_Troll", "Danger of Troll Banner", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Imperium event banner."), new RelicRegistration("Imperium_Horn", "Horn of Farting", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Imperium event banner."), new RelicRegistration("Start_Rune", "Start Registration", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "For player registration to the event."), new RelicRegistration("Finish_Rune", "Finish line", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "To stop timers."), new RelicRegistration("Imperium_Scoreboard", "Scoreboard", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("FineWood", 2, 0, true) }, "Timers.") }; public static void RegisterAllRelics(AssetBundle bundle) { if (wasAlreadyRegistered || (Object)(object)bundle == (Object)null) { return; } int num = 0; int num2 = 0; foreach (RelicRegistration allRegistration in AllRegistrations) { if (RegisterRelic(bundle, allRegistration)) { num++; } else { num2++; } } wasAlreadyRegistered = true; } private static bool RegisterRelic(AssetBundle bundle, RelicRegistration reg) { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Expected O, but got Unknown if ((Object)(object)bundle == (Object)null) { return false; } GameObject val = bundle.LoadAsset<GameObject>(reg.PrefabName); if ((Object)(object)val == (Object)null) { return false; } ((Object)val).name = reg.PrefabName; ZNetView val2 = val.GetComponent<ZNetView>(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent<ZNetView>(); } val2.m_persistent = true; val2.m_syncInitialScale = true; if (!Object.op_Implicit((Object)(object)val.GetComponent<ZSyncTransform>())) { val.AddComponent<ZSyncTransform>(); } Piece val3 = val.GetComponent<Piece>() ?? val.AddComponent<Piece>(); val3.m_name = reg.DisplayName; val3.m_description = reg.Description; val3.m_groundOnly = false; SFX_VFX_Registry.GetEffects(reg.PrefabName, out var vfxPlace, out var sfxPlace, out var destroyVFX, out var destroySFX); EffectList val4 = new EffectList(); List<EffectData> list = new List<EffectData>(); if ((Object)(object)vfxPlace != (Object)null) { list.Add(new EffectData { m_prefab = vfxPlace, m_enabled = true }); } if ((Object)(object)sfxPlace != (Object)null) { list.Add(new EffectData { m_prefab = sfxPlace, m_enabled = true }); } val4.m_effectPrefabs = list.ToArray(); val3.m_placeEffect = val4; WearNTear val5 = val.GetComponent<WearNTear>() ?? val.AddComponent<WearNTear>(); val5.m_health = 10000f; val5.m_noRoofWear = true; EffectList val6 = new EffectList(); List<EffectData> list2 = new List<EffectData>(); if ((Object)(object)destroyVFX != (Object)null) { list2.Add(new EffectData { m_prefab = destroyVFX, m_enabled = true }); } if ((Object)(object)destroySFX != (Object)null) { list2.Add(new EffectData { m_prefab = destroySFX, m_enabled = true }); } val6.m_effectPrefabs = list2.ToArray(); val5.m_destroyedEffect = val6; if (reg.Comfort > 0) { val3.m_comfort = reg.Comfort; } Sprite val7 = bundle.LoadAsset<Sprite>(reg.PrefabName); if ((Object)(object)val7 != (Object)null) { val3.m_icon = val7; } string craftingStation = "piece_workbench"; PieceConfig val8 = new PieceConfig { PieceTable = "Hammer", Category = ImperiumEvents.PlayerPreferredCategory.Value, CraftingStation = craftingStation, Requirements = reg.Requirements }; PieceManager.Instance.AddPiece(new CustomPiece(val, true, val8)); if (reg.IsWerewolf && (Object)(object)val.GetComponent<PlacementWatcher>() == (Object)null) { val.AddComponent<PlacementWatcher>().RegisterList = placedWerewolves; } return true; } } public class ScoreboardEmissionNight : MonoBehaviour { private Renderer rend; private Material mat; private Color originalEmission; private float nextCheckTime; private bool lastNightState; private void Awake() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) rend = ((Component)this).GetComponent<Renderer>(); if ((Object)(object)rend != (Object)null) { mat = rend.material; if (mat.HasProperty("_EmissionColor")) { originalEmission = mat.GetColor("_EmissionColor"); } } } private void Update() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mat == (Object)null || (Object)(object)EnvMan.instance == (Object)null || Time.time < nextCheckTime) { return; } nextCheckTime = Time.time + 2f; bool flag = EnvMan.IsNight(); if (flag != lastNightState) { lastNightState = flag; if (flag) { mat.SetColor("_EmissionColor", originalEmission); mat.EnableKeyword("_EMISSION"); } else { mat.SetColor("_EmissionColor", Color.black); mat.DisableKeyword("_EMISSION"); } } } } public static class SFX_VFX_Registry { private static readonly HashSet<string> MetalObjects = new HashSet<string>(); private static readonly HashSet<string> WoodObjects = new HashSet<string> { "Imperium_Standing_Banner", "Imperium_Hanging_Banner", "Start_Gate", "Finish_Gate", "Arrow_Left", "Arrow_Right", "Arrow_Straight", "Welcome_Banner", "Danger_Troll", "Danger_Other", "Safe_Zone", "Imperium_Horn", "Start_Rune", "Finish_Rune", "Imperium_Scoreboard" }; public static void GetEffects(string prefabName, out GameObject vfxPlace, out GameObject sfxPlace, out GameObject destroyVFX, out GameObject destroySFX) { if (MetalObjects.Contains(prefabName)) { ZNetScene instance = ZNetScene.instance; vfxPlace = ((instance != null) ? instance.GetPrefab("vfx_Place_stone") : null); ZNetScene instance2 = ZNetScene.instance; sfxPlace = ((instance2 != null) ? instance2.GetPrefab("sfx_build_hammer_metal") : null); ZNetScene instance3 = ZNetScene.instance; destroyVFX = ((instance3 != null) ? instance3.GetPrefab("vfx_destroyed") : null); ZNetScene instance4 = ZNetScene.instance; destroySFX = ((instance4 != null) ? instance4.GetPrefab("sfx_metal_blocked") : null); } else if (WoodObjects.Contains(prefabName)) { ZNetScene instance5 = ZNetScene.instance; vfxPlace = ((instance5 != null) ? instance5.GetPrefab("vfx_Place_wood") : null); ZNetScene instance6 = ZNetScene.instance; sfxPlace = ((instance6 != null) ? instance6.GetPrefab("sfx_build_hammer_wood") : null); ZNetScene instance7 = ZNetScene.instance; destroyVFX = ((instance7 != null) ? instance7.GetPrefab("vfx_destroyed") : null); ZNetScene instance8 = ZNetScene.instance; destroySFX = ((instance8 != null) ? instance8.GetPrefab("sfx_wood_break") : null); } else { ZNetScene instance9 = ZNetScene.instance; vfxPlace = ((instance9 != null) ? instance9.GetPrefab("vfx_Place_stone") : null); ZNetScene instance10 = ZNetScene.instance; sfxPlace = ((instance10 != null) ? instance10.GetPrefab("sfx_build_hammer_stone") : null); ZNetScene instance11 = ZNetScene.instance; destroyVFX = ((instance11 != null) ? instance11.GetPrefab("vfx_destroyed") : null); ZNetScene instance12 = ZNetScene.instance; destroySFX = ((instance12 != null) ? instance12.GetPrefab("sfx_rock_destroyed") : null); } } } public class StartRuneInteract : MonoBehaviour, Hoverable, Interactable { private Piece m_piece; private void Awake() { m_piece = ((Component)this).GetComponent<Piece>(); } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null || (Object)(object)ImperiumTriathlonManager.Instance == (Object)null) { return false; } if (ImperiumTriathlonManager.Instance.IsRaceEnded()) { if (!ImperiumTriathlonManager.Instance.IsConfiguredAdmin(val)) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, "Only configured admin can reset the event.", 0, (Sprite)null, false); } return false; } ImperiumTriathlonManager.Instance.RequestAdminReset(val); return true; } if (!ImperiumTriathlonManager.Instance.IsRegistrationOpen()) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, "Registration is closed.", 0, (Sprite)null, false); } return false; } ImperiumTriathlonManager.Instance.RequestRegister(val); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverText() { string text = (((Object)(object)m_piece != (Object)null) ? m_piece.m_name : "Start Rune"); if ((Object)(object)ImperiumTriathlonManager.Instance != (Object)null && ImperiumTriathlonManager.Instance.IsRaceEnded()) { return text + "\n[<color=yellow><b>E</b></color>] Admin Reset Event"; } return text + "\n[<color=yellow><b>E</b></color>] Register for Imperium Triathlon"; } public string GetHoverName() { return ((Object)(object)m_piece != (Object)null) ? m_piece.m_name : "Start Rune"; } }