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 RepoWebListener v1.0.8
RepoWebListener.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using MissionUtils; using REPOLib.Modules; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("PencilFoxStudios")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.7.0")] [assembly: AssemblyInformationalVersion("1.0.7+2607853c5147b08730f6f14bf26cb8677dee6520")] [assembly: AssemblyProduct("RepoWebListener")] [assembly: AssemblyTitle("RepoWebListener")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.7.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RepoWebListener { public class Dictionaries { public static readonly Dictionary<string, string> ItemPaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "Item Cart Medium", "items/Item Cart Medium" }, { "Item Cart Small", "items/Item Cart Small" }, { "Item Drone Battery", "items/Item Drone Battery" }, { "Item Drone Feather", "items/Item Drone Feather" }, { "Item Drone Indestructible", "items/Item Drone Indestructible" }, { "Item Drone Torque", "items/Item Drone Torque" }, { "Item Drone Zero Gravity", "items/Item Drone Zero Gravity" }, { "Item Extraction Tracker", "items/Item Extraction Tracker" }, { "Item Grenade Duct Taped", "items/Item Grenade Duct Taped" }, { "Item Grenade Explosive", "items/Item Grenade Explosive" }, { "Item Grenade Human", "items/Item Grenade Human" }, { "Item Grenade Shockwave", "items/Item Grenade Shockwave" }, { "Item Grenade Stun", "items/Item Grenade Stun" }, { "Item Gun Handgun", "items/Item Gun Handgun" }, { "Item Gun Shotgun", "items/Item Gun Shotgun" }, { "Item Gun Tranq", "items/Item Gun Tranq" }, { "Item Health Pack Large", "items/Item Health Pack Large" }, { "Item Health Pack Medium", "items/Item Health Pack Medium" }, { "Item Health Pack Small", "items/Item Health Pack Small" }, { "Item Melee Baseball Bat", "items/Item Melee Baseball Bat" }, { "Item Melee Frying Pan", "items/Item Melee Frying Pan" }, { "Item Melee Inflatable Hammer", "items/Item Melee Inflatable Hammer" }, { "Item Melee Sledge Hammer", "items/Item Melee Sledge Hammer" }, { "Item Melee Sword", "items/Item Melee Sword" }, { "Item Mine Explosive", "items/Item Mine Explosive" }, { "Item Mine Shockwave", "items/Item Mine Shockwave" }, { "Mine Stun", "items/Item Mine Stun" }, { "Item Orb Zero Gravity", "items/Item Orb Zero Gravity" }, { "Item Power Crystal", "items/Item Power Crystal" }, { "Item Rubber Duck", "items/Item Rubber Duck" }, { "Item Upgrade Map Player Count", "items/Item Upgrade Map Player Count" }, { "Item Upgrade Player Energy", "items/Item Upgrade Player Energy" }, { "Item Upgrade Player Extra Jump", "items/Item Upgrade Player Extra Jump" }, { "Item Upgrade Player Grab Range", "items/Item Upgrade Player Grab Range" }, { "Item Upgrade Player Grab Strength", "items/Item Upgrade Player Grab Strength" }, { "Item Upgrade Player Grab Throw", "items/Item Upgrade Player Grab Throw" }, { "Item Upgrade Player Health", "items/Item Upgrade Player Health" }, { "Item Upgrade Player Sprint Speed", "items/Item Upgrade Player Sprint Speed" }, { "Item Upgrade Player Tumble Launch", "items/Item Upgrade Player Tumble Launch" }, { "Item Valuable Tracker", "items/Item Valuable Tracker" } }; public static readonly Dictionary<string, string> ValuablePaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "Valuable Diamond", "valuables/01 tiny/Valuable Diamond" }, { "Valuable Emerald Bracelet", "valuables/01 tiny/Valuable Emerald Bracelet" }, { "Valuable Goblet", "valuables/01 tiny/Valuable Goblet" }, { "Valuable Ocarina", "valuables/01 tiny/Valuable Ocarina" }, { "Valuable Pocket Watch", "valuables/01 tiny/Valuable Pocket Watch" }, { "Valuable Uranium Mug", "valuables/01 tiny/Valuable Uranium Mug" }, { "Valuable Arctic Bonsai", "valuables/02 small/Valuable Arctic Bonsai" }, { "Valuable Arctic HDD", "valuables/02 small/Valuable Arctic HDD" }, { "Valuable Chomp Book", "valuables/02 small/Valuable Chomp Book" }, { "Valuable Crown", "valuables/02 small/Valuable Crown" }, { "Valuable Doll", "valuables/02 small/Valuable Doll" }, { "Valuable Frog", "valuables/02 small/Valuable Frog" }, { "Valuable Gem Box", "valuables/02 small/Valuable Gem Box" }, { "Valuable Globe", "valuables/02 small/Valuable Globe" }, { "Valuable Love Potion", "valuables/02 small/Valuable Love Potion" }, { "Valuable Money", "valuables/02 small/Valable Money" }, { "Valuable Music Box", "valuables/02 small/Valueable Music Box" }, { "Valuable Toy Monkey", "valuables/02 small/Vauble Toy Monkey" }, { "Valuable Uranium Plate", "valuables/02 small/Vauble Uranium Plate" }, { "Valuable Vase Small", "valuables/02 small/Valuable Vase Small" }, { "Valuable Arctic 3D Printer", "valuables/03 medium/Valuable Arctic 3D Printer" }, { "Valuable Arctic Laptop", "valuables/03 medium/Valuable Arctic Laptop" }, { "Valuable Arctic Propane Tank", "valuables/03 medium/Valuable Arctic Propane Tank" }, { "Valuable Arctic Sample Six Pack", "valuables/03 medium/Valuable Arctic Sample Six Pack" }, { "Valuable Arctic Sample", "valuables/03 medium/Valable Bottle" }, { "Valuable Bottle", "valuables/03 medium/Valable Bottle" }, { "Valuable Clown", "valuables/03 medium/Valueable Clown" }, { "Valuable Computer", "valuables/03 medium/Vauble Computer" }, { "Valuable Fan", "valuables/03 medium/Vauble Fan" }, { "Valuable Gramophone", "valuables/03 medium/Vauble Gramophone" }, { "Valuable Marble Table", "valuables/03 medium/Vauble Marble Table" }, { "Valuable Radio", "valuables/03 medium/Vauble Radio" }, { "Valuable Ship In Bottle", "valuables/03 medium/Vauble Ship in a bottle" }, { "Valuable Trophy", "valuables/03 medium/Vauble Trophy" }, { "Valuable Vase", "valuables/03 medium/Vauble Vase" }, { "Valuable Wizard Goblin Head", "valuables/03 medium/Vauble Wizard Goblin Head" }, { "Valuable Wizard Power Crystal", "valuables/03 medium/Vauble Wizard Power Crystal" }, { "Valuable Wizard Time Glass", "valuables/03 medium/Vauble Wizard Time Glass" }, { "Valuable Arctic Barrel", "valuables/04 big/Valuable Arctic Barrel" }, { "Valuable Arctic Big Sample", "valuables/04 big/Valuable Arctic Big Sample" }, { "Valuable Arctic Creature Leg", "valuables/04 big/Valuable Arctic Creature Leg" }, { "Valuable Arctic Flamethrower", "valuables/04 big/Valuable Arctic Flamethrower" }, { "Valuable Arctic Guitar", "valuables/04 big/Valuable Arctic Guitar" }, { "Valuable Arctic Sample Cooler", "valuables/04 big/Valuable Arctic Sample Cooler" }, { "Valuable Diamond Display", "valuables/04 big/Vauble Diamond Display" }, { "Valuable Ice Saw", "valuables/04 big/Vauble Ice Saw" }, { "Valuable Scream Doll", "valuables/04 big/Vauble Scream Doll" }, { "Valuable Television", "valuables/04 big/Vauble Television" }, { "Valuable Vase Big", "valuables/04 big/Vauble Vase Big" }, { "Valuable Wizard Cube Of Knowledge", "valuables/04 big/Vauble Wizard Cube of Knowledge" }, { "Valuable Wizard Master Potion", "valuables/04 big/Vauble Wizard Master Potion" }, { "Valuable Animal Crate", "valuables/05 wide/Vauble Animal Crate" }, { "Valuable Arctic Ice Block", "valuables/05 wide/Vauble Arctic Ice Block" }, { "Valuable Dinosaur", "valuables/05 wide/Vauble Dinosaur" }, { "Valuable Piano", "valuables/05 wide/Vauble Piano" }, { "Valuable Wizard Griffin Statue", "valuables/05 wide/Vauble Wizard Griffin Statue" }, { "Valuable Arctic Science Station", "valuables/06 tall/Vauble Arctic Science Station" }, { "Valuable Harp", "valuables/06 tall/Vauble Harp" }, { "Valuable Painting", "valuables/06 tall/Vauble Painting" }, { "Valuable Wizard Dumgolfs Staff", "valuables/06 tall/Vauble Wizard Dumgolfs Staff" }, { "Valuable Wizard Sword", "valuables/06 tall/Vauble Wizard Sword" }, { "Valuable Arctic Server Rack", "valuables/07 very tall/Vauble Arctic Server Rack" }, { "Valuable Golden Statue", "valuables/07 very tall/Valuable Golden Statue" }, { "Valuable Grandfather Clock", "valuables/07 very tall/Valuable Grandfather Clock" }, { "Valuable Wizard Broom", "valuables/07 very tall/Valuable Wizard Broom" } }; public static readonly Dictionary<string, string> EnemyPaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "Beamer", "Beamer" }, { "Duck", "Apex Predator" }, { "Robe", "Robe" }, { "Bowtie", "Bowtie" }, { "Floater", "Floater" }, { "Gnome", "Gnome" }, { "Hunter", "Hunter" }, { "Tumbler", "Chef" }, { "Thin Man", "Shadow Child" }, { "Slow Mouth", "Spewer" }, { "Upscream", "Upscream" }, { "Hidden", "Hidden" }, { "Bang", "Banger" }, { "Head", "Headman" }, { "Runner", "Reaper" }, { "Slow Walker", "Trudge" } }; } internal class Events { public class EAction { public string Name { get; set; } public List<string> TeaseMessages { get; set; } public bool IsForAll { get; set; } public PlayerAvatar Victim { get; set; } = null; public EType Type { get; set; } = EType.BAD; public bool IsForOnlyDeadPlayers { get; set; } = false; public bool IsForOnlyAlivePlayers { get; set; } = false; public Func<PlayerAvatar?, string[]> Action { get; set; } public EAction(string name, List<string> teaseMessages, bool isForAll, Func<PlayerAvatar?, string[]> action, bool isForOnlyDeadPlayers = false, bool isForOnlyAlivePlayers = false) { Name = name; TeaseMessages = teaseMessages; IsForAll = isForAll; Action = action; IsForOnlyDeadPlayers = isForOnlyDeadPlayers; IsForOnlyAlivePlayers = isForOnlyAlivePlayers; } public string[] Invoke(PlayerAvatar player = null) { if (IsForAll) { return Action(null); } if ((Object)(object)player == (Object)null) { return new string[1] { "Error: Player is null." }; } Victim = player; return Action(player); } } public enum EType { BAD, GOOD } public class Event { public EAction Action { get; set; } public string ChatterMessage { get; set; } public string Chatter { get; set; } public Event(EAction action, string chatterMessage, string chatter) { Action = action; ChatterMessage = chatterMessage; Chatter = chatter; } public static Event Generate(string chatter) { EType type = (EType)PencilUtils.Randomizer.Next(0, Enum.GetValues(typeof(EType)).Length); return Generate(chatter, type); } public static Event Generate(string chatter, EType type) { EAction eAction = ((type == EType.BAD) ? PossibleBadActions[PencilUtils.Randomizer.Next(PossibleBadActions.Count)] : PossibleGoodActions[PencilUtils.Randomizer.Next(PossibleGoodActions.Count)]); eAction.Type = type; string chatterMessage = chatter + ", you rolled a " + eAction.Name + " event! It has been added to the queue."; return new Event(eAction, chatterMessage, chatter); } public string GenerateTeaseMessage(string template, string[] args, PlayerAvatar? victim = null) { string text = template; text = text.Replace("%chatter%", Chatter); text = text.Replace("%victim%", victim.playerName); foreach (string text2 in args) { text = text.Replace("%" + args.ToList().IndexOf(text2) + "%", text2); } return text; } public string GenerateTeaseMessage(string template, string[] args) { string text = template; text = text.Replace("%chatter%", Chatter); foreach (string text2 in args) { text = text.Replace("%" + args.ToList().IndexOf(text2) + "%", text2); } return text; } public string Execute(PlayerAvatar player) { if (Action.IsForAll) { return "Error occurred: Action is for all players, but a specific player was provided."; } string[] args = Action.Invoke(player); string template = Action.TeaseMessages[PencilUtils.Randomizer.Next(Action.TeaseMessages.Count)]; return GenerateTeaseMessage(template, args, player); } public string Execute() { if (!Action.IsForAll) { return "Error occurred: Action is for a specific player, but no player was provided."; } string[] args = Action.Invoke(); string template = Action.TeaseMessages[PencilUtils.Randomizer.Next(Action.TeaseMessages.Count)]; return GenerateTeaseMessage(template, args); } public override string ToString() { return string.Format("Event: {0} ({1}), Chatter: {2}, ChatterMessage: {3}", Action.Name, Action.IsForAll ? "All" : ((string)(object)Action.Victim), Chatter, ChatterMessage); } } public static List<EAction> PossibleBadActions = new List<EAction>(); public static List<EAction> PossibleGoodActions = new List<EAction>(); public static Queue<Event> EventQueue = new Queue<Event>(); public static void Init() { if (PencilUtils.PencilConfig.BadEventDamageSpecific) { PossibleBadActions.Add(new EAction("Deal Damage", new List<string> { "<b>%chatter%</b> slaps <b>%victim%</b> across the face for <b>-%0%</b> HP!", "<b>%chatter%</b> throws a rock at <b>%victim%</b> for <b>-%0%</b> HP!", "<b>%victim%</b> couldn't avoid <b>%chatter%</b>'s Ford F150 and took <b>-%0%</b> HP!", "<b>%chatter%</b> wanted to play catch with <b>%victim%</b>, but threw the ball too hard and hit them for <b>-%0%</b> HP!" }, isForAll: false, delegate(PlayerAvatar? player) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } int num6 = PencilUtils.Randomizer.Next(PencilUtils.PencilConfig.BadEventDamageMinAmount, PencilUtils.PencilConfig.BadEventDamageMaxAmount); int num7 = num6; if (!PencilUtils.PencilConfig.BadEventDamageCanKill && player.playerHealth.health - num6 < 1) { num6 = ((player.playerHealth.health > 1) ? (player.playerHealth.health - 1) : 0); } player.playerHealth.HurtOther(num6, ((Component)player.playerHealth).transform.position, false, -1); return new string[1] { num7.ToString() }; }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.BadEventDamageAll) { PossibleBadActions.Add(new EAction("Deal Damage to All", new List<string> { "<b>%chatter%</b> threw a grenade and hurt everyone, with <b>%0%</b> getting hurt the most for <b>-%1%</b> HP!", "<b>%chatter%</b> bombed the whole facility, with <b>%0%</b> getting hurt the most for <b>-%1%</b> HP!", "Everyone lost a lot of health because of <b>%chatter%</b>, but <b>%0%</b> lost the most with <b>-%1%</b> HP!" }, isForAll: true, delegate { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar val3 = null; int num4 = 0; foreach (PlayerAvatar alivePlayer in PencilUtils.GetAlivePlayers()) { if (!Object.op_Implicit((Object)(object)val3)) { val3 = alivePlayer; } int num5 = PencilUtils.Randomizer.Next(PencilUtils.PencilConfig.BadEventDamageMinAmount, PencilUtils.PencilConfig.BadEventDamageMaxAmount); if (num5 > num4) { num4 = num5; val3 = alivePlayer; } if (!PencilUtils.PencilConfig.BadEventDamageCanKill && alivePlayer.playerHealth.health - num5 < 1) { num5 = ((alivePlayer.playerHealth.health > 1) ? (alivePlayer.playerHealth.health - 1) : 0); } alivePlayer.playerHealth.HurtOther(num5, ((Component)alivePlayer.playerHealth).transform.position, false, -1); } return ((Object)(object)val3 == (Object)null) ? new string[2] { "???", num4.ToString() } : new string[2] { val3.playerName, num4.ToString() }; }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.BadEventSpawnRandomEnemy) { PossibleBadActions.Add(new EAction("Spawn Random Enemy", new List<string> { "<b>%chatter%</b> summoned a <b>%0%</b> to attack <b>%victim%</b>!", "<b>%chatter%</b> called for help and a <b>%0%</b> appeared!", "<b>%chatter%</b> told a <b>%0%</b> that <b>%victim%</b> said something bad their mom!", "<b>%chatter%</b> threw a rock at a <b>%0%</b> and it thought <b>%victim%</b> did it!" }, isForAll: false, delegate(PlayerAvatar? player) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) string text3 = RepoWebListener.AllowedEnemies.Keys.ElementAt(PencilUtils.Randomizer.Next(RepoWebListener.AllowedEnemies.Count)); EnemySetup val2 = RepoWebListener.AllowedEnemies[text3]; if ((Object)(object)val2 == (Object)null) { RepoWebListener.Logger.LogError((object)("Enemy " + text3 + " not found. Cannot spawn.")); return new string[1] { "???" }; } Enemies.SpawnEnemy(val2, ((Component)player).transform.position + ((Component)player).transform.up * 0.2f, Quaternion.identity, false); return new string[1] { Dictionaries.EnemyPaths[text3] }; }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventHealAll) { PossibleGoodActions.Add(new EAction("Heal All", new List<string> { "<b>%chatter%</b> healed everyone a bit, but <b>%0%</b> got healed the most with +<b>%1%</b> HP!", "<b>%chatter%</b> used a splash potion, healing everyone with <b>%0%</b> getting healed the most! (+<b>%1%</b> HP)", "<b>%chatter%</b> used a health pack on <b>%0%</b> for +<b>%1%</b> HP, but it had a ripple effect on everyone else!" }, isForAll: true, delegate { PlayerAvatar val = null; int num2 = 0; foreach (PlayerAvatar alivePlayer2 in PencilUtils.GetAlivePlayers()) { if (!Object.op_Implicit((Object)(object)val)) { val = alivePlayer2; } int num3 = PencilUtils.Randomizer.Next(PencilUtils.PencilConfig.GoodEventHealMinAmount, PencilUtils.PencilConfig.GoodEventHealMaxAmount); if (num3 > num2) { num2 = num3; val = alivePlayer2; } alivePlayer2.playerHealth.HealOther(num3, true); } return ((Object)(object)val == (Object)null) ? new string[2] { "???", num2.ToString() } : new string[2] { val.playerName, num2.ToString() }; }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventHealSpecific) { PossibleGoodActions.Add(new EAction("Heal Specific", new List<string> { "<b>%chatter%</b> healed <b>%victim%</b> for +<b>%0%</b> HP!", "<b>%chatter%</b> used a health pack on <b>%victim%</b> for +<b>%0%</b> HP!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } int num = PencilUtils.Randomizer.Next(PencilUtils.PencilConfig.GoodEventHealMinAmount, PencilUtils.PencilConfig.GoodEventHealMaxAmount); player.playerHealth.HealOther(num, true); return new string[1] { num.ToString() }; })); } if (PencilUtils.PencilConfig.GoodEventSpawnRandomItem && PencilUtils.GetAllowedItems().Count > 0) { PossibleGoodActions.Add(new EAction("Spawn Random Item", new List<string> { "<b>%chatter%</b> bought a <b>%0%</b> for <b>%victim%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { RepoWebListener.Logger.LogError((object)"Player is null. Cannot spawn item."); return new string[1] { "???" }; } string text2 = RepoWebListener.AllowedItems.Keys.ElementAt(PencilUtils.Randomizer.Next(RepoWebListener.AllowedItems.Count)); Item itemThatContainsName = Items.GetItemThatContainsName(text2); if ((Object)(object)itemThatContainsName == (Object)null) { RepoWebListener.Logger.LogError((object)$"Item {text2} not found out of {Items.GetItems().Count} items. Cannot spawn."); ManualLogSource logger2 = RepoWebListener.Logger; Item? obj2 = Items.GetItems().FirstOrDefault(); logger2.LogError((object)("First item: " + ((obj2 != null) ? ((Object)obj2).name : null))); return new string[1] { "???" }; } Items.SpawnItem(itemThatContainsName, ((Component)player).transform.position + ((Component)player).transform.up * 0.2f, Quaternion.identity); return new string[1] { text2.Replace("Item ", "") }; }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventSpawnRandomValuable && PencilUtils.GetAllowedValuables().Count > 0) { PossibleGoodActions.Add(new EAction("Spawn Random Valuable", new List<string> { "<b>%chatter%</b> found a <b>%0%</b> and put it next to <b>%victim%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { RepoWebListener.Logger.LogError((object)"Player is null. Cannot spawn item."); return new string[1] { "???" }; } string text = RepoWebListener.AllowedValuables.Keys.ElementAt(PencilUtils.Randomizer.Next(RepoWebListener.AllowedValuables.Count)); ValuableObject valuableThatContainsName = Valuables.GetValuableThatContainsName(text); if ((Object)(object)valuableThatContainsName == (Object)null) { RepoWebListener.Logger.LogError((object)$"Valuable {text} not found out of {Valuables.GetValuables().Count} valuables. Cannot spawn."); ManualLogSource logger = RepoWebListener.Logger; GameObject? obj = Valuables.GetValuables().FirstOrDefault(); logger.LogError((object)("First valuable: " + ((obj != null) ? ((Object)obj).name : null))); return new string[1] { "???" }; } Valuables.SpawnValuable(valuableThatContainsName, ((Component)player).transform.position + ((Component)player).transform.up * 0.2f, Quaternion.identity); return new string[1] { text.Replace("Valuable ", "") }; }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } PunManager punManager = PunManager.instance; if (PencilUtils.PencilConfig.GoodEventUpgradeAllEnergy) { PossibleGoodActions.Add(new EAction("Upgrade All Energy", new List<string> { "<b>%chatter%</b> upgraded everyone's energy!", "<b>%chatter%</b> used a power crystal to upgrade everyone's energy!", "Everyone feels more energetic thanks to <b>%chatter%</b>!", "<b>%chatter%</b> bought an energy drink and shared it with everyone!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer3 in PencilUtils.GetAlivePlayers()) { punManager.UpgradePlayerEnergy(alivePlayer3.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificEnergy) { PossibleGoodActions.Add(new EAction("Upgrade Specific Energy", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s energy!", "<b>%chatter%</b> used a power crystal to upgrade <b>%victim%</b>'s energy!", "<b>%victim%</b> feels more energetic thanks to <b>%chatter%</b>!", "<b>%chatter%</b> bought an energy drink and shared it with <b>%victim%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradePlayerEnergy(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeAllHealth) { PossibleGoodActions.Add(new EAction("Upgrade All Health", new List<string> { "<b>%chatter%</b> upgraded everyone's health!", "Everyone feels healthier thanks to <b>%chatter%</b>!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer4 in PencilUtils.GetAlivePlayers()) { punManager.UpgradePlayerHealth(alivePlayer4.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificHealth) { PossibleGoodActions.Add(new EAction("Upgrade Specific Health", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s health!", "<b>%victim%</b> feels healthier thanks to <b>%chatter%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradePlayerHealth(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeAllGrabStrength) { PossibleGoodActions.Add(new EAction("Upgrade All Grab Strength", new List<string> { "<b>%chatter%</b> upgraded everyone's grab strength!", "Everyone feels stronger thanks to <b>%chatter%</b>!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer5 in PencilUtils.GetAlivePlayers()) { punManager.UpgradePlayerGrabStrength(alivePlayer5.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificGrabStrength) { PossibleGoodActions.Add(new EAction("Upgrade Specific Grab Strength", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s grab strength!", "<b>%victim%</b> feels stronger thanks to <b>%chatter%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradePlayerGrabStrength(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeAllRange) { PossibleGoodActions.Add(new EAction("Upgrade All Range", new List<string> { "<b>%chatter%</b> upgraded everyone's grab range!", "Everyone feels more agile thanks to <b>%chatter%</b>!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer6 in PencilUtils.GetAlivePlayers()) { punManager.UpgradePlayerGrabRange(alivePlayer6.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificRange) { PossibleGoodActions.Add(new EAction("Upgrade Specific Range", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s grab range!", "<b>%victim%</b> feels more agile thanks to <b>%chatter%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradePlayerGrabRange(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeAllExtraJump) { PossibleGoodActions.Add(new EAction("Upgrade All Extra Jump", new List<string> { "<b>%chatter%</b> upgraded everyone's extra jump!", "Everyone feels more jumpy thanks to <b>%chatter%</b>!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer7 in PencilUtils.GetAlivePlayers()) { punManager.UpgradePlayerExtraJump(alivePlayer7.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificExtraJump) { PossibleGoodActions.Add(new EAction("Upgrade Specific Extra Jump", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s extra jump!", "<b>%victim%</b> feels more jumpy thanks to <b>%chatter%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradePlayerExtraJump(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeAllSpeed) { PossibleGoodActions.Add(new EAction("Upgrade All Speed", new List<string> { "<b>%chatter%</b> upgraded everyone's speed!", "Everyone feels faster thanks to <b>%chatter%</b>!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer8 in PencilUtils.GetAlivePlayers()) { punManager.UpgradePlayerSprintSpeed(alivePlayer8.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificSpeed) { PossibleGoodActions.Add(new EAction("Upgrade Specific Speed", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s speed!", "<b>%victim%</b> feels faster thanks to <b>%chatter%</b>!", "<b>%chatter%</b> gave <b>%victim%</b> a speed boost!", "<b>%chatter%</b> is running CIRCLES around y'all!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradePlayerSprintSpeed(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeAllTumbleLaunch) { PossibleGoodActions.Add(new EAction("Upgrade All Tumble Launch", new List<string> { "<b>%chatter%</b> upgraded everyone's tumble launch!", "Everyone has stronger foreheads thanks to <b>%chatter%</b>!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer9 in PencilUtils.GetAlivePlayers()) { punManager.UpgradePlayerTumbleLaunch(alivePlayer9.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificTumbleLaunch) { PossibleGoodActions.Add(new EAction("Upgrade Specific Tumble Launch", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s tumble launch!", "<b>%victim%</b> has a stronger forehead thanks to <b>%chatter%</b>!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradePlayerTumbleLaunch(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeAllMapPlayerCount) { PossibleGoodActions.Add(new EAction("Upgrade All Map Player Count", new List<string> { "<b>%chatter%</b> upgraded everyone's map!", "<b>%chatter%</b> wanted to make sure everyone can see each other!", "<b>%chatter%</b> wants everyone to press TAB!" }, isForAll: true, delegate { foreach (PlayerAvatar alivePlayer10 in PencilUtils.GetAlivePlayers()) { punManager.UpgradeMapPlayerCount(alivePlayer10.steamID); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventUpgradeSpecificMapPlayerCount) { PossibleGoodActions.Add(new EAction("Upgrade Specific Map Player Count", new List<string> { "<b>%chatter%</b> upgraded <b>%victim%</b>'s map!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } punManager.UpgradeMapPlayerCount(player.steamID); return Array.Empty<string>(); }, isForOnlyDeadPlayers: false, isForOnlyAlivePlayers: true)); } if (PencilUtils.PencilConfig.GoodEventReviveAll && PencilUtils.GetDeadPlayers().Count > 0) { PossibleGoodActions.Add(new EAction("Revive All", new List<string> { "<b>%chatter%</b> revived everyone!", "Everyone is back to life thanks to <b>%chatter%</b>!" }, isForAll: true, delegate { foreach (PlayerAvatar deadPlayer in PencilUtils.GetDeadPlayers()) { deadPlayer.Revive(false); } return Array.Empty<string>(); }, isForOnlyDeadPlayers: true)); } if (!PencilUtils.PencilConfig.GoodEventReviveSpecific || PencilUtils.GetDeadPlayers().Count <= 0) { return; } PossibleGoodActions.Add(new EAction("Revive Specific", new List<string> { "<b>%chatter%</b> revived <b>%victim%</b>!", "<b>%victim%</b> is back to life thanks to <b>%chatter%</b>!", "<b>%chatter%</b> used a revive potion on <b>%victim%</b>!", "<b>%chatter%</b> brought <b>%victim%</b> back to life!", "<b>%chatter%</b> used a defibrillator on <b>%victim%</b>!", "<b>%chatter%</b> brought <b>%victim%</b> back from the dead!" }, isForAll: false, delegate(PlayerAvatar? player) { if ((Object)(object)player == (Object)null) { return new string[1] { "???" }; } player.Revive(false); return Array.Empty<string>(); }, isForOnlyDeadPlayers: true)); } public static string AddEventToQueueFrom(string chatter) { Event @event = Event.Generate(chatter); EventQueue.Enqueue(@event); RepoWebListener.Logger.LogInfo((object)$"Event added to queue: {@event}"); return @event.ChatterMessage; } public static void RunNextEvent() { //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) if (EventQueue.Count == 0) { return; } Event @event = EventQueue.Dequeue(); string text; if (!@event.Action.IsForAll) { Func<List<PlayerAvatar>> func = (@event.Action.IsForOnlyDeadPlayers ? new Func<List<PlayerAvatar>>(PencilUtils.GetDeadPlayers) : ((!@event.Action.IsForOnlyAlivePlayers) ? new Func<List<PlayerAvatar>>(PencilUtils.GetAllPlayers) : new Func<List<PlayerAvatar>>(PencilUtils.GetAlivePlayers))); List<PlayerAvatar> list = func(); if (list.Count == 0) { return; } PlayerAvatar player = func()[PencilUtils.Randomizer.Next(PencilUtils.GetAlivePlayers().Count)]; text = @event.Execute(player); } else { text = @event.Execute(); } RepoWebListener.Logger.LogInfo((object)string.Format("Event executed: {0} ({1})", @event.Action.Name, @event.Action.IsForAll ? "All" : ((string)(object)@event.Action.Victim))); RepoWebListener.Logger.LogInfo((object)("Result: " + text)); MissionOptions val = MissionOptions.Create((@event.Action.Type == EType.BAD) ? "<color=#CC250B>" : ("<color=#7DCC0B>" + text + "</color>"), Color.white, Color.white, (float)(PencilUtils.PencilConfig.MinimumTimeBetweenEvents - PencilUtils.PencilConfig.MinimumTimeBetweenEvents / 4)); MissionUI.instance.MissionText("%broadcast%" + ((@event.Action.Type == EType.BAD) ? "<color=#CC250B>" : "<color=#7DCC0B>") + text + "</color>", Color.white, Color.white, (float)(PencilUtils.PencilConfig.MinimumTimeBetweenEvents - PencilUtils.PencilConfig.MinimumTimeBetweenEvents / 4)); } } internal class PencilUtils { public static Random Randomizer = new Random(); public static RepoWebListenerConfigActivator PencilConfig { get; private set; } = null; public static void Initialize(RepoWebListenerConfigActivator config) { PencilConfig = config; } public static bool IsBlacklistedLevel() { HashSet<Level> hashSet = new HashSet<Level> { RunManager.instance.levelLobby, RunManager.instance.levelTutorial, RunManager.instance.levelLobbyMenu, RunManager.instance.levelMainMenu, RunManager.instance.levelRecording }; if (!PencilConfig.EnabledInShopLevel) { hashSet.Add(RunManager.instance.levelShop); } if (!PencilConfig.EnabledInArenaLevel) { hashSet.Add(RunManager.instance.levelArena); } return hashSet.Contains(RunManager.instance.levelCurrent); } public static List<PlayerAvatar> GetAllPlayers() { return SemiFunc.PlayerGetAll().ToList(); } public static List<PlayerAvatar> GetAlivePlayers() { List<PlayerAvatar> list = new List<PlayerAvatar>(); foreach (PlayerAvatar allPlayer in GetAllPlayers()) { if (allPlayer.playerHealth.health > 0) { list.Add(allPlayer); } } return list; } public static List<PlayerAvatar> GetDeadPlayers() { List<PlayerAvatar> list = new List<PlayerAvatar>(); foreach (PlayerAvatar allPlayer in GetAllPlayers()) { if (allPlayer.playerHealth.health <= 0) { list.Add(allPlayer); } } return list; } public static Dictionary<string, string> GetAllowedItems() { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); foreach (string key in PencilConfig.WhitelistedItems.Keys) { if (PencilConfig.WhitelistedItems[key].Value) { dictionary.Add(key, Dictionaries.ItemPaths[key]); } } return dictionary; } public static Dictionary<string, string> GetAllowedValuables() { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); foreach (string key in PencilConfig.WhitelistedValuables.Keys) { if (PencilConfig.WhitelistedValuables[key].Value) { dictionary.Add(key, Dictionaries.ValuablePaths[key]); } } return dictionary; } public static Dictionary<string, EnemySetup> GetAllowedEnemies() { List<EnemySetup> enemiesDifficulty = EnemyDirector.instance.enemiesDifficulty1; List<EnemySetup> enemiesDifficulty2 = EnemyDirector.instance.enemiesDifficulty2; List<EnemySetup> enemiesDifficulty3 = EnemyDirector.instance.enemiesDifficulty3; List<EnemySetup> list = new List<EnemySetup>(enemiesDifficulty.Count + enemiesDifficulty2.Count + enemiesDifficulty3.Count); list.AddRange(enemiesDifficulty); list.AddRange(enemiesDifficulty2); list.AddRange(enemiesDifficulty3); List<EnemySetup> source = list; Dictionary<string, EnemySetup> dictionary = new Dictionary<string, EnemySetup>(StringComparer.OrdinalIgnoreCase); foreach (string item in PencilConfig.WhitelistedEnemies.Keys) { if (PencilConfig.WhitelistedEnemies[item].Value) { EnemySetup val = ((IEnumerable<EnemySetup>)source).FirstOrDefault((Func<EnemySetup, bool>)((EnemySetup x) => ((Object)x).name == "Enemy - " + item)); if ((Object)(object)val != (Object)null) { dictionary.Add(item, val); } else { RepoWebListener.Logger.LogError((object)("Enemy " + item + " not found. Cannot add to allowed enemies.")); } } } return dictionary; } } [BepInPlugin("PencilFoxStudios.RepoWebListener", "RepoWebListener", "1.0.7")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RepoWebListener : BaseUnityPlugin { [CompilerGenerated] private sealed class <GoThroughChattersCoroutine>d__21 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public RepoWebListener <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GoThroughChattersCoroutine>d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } if (Events.EventQueue.Count == 0 || !SemiFunc.IsMultiplayer() || PencilUtils.IsBlacklistedLevel() || !LevelGenerator.Instance.Generated || ((!((Object)(object)RunManager.instance.levelArena == (Object)(object)RunManager.instance.levelCurrent) || !PencilUtils.PencilConfig.EnabledInArenaLevel) && RoundDirector.instance.extractionPointsCompleted == 0 && !RoundDirector.instance.extractionPointActive)) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } Events.RunNextEvent(); <>2__current = (object)new WaitForSeconds((float)Math.Max(PencilUtils.PencilConfig.MinimumTimeBetweenEvents, 3)); <>1__state = 2; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static HttpListener listener = new HttpListener(); private string url = "http://localhost"; private CancellationTokenSource cts = new CancellationTokenSource(); public static Dictionary<string, string> AllowedItems = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); public static Dictionary<string, string> AllowedValuables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); public static Dictionary<string, EnemySetup> AllowedEnemies = new Dictionary<string, EnemySetup>(StringComparer.OrdinalIgnoreCase); private static Dictionary<string, EnemySetup> enemySetups = new Dictionary<string, EnemySetup>(); internal static RepoWebListener Instance { get; private set; } = null; public static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); PencilUtils.Initialize(new RepoWebListenerConfigActivator(((BaseUnityPlugin)this).Config)); url = $"http://{PencilUtils.PencilConfig.WebServerListenIP}:{PencilUtils.PencilConfig.WebServerListenPort}/"; Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); if (PencilUtils.PencilConfig.WebServerEnabled) { Logger.LogInfo((object)"Starting web server..."); listener.Prefixes.Add(url); listener.Start(); Logger.LogInfo((object)("Listening on " + url)); } else { Logger.LogInfo((object)"Web server is disabled. Check the config file to enable it."); } Task.Run(() => ListenLoop(cts.Token)); ((MonoBehaviour)this).StartCoroutine(GoThroughChattersCoroutine()); } private void Start() { Logger.LogInfo((object)"RepoWebListener is ready!"); Events.Init(); } [IteratorStateMachine(typeof(<GoThroughChattersCoroutine>d__21))] private IEnumerator GoThroughChattersCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GoThroughChattersCoroutine>d__21(0) { <>4__this = this }; } private async Task ListenLoop(CancellationToken token) { try { while (!token.IsCancellationRequested) { HandleRequest(await listener.GetContextAsync()); } } catch (HttpListenerException ex3) { HttpListenerException ex2 = ex3; Logger.LogWarning((object)("Listener stopped: " + ex2.Message)); } catch (Exception ex4) { Exception ex = ex4; Logger.LogError((object)$"Error in ListenLoop: {ex}"); } } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void OnDestroy() { cts.Cancel(); if (listener.IsListening) { listener.Stop(); listener.Close(); } Unpatch(); } private void HandleRequest(HttpListenerContext context) { HttpListenerRequest request = context.Request; Logger.LogInfo((object)("Received " + request.HttpMethod + " request")); if (request.HttpMethod == "GET") { string chatter = request.QueryString["username"]; HttpListenerResponse response = context.Response; string s = Events.AddEventToQueueFrom(chatter); byte[] bytes = Encoding.UTF8.GetBytes(s); response.ContentLength64 = bytes.Length; response.OutputStream.Write(bytes, 0, bytes.Length); response.OutputStream.Close(); Logger.LogInfo((object)$"Chatters in queue: {Events.EventQueue.Count}"); } else { context.Response.StatusCode = 405; context.Response.Close(); } } private void Update() { } } internal class RepoWebListenerConfigActivator { private readonly ConfigEntry<int> webServerListenPort; private readonly ConfigEntry<string> webServerListenIP; private readonly ConfigEntry<bool> webServerEnabled; private readonly ConfigEntry<bool> enabledInShopLevel; private readonly ConfigEntry<bool> enabledInArenaLevel; private readonly ConfigEntry<bool> goodThings; private readonly ConfigEntry<int> minimumTimeBetweenEvents; private readonly ConfigEntry<bool> badThings; private readonly ConfigEntry<bool> goodEventHealAll; private readonly ConfigEntry<bool> goodEventHealSpecific; private readonly ConfigEntry<int> goodEventHealMinAmount; private readonly ConfigEntry<int> goodEventHealMaxAmount; private readonly ConfigEntry<bool> goodEventUpgradeAllEnergy; private readonly ConfigEntry<bool> goodEventUpgradeSpecificEnergy; private readonly ConfigEntry<bool> goodEventUpgradeAllHealth; private readonly ConfigEntry<bool> goodEventUpgradeSpecificHealth; private readonly ConfigEntry<bool> goodEventUpgradeAllGrabStrength; private readonly ConfigEntry<bool> goodEventUpgradeSpecificGrabStrength; private readonly ConfigEntry<bool> goodEventUpgradeAllRange; private readonly ConfigEntry<bool> goodEventUpgradeSpecificRange; private readonly ConfigEntry<bool> goodEventUpgradeAllSpeed; private readonly ConfigEntry<bool> goodEventUpgradeSpecificSpeed; private readonly ConfigEntry<bool> goodEventUpgradeAllExtraJump; private readonly ConfigEntry<bool> goodEventUpgradeSpecificExtraJump; private readonly ConfigEntry<bool> goodEventUpgradeAllTumbleLaunch; private readonly ConfigEntry<bool> goodEventUpgradeSpecificTumbleLaunch; private readonly ConfigEntry<bool> goodEventUpgradeAllMapPlayerCount; private readonly ConfigEntry<bool> goodEventUpgradeSpecificMapPlayerCount; private readonly ConfigEntry<bool> goodEventSpawnRandomItem; public Dictionary<string, ConfigEntry<bool>> WhitelistedItems = new Dictionary<string, ConfigEntry<bool>>(); private readonly ConfigEntry<bool> goodEventSpawnRandomValuable; private readonly ConfigEntry<bool> goodEventReviveSpecific; private readonly ConfigEntry<bool> goodEventReviveAll; public Dictionary<string, ConfigEntry<bool>> WhitelistedValuables = new Dictionary<string, ConfigEntry<bool>>(); private readonly ConfigEntry<bool> badEventDamageAll; private readonly ConfigEntry<bool> badEventDamageSpecific; private readonly ConfigEntry<int> badEventDamageMinAmount; private readonly ConfigEntry<int> badEventDamageMaxAmount; private readonly ConfigEntry<bool> badEventDamageCanKill; private readonly ConfigEntry<bool> badEventSpawnRandomEnemy; public Dictionary<string, ConfigEntry<bool>> WhitelistedEnemies = new Dictionary<string, ConfigEntry<bool>>(); public int WebServerListenPort => webServerListenPort.Value; public string WebServerListenIP => webServerListenIP.Value; public bool WebServerEnabled => webServerEnabled.Value; public bool EnabledInShopLevel => enabledInShopLevel.Value; public bool EnabledInArenaLevel => enabledInArenaLevel.Value; public bool GoodThings => goodThings.Value; public int MinimumTimeBetweenEvents => minimumTimeBetweenEvents.Value; public bool BadThings => badThings.Value; public bool GoodEventHealAll => goodEventHealAll.Value; public bool GoodEventHealSpecific => goodEventHealSpecific.Value; public int GoodEventHealMinAmount => goodEventHealMinAmount.Value; public int GoodEventHealMaxAmount => goodEventHealMaxAmount.Value; public bool GoodEventUpgradeAllEnergy => goodEventUpgradeAllEnergy.Value; public bool GoodEventUpgradeSpecificEnergy => goodEventUpgradeSpecificEnergy.Value; public bool GoodEventUpgradeAllHealth => goodEventUpgradeAllHealth.Value; public bool GoodEventUpgradeSpecificHealth => goodEventUpgradeSpecificHealth.Value; public bool GoodEventUpgradeAllGrabStrength => goodEventUpgradeAllGrabStrength.Value; public bool GoodEventUpgradeSpecificGrabStrength => goodEventUpgradeSpecificGrabStrength.Value; public bool GoodEventUpgradeAllRange => goodEventUpgradeAllRange.Value; public bool GoodEventUpgradeSpecificRange => goodEventUpgradeSpecificRange.Value; public bool GoodEventUpgradeAllSpeed => goodEventUpgradeAllSpeed.Value; public bool GoodEventUpgradeSpecificSpeed => goodEventUpgradeSpecificSpeed.Value; public bool GoodEventUpgradeAllExtraJump => goodEventUpgradeAllExtraJump.Value; public bool GoodEventUpgradeSpecificExtraJump => goodEventUpgradeSpecificExtraJump.Value; public bool GoodEventUpgradeAllTumbleLaunch => goodEventUpgradeAllTumbleLaunch.Value; public bool GoodEventUpgradeSpecificTumbleLaunch => goodEventUpgradeSpecificTumbleLaunch.Value; public bool GoodEventUpgradeAllMapPlayerCount => goodEventUpgradeAllMapPlayerCount.Value; public bool GoodEventUpgradeSpecificMapPlayerCount => goodEventUpgradeSpecificMapPlayerCount.Value; public bool GoodEventSpawnRandomItem => goodEventSpawnRandomItem.Value; public bool GoodEventSpawnRandomValuable => goodEventSpawnRandomValuable.Value; public bool GoodEventReviveSpecific => goodEventReviveSpecific.Value; public bool GoodEventReviveAll => goodEventReviveAll.Value; public bool BadEventDamageAll => badEventDamageAll.Value; public bool BadEventDamageSpecific => badEventDamageSpecific.Value; public int BadEventDamageMinAmount => badEventDamageMinAmount.Value; public int BadEventDamageMaxAmount => badEventDamageMaxAmount.Value; public bool BadEventDamageCanKill => badEventDamageCanKill.Value; public bool BadEventSpawnRandomEnemy => badEventSpawnRandomEnemy.Value; public RepoWebListenerConfigActivator(ConfigFile cfg) { webServerEnabled = cfg.Bind<bool>("Web Server", "WebServerEnabled", true, "Should I start the web server?\nIf you don't plan on being the host, you can probably turn this off."); webServerListenPort = cfg.Bind<int>("Web Server", "WebServerListenPort", 7390, "What port should I listen on for requests? (i.e. http://localhost:XXXX)"); webServerListenIP = cfg.Bind<string>("Web Server", "WebServerListenIP", "localhost", "What IP should I listen on for requests? (i.e. http://XXXX:7390)\nIf you're unsure, leave this as localhost!"); if (webServerListenPort.Value < 1024 || webServerListenPort.Value > 65535) { RepoWebListener.Logger.LogError((object)"Port must be between 1024 and 65535. Defaulting to 7390."); webServerListenPort.Value = 7390; } if (string.IsNullOrEmpty(webServerListenIP.Value)) { RepoWebListener.Logger.LogError((object)"IP must be a valid IP address. Defaulting to localhost."); webServerListenIP.Value = "localhost"; } enabledInShopLevel = cfg.Bind<bool>("Levels", "EnabledInShopLevel", true, "Should I send events when you're in the shop level?"); enabledInArenaLevel = cfg.Bind<bool>("Levels", "EnabledInArenaLevel", true, "Should I send events when you're in the arena level?"); minimumTimeBetweenEvents = cfg.Bind<int>("Events.General", "MinimumTimeBetweenEvents", 10, "How long should I wait between events in the queue?\nThis is in seconds, and has a hard-coded minimum of 3 seconds."); if (minimumTimeBetweenEvents.Value < 3) { RepoWebListener.Logger.LogWarning((object)"To avoid spamming the multiplayer servers, the minimum time between events must be at least 3 seconds. Setting to 3."); minimumTimeBetweenEvents.Value = 3; } goodThings = cfg.Bind<bool>("Events.General", "GoodEvents", true, "Should I enable good things happening to players?\nSetting this to false will disable all good events."); badThings = cfg.Bind<bool>("Events.General", "BadEvents", true, "Should I enable bad things happening to players?\nSetting this to false will disable all bad events."); goodEventHealAll = cfg.Bind<bool>("Good Events.Healing", "GoodEventHealAll", true, "Should healing all players be a possible event?"); goodEventHealSpecific = cfg.Bind<bool>("Good Events.Healing", "GoodEventHealSpecific", true, "Should healing a specific player be a possible event?\nSetting this to false will ignore GoodEventHealMaxAmount."); goodEventReviveSpecific = cfg.Bind<bool>("Good Events.Healing", "GoodEventReviveSpecific", true, "Should reviving a specific player be a possible event?"); goodEventReviveAll = cfg.Bind<bool>("Good Events.Healing", "GoodEventReviveAll", true, "Should reviving all players be a possible event?"); goodEventHealMinAmount = cfg.Bind<int>("Good Events.Healing", "GoodEventHealMinAmount", 0, "What's the minimum healing I'm allowed to grant per goodEventHealAll/GoodEventHealSpecific event?\nA random amount between this value and GoodEventHealMaxAmount and this value will rolled per player."); goodEventHealMaxAmount = cfg.Bind<int>("Good Events.Healing", "GoodEventHealMaxAmount", 25, "What's the maximum healing I'm allowed to grant per goodEventHealAll/GoodEventHealSpecific event?\nA random amount between GoodEventHealMinAmount and this value will rolled per player."); goodEventUpgradeAllEnergy = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllEnergy", true, "Should upgrading all players' stamina be a possible event?"); goodEventUpgradeSpecificEnergy = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificEnergy", true, "Should upgrading a specific player's stamina be a possible event?"); goodEventUpgradeAllHealth = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllHealth", true, "Should upgrading all players' health be a possible event?"); goodEventUpgradeSpecificHealth = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificHealth", true, "Should upgrading a specific player's health be a possible event?"); goodEventUpgradeAllGrabStrength = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllGrabStrength", true, "Should upgrading all players' strength be a possible event?"); goodEventUpgradeSpecificGrabStrength = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificGrabStrength", true, "Should upgrading a specific player's strength be a possible event?"); goodEventUpgradeAllRange = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllRange", true, "Should upgrading all players' grab range be a possible event?"); goodEventUpgradeSpecificRange = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificRange", true, "Should upgrading a specific player's grab range be a possible event?"); goodEventUpgradeAllSpeed = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllSpeed", true, "Should upgrading all players' sprint speed be a possible event?"); goodEventUpgradeSpecificSpeed = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificSpeed", true, "Should upgrading a specific player's sprint speed be a possible event?"); goodEventUpgradeAllExtraJump = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllExtraJump", true, "Should upgrading all players' extra jumps (+1) be a possible event?"); goodEventUpgradeSpecificExtraJump = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificExtraJump", true, "Should upgrading a specific player's extra jumps (+1) be a possible event?"); goodEventUpgradeAllTumbleLaunch = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllTumbleLaunch", true, "Should upgrading all players' tumble launch be a possible event?"); goodEventUpgradeSpecificTumbleLaunch = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificTumbleLaunch", true, "Should upgrading a specific player's tumble launch be a possible event?"); goodEventUpgradeAllMapPlayerCount = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeAllMapPlayerCount", true, "Should upgrading all players' map player count be a possible event?"); goodEventUpgradeSpecificMapPlayerCount = cfg.Bind<bool>("Good Events.Upgrading", "GoodEventUpgradeSpecificMapPlayerCount", true, "Should upgrading a specific player's map player count be a possible event?"); goodEventSpawnRandomItem = cfg.Bind<bool>("Good Events.Item Spawning", "GoodEventSpawnRandomItem", true, "Should spawning a random item near a random player be a possible event?\nSetting this to false will ignore all below events starting with GoodEventSpawnItem"); bool flag = false; foreach (KeyValuePair<string, string> itemPath in Dictionaries.ItemPaths) { WhitelistedItems[itemPath.Key] = cfg.Bind<bool>("Good Events.Item Spawning", "GoodEventSpawn" + itemPath.Key, true, "Should a \"" + itemPath.Key.Replace("Item", "") + "\" item be possible for GoodEventSpawnRandomItem?"); if (WhitelistedItems[itemPath.Key].Value) { flag = true; } } if (!flag) { goodEventSpawnRandomItem.Value = false; RepoWebListener.Logger.LogWarning((object)"All items are disabled. Assuming GoodEventSpawnRandomItem config entry to false."); } goodEventSpawnRandomValuable = cfg.Bind<bool>("Good Events.Valuable Spawning", "GoodEventSpawnRandomValuable", true, "Should spawning a random Valuable be a possible event?\nSetting this to false will ignore all below events starting with GoodEventSpawnValuable."); bool flag2 = false; foreach (KeyValuePair<string, string> valuablePath in Dictionaries.ValuablePaths) { WhitelistedValuables[valuablePath.Key] = cfg.Bind<bool>("Good Events.Valuable Spawning", "GoodEventSpawn" + valuablePath.Key, true, "Should a \"" + valuablePath.Key.Replace("Valuable", "") + "\" valuable be possible for GoodEventSpawnRandomValuable?"); if (WhitelistedValuables[valuablePath.Key].Value) { flag2 = true; } } if (!flag2) { goodEventSpawnRandomValuable.Value = false; RepoWebListener.Logger.LogWarning((object)"All valuables are disabled. Assuming GoodEventSpawnRandomValuable config entry to false."); } if (!GoodThings || (!GoodEventHealAll && !GoodEventHealSpecific && !GoodEventUpgradeAllEnergy && !GoodEventUpgradeSpecificEnergy && !GoodEventUpgradeAllHealth && !GoodEventUpgradeSpecificHealth && !GoodEventUpgradeAllGrabStrength && !GoodEventUpgradeSpecificGrabStrength && !GoodEventUpgradeAllRange && !GoodEventUpgradeSpecificRange && !GoodEventUpgradeAllSpeed && !GoodEventUpgradeSpecificSpeed && !GoodEventUpgradeAllExtraJump && !GoodEventUpgradeSpecificExtraJump && !GoodEventUpgradeAllTumbleLaunch && !GoodEventUpgradeSpecificTumbleLaunch && !GoodEventUpgradeAllMapPlayerCount && !GoodEventUpgradeSpecificMapPlayerCount && !GoodEventSpawnRandomItem && !GoodEventSpawnRandomValuable && !GoodEventReviveSpecific && !GoodEventReviveAll)) { goodThings.Value = false; RepoWebListener.Logger.LogWarning((object)"All good events are disabled. Assuming GoodThings config entry to false."); } else { goodThings.Value = true; } badEventDamageAll = cfg.Bind<bool>("Bad Events.Damage", "BadEventDamageAll", true, "Should damaging all players be a possible event?"); badEventDamageSpecific = cfg.Bind<bool>("Bad Events.Damage", "BadEventDamageSpecific", true, "Should damaging a specific player be a possible event?"); badEventDamageMinAmount = cfg.Bind<int>("Bad Events.Damage", "BadEventDamageMinAmount", 0, "What's the minimum damage I'm allowed to deal per BadEventDamageAll/BadEventDamageSpecific event?\nA random amount between this value and BadEventDamageMaxAmount will rolled per player."); badEventDamageMaxAmount = cfg.Bind<int>("Bad Events.Damage", "BadEventDamageMaxAmount", 25, "What's the maximum damage I'm allowed to deal per BadEventDamageAll/BadEventDamageSpecific event?\nA random amount between BadEventDamageMinAmount and this value will rolled per player."); badEventDamageCanKill = cfg.Bind<bool>("Bad Events.Damage", "BadEventDamageCanKill", false, "Should I be allowed to finish off the player via damage?\n(If true, BadEventDamageAll/BadEventDamageSpecific will only be able to get the player(s) down to 1 health.)"); badEventSpawnRandomEnemy = cfg.Bind<bool>("Bad Events.Enemy Spawning", "BadEventSpawnRandomEnemy", true, "Should spawning a random enemy near a random player be a possible event?\nSetting this to false will ignore all below events starting with BadEventSpawnEnemy."); bool flag3 = false; foreach (KeyValuePair<string, string> enemyPath in Dictionaries.EnemyPaths) { WhitelistedEnemies[enemyPath.Key] = cfg.Bind<bool>("Bad Events.Enemy Spawning", "BadEventSpawn" + enemyPath.Key, true, "Should a \"" + enemyPath.Key.Replace("Enemy", "") + "\" enemy be possible for BadEventSpawnRandomEnemy?"); if (WhitelistedEnemies[enemyPath.Key].Value) { flag3 = true; } } if (!flag3) { badEventSpawnRandomEnemy.Value = false; RepoWebListener.Logger.LogWarning((object)"All enemies are disabled. Assuming BadEventSpawnRandomEnemy config entry to false."); } else { badEventSpawnRandomEnemy.Value = true; } if (!BadThings || (!BadEventDamageAll && !BadEventDamageSpecific && !BadEventSpawnRandomEnemy)) { badThings.Value = false; RepoWebListener.Logger.LogWarning((object)"All bad events are disabled. Assuming BadThings config entry to false."); } else { badThings.Value = true; } } } [HarmonyPatch(typeof(RunManager))] internal class RunManagerPatch { [HarmonyPatch("ChangeLevel")] [HarmonyPostfix] private static void ChangeLevel_Postfix() { RepoWebListener.AllowedItems.Clear(); RepoWebListener.AllowedValuables.Clear(); RepoWebListener.AllowedEnemies.Clear(); RepoWebListener.AllowedItems = PencilUtils.GetAllowedItems(); RepoWebListener.AllowedValuables = PencilUtils.GetAllowedValuables(); RepoWebListener.AllowedEnemies = PencilUtils.GetAllowedEnemies(); } } }