Decompiled source of CrowdControl PEAK v1.8.3
BepInEx/plugins/ConnectorLib.JSON.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Warp World, Inc.")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("© 2026 Warp World, Inc.")] [assembly: AssemblyFileVersion("5.0.9743.17838")] [assembly: AssemblyInformationalVersion("5.0.9743.17838+a6993e4182623c29d8bfb92c7312d529ac8849f5")] [assembly: AssemblyProduct("ConnectorLib.JSON")] [assembly: AssemblyTitle("ConnectorLib.JSON")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("5.0.9743.17838")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class ParamCollectionAttribute : Attribute { } [CompilerGenerated] [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] [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] [Embedded] [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] internal sealed class ScopedRefAttribute : Attribute { } [CompilerGenerated] [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 ConnectorLib.JSON { public class CamelCaseStringEnumConverter : JsonConverter<Enum> { public override void WriteJson(JsonWriter writer, Enum? value, JsonSerializer serializer) { if (value == null) { serializer.Serialize(writer, (object)null); } else { serializer.Serialize(writer, (object)value.ToCamelCase()); } } public override Enum ReadJson(JsonReader reader, Type objectType, Enum? existingValue, bool hasExistingValue, JsonSerializer serializer) { return ReadJToken(JToken.ReadFrom(reader), objectType); } public static Enum ReadJToken(JToken reader, Type objectType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 JTokenType type = reader.Type; if ((int)type != 6) { if ((int)type == 8) { string text = Extensions.Value<string>((IEnumerable<JToken>)reader); if (text == null) { throw new SerializationException("The value was null."); } if (Enum.TryParse(objectType, text, ignoreCase: true, out object result)) { return (Enum)result; } throw new SerializationException("The value was not recognized."); } throw new SerializationException("The value was not a string or number."); } int? num = Extensions.Value<int>((IEnumerable<JToken>)reader); if (!num.HasValue) { throw new SerializationException("The value was null."); } return (Enum)Enum.ToObject(objectType, num.Value); } } [Serializable] public class DataRequest : SimpleJSONRequest { public string key; public DataRequest(string key) { this.key = key; type = RequestType.DataRequest; } } [Serializable] public class DataResponse : SimpleJSONResponse { public string key; public JToken? value; public EffectStatus status; public long timeRemaining; public string? message; [JsonConstructor] public DataResponse(string key, EffectStatus status, object? value = null, long timeRemaining = 0L, string? message = null) { this.key = key; this.value = value.IfNotNull((Func<object, JToken?>)JToken.FromObject); this.status = status; this.timeRemaining = timeRemaining; this.message = message; type = ResponseType.DataResponse; } public static DataResponse SuccessIfDefined(string key, object? value, string failMessage = "") { if (value == null) { return Retry(key, 0L, failMessage); } if (value is string input && input.IsNullOrWhiteSpace()) { return Retry(key, 0L, failMessage); } return Success(key, value); } public static DataResponse Success(string key, object? value) { return new DataResponse(key, EffectStatus.Success, value, 0L); } public static DataResponse Success(string key, object? value, string? message) { return new DataResponse(key, EffectStatus.Success, value, 0L, message); } public static DataResponse Failure(string key) { return new DataResponse(key, EffectStatus.Failure, null, 0L); } public static DataResponse Failure(string key, string? message) { return new DataResponse(key, EffectStatus.Failure, null, 0L, message); } public static DataResponse Failure(string key, object? value, string? message = null) { return new DataResponse(key, EffectStatus.Failure, value, 0L, message); } public static DataResponse Retry(string key, long delay = 0L, string? message = null) { return new DataResponse(key, EffectStatus.Retry, null, delay, message); } } [Serializable] public class EffectRequest : SimpleJSONRequest { [Serializable] public class Target { public string? service; public string? id; public string? name; public string? avatar; } public string? code; public string? message; public JToken? parameters; public uint? quantity; public JArray? targets; public long? duration; public string? viewer; public JArray? viewers; public long? cost; public Dictionary<string, object?>? arguments; public Guid? requestID; [JsonConverter(typeof(IEffectSourceDetails.Converter))] public IEffectSourceDetails? sourceDetails; public EffectRequest() { type = RequestType.EffectStart; } } [Serializable] public class EffectResponse : SimpleJSONResponse { private class MetadataConverter : JsonConverter<Dictionary<string, DataResponse>?> { public override void WriteJson(JsonWriter writer, Dictionary<string, DataResponse>? value, JsonSerializer serializer) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown if (value == null) { serializer.Serialize(writer, (object)null); return; } JObject val = new JObject(); foreach (KeyValuePair<string, DataResponse> item in value) { JObject val2 = JObject.FromObject((object)item.Value); val2.Remove("key"); val[item.Key] = (JToken)(object)val2; } serializer.Serialize(writer, (object)val); } public override Dictionary<string, DataResponse>? ReadJson(JsonReader reader, Type objectType, Dictionary<string, DataResponse>? existingValue, bool hasExistingValue, JsonSerializer serializer) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown JObject val = (JObject)serializer.Deserialize(reader); if (val == null) { return null; } Dictionary<string, DataResponse> dictionary = new Dictionary<string, DataResponse>(); foreach (JProperty item in val.Properties()) { JObject val2 = (JObject)item.Value; val2["key"] = JToken.op_Implicit(item.Name); dictionary.Add(item.Name, ((JToken)val2).ToObject<DataResponse>()); } return dictionary; } } public EffectStatus status; public string? message; public StandardErrors messageID; public long timeRemaining; [JsonConverter(typeof(MetadataConverter))] public Dictionary<string, DataResponse>? metadata; public EffectResponse() { } public EffectResponse(uint id, EffectStatus status) : this(id, status, 0L) { } public EffectResponse(uint id, EffectStatus status, StandardErrors messageID, string? message = null) : this(id, status, 0L, messageID, message) { } public EffectResponse(uint id, EffectStatus status, string? message) : this(id, status, 0L, message) { } public EffectResponse(uint id, EffectStatus status, TimeSpan timeRemaining) : this(id, status, checked((long)timeRemaining.TotalMilliseconds)) { } public EffectResponse(uint id, EffectStatus status, TimeSpan timeRemaining, StandardErrors messageID) : this(id, status, checked((long)timeRemaining.TotalMilliseconds), messageID) { } public EffectResponse(uint id, EffectStatus status, TimeSpan timeRemaining, string? message) : this(id, status, checked((long)timeRemaining.TotalMilliseconds), message) { } public EffectResponse(uint id, EffectStatus status, long timeRemaining, string? message = null) { base.id = id; this.status = status; this.timeRemaining = timeRemaining; this.message = message; type = ResponseType.EffectRequest; } [JsonConstructor] public EffectResponse(uint id, EffectStatus status, long timeRemaining, StandardErrors messageID, string? message = null) { base.id = id; this.status = status; this.timeRemaining = timeRemaining; this.messageID = messageID; this.message = message; type = ResponseType.EffectRequest; } public static EffectResponse Success(uint id, string? message = null) { return new EffectResponse(id, EffectStatus.Success, message); } public static EffectResponse Success(uint id, long delay, string? message = null) { return new EffectResponse(id, EffectStatus.Success, delay, message); } public static EffectResponse Success(uint id, TimeSpan delay, string? message = null) { return new EffectResponse(id, EffectStatus.Success, delay, message); } public static EffectResponse Failure(uint id, string? message = null) { return new EffectResponse(id, EffectStatus.Failure, message); } public static EffectResponse Failure(uint id, StandardErrors error, string? message = null) { return new EffectResponse(id, EffectStatus.Failure, error, message); } public static EffectResponse Unavailable(uint id, string? message = null) { return new EffectResponse(id, EffectStatus.Unavailable, message); } public static EffectResponse Unavailable(uint id, StandardErrors error) { return new EffectResponse(id, EffectStatus.Unavailable, error); } public static EffectResponse Retry(uint id, string? message = null) { return new EffectResponse(id, EffectStatus.Retry, 0L, message); } public static EffectResponse Retry(uint id, long delay, string? message = null) { return new EffectResponse(id, EffectStatus.Retry, delay, message); } public static EffectResponse Retry(uint id, TimeSpan delay, string? message = null) { return new EffectResponse(id, EffectStatus.Retry, delay, message); } public static EffectResponse Retry(uint id, StandardErrors error) { return new EffectResponse(id, EffectStatus.Retry, 0L, error); } public static EffectResponse Retry(uint id, long delay, StandardErrors error) { return new EffectResponse(id, EffectStatus.Retry, delay, error); } public static EffectResponse Retry(uint id, TimeSpan delay, StandardErrors error) { return new EffectResponse(id, EffectStatus.Retry, delay, error); } public static EffectResponse Paused(uint id, string? message = null) { return new EffectResponse(id, EffectStatus.Paused, 0L, message); } public static EffectResponse Paused(uint id, long timeRemaining, string? message = null) { return new EffectResponse(id, EffectStatus.Paused, timeRemaining, message); } public static EffectResponse Paused(uint id, TimeSpan timeRemaining, string? message = null) { return new EffectResponse(id, EffectStatus.Paused, timeRemaining, message); } public static EffectResponse Paused(uint id, StandardErrors error) { return new EffectResponse(id, EffectStatus.Paused, 0L, error); } public static EffectResponse Paused(uint id, long timeRemaining, StandardErrors error) { return new EffectResponse(id, EffectStatus.Paused, timeRemaining, error); } public static EffectResponse Paused(uint id, TimeSpan timeRemaining, StandardErrors error) { return new EffectResponse(id, EffectStatus.Paused, timeRemaining, error); } public static EffectResponse Resumed(uint id, string? message = null) { return new EffectResponse(id, EffectStatus.Resumed, 0L, message); } public static EffectResponse Resumed(uint id, long timeRemaining, string? message = null) { return new EffectResponse(id, EffectStatus.Resumed, timeRemaining, message); } public static EffectResponse Resumed(uint id, TimeSpan timeRemaining, string? message = null) { return new EffectResponse(id, EffectStatus.Resumed, timeRemaining, message); } public static EffectResponse Resumed(uint id, StandardErrors error) { return new EffectResponse(id, EffectStatus.Resumed, 0L, error); } public static EffectResponse Resumed(uint id, long timeRemaining, StandardErrors error) { return new EffectResponse(id, EffectStatus.Resumed, timeRemaining, error); } public static EffectResponse Resumed(uint id, TimeSpan timeRemaining, StandardErrors error) { return new EffectResponse(id, EffectStatus.Resumed, timeRemaining, error); } public static EffectResponse Finished(uint id, string? message = null) { return new EffectResponse(id, EffectStatus.Finished, 0L, message); } public static EffectResponse Finished(uint id, StandardErrors error) { return new EffectResponse(id, EffectStatus.Finished, 0L, error); } } public interface IEffectSourceDetails { public class Converter : JsonConverter<IEffectSourceDetails?> { public static readonly Converter Instance = new Converter(); public override IEffectSourceDetails? ReadJson(JsonReader reader, Type objectType, IEffectSourceDetails? existingValue, bool hasExistingValue, JsonSerializer serializer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)reader.TokenType == 11) { return null; } JObject val = JObject.Load(reader); JToken obj = val["type"]; return ((obj != null) ? Extensions.Value<string>((IEnumerable<JToken>)obj) : null) switch { "twitch-channel-reward" => ((JToken)val).ToObject<TwitchChannelRewardSourceDetails>(), "stream-labs-donation" => ((JToken)val).ToObject<StreamLabsDonationSourceDetails>(), "event-hype-train" => ((JToken)val).ToObject<HypeTrainSourceDetails>(), "tiktok-gift" => ((JToken)val).ToObject<TikTokGiftSourceDetails>(), "tiktok-like" => ((JToken)val).ToObject<TikTokLikeSourceDetails>(), "tiktok-follow" => ((JToken)val).ToObject<TikTokFollowSourceDetails>(), "tiktok-share" => ((JToken)val).ToObject<TikTokShareSourceDetails>(), "pulsoid-trigger" => ((JToken)val).ToObject<PulsoidTriggerSourceDetails>(), "crowd-control-test" => ((JToken)val).ToObject<CrowdControlTestSourceDetails>(), "crowd-control-chaos-mode" => ((JToken)val).ToObject<CrowdControlChaosModeSourceDetails>(), "crowd-control-retry" => ((JToken)val).ToObject<CrowdControlRetrySourceDetails>(), _ => null, }; } public override void WriteJson(JsonWriter writer, IEffectSourceDetails? value, JsonSerializer serializer) { serializer.Serialize(writer, (object)((value == null) ? null : JObject.FromObject((object)value))); } } [JsonProperty("type")] string Type { get; } } public class TwitchChannelRewardSourceDetails : IEffectSourceDetails { [JsonProperty("type")] public string Type => "twitch-channel-reward"; [JsonProperty("rewardID")] public string RewardID { get; set; } [JsonProperty("redemptionID")] public string RedemptionID { get; set; } [JsonProperty("twitchID")] public string TwitchID { get; set; } [JsonProperty("name")] public string Name { get; set; } [JsonProperty("cost")] public int Cost { get; set; } } public class StreamLabsDonationSourceDetails : IEffectSourceDetails { [JsonProperty("type")] public string Type => "stream-labs-donation"; [JsonProperty("donationID")] public string DonationID { get; set; } [JsonProperty("cost")] public string Cost { get; set; } [JsonProperty("currency")] public string Currency { get; set; } [JsonProperty("name")] public string? Name { get; set; } [JsonProperty("message")] public string? Message { get; set; } } public class HypeTrainSourceDetails : IEffectSourceDetails { public class Contribution { [JsonProperty("user_id")] public string UserID { get; set; } [JsonProperty("user_login")] public string UserLogin { get; set; } [JsonProperty("user_name")] public string UserName { get; set; } [JsonProperty("type")] public string Type { get; set; } [JsonProperty("total")] public int Total { get; set; } } [JsonProperty("type")] public string Type => "event-hype-train"; [JsonProperty("total")] public int Total { get; set; } [JsonProperty("progress")] public int Progress { get; set; } [JsonProperty("goal")] public int Goal { get; set; } [JsonProperty("top_contributions")] public List<Contribution> TopContributions { get; set; } [JsonProperty("last_contribution")] public Contribution LastContribution { get; set; } [JsonProperty("level")] public int Level { get; set; } } public abstract class TikTokSourceDetails : IEffectSourceDetails { [JsonProperty("type")] public abstract string Type { get; } [JsonProperty("cost")] public int Cost { get; set; } [JsonProperty("name")] public string Name { get; set; } [JsonProperty("userID")] public string UserID { get; set; } } public class TikTokGiftSourceDetails : TikTokSourceDetails { [JsonProperty("type")] public override string Type => "tiktok-gift"; [JsonProperty("giftID")] public int GiftID { get; set; } [JsonProperty("giftName")] public string GiftName { get; set; } [JsonProperty("transactionID")] public string? TransactionID { get; set; } } public class TikTokLikeSourceDetails : TikTokSourceDetails { [JsonProperty("type")] public override string Type => "tiktok-like"; } public class TikTokFollowSourceDetails : TikTokSourceDetails { [JsonProperty("type")] public override string Type => "tiktok-follow"; } public class TikTokShareSourceDetails : TikTokSourceDetails { [JsonProperty("type")] public override string Type => "tiktok-share"; } public class PulsoidTriggerSourceDetails : IEffectSourceDetails { [JsonProperty("type")] public string Type => "pulsoid-trigger"; [JsonProperty("heartRate")] public int HeartRate { get; set; } [JsonProperty("uuid")] public Guid Uuid { get; set; } [JsonProperty("triggerType")] public string TriggerType { get; set; } [JsonProperty("targetHeartRate")] public int TargetHeartRate { get; set; } [JsonProperty("holdTime")] public int HoldTime { get; set; } [JsonProperty("cooldown")] public int Cooldown { get; set; } } public class CrowdControlTestSourceDetails : IEffectSourceDetails { [JsonProperty("type")] public string Type => "crowd-control-test"; } public class CrowdControlChaosModeSourceDetails : IEffectSourceDetails { [JsonProperty("type")] public string Type => "crowd-control-chaos-mode"; } public class CrowdControlRetrySourceDetails : IEffectSourceDetails { [JsonProperty("type")] public string Type => "crowd-control-retry"; } [JsonConverter(typeof(CamelCaseStringEnumConverter))] public enum EffectStatus { Success = 0, Failure = 1, Unavailable = 2, Retry = 3, Queue = 4, Running = 5, Paused = 6, Resumed = 7, Finished = 8, Wait = 9, RemoteScheduled = 10, Visible = 128, NotVisible = 129, Selectable = 130, NotSelectable = 131, Reserved0 = 160, NotReady = 255 } [Serializable] public class EffectUpdate : SimpleJSONResponse { [JsonConverter(typeof(CamelCaseStringEnumConverter))] public enum IdentifierType { Effect, Group, Category } [Obsolete("This field is deprecated. Please use the ids field instead.")] [JsonProperty(/*Could not decode attribute arguments.*/)] public string? code; [JsonProperty(/*Could not decode attribute arguments.*/)] public string[]? ids; public IdentifierType idType; public EffectStatus status; public string? message; public EffectUpdate() { } public EffectUpdate(string id, EffectStatus status, string? message = null) { ids = new string[1] { id }; idType = IdentifierType.Effect; this.status = status; this.message = message; type = ResponseType.EffectStatus; } public EffectUpdate(string id, IdentifierType idType, EffectStatus status, string? message = null) { ids = new string[1] { id }; this.idType = idType; this.status = status; this.message = message; type = ResponseType.EffectStatus; } public EffectUpdate(string[] ids, EffectStatus status, string? message = null) { this.ids = ids; idType = IdentifierType.Effect; this.status = status; this.message = message; type = ResponseType.EffectStatus; } public EffectUpdate(string[] ids, IdentifierType idType, EffectStatus status, string? message = null) { this.ids = ids; this.idType = idType; this.status = status; this.message = message; type = ResponseType.EffectStatus; } public EffectUpdate(IEnumerable<string> ids, EffectStatus status, string? message = null) { this.ids = ids.ToArray(); idType = IdentifierType.Effect; this.status = status; this.message = message; type = ResponseType.EffectStatus; } public EffectUpdate(IEnumerable<string> ids, IdentifierType idType, EffectStatus status, string? message = null) { this.ids = ids.ToArray(); this.idType = idType; this.status = status; this.message = message; type = ResponseType.EffectStatus; } } [Serializable] public class EmptyRequest : SimpleJSONRequest { } [Serializable] public class EmptyResponse : SimpleJSONResponse { } internal static class EnumEx { internal static string ToCamelCase(this Enum value) { return value.ToString("G").ToCamelCase(); } } [JsonConverter(typeof(CamelCaseStringEnumConverter))] public enum GameState { Unknown = 0, Error = -1, Unmodded = -2, BadGameSettings = -3, WrongVersion = -4, NotFocused = -5, Loading = -6, InLevel = 1, [Obsolete("Use InLevel instead. This state is redundant and does not provide any additional information about the game state.")] Ready = 1, TitleScreen = -17, Credits = -18, Menu = -13, Paused = -7, WrongMode = -8, SafeArea = -9, StartingArea = -19, Dialogue = -20, Cutscene = -11, BadPlayerState = -12, InputLocked = -21, Map = -14, UntimedArea = -10, InCombat = -15, NotInCombat = -16, PipelineBusy = -128, NotReady = int.MinValue } [Serializable] public class GameUpdate : SimpleJSONResponse { public GameState state; public string? message; public GameUpdate(GameState state, string? message = null) { this.state = state; this.message = message; type = ResponseType.GameUpdate; } } [Serializable] public class GenericEventRequest : SimpleJSONRequest { [JsonProperty(PropertyName = "internal")] public bool @internal; public string eventType; public Dictionary<string, object?>? data; public GenericEventRequest(string eventType) { type = RequestType.GenericEvent; this.eventType = eventType; } [JsonConstructor] public GenericEventRequest(string eventType, IEnumerable<KeyValuePair<string, object?>>? data) : this(eventType) { this.data = ((data != null) ? data.ToDictionary() : null); } [JsonConstructor] public GenericEventRequest(string eventType, IEnumerable<KeyValuePair<string, object?>>? data, bool @internal) : this(eventType, data) { this.@internal = @internal; } } [Serializable] public class GenericEventResponse : SimpleJSONResponse { [JsonProperty(PropertyName = "internal")] public bool @internal; public string eventType; public Dictionary<string, object?>? data; public GenericEventResponse(string eventType) { type = ResponseType.GenericEvent; this.eventType = eventType; } public GenericEventResponse(string eventType, IEnumerable<KeyValuePair<string, object>>? data, bool @internal = false) : this(eventType) { this.data = ((data != null) ? data.ToDictionary() : null); this.@internal = @internal; } [JsonConstructor] public GenericEventResponse(string eventType, Dictionary<string, object>? data, [JsonProperty(PropertyName = "internal")] bool @internal) : this(eventType, data) { this.@internal = @internal; } } internal class HexColorConverter : JsonConverter<ParameterColorValue> { private static readonly Dictionary<char, byte> CHAR_LOOKUP = new Dictionary<char, byte> { { '0', 0 }, { '1', 1 }, { '2', 2 }, { '3', 3 }, { '4', 4 }, { '5', 5 }, { '6', 6 }, { '7', 7 }, { '8', 8 }, { '9', 9 }, { 'A', 10 }, { 'B', 11 }, { 'C', 12 }, { 'D', 13 }, { 'E', 14 }, { 'F', 15 } }; public override void WriteJson(JsonWriter writer, ParameterColorValue value, JsonSerializer serializer) { serializer.Serialize(writer, (object)string.Format("#{0}{1:X2}{2:X2}{3:X2}", (value.A != byte.MaxValue) ? value.A.ToString("X2") : string.Empty, value.R, value.G, value.B)); } public override ParameterColorValue ReadJson(JsonReader reader, Type objectType, ParameterColorValue existingValue, bool hasExistingValue, JsonSerializer serializer) { if (TryParse(serializer.Deserialize<string>(reader), out var color)) { return color; } throw new SerializationException("Unrecognized color code."); } public static bool TryParse(string? value, out ParameterColorValue color) { if (value == null) { color = default(ParameterColorValue); return false; } value = value.TrimStart('#'); switch (value.Length) { case 6: { string[] array2 = value.Chop(2); byte result2; byte red3 = (byte)(byte.TryParse(array2[0], NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result2) ? result2 : 0); byte green3 = (byte)(byte.TryParse(array2[1], NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result2) ? result2 : 0); byte blue3 = (byte)(byte.TryParse(array2[2], NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result2) ? result2 : 0); color = ParameterColorValue.FromArgb(red3, green3, blue3); return true; } case 8: { string[] array = value.Chop(2); byte result; byte alpha2 = (byte)(byte.TryParse(array[0], NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result) ? result : 0); byte red2 = (byte)(byte.TryParse(array[1], NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result) ? result : 0); byte green2 = (byte)(byte.TryParse(array[2], NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result) ? result : 0); byte blue2 = (byte)(byte.TryParse(array[3], NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result) ? result : 0); color = ParameterColorValue.FromArgb(alpha2, red2, green2, blue2); return true; } case 3: { byte value3; byte red4 = (byte)(CHAR_LOOKUP.TryGetValue(value[0], out value3) ? checked((byte)(value3 * 16)) : 0); byte green4 = (byte)(CHAR_LOOKUP.TryGetValue(value[1], out value3) ? checked((byte)(value3 * 16)) : 0); byte blue4 = (byte)(CHAR_LOOKUP.TryGetValue(value[2], out value3) ? checked((byte)(value3 * 16)) : 0); color = ParameterColorValue.FromArgb(red4, green4, blue4); return true; } case 4: { byte value2; byte alpha = (byte)(CHAR_LOOKUP.TryGetValue(value[0], out value2) ? checked((byte)(value2 * 16)) : 0); byte red = (byte)(CHAR_LOOKUP.TryGetValue(value[1], out value2) ? checked((byte)(value2 * 16)) : 0); byte green = (byte)(CHAR_LOOKUP.TryGetValue(value[2], out value2) ? checked((byte)(value2 * 16)) : 0); byte blue = (byte)(CHAR_LOOKUP.TryGetValue(value[3], out value2) ? checked((byte)(value2 * 16)) : 0); color = ParameterColorValue.FromArgb(alpha, red, green, blue); return true; } default: color = default(ParameterColorValue); return false; } } } internal static class IEnumerableEx { internal static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> values) where TKey : notnull { Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>(); foreach (KeyValuePair<TKey, TValue> value in values) { dictionary.Add(value.Key, value.Value); } return dictionary; } } public interface IParameterValue { string ID { get; } string Name { get; } ParameterBase.ParameterType Type { get; } object? Value { get; } } [Serializable] public class LoginRequest : SimpleJSONRequest { public string? login; public string? password; } [Serializable] public class MessageRequest : SimpleJSONRequest { public string? message; } [Serializable] public class MessageResponse : SimpleJSONResponse { public string? message; } internal static class ObjectEx { internal static T2? IfNotNull<T1, T2>(this T1? value, Func<T1, T2?> selector) where T2 : class { if (value == null) { return null; } return selector(value); } } public abstract class ParameterBase { [JsonConverter(typeof(ParameterTypeConverter))] public enum ParameterType { Options, HexColor } private class ParameterTypeConverter : JsonConverter<ParameterType> { public override void WriteJson(JsonWriter writer, ParameterType value, JsonSerializer serializer) { writer.WriteValue(value switch { ParameterType.Options => "options", ParameterType.HexColor => "hex-color", _ => throw new SerializationException("Unknown parameter type."), }); } public override ParameterType ReadJson(JsonReader reader, Type objectType, ParameterType existingValue, bool hasExistingValue, JsonSerializer serializer) { switch (reader.Value?.ToString().ToLowerInvariant()) { case "options": return ParameterType.Options; case "hexcolor": case "hex-color": return ParameterType.HexColor; default: throw new SerializationException("Unknown parameter type."); } } } [JsonIgnore] public readonly string ID; [JsonProperty(PropertyName = "title")] public readonly string Name; [JsonProperty(PropertyName = "type")] public readonly ParameterType Type; protected ParameterBase(string name, string id, ParameterType type) { ID = id; Name = name; Type = type; } } public class ParameterColor : ParameterBase, IParameterValue { [JsonProperty(PropertyName = "value")] [JsonConverter(typeof(HexColorConverter))] public ParameterColorValue Value; [JsonIgnore] string IParameterValue.ID => ID; [JsonIgnore] string IParameterValue.Name => Name; [JsonIgnore] ParameterType IParameterValue.Type => Type; [JsonIgnore] object? IParameterValue.Value => Value; [JsonConstructor] public ParameterColor(string name, string id, ParameterColorValue value) : base(name, id, ParameterType.HexColor) { Value = value; } [JsonConstructor] public ParameterColor(string name, string id, string value) : base(name, id, ParameterType.HexColor) { if (!HexColorConverter.TryParse(value, out Value)) { throw new ArgumentException("Unknown color code.", "value"); } } } [Serializable] [DebuggerDisplay("{NameAndARGBValue}")] [TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public readonly struct ParameterColorValue : IEquatable<ParameterColorValue> { public static readonly ParameterColorValue Empty; private const short StateARGBValueValid = 2; private const short StateValueMask = 2; private const short StateNameValid = 8; private const long NotDefinedValue = 0L; internal const int ARGBAlphaShift = 24; internal const int ARGBRedShift = 16; internal const int ARGBGreenShift = 8; internal const int ARGBBlueShift = 0; internal const uint ARGBAlphaMask = 4278190080u; internal const uint ARGBRedMask = 16711680u; internal const uint ARGBGreenMask = 65280u; internal const uint ARGBBlueMask = 255u; private readonly long value; private readonly short state; public byte R => (byte)(Value >> 16); public byte G => (byte)(Value >> 8); public byte B => (byte)Value; public byte A => (byte)(Value >> 24); public bool IsEmpty => state == 0; private long Value { get { if ((state & 2) != 0) { return value; } return 0L; } } private ParameterColorValue(long value, short state) { this.value = value; this.state = state; } private static ParameterColorValue FromArgb(uint argb) { return new ParameterColorValue(argb, 2); } public static ParameterColorValue FromArgb(int argb) { return FromArgb((uint)argb); } public static ParameterColorValue FromArgb(byte alpha, byte red, byte green, byte blue) { return FromArgb((uint)((alpha << 24) | (red << 16) | (green << 8) | blue)); } public static ParameterColorValue FromArgb(int alpha, ParameterColorValue baseColor) { return FromArgb(checked(((uint)alpha << 24) | ((uint)baseColor.Value & 0xFFFFFF))); } public static ParameterColorValue FromArgb(byte red, byte green, byte blue) { return FromArgb(byte.MaxValue, red, green, blue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void GetRgbValues(out byte r, out byte g, out byte b) { checked { uint num = (uint)Value; r = (byte)((num & 0xFF0000) >> 16); g = (byte)((num & 0xFF00) >> 8); b = (byte)(num & 0xFF); } } public float GetBrightness() { GetRgbValues(out var r, out var g, out var b); int num = Math.Min(Math.Min(r, g), b); return (float)checked(Math.Max(Math.Max(r, g), b) + num) / 510f; } public float GetHue() { GetRgbValues(out var r, out var g, out var b); if (r == g && g == b) { return 0f; } int num = Math.Min(Math.Min(r, g), b); int num2 = Math.Max(Math.Max(r, g), b); checked { float num3 = num2 - num; float num4 = ((r == num2) ? ((float)(g - b) / num3) : ((g != num2) ? ((float)(r - g) / num3 + 4f) : ((float)(b - r) / num3 + 2f))); num4 *= 60f; if (num4 < 0f) { num4 += 360f; } return num4; } } public float GetSaturation() { GetRgbValues(out var r, out var g, out var b); if (r == g && g == b) { return 0f; } int num = Math.Min(Math.Min(r, g), b); int num2 = Math.Max(Math.Max(r, g), b); checked { int num3 = num2 + num; if (num3 > 255) { num3 = 510 - num2 - num; } return (float)(num2 - num) / (float)num3; } } public int ToArgb() { return (int)Value; } public override string ToString() { if ((state & 2) != 0) { return "ParameterColorValue [A=" + A + ", R=" + R + ", G=" + G + ", B=" + B + "]"; } return "ParameterColorValue [Empty]"; } public static bool operator ==(ParameterColorValue left, ParameterColorValue right) { if (left.value == right.value) { return left.state == right.state; } return false; } public static bool operator !=(ParameterColorValue left, ParameterColorValue right) { return !(left == right); } public override bool Equals(object? obj) { if (obj is ParameterColorValue other) { return Equals(other); } return false; } public bool Equals(ParameterColorValue other) { return this == other; } public override int GetHashCode() { return (value.GetHashCode() * 397) ^ state.GetHashCode(); } } public class ParameterValue<TValue> : ParameterBase, IParameterValue { [JsonProperty(PropertyName = "value")] public TValue? Value; [JsonIgnore] string IParameterValue.ID => ID; [JsonIgnore] string IParameterValue.Name => Name; [JsonIgnore] ParameterType IParameterValue.Type => Type; [JsonIgnore] object? IParameterValue.Value => Value; [JsonConstructor] public ParameterValue(string name, string id, TValue? value) : base(name, id, ParameterType.Options) { Value = value; } public override string ToString() { return Name; } } [Serializable] public class PlayerInfo : SimpleJSONRequest { public JObject? player; public PlayerInfo() { type = RequestType.PlayerInfo; } } [Serializable] [JsonConverter(typeof(Converter))] public class RequestParameters : IReadOnlyList<string>, IEnumerable<string>, IEnumerable, IReadOnlyCollection<string>, IReadOnlyDictionary<string, IParameterValue>, IEnumerable<KeyValuePair<string, IParameterValue>>, IReadOnlyCollection<KeyValuePair<string, IParameterValue>> { private class Converter : JsonConverter<RequestParameters> { public override void WriteJson(JsonWriter writer, RequestParameters? value, JsonSerializer serializer) { serializer.Serialize(writer, (object)value?._parameters); } public override RequestParameters? ReadJson(JsonReader reader, Type objectType, RequestParameters? existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject obj = JObject.Load(reader); List<IParameterValue> list = new List<IParameterValue>(); foreach (KeyValuePair<string, JToken> item in obj) { string key = item.Key; string name = Extensions.Value<string>((IEnumerable<JToken>)item.Value[(object)"name"]); switch (Extensions.Value<ParameterBase.ParameterType>((IEnumerable<JToken>)item.Value[(object)"type"])) { case ParameterBase.ParameterType.Options: { string value = Extensions.Value<string>((IEnumerable<JToken>)item.Value[(object)"value"]); list.Add(new ParameterValue<string>(name, key, value)); break; } case ParameterBase.ParameterType.HexColor: { if (HexColorConverter.TryParse(Extensions.Value<string>((IEnumerable<JToken>)item.Value[(object)"value"]), out var color)) { list.Add(new ParameterColor(name, key, color)); } break; } default: throw new SerializationException(); } } return new RequestParameters(list); } } private readonly Dictionary<string, IParameterValue> _parameters; private readonly List<string> _parameter_list; int IReadOnlyCollection<string>.Count => _parameters.Count; int IReadOnlyCollection<KeyValuePair<string, IParameterValue>>.Count => _parameters.Count; public string this[int index] => _parameter_list[index]; public IParameterValue this[string key] => _parameters[key]; public IEnumerable<string> Keys => _parameters.Keys; public IEnumerable<IParameterValue> Values => _parameters.Values; public int Count => _parameters.Count; private RequestParameters() { _parameters = new Dictionary<string, IParameterValue>(); _parameter_list = new List<string>(); } public RequestParameters(IEnumerable<IParameterValue> parameters) { parameters = parameters.ToArray(); _parameters = parameters.ToDictionary((IParameterValue d) => d.ID); _parameter_list = parameters.Select((IParameterValue v) => v.Value.ToString()).ToList(); } public RequestParameters(IEnumerable<KeyValuePair<string, IParameterValue>> parameters) { _parameters = parameters.ToDictionary(); _parameter_list = _parameters.Values.Select((IParameterValue p) => p.Value.ToString()).ToList(); } IEnumerator<KeyValuePair<string, IParameterValue>> IEnumerable<KeyValuePair<string, IParameterValue>>.GetEnumerator() { return _parameters.GetEnumerator(); } IEnumerator<string> IEnumerable<string>.GetEnumerator() { return _parameters.Values.Select((IParameterValue v) => v.Value?.ToString()).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } public bool ContainsKey(string key) { return _parameters.ContainsKey(key); } public bool TryGetValue(string key, out IParameterValue value) { return _parameters.TryGetValue(key, out value); } public IEnumerable<string> Where(Func<string, bool> predicate) { return Enumerable.Where(this, predicate); } public IEnumerable<TResult> Select<TResult>(Func<string, TResult> selector) { return Enumerable.Select(this, selector); } public IEnumerable<TResult> SelectMany<TResult>(Func<string, IEnumerable<TResult>> selector) { return Enumerable.SelectMany(this, selector); } public IEnumerable<TResult> SelectMany<TResult>(Func<string, int, IEnumerable<TResult>> selector) { return Enumerable.SelectMany(this, selector); } public string First() { return this.First<string>(); } public string First(Func<string, bool> predicate) { return Enumerable.First(this, predicate); } public string? FirstOrDefault() { return this.FirstOrDefault<string>(); } public string FirstOrDefault(string defaultValue) { return this.FirstOrDefault<string>() ?? defaultValue; } public string? FirstOrDefault(Func<string, bool> predicate) { return Enumerable.FirstOrDefault(this, predicate); } public string FirstOrDefault(Func<string, bool> predicate, string defaultValue) { return Enumerable.FirstOrDefault(this, predicate) ?? defaultValue; } public bool Any() { return this.Any<string>(); } public bool Any(Func<string, bool> predicate) { return Enumerable.Any(this, predicate); } } public enum RequestType : byte { EffectTest = 0, EffectStart = 1, EffectStop = 2, [Obsolete("Use EffectTest instead.")] Test = 0, [Obsolete("Use EffectStart instead.")] Start = 1, [Obsolete("Use EffectStop instead.")] Stop = 2, GenericEvent = 16, DataRequest = 32, RpcResponse = 208, PlayerInfo = 224, Login = 240, Version = 252, GameUpdate = 253, KeepAlive = byte.MaxValue } [JsonConverter(typeof(CamelCaseStringEnumConverter))] public enum ResponseType : byte { EffectRequest = 0, EffectStatus = 1, GenericEvent = 16, LoadEvent = 24, SaveEvent = 25, DataResponse = 32, RpcRequest = 208, Login = 240, LoginSuccess = 241, Version = 252, GameUpdate = 253, Disconnect = 254, KeepAlive = byte.MaxValue } [Serializable] public class RpcRequest : SimpleJSONResponse { public string? method; public object?[]? args; public RpcTarget? target; public RpcRequest() { type = ResponseType.RpcRequest; } } [Serializable] public class RpcResponse : SimpleJSONRequest { public object? value; [JsonProperty(/*Could not decode attribute arguments.*/)] public bool exception; public RpcResponse() { type = RequestType.RpcResponse; } } [Flags] [JsonConverter(typeof(CamelCaseStringEnumConverter))] public enum RpcTarget { Game = 1, Pack = 2, Native = 4, Client = 8, Server = 0x10 } public abstract class SimpleJSONMessage { public static readonly JsonSerializerSettings JSON_SERIALIZER_SETTINGS = new JsonSerializerSettings { NullValueHandling = (NullValueHandling)1, MissingMemberHandling = (MissingMemberHandling)0, Formatting = (Formatting)0 }; public static readonly JsonSerializer JSON_SERIALIZER = new JsonSerializer { NullValueHandling = JSON_SERIALIZER_SETTINGS.NullValueHandling, MissingMemberHandling = JSON_SERIALIZER_SETTINGS.MissingMemberHandling, Formatting = JSON_SERIALIZER_SETTINGS.Formatting }; private static int _next_id = 0; public static uint NextID { get { uint result; while ((result = (uint)Interlocked.Increment(ref _next_id)) == 0) { } return result; } } public abstract uint ID { get; } public abstract bool IsKeepAlive { get; } public string Serialize() { return JsonConvert.SerializeObject((object)this, JSON_SERIALIZER_SETTINGS); } } [Serializable] public class SimpleJSONRequest : SimpleJSONMessage { public uint id = SimpleJSONMessage.NextID; public RequestType type; [JsonIgnore] public override uint ID => id; [JsonIgnore] public override bool IsKeepAlive => type == RequestType.KeepAlive; public static bool TryParse(string json, [MaybeNullWhen(false)] out SimpleJSONRequest request) { return TryParse(JObject.Parse(json), out request); } public static bool TryParse(JObject j, [MaybeNullWhen(false)] out SimpleJSONRequest request) { try { JToken value = j.GetValue("type"); switch ((value != null) ? ((RequestType)(object)CamelCaseStringEnumConverter.ReadJToken(value, typeof(RequestType))) : RequestType.EffectTest) { case RequestType.EffectTest: case RequestType.EffectStart: request = ((JToken)j).ToObject<EffectRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.EffectStop: request = ((JToken)j).ToObject<EffectRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.DataRequest: request = ((JToken)j).ToObject<DataRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.RpcResponse: request = ((JToken)j).ToObject<RpcResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.PlayerInfo: request = ((JToken)j).ToObject<PlayerInfo>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.Login: request = ((JToken)j).ToObject<MessageRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.Version: request = ((JToken)j).ToObject<EmptyRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.GameUpdate: request = ((JToken)j).ToObject<EmptyRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; case RequestType.KeepAlive: request = ((JToken)j).ToObject<EmptyRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; } } catch { } request = null; return false; } } [Serializable] public class SimpleJSONResponse : SimpleJSONMessage { public uint id; public ResponseType type; [JsonIgnore] public override uint ID => id; [JsonIgnore] public override bool IsKeepAlive => type == ResponseType.KeepAlive; [JsonIgnore] public static SimpleJSONResponse KeepAlive { get; } = new EmptyResponse { type = ResponseType.KeepAlive }; public static bool TryParse(string json, [MaybeNullWhen(false)] out SimpleJSONResponse response) { return TryParse(JObject.Parse(json), out response); } public static bool TryParse(JObject j, [MaybeNullWhen(false)] out SimpleJSONResponse response) { try { JToken value = j.GetValue("type"); ResponseType responseType = ((value != null) ? ((ResponseType)(object)CamelCaseStringEnumConverter.ReadJToken(value, typeof(ResponseType))) : ResponseType.EffectRequest); switch (responseType) { case ResponseType.EffectStatus: if (responseType != ResponseType.EffectStatus) { break; } response = ((JToken)j).ToObject<EffectUpdate>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.EffectRequest: response = ((JToken)j).ToObject<EffectResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.RpcRequest: response = ((JToken)j).ToObject<RpcRequest>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.GenericEvent: response = ((JToken)j).ToObject<GenericEventResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.DataResponse: response = ((JToken)j).ToObject<DataResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.Login: response = ((JToken)j).ToObject<EmptyResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.LoginSuccess: response = ((JToken)j).ToObject<EmptyResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.Version: response = ((JToken)j).ToObject<VersionResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.GameUpdate: response = ((JToken)j).ToObject<GameUpdate>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.Disconnect: response = ((JToken)j).ToObject<MessageResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; case ResponseType.KeepAlive: response = ((JToken)j).ToObject<EmptyResponse>(SimpleJSONMessage.JSON_SERIALIZER); return true; } } catch { } response = null; return false; } } [JsonConverter(typeof(CamelCaseStringEnumConverter))] public enum StandardErrors { Unknown = 0, ExceptionThrown = 1, BadRequest = 4096, EffectUnknown = 4097, [Obsolete("Use EffectUnknown instead.")] UnknownEffect = 4097, EffectDisabled = 4098, AlreadyFailed = 4099, CannotParseNumber = 4112, UnknownSelection = 4113, ConnectorError = 8192, ConnectorReadFailure = 8193, ConnectorWriteFailure = 8194, ConnectorNotConnected = 8195, ConnectorNotSupported = 8196, NoResponse = 8448, SettingsError = 12288, CooldownPerEffect = 12545, CooldownGlobal = 12546, RetryMaxTime = 12291, RetryMaxAttempts = 12292, NoSession = 20480, SessionEnding = 20481, BadGameState = 16384, GameObjectNotFound = 16640, PlayerNotFound = 16641, CharacterNotFound = 16642, EnemyNotFound = 16643, ObjectNotFound = 16644, PrerequisiteNotFound = 16645, ObjectStateError = 16896, AlreadyInState = 16897, AlreadyAcquired = 16898, AlreadyFinished = 16899, NoEmptyContainers = 16912, PartyFull = 16913, InvalidArea = 16928, InvalidTarget = 16929, NoValidTargets = 16930, SpawnNotAllowedHere = 16932, RangeError = 17152, AlreadyMinimum = 17153, AlreadyMaximum = 17154, EffectNotImplemented = 24576, PackResourceMissing = 24577, EmulatorNotSupported = 28672, EmulatorInvalidSetting = 28673, ConflictingEffectRunning = 32768, UnqueueablePending = 32769 } internal static class StringEx { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNullOrWhiteSpace(this string? input) { return string.IsNullOrWhiteSpace(input); } internal static string ToCamelCase(this string input) { bool flag = false; string text = ""; checked { for (int i = 0; i < input.Length; i++) { if (char.IsUpper(input[i])) { if (flag) { text += input.Substring(i); break; } text += char.ToLower(input[i]); } else { flag = true; text = ((i <= 1 || !char.IsUpper(input[i - 1]) || !char.IsUpper(input[i - 2])) ? (text + input[i]) : (text.Substring(0, text.Length - 1) + char.ToUpper(input[i - 1]) + input[i])); } } return text; } } internal unsafe static string[] Chop(this string value, int chopLength) { int length = value.Length; char* ptr = stackalloc char[chopLength]; string[] array = new string[length]; for (int i = 0; i < length; i = checked(i + chopLength)) { int j; for (j = 0; j < chopLength; j = checked(j + 1)) { int num = checked(i + j); if (num >= length) { break; } *(char*)((byte*)ptr + checked(unchecked((nint)j) * (nint)2)) = value[num]; } array[i / chopLength] = new string(ptr, 0, j); } return array; } } public static class TypeEx { public static bool IsAssignableTo(this Type? type, Type? targetType) { if ((object)type != null && (object)targetType != null) { return targetType.IsAssignableFrom(type); } return false; } } [Serializable] [JsonConverter(typeof(Converter))] public class VersionNumber : IEquatable<VersionNumber>, IComparable<VersionNumber> { private class Converter : JsonConverter<VersionNumber> { public override void WriteJson(JsonWriter writer, VersionNumber? value, JsonSerializer serializer) { if (value == null) { writer.WriteNull(); } else { writer.WriteValue((string)value); } } public override VersionNumber? ReadJson(JsonReader reader, Type objectType, VersionNumber? existingValue, bool hasExistingValue, JsonSerializer serializer) { object value = reader.Value; if (value == null) { return null; } if (!(value is string value2)) { return null; } return new VersionNumber(value2); } } public static readonly VersionNumber Zero = new VersionNumber(new Span<uint>(new uint[1])); public static readonly VersionNumber One = new VersionNumber(new Span<uint>(new uint[1] { 1u })); private readonly uint[] _version; public VersionNumber(string value) { _version = (from v in value.Split('.') select uint.TryParse(Sanitize(v), out var result) ? result : 0u).ToArray(); } public VersionNumber(IEnumerable<uint> values) { _version = values.ToArray(); } public VersionNumber(VersionNumber version) { _version = version._version.ToArray(); } public VersionNumber([ParamCollection] scoped Span<uint> values) { _version = values.ToArray(); } public static implicit operator VersionNumber(string value) { return new VersionNumber(value); } public static implicit operator VersionNumber(uint value) { return new VersionNumber(new Span<uint>(new uint[1] { value })); } public static implicit operator VersionNumber(uint[] values) { return new VersionNumber((Span<uint>)values); } public static implicit operator VersionNumber(Span<uint> values) { return new VersionNumber(values); } public static implicit operator VersionNumber(List<uint> values) { return new VersionNumber((IEnumerable<uint>)values); } public static implicit operator string(VersionNumber value) { return value.ToString(); } public static implicit operator uint[](VersionNumber value) { return value._version.ToArray(); } public static bool operator ==(VersionNumber? a, VersionNumber? b) { return Equals(a, b); } public static bool operator !=(VersionNumber? a, VersionNumber? b) { return !Equals(a, b); } public static bool operator <(VersionNumber? a, VersionNumber? b) { return CompareTo(a, b) < 0; } public static bool operator >(VersionNumber? a, VersionNumber? b) { return CompareTo(a, b) > 0; } public static bool operator <=(VersionNumber? a, VersionNumber? b) { return CompareTo(a, b) <= 0; } public static bool operator >=(VersionNumber? a, VersionNumber? b) { return CompareTo(a, b) >= 0; } public override string ToString() { return string.Join('.', _version.Select((uint v) => v.ToString("D"))); } public static bool Equals(VersionNumber? a, VersionNumber? b) { return a?.Equals(b) ?? ((object)b == null); } public override bool Equals(object? obj) { if (obj == null) { return false; } if (this == obj) { return true; } if (TypeEx.IsAssignableTo(obj.GetType(), typeof(VersionNumber))) { return false; } return Equals((VersionNumber)obj); } public override int GetHashCode() { return _version.GetHashCode(); } public bool Equals(VersionNumber? other) { if ((object)other == null) { return false; } if ((object)this == other) { return true; } int num = _version.Length; if (num != other._version.Length) { return false; } for (int i = 0; i < num; i = checked(i + 1)) { if (_version[i] != other._version[i]) { return false; } } return true; } public static int CompareTo(VersionNumber? a, VersionNumber? b) { if ((object)a == null) { if ((object)b != null) { return -1; } return 0; } return a.CompareTo(b); } public int CompareTo(VersionNumber? other) { if ((object)other == null) { return 1; } int num = _version.Length; int num2 = other._version.Length; int num3 = Math.Min(num, num2); checked { int i; for (i = 0; i < num3; i++) { uint num4 = _version[i]; uint num5 = other._version[i]; if (num4 != num5) { if (num4 > num5) { return 1; } return -1; } } if (num == num2) { return 0; } if (num > num2) { for (; i < num; i++) { if (_version[i] != 0) { return 1; } } return 0; } for (; i < num2; i++) { if (other._version[i] != 0) { return -1; } } return 0; } } public static VersionNumber GetAssemblyVersion(IEnumerable<Assembly> assemblies) { VersionNumber versionNumber = Zero; foreach (Assembly assembly in assemblies) { VersionNumber versionNumber2; try { versionNumber2 = GetAssemblyVersion(assembly); } catch { versionNumber2 = Zero; } if (versionNumber2 > versionNumber) { versionNumber = versionNumber2; } } return versionNumber; } public static VersionNumber GetAssemblyVersion(Assembly assembly) { string text = null; object[] customAttributes = assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), inherit: false); if (customAttributes != null && customAttributes.Length > 0) { text = ((AssemblyInformationalVersionAttribute)customAttributes[0]).InformationalVersion; } if (text == null || text.Length == 0) { text = GetFileVersionInfo(assembly).ProductVersion?.Trim(); } if (text == null || text.Length == 0) { text = Zero; } return text; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static string Sanitize(string value) { for (int i = 0; i < value.Length; i = checked(i + 1)) { if (!char.IsDigit(value[i])) { return value.Substring(0, i); } } return value; } private static FileVersionInfo GetFileVersionInfo(Assembly assembly) { return FileVersionInfo.GetVersionInfo(assembly.Location); } } [Serializable] public class VersionResponse : SimpleJSONResponse { public VersionNumber version; [JsonConstructor] public VersionResponse(VersionNumber version) { this.version = version; type = ResponseType.Version; } public VersionResponse(uint id, VersionNumber version) { base.id = id; this.version = version; type = ResponseType.Version; } } }
BepInEx/plugins/CrowdControl.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net.Sockets; 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 BepinControl; using ConnectorLib.JSON; using CrowdControl; using CrowdControl.Delegates.Effects; using CrowdControl.Delegates.Effects.Implementations; using CrowdControl.Delegates.Metadata; using CrowdControl.UI; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Peak.Afflictions; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class ParamCollectionAttribute : Attribute { } [CompilerGenerated] [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] [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] [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 BepinControl { public class RPCCommands { public class MessageHandler : MonoBehaviourPunCallbacks, IPunObservable { public class NetworkMessage { public string type; public int id; public int targetActor; public int senderID; public Dictionary<string, object> payload; public NetworkMessage(string type, int id = 0, int senderID = 0, int targetActor = 0, Dictionary<string, object> payload = null) { this.type = type; this.payload = payload ?? new Dictionary<string, object>(); this.id = id; this.senderID = senderID; this.targetActor = targetActor; } } private class RequestMessage { public string type { get; set; } public Dictionary<string, object> payload { get; set; } public int id { get; set; } public int senderID { get; set; } public int targetActor { get; set; } public bool random { get; set; } } private class ResponseMessage { public string type { get; set; } = "response"; public int id { get; set; } public int senderID { get; set; } public int targetActor { get; set; } public string status { get; set; } public string message { get; set; } public string version { get; set; } public Dictionary<string, object> payload { get; set; } } public static MessageHandler instance; public static PhotonView networkView; private static ConcurrentQueue<NetworkMessage> messageQueue = new ConcurrentQueue<NetworkMessage>(); public static void Initialize() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)instance != (Object)null) { return; } CrowdControlMod.Instance.Logger.LogInfo((object)"Initializing MessageHandler..."); GameObject val = new GameObject("MessageHandler"); instance = val.AddComponent<MessageHandler>(); networkView = val.AddComponent<PhotonView>(); if ((Object)(object)networkView != (Object)null) { networkView.ViewID = 6767; networkView.Synchronization = (ViewSynchronization)3; networkView.ObservedComponents = new List<Component> { (Component)(object)instance }; CrowdControlMod.Instance.Logger.LogInfo((object)$"MessageHandler initialized with PhotonView {networkView.ViewID}"); Object.DontDestroyOnLoad((Object)(object)val); lock (networkLock) { _isNetworkReady = null; _isViewValid = null; return; } } CrowdControlMod.Instance.Logger.LogError((object)"Failed to add PhotonView to MessageHandler"); CrowdControlMod.modActivated = false; } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("Error in Initialize: " + ex.Message)); CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex.StackTrace)); } } private void OnLevelWasLoaded(int level) { lock (networkLock) { _isNetworkReady = null; _isViewValid = null; } if ((Object)(object)networkView == (Object)null || !networkView.ViewID.Equals(6767)) { Initialize(); } } private void Update() { if (messageQueue.TryDequeue(out NetworkMessage result)) { SendQueuedMessage(result); } } private static void SendQueuedMessage(NetworkMessage message) { if (IsNetworkReady()) { try { string text = JsonConvert.SerializeObject((object)message); PhotonNetwork.CurrentRoom.GetPlayer(message.senderID, false); networkView.RPC("OnNetworkMessageRPC", (RpcTarget)0, new object[1] { text }); } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("Failed to send message: " + ex.Message)); CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex.StackTrace)); } } } public static void SendMessageToHost(string type, int id = 0, int senderID = 0, int targetActor = 0, Dictionary<string, object> payload = null) { try { if (!IsNetworkReady()) { return; } NetworkMessage item = new NetworkMessage(type, id, senderID, targetActor, payload); if (id > 0) { lock (pendingRequestIDs) { pendingRequestIDs.Add(id.ToString()); } } messageQueue.Enqueue(item); } catch (Exception arg) { CrowdControlMod.Instance.Logger.LogInfo((object)$"Failed to queue message: {arg}"); } } public static void SendMessageToAll(string type, Dictionary<string, object> payload = null) { try { if (IsNetworkReady()) { int senderID = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : 0); NetworkMessage item = new NetworkMessage(type, 0, senderID, 0, payload); messageQueue.Enqueue(item); } } catch (Exception arg) { CrowdControlMod.Instance.Logger.LogInfo((object)$"Failed to queue broadcast message: {arg}"); } } public override void OnEnable() { ((MonoBehaviourPunCallbacks)this).OnEnable(); } public override void OnJoinedRoom() { ((MonoBehaviourPunCallbacks)this).OnJoinedRoom(); lock (networkLock) { _isNetworkReady = null; _isViewValid = null; } CrowdControlMod.modActivated = false; if (PhotonNetwork.IsMasterClient) { CrowdControlMod.modActivated = true; } } [PunRPC] public void OnNetworkMessageRPC(string jsonMessage) { try { NetworkMessage networkMessage = JsonConvert.DeserializeObject<NetworkMessage>(jsonMessage); CrowdControlMod.Instance.Logger.LogInfo((object)$"[OnNetworkMessageRPC] Received message type: {networkMessage.type}, targetActor: {networkMessage.targetActor}, local ActorNumber: {PhotonNetwork.LocalPlayer.ActorNumber}"); if (networkMessage.type == "revive_self") { CrowdControlMod.Instance.Logger.LogInfo((object)$"[OnNetworkMessageRPC] revive_self: targetActor={networkMessage.targetActor}, local={PhotonNetwork.LocalPlayer.ActorNumber}"); } if (networkMessage == null) { CrowdControlMod.Instance.Logger.LogError((object)"Failed to deserialize message"); return; } if (networkMessage.type == "custom_event") { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HOST] Received custom event message from player {networkMessage.senderID}"); CrowdControlMod.Instance.Logger.LogInfo((object)("[HOST] Message payload: " + JsonConvert.SerializeObject((object)networkMessage.payload))); if (networkMessage.payload.TryGetValue("eventName", out object value)) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HOST] Event name: {value}"); } if (networkMessage.payload.TryGetValue("data", out object value2)) { CrowdControlMod.Instance.Logger.LogInfo((object)("[HOST] Event data: " + JsonConvert.SerializeObject(value2))); } } if (networkMessage.type == "response") { ProcessMessage(jsonMessage); } else if (networkMessage.type == "storm_visual") { StormEffect.HandleStormVisualMessage(networkMessage.payload); } else if (networkMessage.type == "storm_end") { StormEffect.HandleStormEndMessage(); } else if (networkMessage.type == "spawn_local_hazard") { SpawnHazardEffect.HandleLocalHazardMessage(networkMessage.payload); } else if (networkMessage.type == "CC_CONNECT") { ModVersionCheck(networkMessage); } else if (networkMessage.type == "override_voice") { CrowdControlMod.Instance.Logger.LogInfo((object)"Voice override effect triggered (not implemented)"); } else if (networkMessage.type == "revive_self" && networkMessage.targetActor == PhotonNetwork.LocalPlayer.ActorNumber) { CrowdControlMod.Instance.Logger.LogInfo((object)"[LOCAL] Received revive_self request from host"); HandleReviveSelf(); } else { if (!PhotonNetwork.IsMasterClient) { return; } if (networkMessage.type == "custom_event") { if (networkMessage.payload.TryGetValue("eventName", out object value3) && networkMessage.payload.TryGetValue("data", out object value4)) { string text = value3.ToString(); JObject val = (JObject)((value4 is JObject) ? value4 : null); Dictionary<string, object> dictionary = ((val != null) ? ((JToken)val).ToObject<Dictionary<string, object>>() : ((!(value4 is Dictionary<string, object> dictionary2)) ? new Dictionary<string, object>() : dictionary2)); string requestId = networkMessage.id.ToString(); CrowdControlMod.Instance.Logger.LogInfo((object)("[HOST] Processing custom event '" + text + "' with data: " + JsonConvert.SerializeObject((object)dictionary))); CustomEventSystem.Instance.OnCustomEventRequest(text, dictionary, requestId, networkMessage.senderID); } else { CrowdControlMod.Instance.Logger.LogError((object)("[HOST] Missing required fields in custom event message. Payload: " + JsonConvert.SerializeObject((object)networkMessage.payload))); } } else { CrowdControlMod.Instance.Logger.LogWarning((object)("Unknown message type: " + networkMessage.type)); } } } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("Failed to process message: " + ex.Message)); CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex.StackTrace)); } } public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { } public unsafe static void SendResponse(int id, int senderID, EffectStatus status, string message = "", Dictionary<string, object> payload = null) { try { int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber; Dictionary<string, object> dictionary = new Dictionary<string, object> { { "status", ((object)(*(EffectStatus*)(&status))/*cast due to .constrained prefix*/).ToString() }, { "message", message.ToString() }, { "cmd", "response" } }; if (payload != null && payload.ContainsKey("version") && payload["version"] != null) { dictionary["version"] = payload["version"].ToString(); } string text = JsonConvert.SerializeObject((object)new NetworkMessage("response", id, senderID, actorNumber, dictionary)); Player player = PhotonNetwork.CurrentRoom.GetPlayer(senderID, false); if (id == 0) { networkView.RPC("OnNetworkMessageRPC", (RpcTarget)0, new object[1] { text }); } else { networkView.RPC("OnNetworkMessageRPC", player, new object[1] { text }); } } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogInfo((object)("SEND RESPONSE CRASHED " + ex)); } } private IEnumerator SendDelayedResponse(int id, int senderID, bool success) { yield return (object)new WaitForSeconds(0.1f); SendResponse(id, senderID, (EffectStatus)(!success)); } public static bool IsHost() { return PhotonNetwork.IsMasterClient; } private static void HandleReviveSelf() { //IL_00e6: 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) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) try { Character character = Character.localCharacter; if (!Object.op_Implicit((Object)(object)character)) { CrowdControlMod.Instance.Logger.LogError((object)"[HandleReviveSelf] Local character not found"); return; } CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveSelf] State before revive: dead={character.data.dead}, fullyPassedOut={character.data.fullyPassedOut}"); if (!character.data.dead && !character.data.fullyPassedOut) { CrowdControlMod.Instance.Logger.LogWarning((object)"[HandleReviveSelf] Local character is not dead or passed out, forcing revive anyway!"); Character.Revive(); CrowdControlMod.Instance.Logger.LogInfo((object)"[HandleReviveSelf] Forced revive for local player"); return; } Rigidbody component = ((Component)character).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.velocity = Vector3.zero; component.angularVelocity = Vector3.zero; component.Sleep(); } if (character.data.dead) { CrowdControlMod.Instance.Logger.LogInfo((object)"[HandleReviveSelf] Reviving from dead"); Character.Revive(); } else if (character.data.fullyPassedOut) { CrowdControlMod.Instance.Logger.LogInfo((object)"[HandleReviveSelf] Reviving from fullyPassedOut"); Character.Revive(); } List<Character> list = Character.AllCharacters.Where((Character c) => (Object)(object)c != (Object)(object)character && !c.data.dead && !c.data.fullyPassedOut).ToList(); if (list.Count > 0) { Character val = list[Random.Range(0, list.Count)]; Vector3 val2 = ((Component)val).transform.position + ((Component)val).transform.forward * 1.5f + Vector3.up; Transform[] componentsInChildren = ((Component)((Component)val).transform).GetComponentsInChildren<Transform>(); foreach (Transform val3 in componentsInChildren) { if (((Object)val3).name == "Hip") { val2 = val3.position + val3.forward * 1.5f + Vector3.up; break; } } character.WarpPlayerRPC(val2, true); } if ((Object)(object)component != (Object)null) { component.WakeUp(); } CrowdControlMod.Instance.Logger.LogInfo((object)"[HandleReviveSelf] Successfully revived local player"); } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("[HandleReviveSelf] Error reviving local player: " + ex.Message)); } } public static void SendRequest(string type, int id, int senderID, int targetActor, Dictionary<string, object> payload) { try { string text = JsonConvert.SerializeObject((object)new RequestMessage { type = type, id = id, senderID = senderID, targetActor = targetActor, payload = payload }, jsonSettings); if (type == "revive_self") { CrowdControlMod.Instance.Logger.LogInfo((object)$"[SendRequest] Sending revive_self to RpcTarget.All (targetActor: {targetActor})"); networkView.RPC("OnNetworkMessageRPC", (RpcTarget)0, new object[1] { text }); } else { Player player = PhotonNetwork.CurrentRoom.GetPlayer(targetActor, false); networkView.RPC("OnNetworkMessageRPC", player, new object[1] { text }); } } catch (Exception arg) { CrowdControlMod.Instance.Logger.LogInfo((object)$"SEND REQUEST CRASHED {arg}"); } } public unsafe static void SendResponse(int id, int senderID, EffectStatus status, Dictionary<string, object> payload) { try { string text = JsonConvert.SerializeObject((object)new ResponseMessage { id = id, senderID = senderID, status = ((object)(*(EffectStatus*)(&status))/*cast due to .constrained prefix*/).ToString(), payload = payload }, jsonSettings); if ((Object)(object)networkView != (Object)null) { Player player = PhotonNetwork.CurrentRoom.GetPlayer(senderID, false); if (id == 0) { networkView.RPC("OnNetworkMessageRPC", (RpcTarget)3, new object[1] { text }); } else { networkView.RPC("OnNetworkMessageRPC", player, new object[1] { text }); } } } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogInfo((object)("SEND RESPONSE2 " + ex)); } } public static void AddResponder(int msgID, Action<EffectStatus> responder) { rspResponders[msgID] = responder; } public static void RemoveResponder(int msgID) { rspResponders.TryRemove(msgID, out Action<EffectStatus> _); } public static void ProcessMessage(string message) { try { if (string.IsNullOrEmpty(message)) { return; } JObject val = JObject.Parse(message); if (val == null) { CrowdControlMod.Instance.Logger.LogWarning((object)("Received malformed message: " + message)); return; } if (((object)val["type"])?.ToString() == "response") { ResponseMessage responseMessage = new ResponseMessage(); JToken obj = val["id"]; responseMessage.id = ((obj != null) ? Extensions.Value<int>((IEnumerable<JToken>)obj) : 0); JToken obj2 = val["senderID"]; responseMessage.senderID = ((obj2 != null) ? Extensions.Value<int>((IEnumerable<JToken>)obj2) : 0); JToken obj3 = val["targetActor"]; responseMessage.targetActor = ((obj3 != null) ? Extensions.Value<int>((IEnumerable<JToken>)obj3) : 0); JToken obj4 = val["payload"]; responseMessage.payload = ((obj4 != null) ? obj4.ToObject<Dictionary<string, object>>() : null) ?? new Dictionary<string, object>(); JToken obj5 = val["payload"]; responseMessage.status = ((obj5 == null) ? null : ((object)obj5[(object)"status"])?.ToString()); JToken obj6 = val["payload"]; responseMessage.version = ((obj6 == null) ? null : ((object)obj6[(object)"version"])?.ToString()); ResponseMessage responseMessage2 = responseMessage; if (responseMessage2.payload.TryGetValue("custom_event_response", out object _)) { if (responseMessage2.payload.TryGetValue("requestId", out object value2) && responseMessage2.payload.TryGetValue("message", out object value3) && responseMessage2.payload.TryGetValue("data", out object value4)) { string requestId = value2.ToString(); string message2 = value3.ToString(); Dictionary<string, object> data = (value4 as Dictionary<string, object>) ?? new Dictionary<string, object>(); bool success = responseMessage2.status == "Success"; CustomEventSystem.Instance.OnEventResponse(requestId, success, message2, data); } } else { ProcessResponse(responseMessage2); } return; } try { JsonConvert.DeserializeObject<RequestMessage>(message, jsonSettings); } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("Error processing message2: " + ex.Message)); } } catch (Exception ex2) { CrowdControlMod.Instance.Logger.LogError((object)("Error processing message: " + ex2.Message)); CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex2.StackTrace)); } } private static void ProcessResponse(ResponseMessage message) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (message.senderID != PhotonNetwork.LocalPlayer.ActorNumber) { return; } if (message.id == 0 && message.version == "1.8.3.0") { CrowdControlMod.modActivated = true; } if (!rspResponders.TryGetValue(message.id, out Action<EffectStatus> value) || !pendingRequestIDs.Remove(message.id.ToString()) || !Enum.TryParse<EffectStatus>(message.status, out EffectStatus result)) { return; } try { value(result); } catch (Exception arg) { CrowdControlMod.Instance.Logger.LogInfo((object)$"Error processing response for message ID {message.id}: {arg}"); } } public static async Task ModVersionCheck(NetworkMessage message) { Convert.ToString(message.payload["version"]); _ = message.senderID; } } internal static HashSet<string> pendingRequestIDs = new HashSet<string>(); private static readonly ConcurrentDictionary<int, Action<EffectStatus>> rspResponders = new ConcurrentDictionary<int, Action<EffectStatus>>(); private static readonly JsonSerializerSettings jsonSettings = new JsonSerializerSettings { NullValueHandling = (NullValueHandling)1, ReferenceLoopHandling = (ReferenceLoopHandling)1 }; private static readonly object networkLock = new object(); private static bool? _isNetworkReady = null; private static bool? _isViewValid = null; private static readonly Dictionary<string, string> PlayerVersions = new Dictionary<string, string>(); private static bool IsViewValid() { lock (networkLock) { if (_isViewValid.HasValue) { return _isViewValid.Value; } PhotonView networkView = MessageHandler.networkView; if ((Object)(object)networkView == (Object)null) { _isViewValid = false; CrowdControlMod.Instance.Logger.LogWarning((object)"NetworkView is null"); return false; } _isViewValid = networkView.ViewID != 0; return _isViewValid.Value; } } private static bool IsNetworkReady() { lock (networkLock) { if (_isNetworkReady.HasValue) { return _isNetworkReady.Value; } bool flag = IsViewValid(); _isNetworkReady = PhotonNetwork.IsConnected && PhotonNetwork.InRoom && flag && MessageHandler.networkView.ObservedComponents != null; return _isNetworkReady.Value; } } } } namespace CrowdControl { [BepInPlugin("WarpWorld.CrowdControl", "Crowd Control", "1.8.3.0")] public class CrowdControlMod : BaseUnityPlugin { public const string MOD_GUID = "WarpWorld.CrowdControl"; public const string MOD_NAME = "Crowd Control"; public const string MOD_VERSION = "1.8.3.0"; private readonly Harmony harmony = new Harmony("WarpWorld.CrowdControl"); internal static bool modActivated = false; internal static bool modEnabled = true; private const float GAME_STATUS_UPDATE_INTERVAL = 1f; private float m_gameStatusUpdateTimer; private const double MANUAL_RECONNECT_COOLDOWN_SECONDS = 5.0; private DateTime m_nextManualReconnectAllowedUtc = DateTime.MinValue; private bool m_clientPresent; private float m_nextClientCheck; private const float CLIENT_CHECK_INTERVAL = 2f; private string? _modVersion; public static float DeltaTime { get { if (!(Time.timeScale > 0f)) { return 0f; } return Time.fixedDeltaTime / Time.timeScale; } } public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger; internal static CrowdControlMod Instance { get; private set; } = null; public GameStateManager GameStateManager { get; private set; } public EffectLoader EffectLoader { get; private set; } public bool ClientConnected => Client.Connected; public NetworkClient Client { get; private set; } public Scheduler Scheduler { get; private set; } public static bool HasFocus { get; private set; } = true; public string Version { get { try { if (!string.IsNullOrEmpty(_modVersion)) { return _modVersion; } string text = File.ReadAllText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ccver")); if (string.IsNullOrEmpty(text)) { _modVersion = "1.8.3.0"; } else { _modVersion = text; } return _modVersion; } catch (Exception arg) { Logger.LogInfo((object)$"Error retrieving mod version: {arg}"); return "0"; } } } private void Awake() { Instance = this; Logger.LogInfo((object)"Loaded WarpWorld.CrowdControl. Patching."); harmony.PatchAll(); ModSettings.Initialize(((BaseUnityPlugin)this).Config); Logger.LogInfo((object)"Initializing Crowd Control"); try { GameStateManager = new GameStateManager(this); Client = new NetworkClient(this); EffectLoader = new EffectLoader(this, Client); Scheduler = new Scheduler(this, Client); _ = CustomEventSystem.Instance; RPCCommands.MessageHandler.Initialize(); } catch (Exception arg) { Logger.LogError((object)$"Crowd Control Init Error: {arg}"); } Logger.LogInfo((object)"Crowd Control Initialized"); } private void OnApplicationQuit() { try { Client?.Stop(); Client?.Dispose(); } catch { } } private void OnDestroy() { try { Client?.Stop(); Client?.Dispose(); } catch { } } private void FixedUpdate() { if (modEnabled && GameStateManager != null) { m_gameStatusUpdateTimer += Time.fixedDeltaTime; if (m_gameStatusUpdateTimer >= 1f) { GameStateManager.UpdateGameState(); GameStateManager.UpdateTeleportRandomPlayerVisibility(); m_gameStatusUpdateTimer = 0f; } Scheduler?.Tick(); } } private void Update() { UpdateClientPresence(); HandleOverlayToggleHotkey(); HandleManualReconnectHotkey(); } private void UpdateClientPresence() { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup < m_nextClientCheck) { return; } m_nextClientCheck = realtimeSinceStartup + 2f; try { m_clientPresent = Client?.CrowdControlClientFound ?? false; } catch { m_clientPresent = false; } } private void OnGUI() { try { Overlay.Draw(ClientConnected, m_clientPresent); } catch { } } private void HandleOverlayToggleHotkey() { if (Input.GetKeyDown((KeyCode)289)) { bool flag = Overlay.Toggle(); Logger.LogInfo((object)("F8 pressed - overlay " + (flag ? "shown" : "hidden") + ".")); if (flag) { Overlay.Show("Crowd Control display on (F8)", force: true); } } } private void HandleManualReconnectHotkey() { if (!Input.GetKeyDown((KeyCode)290)) { return; } DateTime utcNow = DateTime.UtcNow; if (!(utcNow < m_nextManualReconnectAllowedUtc)) { m_nextManualReconnectAllowedUtc = utcNow.AddSeconds(5.0); Logger.LogInfo((object)"F9 pressed - manual Crowd Control reconnect requested."); NetworkClient client = Client; if (client != null && client.RequestReconnect()) { Overlay.Show("Reconnecting to Crowd Control...", force: true); ShowGameUiMessage("Reconnecting to Crowd Control..."); Logger.LogInfo((object)"Manual Crowd Control reconnect queued."); } else { Overlay.Show("Crowd Control client not found.", force: true); ShowGameUiMessage("Crowd Control client not found."); Logger.LogInfo((object)"Manual Crowd Control reconnect skipped because the Crowd Control client was not found."); } } } public void ShowGameUiMessage(string message) { Overlay.Show(message); GameNotifications.Show(message); CrowdControl.GameStateManager.DialogMsgAsync(message, playSound: false); } private void OnApplicationFocus(bool hasFocus) { HasFocus = hasFocus; try { GameStateManager?.UpdateGameState(); } catch { } } private void OnApplicationPause(bool isPaused) { if (isPaused) { HasFocus = false; } try { GameStateManager?.UpdateGameState(); } catch { } } public void DisableMod() { modEnabled = false; Logger.LogInfo((object)"[HotReload] Mod disabled - safe to replace DLL"); } public void EnableMod() { modEnabled = true; Logger.LogInfo((object)"[HotReload] Mod enabled"); } } public class CustomEventSystem : MonoBehaviourPunCallbacks { public static bool EnableDebugLogging; private static CustomEventSystem _instance; private readonly ConcurrentDictionary<string, CustomEventHandler> _registeredEvents = new ConcurrentDictionary<string, CustomEventHandler>(); private readonly ConcurrentQueue<EventRequest> _pendingRequests = new ConcurrentQueue<EventRequest>(); private readonly ConcurrentDictionary<string, Action<EventResponse>> _responseCallbacks = new ConcurrentDictionary<string, Action<EventResponse>>(); public static CustomEventSystem Instance { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("CustomEventSystem"); _instance = val.AddComponent<CustomEventSystem>(); Object.DontDestroyOnLoad((Object)val); } return _instance; } } private void Awake() { if ((Object)(object)_instance == (Object)null) { _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } else if ((Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Update() { EventRequest result; while (_pendingRequests.TryDequeue(out result)) { ProcessEventRequest(result); } } public bool RegisterEvent(string eventName, CustomEventHandler handler) { if (!PhotonNetwork.IsMasterClient) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogWarning((object)("Cannot register event '" + eventName + "' - not the host")); } return false; } if (_registeredEvents.TryAdd(eventName, handler)) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("Registered custom event: " + eventName)); } return true; } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogWarning((object)("Event '" + eventName + "' is already registered")); } return false; } public bool UnregisterEvent(string eventName) { if (!PhotonNetwork.IsMasterClient) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogWarning((object)("Cannot unregister event '" + eventName + "' - not the host")); } return false; } if (_registeredEvents.TryRemove(eventName, out CustomEventHandler _)) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("Unregistered custom event: " + eventName)); } return true; } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogWarning((object)("Event '" + eventName + "' was not registered")); } return false; } public bool TriggerEvent(string eventName, Dictionary<string, object> data = null, Action<EventResponse> callback = null) { if (PhotonNetwork.IsMasterClient) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogWarning((object)("Cannot trigger event '" + eventName + "' - you are the host")); } return false; } int id = Random.Range(1000000, 9999999); string text = id.ToString(); new EventRequest { Id = text, EventName = eventName, Data = (data ?? new Dictionary<string, object>()), SenderId = PhotonNetwork.LocalPlayer.ActorNumber }; if (callback != null) { _responseCallbacks[text] = callback; } Dictionary<string, object> dictionary = new Dictionary<string, object> { ["eventName"] = eventName, ["data"] = data ?? new Dictionary<string, object>() }; if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Sending event '" + eventName + "' to host with payload: " + JsonConvert.SerializeObject((object)dictionary))); } RPCCommands.MessageHandler.SendMessageToHost("custom_event", id, PhotonNetwork.LocalPlayer.ActorNumber, 0, dictionary); if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("Triggered custom event: " + eventName)); } return true; } private void ProcessEventRequest(EventRequest request) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Processing event request: " + request.EventName)); } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Request data: " + JsonConvert.SerializeObject((object)request.Data))); } if (!PhotonNetwork.IsMasterClient) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogWarning((object)"Received event request but not the host"); } return; } if (!_registeredEvents.TryGetValue(request.EventName, out CustomEventHandler value)) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("[CustomEventSystem] Event '" + request.EventName + "' not found in registered events")); } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Available events: " + string.Join(", ", _registeredEvents.Keys))); } SendEventResponse(request.Id, request.SenderId, success: false, "Event '" + request.EventName + "' not found"); return; } try { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Executing handler for event: " + request.EventName)); } EventResult eventResult = value(request.Data); if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[CustomEventSystem] Handler result: Success={eventResult.Success}, Message={eventResult.Message}"); } SendEventResponse(request.Id, request.SenderId, eventResult.Success, eventResult.Message, eventResult.Data); } catch (Exception ex) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("[CustomEventSystem] Error processing event '" + request.EventName + "': " + ex.Message)); } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("[CustomEventSystem] Stack trace: " + ex.StackTrace)); } SendEventResponse(request.Id, request.SenderId, success: false, "Error: " + ex.Message); } } private void SendEventResponse(string requestId, int senderId, bool success, string message = "", Dictionary<string, object> data = null) { Dictionary<string, object> payload = new Dictionary<string, object> { ["custom_event_response"] = true, ["requestId"] = requestId, ["message"] = message, ["data"] = data ?? new Dictionary<string, object>() }; RPCCommands.MessageHandler.SendResponse(int.Parse(requestId), senderId, (EffectStatus)(!success), payload); } public void OnEventResponse(string requestId, bool success, string message, Dictionary<string, object> data) { if (_responseCallbacks.TryRemove(requestId, out Action<EventResponse> callback)) { EventResponse response = new EventResponse { Success = success, Message = message, Data = (data ?? new Dictionary<string, object>()) }; UnityMainThreadDispatcher.Instance.Enqueue(delegate { callback?.Invoke(response); }); } } public void OnCustomEventRequest(string eventName, Dictionary<string, object> data, string requestId, int senderId) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Received event request: " + eventName)); } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Request ID: " + requestId)); } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[CustomEventSystem] Sender ID: {senderId}"); } if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[CustomEventSystem] Data: " + JsonConvert.SerializeObject((object)data))); } EventRequest item = new EventRequest { Id = requestId, EventName = eventName, Data = (data ?? new Dictionary<string, object>()), SenderId = senderId }; _pendingRequests.Enqueue(item); if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)"[CustomEventSystem] Queued event request for processing"); } } public List<string> GetRegisteredEvents() { return new List<string>(_registeredEvents.Keys); } public void ClearAllEvents() { _registeredEvents.Clear(); if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)"Cleared all registered custom events"); } } public override void OnMasterClientSwitched(Player newMasterClient) { if (PhotonNetwork.IsMasterClient) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)"Became host - ready to register custom events"); } HostEventHandlers.RegisterAllHandlers(); } else { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)"No longer host - clearing registered events"); } ClearAllEvents(); } } public override void OnJoinedRoom() { if (PhotonNetwork.IsMasterClient) { if (EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)"Joined room as host - ready to register custom events"); } HostEventHandlers.RegisterAllHandlers(); } } } public delegate EventResult CustomEventHandler(Dictionary<string, object> data); public class EventRequest { public string Id { get; set; } public string EventName { get; set; } public Dictionary<string, object> Data { get; set; } public int SenderId { get; set; } } public class EventResult { public bool Success { get; set; } public string Message { get; set; } public Dictionary<string, object> Data { get; set; } public static EventResult SuccessResult(string message = "", Dictionary<string, object> data = null) { return new EventResult { Success = true, Message = message, Data = (data ?? new Dictionary<string, object>()) }; } public static EventResult FailureResult(string message = "", Dictionary<string, object> data = null) { return new EventResult { Success = false, Message = message, Data = (data ?? new Dictionary<string, object>()) }; } } public class EventResponse { public bool Success { get; set; } public string Message { get; set; } public Dictionary<string, object> Data { get; set; } } public class UnityMainThreadDispatcher : MonoBehaviour { private static UnityMainThreadDispatcher _instance; private readonly Queue<Action> _executionQueue = new Queue<Action>(); public static UnityMainThreadDispatcher Instance { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("UnityMainThreadDispatcher"); _instance = val.AddComponent<UnityMainThreadDispatcher>(); Object.DontDestroyOnLoad((Object)val); } return _instance; } } public void Enqueue(Action action) { lock (_executionQueue) { _executionQueue.Enqueue(action); } } private void Update() { lock (_executionQueue) { while (_executionQueue.Count > 0) { _executionQueue.Dequeue()(); } } } } public class DelimitedStreamReader(NetworkStream stream) : IDisposable { private readonly MemoryStream _memory_stream = new MemoryStream(); private const int MAX_MESSAGE_SIZE = 1048576; ~DelimitedStreamReader() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); } protected virtual void Dispose(bool disposing) { if (!disposing) { return; } try { _memory_stream.Dispose(); } catch { } } public string ReadUntilNullTerminator() { int num; while ((num = stream.ReadByte()) != -1 && num != 0) { if (_memory_stream.Length >= 1048576) { _memory_stream.SetLength(0L); throw new InvalidDataException("Message exceeded the maximum allowed size without a null terminator. Dropping the connection."); } _memory_stream.WriteByte(checked((byte)num)); } if (num == -1) { throw new EndOfStreamException("Reached end of stream without finding a null terminator."); } string result = Encoding.UTF8.GetString(_memory_stream.ToArray()); _memory_stream.SetLength(0L); return result; } } public static class EffectRequestEx { public const string DEFAULT_VIEWER_NAME = "the crowd"; public const int MAX_VIEWER_NAME_LENGTH = 32; public static string GetViewerDisplayName(this EffectRequest request, string fallback = "the crowd") { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 string text = request.viewer; if (string.IsNullOrWhiteSpace(text) && request.viewers != null) { foreach (JToken viewer in request.viewers) { JToken obj = ((viewer is JObject) ? viewer : null); string text2 = ((obj != null) ? obj.Value<string>((object)"name") : null); if (text2 == null) { string text3 = (((int)viewer.Type != 8) ? null : Extensions.Value<string>((IEnumerable<JToken>)viewer)); text2 = text3; } text = text2; if (!string.IsNullOrWhiteSpace(text)) { break; } } } string text4 = SanitizeDisplayName(text); if (text4.Length <= 0) { return fallback; } return text4; } public static string SanitizeDisplayName(string? name) { if (string.IsNullOrWhiteSpace(name)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(Math.Min(name.Length, 32)); bool flag = true; foreach (char c in name) { if (char.IsControl(c) || char.IsSurrogate(c) || ((c == '<' || c == '>') ? true : false)) { continue; } if (char.IsWhiteSpace(c)) { if (flag) { continue; } stringBuilder.Append(' '); flag = true; } else { stringBuilder.Append(c); flag = false; } if (stringBuilder.Length >= 32) { break; } } return stringBuilder.ToString().TrimEnd(); } } internal static class GameNotifications { public static void Show(string message) { if (string.IsNullOrWhiteSpace(message)) { return; } UnityMainThreadDispatcher.Instance.Enqueue(delegate { try { UI_Notifications val = Object.FindObjectOfType<UI_Notifications>(); if ((Object)(object)val != (Object)null) { val.AddNotification(message); } else { PlayerConnectionLog val2 = Object.FindObjectOfType<PlayerConnectionLog>(); if ((Object)(object)val2 != (Object)null) { ((object)val2).GetType().GetMethod("AddMessage", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(val2, new object[1] { message }); } } } catch (Exception ex) { CrowdControlMod instance = CrowdControlMod.Instance; if (instance != null) { instance.Logger.LogWarning((object)("[GameNotifications] Failed to show notification: " + ex.Message)); } } }); } } public class GameStateManager(CrowdControlMod mod) { public static bool? isHostLastStatus = null; private bool? _teleportRandomPlayerTargetsAvailable; private static readonly FieldInfo? IN_AIRPORT_FIELD = typeof(CharacterAfflictions).GetField("m_inAirport", BindingFlags.Instance | BindingFlags.NonPublic); private Character? m_cachedCharacter; private CharacterAfflictions? m_cachedAfflictions; private const float GAME_STATE_CACHE_SECONDS = 0.25f; private GameState _cachedGameState; private float _cachedGameStateTime = float.NegativeInfinity; private GameState? _last_game_state; private volatile bool m_stateResendRequested; public static async Task DialogMsgAsync(string message, bool playSound) { } public void UpdateTeleportRandomPlayerVisibility() { if (!mod.Client.Connected) { return; } bool flag = PlayerTeleport.HasValidRandomPlayerTargets(); if (_teleportRandomPlayerTargetsAvailable != flag) { _teleportRandomPlayerTargetsAvailable = flag; if (flag) { mod.Client.ShowEffects("teleport_random_player"); } else { mod.Client.HideEffects("teleport_random_player"); } } } public static void updateEffects() { bool isMasterClient = PhotonNetwork.IsMasterClient; if (!isHostLastStatus.HasValue || isHostLastStatus != isMasterClient) { isHostLastStatus = isMasterClient; string[] codes = new string[16] { "spawn_item_rope", "spawn_item_marshmallow", "spawn_item_appleberryred", "spawn_item_appleberryyellow", "spawn_item_appleberrygreen", "spawn_item_bandage", "spawn_item_ropecannon", "spawn_item_backpack", "spawn_item_bugle", "spawn_item_flare", "spawn_item_book", "spawn_item_toy", "spawn_item_energydrink", "spawn_item_compass", "spawn_item_piratecompass", "spawn_item_warpcompass" }; if (isMasterClient) { CrowdControlMod.Instance.Client.ShowEffects(codes); } else { CrowdControlMod.Instance.Client.ShowEffects(codes); } } } public (bool isReady, string? message) IsReady(string code = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 GameState gameState = GetGameState(); if ((int)gameState == 1) { if (IsLocalPlayerInMenu()) { return (isReady: false, message: "Effects do not work while the pause menu is open."); } if (!CrowdControlMod.HasFocus) { return (isReady: false, message: "Effects do not work while the game is not in focus."); } return (isReady: true, message: null); } string text; if ((int)gameState <= -12) { if ((int)gameState != -13) { if ((int)gameState != -12) { goto IL_0082; } text = "Effects do not work in current player state."; } else { text = "Effects do not work in the airport."; } } else if ((int)gameState != -7) { if ((int)gameState != -6) { if ((int)gameState != -1) { goto IL_0082; } text = "Effects cannot be applied due to an error."; } else { text = "Effects do not work while loading."; } } else { text = "Effects do not work while paused."; } goto IL_0088; IL_0082: text = "Effects cannot be applied at this time."; goto IL_0088; IL_0088: string item = text; return (isReady: false, message: item); } public bool IsReadyBool(string code = "") { return IsReady(code).isReady; } private static bool IsLocalPlayerInMenu() { try { return Object.op_Implicit((Object)(object)GUIManager.instance) && GUIManager.InPauseMenu; } catch { return false; } } public GameState GetGameState() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return GetGameState(fresh: false); } public GameState GetGameState(bool fresh) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!fresh && Time.unscaledTime - _cachedGameStateTime < 0.25f) { return _cachedGameState; } GameState result = (_cachedGameState = ComputeGameState()); _cachedGameStateTime = Time.unscaledTime; return result; } private GameState ComputeGameState() { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) try { if (LoadingScreenHandler.loading) { return (GameState)(-6); } Character localCharacter = Character.localCharacter; if (!Object.op_Implicit((Object)(object)localCharacter)) { return (GameState)(-12); } if (localCharacter != m_cachedCharacter || (Object)(object)m_cachedAfflictions == (Object)null) { m_cachedCharacter = localCharacter; m_cachedAfflictions = ((Component)localCharacter).GetComponent<CharacterAfflictions>(); } CharacterAfflictions cachedAfflictions = m_cachedAfflictions; if ((Object)(object)cachedAfflictions == (Object)null) { return (GameState)(-13); } if (IN_AIRPORT_FIELD == null) { return (GameState)(-13); } if ((bool)IN_AIRPORT_FIELD.GetValue(cachedAfflictions)) { return (GameState)(-13); } if (!Object.op_Implicit((Object)(object)GUIManager.instance)) { return (GameState)(-13); } if ((Object)(object)RunManager.Instance != (Object)null) { if ((double)RunManager.Instance.TimeSinceRunStarted <= 8.0) { return (GameState)(-6); } return (GameState)1; } return (GameState)(-6); } catch (Exception arg) { CrowdControlMod.Instance.Logger.LogError((object)$"ERROR {arg}"); return (GameState)(-1); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool UpdateGameState(bool force = false) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return UpdateGameState(GetGameState(force), force); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool UpdateGameState(GameState newState, bool force) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return UpdateGameState(newState, null, force); } public void RequestStateResend() { m_stateResendRequested = true; } public bool UpdateGameState(GameState newState, string? message = null, bool force = false) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (m_stateResendRequested) { m_stateResendRequested = false; force = true; } if (force || _last_game_state != (GameState?)newState) { _last_game_state = newState; return mod.Client.Send((SimpleJSONResponse?)new GameUpdate(newState, message)); } return true; } } public static class HostEventHandlers { private enum StormType { Unknown, Rain, Snow, Wind } public static void RegisterAllHandlers() { if (!PhotonNetwork.IsMasterClient) { CrowdControlMod.Instance.Logger.LogWarning((object)"Cannot register host handlers - not the host"); return; } CustomEventSystem.Instance.RegisterEvent("spawn_item", HandleSpawnItem); CustomEventSystem.Instance.RegisterEvent("spawn_hazard", HandleSpawnHazard); CustomEventSystem.Instance.RegisterEvent("custom_effect", HandleCustomEffect); CustomEventSystem.Instance.RegisterEvent("revive_player", HandleRevivePlayer); CustomEventSystem.Instance.RegisterEvent("spawn_scoutmaster", HandleSpawnScoutmaster); CustomEventSystem.Instance.RegisterEvent("spawn_tornado", HandleSpawnTornado); CustomEventSystem.Instance.RegisterEvent("spawn_ticks", HandleSpawnTicks); CustomEventSystem.Instance.RegisterEvent("revive_random_player", HandleReviveRandomPlayer); CustomEventSystem.Instance.RegisterEvent("spawn_zombie", HandleSpawnZombie); CustomEventSystem.Instance.RegisterEvent("create_storm", HandleCreateStorm); CrowdControlMod.Instance.Logger.LogInfo((object)"Registered all host event handlers"); } public static void UnregisterAllHandlers() { if (PhotonNetwork.IsMasterClient) { CustomEventSystem.Instance.UnregisterEvent("spawn_item"); CustomEventSystem.Instance.UnregisterEvent("spawn_hazard"); CustomEventSystem.Instance.UnregisterEvent("custom_effect"); CustomEventSystem.Instance.UnregisterEvent("revive_player"); CustomEventSystem.Instance.UnregisterEvent("spawn_scoutmaster"); CustomEventSystem.Instance.UnregisterEvent("spawn_tornado"); CustomEventSystem.Instance.UnregisterEvent("spawn_ticks"); CustomEventSystem.Instance.UnregisterEvent("spawn_zombie"); CustomEventSystem.Instance.UnregisterEvent("create_storm"); CrowdControlMod.Instance.Logger.LogInfo((object)"Unregistered all host event handlers"); } } private static EventResult HandleSpawnItem(Dictionary<string, object> data) { //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: 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) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[HostEventHandlers] HandleSpawnItem called with data: " + JsonConvert.SerializeObject((object)data))); } try { if (!data.TryGetValue("prefabPath", out object value)) { if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("[HostEventHandlers] Missing prefabPath parameter. Available keys: " + string.Join(", ", data.Keys))); } return EventResult.FailureResult("Missing prefabPath parameter"); } string text = value.ToString(); if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[HostEventHandlers] Prefab path: " + text)); } Vector3 val; object value2; if (SpawnedItemProtection.TryResolveTargetCharacter(data, out Character character)) { val = SpawnedItemProtection.GetGroundedSpawnPosition(character); if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HostEventHandlers] Using live position for player {((Object)character).name}: {val}"); } } else if (data.TryGetValue("spawnPosition", out value2)) { Dictionary<string, object> dictionary = null; JObject val2 = (JObject)((value2 is JObject) ? value2 : null); if (val2 != null) { dictionary = ((JToken)val2).ToObject<Dictionary<string, object>>(); } else if (value2 is Dictionary<string, object> dictionary2) { dictionary = dictionary2; } if (dictionary != null && dictionary.TryGetValue("x", out var value3) && dictionary.TryGetValue("y", out var value4) && dictionary.TryGetValue("z", out var value5)) { val = SpawnedItemProtection.GroundPoint(new Vector3(Convert.ToSingle(value3), Convert.ToSingle(value4), Convert.ToSingle(value5))); if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HostEventHandlers] Using provided spawn position: {val}"); } } else { val = Vector3.up * 2f; if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)"[HostEventHandlers] spawnPosition present but could not parse x/y/z."); } } } else { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { val = SpawnedItemProtection.GetGroundedSpawnPosition(localCharacter); if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HostEventHandlers] Using default spawn position: {val}"); } } else { val = Vector3.up * 2f; if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HostEventHandlers] Using fallback spawn position: {val}"); } } } if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HostEventHandlers] Attempting to spawn item '{text}' at {val}"); } bool flag = text.Contains("BeeSwarm"); GameObject val3; if (flag) { val3 = PhotonNetwork.InstantiateRoomObject(text, val, Quaternion.identity, (byte)0, (object[])null); try { BeeSwarm component = val3.GetComponent<BeeSwarm>(); typeof(BeeSwarm).GetMethod("GetAngry", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(component, new object[1] { 15f }); } catch (Exception) { } } else { val3 = PhotonNetwork.InstantiateItemRoom(text, val, Quaternion.identity, true); } if ((Object)(object)val3 == (Object)null) { if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("[HostEventHandlers] Failed to instantiate item: " + text)); } return EventResult.FailureResult("Failed to instantiate item: " + text); } if (!flag) { val = SpawnedItemProtection.GroundPoint(val); val3.transform.position = val; SpawnedItemProtection.Apply(val3); } if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"Host spawned item '{text}' at {val} for client"); } if (string.Equals(text, "TumbleWeed", StringComparison.OrdinalIgnoreCase)) { GameNotifications.Show("Spawned hazard: Tumbleweed"); } return EventResult.SuccessResult("Successfully spawned " + text, new Dictionary<string, object> { ["spawnedItem"] = text, ["position"] = val }); } catch (Exception ex2) { if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("Error in HandleSpawnItem: " + ex2.Message)); } if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex2.StackTrace)); } return EventResult.FailureResult("Error: " + ex2.Message); } } private static EventResult HandleSpawnHazard(Dictionary<string, object> data) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) try { if (!data.TryGetValue("prefabPath", out object value)) { return EventResult.FailureResult("Missing prefabPath parameter"); } string text = value.ToString(); Vector3 zero = Vector3.zero; Quaternion rotation = Quaternion.identity; if (data.TryGetValue("spawnPosition", out object value2)) { Dictionary<string, object> dictionary = null; JObject val = (JObject)((value2 is JObject) ? value2 : null); if (val != null) { dictionary = ((JToken)val).ToObject<Dictionary<string, object>>(); } else if (value2 is Dictionary<string, object> dictionary2) { dictionary = dictionary2; } if (dictionary != null && dictionary.TryGetValue("x", out var value3) && dictionary.TryGetValue("y", out var value4) && dictionary.TryGetValue("z", out var value5)) { ((Vector3)(ref zero))..ctor(Convert.ToSingle(value3), Convert.ToSingle(value4), Convert.ToSingle(value5)); } } if (data.TryGetValue("rotation", out object value6)) { Dictionary<string, object> dictionary3 = null; JObject val2 = (JObject)((value6 is JObject) ? value6 : null); if (val2 != null) { dictionary3 = ((JToken)val2).ToObject<Dictionary<string, object>>(); } else if (value6 is Dictionary<string, object> dictionary4) { dictionary3 = dictionary4; } if (dictionary3 != null && dictionary3.TryGetValue("x", out var value7) && dictionary3.TryGetValue("y", out var value8) && dictionary3.TryGetValue("z", out var value9)) { rotation = Quaternion.Euler(Convert.ToSingle(value7), Convert.ToSingle(value8), Convert.ToSingle(value9)); } } SpawnedItemProtection.TryResolveTargetCharacter(data, out Character character); string text2 = SpawnHazardEffect.SpawnHazardAsHost(text, zero, rotation, character); if (text2 != null) { return EventResult.FailureResult(text2); } return EventResult.SuccessResult("Successfully spawned " + text, new Dictionary<string, object> { ["spawnedItem"] = text, ["position"] = zero }); } catch (Exception ex) { return EventResult.FailureResult("Error: " + ex.Message); } } private static EventResult HandleCustomEffect(Dictionary<string, object> data) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) try { if (!data.TryGetValue("effectType", out object value)) { return EventResult.FailureResult("Missing effectType parameter"); } string text = value.ToString(); string text2 = text.ToLower(); if (!(text2 == "explosion")) { if (text2 == "weather") { if (data.TryGetValue("weatherType", out object value2)) { string text3 = value2.ToString(); CrowdControlMod.Instance.Logger.LogInfo((object)("Host changed weather to " + text3)); return EventResult.SuccessResult("Weather changed to " + text3); } return EventResult.FailureResult("Missing weatherType parameter"); } return EventResult.FailureResult("Unknown effect type: " + text); } Vector3 zero = Vector3.zero; if (data.TryGetValue("position", out object value3) && value3 is Dictionary<string, object> dictionary) { ((Vector3)(ref zero))..ctor(float.Parse(dictionary["x"].ToString()), float.Parse(dictionary["y"].ToString()), float.Parse(dictionary["z"].ToString())); } CrowdControlMod.Instance.Logger.LogInfo((object)$"Host created explosion effect at {zero}"); return EventResult.SuccessResult("Explosion effect created"); } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("Error in HandleCustomEffect: " + ex.Message)); return EventResult.FailureResult("Error: " + ex.Message); } } private static EventResult HandleRevivePlayer(Dictionary<string, object> data) { //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_05f5: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Unknown result type (might be due to invalid IL or missing references) //IL_061a: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Unknown result type (might be due to invalid IL or missing references) //IL_0679: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_0569: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)("[HostEventHandlers] HandleRevivePlayer called with data: " + JsonConvert.SerializeObject((object)data))); } try { if (!data.TryGetValue("targetPlayerId", out object value)) { if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("[HostEventHandlers] Missing targetPlayerId parameter. Available keys: " + string.Join(", ", data.Keys))); } return EventResult.FailureResult("Missing targetPlayerId parameter"); } int targetPlayerId = Convert.ToInt32(value); if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[HostEventHandlers] Target player ID: {targetPlayerId}"); } Character val = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)delegate(Character c) { PhotonView component2 = ((Component)c).GetComponent<PhotonView>(); if (component2 == null) { return false; } Player owner2 = component2.Owner; return ((owner2 != null) ? new int?(owner2.ActorNumber) : ((int?)null)) == targetPlayerId; }); if ((Object)(object)val == (Object)null) { if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)$"[HostEventHandlers] Target player with ID {targetPlayerId} not found"); } return EventResult.FailureResult($"Target player with ID {targetPlayerId} not found"); } PhotonView component = ((Component)val).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null) { CrowdControlMod.Instance.Logger.LogError((object)("[HostEventHandlers] Target player " + ((Object)val).name + " has no PhotonView")); return EventResult.FailureResult("Target player " + ((Object)val).name + " has no PhotonView"); } bool dead = val.data.dead; bool fullyPassedOut = val.data.fullyPassedOut; bool passedOut = val.data.passedOut; bool flag = (Object)(object)val.Ghost != (Object)null; int viewID = component.ViewID; Player owner = component.Owner; int num = ((owner != null) ? owner.ActorNumber : (-1)); bool isMine = component.IsMine; CrowdControlMod.Instance.Logger.LogInfo((object)("[HandleRevivePlayer] Player: " + ((Object)val).name)); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] - dead: {dead}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] - fullyPassedOut: {fullyPassedOut}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] - passedOut: {passedOut}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] - isGhost: {flag}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] - PhotonView ID: {viewID}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] - Owner ID: {num}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] - IsMine: {isMine}"); if (!val.data.dead && !val.data.fullyPassedOut) { CrowdControlMod.Instance.Logger.LogWarning((object)("[HostEventHandlers] Target player " + ((Object)val).name + " is not dead or passed out")); return EventResult.FailureResult("Target player " + ((Object)val).name + " is not dead or passed out"); } if (val.data.dead) { PlayerGhost ghost = val.Ghost; Vector3 val2; if ((Object)(object)ghost != (Object)null) { if ((Object)(object)ghost.m_target != (Object)null) { val2 = ghost.m_target.Head + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] Using target player's head + 4 up for revive: {val2}"); } else if ((Object)(object)((Component)ghost).transform != (Object)null) { Vector3 position = ((Component)ghost).transform.position; RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(position, Vector3.down, ref val3, 100f)) { val2 = ((RaycastHit)(ref val3)).point + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] Using ground level + 4 up below ghost: {val2} (ghost was at {position}, ground at {((RaycastHit)(ref val3)).point})"); } else { val2 = new Vector3(position.x, position.y - 10f, position.z) + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] No ground found, using ghost position lowered + 4 up: {val2}"); } } else { val2 = val.Head + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] Ghost transform is null, using head position + 4 up: {val2}"); } } else { val2 = val.Head + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] Ghost is null, using head position + 4 up: {val2}"); } CrowdControlMod.Instance.Logger.LogInfo((object)"[HandleRevivePlayer] Attempting to revive from dead state using RPCA_ReviveAtPosition"); try { component.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[3] { val2, false, -1 }); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] Successfully sent RPCA_ReviveAtPosition RPC to player {((Object)val).name} (ID: {targetPlayerId}) at position {val2}"); } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("[HandleRevivePlayer] RPC failed: " + ex.Message)); CrowdControlMod.Instance.Logger.LogError((object)("[HandleRevivePlayer] Stack trace: " + ex.StackTrace)); return EventResult.FailureResult("RPC failed: " + ex.Message); } } else if (val.data.fullyPassedOut) { Vector3 val4 = val.Head + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] Attempting to revive from fullyPassedOut state at position: {val4}"); try { component.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[3] { val4, false, -1 }); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleRevivePlayer] Successfully sent RPCA_ReviveAtPosition RPC to player {((Object)val).name} (ID: {targetPlayerId}) at position {val4}"); } catch (Exception ex2) { CrowdControlMod.Instance.Logger.LogError((object)("[HandleRevivePlayer] RPC failed: " + ex2.Message)); CrowdControlMod.Instance.Logger.LogError((object)("[HandleRevivePlayer] Stack trace: " + ex2.StackTrace)); return EventResult.FailureResult("RPC failed: " + ex2.Message); } } return EventResult.SuccessResult("Revived player " + ((Object)val).name, new Dictionary<string, object> { ["revivedPlayer"] = ((Object)val).name, ["targetPlayerId"] = targetPlayerId }); } catch (Exception ex3) { if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("Error in HandleRevivePlayer: " + ex3.Message)); } if (CustomEventSystem.EnableDebugLogging) { CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex3.StackTrace)); } return EventResult.FailureResult("Error: " + ex3.Message); } } private static EventResult HandleReviveRandomPlayer(Dictionary<string, object> data) { //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) CrowdControlMod.Instance.Logger.LogInfo((object)"[HostEventHandlers] HandleReviveRandomPlayer called"); try { foreach (Character allCharacter in Character.AllCharacters) { string name = ((Object)allCharacter).name; bool dead = allCharacter.data.dead; bool fullyPassedOut = allCharacter.data.fullyPassedOut; bool flag = (Object)(object)allCharacter.Ghost != (Object)null; CrowdControlMod.Instance.Logger.LogInfo((object)$"[ReviveRandomPlayer] Character: {name}, dead: {dead}, fullyPassedOut: {fullyPassedOut}, isGhost: {flag}"); } List<Character> list = Character.AllCharacters.Where((Character c) => c.data.dead || c.data.fullyPassedOut).ToList(); if (list.Count == 0) { CrowdControlMod.Instance.Logger.LogWarning((object)"No revivable players (dead or fullyPassedOut) found"); return EventResult.FailureResult("No revivable players (dead or fullyPassedOut) found"); } Character val = list[Random.Range(0, list.Count)]; PhotonView component = ((Component)val).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null) { CrowdControlMod.Instance.Logger.LogWarning((object)"Target player has no network view"); return EventResult.FailureResult("Target player has no network view"); } Player owner = component.Owner; int num = ((owner != null) ? owner.ActorNumber : (-1)); if (num == -1) { CrowdControlMod.Instance.Logger.LogWarning((object)"Target player's PhotonView has no owner"); return EventResult.FailureResult("Target player's PhotonView has no owner"); } bool dead2 = val.data.dead; bool fullyPassedOut2 = val.data.fullyPassedOut; bool passedOut = val.data.passedOut; bool flag2 = (Object)(object)val.Ghost != (Object)null; int viewID = component.ViewID; Player owner2 = component.Owner; int num2 = ((owner2 != null) ? owner2.ActorNumber : (-1)); bool isMine = component.IsMine; CrowdControlMod.Instance.Logger.LogInfo((object)("[HandleReviveRandomPlayer] Selected player: " + ((Object)val).name)); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] - dead: {dead2}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] - fullyPassedOut: {fullyPassedOut2}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] - passedOut: {passedOut}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] - isGhost: {flag2}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] - PhotonView ID: {viewID}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] - Owner ID: {num2}"); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] - IsMine: {isMine}"); if (val.data.dead) { PlayerGhost ghost = val.Ghost; Vector3 val2; if ((Object)(object)ghost != (Object)null) { if ((Object)(object)ghost.m_target != (Object)null) { val2 = ghost.m_target.Head + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] Using target player's head + 4 up for revive: {val2}"); } else if ((Object)(object)((Component)ghost).transform != (Object)null) { Vector3 position = ((Component)ghost).transform.position; RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(position, Vector3.down, ref val3, 100f)) { val2 = ((RaycastHit)(ref val3)).point + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] Using ground level + 4 up below ghost: {val2} (ghost was at {position}, ground at {((RaycastHit)(ref val3)).point})"); } else { val2 = new Vector3(position.x, position.y - 10f, position.z) + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] No ground found, using ghost position lowered + 4 up: {val2}"); } } else { val2 = val.Head + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] Ghost transform is null, using head position + 4 up: {val2}"); } } else { val2 = val.Head + Vector3.up * 4f; CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] Ghost is null, using head position + 4 up: {val2}"); } CrowdControlMod.Instance.Logger.LogInfo((object)"[HandleReviveRandomPlayer] Attempting to revive from dead state using RPCA_ReviveAtPosition"); try { component.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[3] { val2, false, -1 }); CrowdControlMod.Instance.Logger.LogInfo((object)$"[HandleReviveRandomPlayer] Successfully sent RPCA_ReviveAtPosition RPC to player {((Object)val).name} (ID: {num}) at position {val2}"); } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("[HandleReviveRandomPlayer] RPC failed: " + ex.Message)); CrowdControlMod.Instance.Logger.LogError((object)("[HandleReviveRandomPlayer] Stack trace: " + ex.StackTrace)); return EventResult.FailureResult("RPC failed: " + ex.Message); } return EventResult.SuccessResult("Sent revive request to player " + ((Object)val).name, new Dictionary<string, object> { ["revivedPlayer"] = ((Object)val).name, ["targetPlayerId"] = num }); } CrowdControlMod.Instance.Logger.LogWarning((object)("Player " + ((Object)val).name + " is not dead or passed out")); return EventResult.FailureResult("Player " + ((Object)val).name + " is not dead or passed out"); } catch (Exception ex2) { CrowdControlMod.Instance.Logger.LogError((object)("Error in HandleReviveRandomPlayer: " + ex2.Message)); CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex2.StackTrace)); return EventResult.FailureResult("Error: " + ex2.Message); } } private static Vector3 GetSpawnPosition(Character character) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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) Vector3 val = ((Component)character).transform.position + ((Component)character).transform.forward * 1.5f + Vector3.up; bool flag = false; bool flag2 = false; Transform[] componentsInChildren = ((Component)((Component)character).transform).GetComponentsInChildren<Transform>(); foreach (Transform val2 in componentsInChildren) { if (((Object)val2).name == "Hip") { val = val2.position + val2.forward * 1.5f + Vector3.up; flag = true; break; } } Transform val3 = ((Component)character).transform.Find("Hip"); if ((Object)(object)val3 != (Object)null) { val = val3.position + val3.forward * 1.5f + Vector3.up; flag2 = true; } if (CustomEventSystem.EnableDebugLogging) { if (flag2) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[GetSpawnPosition] Used hip transform for spawn position: {val}"); } else if (flag) { CrowdControlMod.Instance.Logger.LogInfo((object)$"[GetSpawnPosition] Used child Hip for spawn position: {val}"); } else { CrowdControlMod.Instance.Logger.LogInfo((object)$"[GetSpawnPosition] Used default spawn position: {val}"); } } return val; } private static EventResult HandleSpawnScoutmaster(Dictionary<string, object> data) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) CrowdControlMod.Instance.Logger.LogInfo((object)("[HostEventHandlers] HandleSpawnScoutmaster called with data: " + JsonConvert.SerializeObject((object)data))); try { if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom) { CrowdControlMod.Instance.Logger.LogWarning((object)"Not connected to Photon room, cannot spawn Scoutmaster."); return EventResult.FailureResult("Not connected to Photon room"); } if (!PhotonNetwork.IsMasterClient) { CrowdControlMod.Instance.Logger.LogWarning((object)"Only the Master Client can spawn Scoutmaster."); return EventResult.FailureResult("Only the Master Client can spawn Scoutmaster"); } Vector3 val = Vector3.zero; bool flag = false; if (data.TryGetValue("spawnPosition", out object value)) { Dictionary<string, object> dictionary = null; JObject val2 = (JObject)((value is JObject) ? value : null); if (val2 != null) { dictionary = ((JToken)val2).ToObject<Dictionary<string, object>>(); } else if (value is Dictionary<string, object> dictionary2) { dictionary = dictionary2; } if (dictionary != null && dictionary.TryGetValue("x", out var value2) && dictionary.TryGetValue("y", out var value3) && dictionary.TryGetValue("z", out var value4)) { ((Vector3)(ref val))..ctor(Convert.ToSingle(value2), Convert.ToSingle(value3), Convert.ToSingle(value4)); flag = true; } } int targetPlayerId = -1; if (data.TryGetValue("targetPlayerId", out object value5)) { targetPlayerId = Convert.ToInt32(value5); } Character val3 = null; if (targetPlayerId != -1) { val3 = ((IEnumerable<Character>)Character.AllCharacters).FirstOrDefault((Func<Character, bool>)delegate(Character c) { PhotonView component = ((Component)c).GetComponent<PhotonView>(); if (component == null) { return false; } Player owner = component.Owner; return ((owner != null) ? new int?(owner.ActorNumber) : ((int?)null)) == targetPlayerId; }); } if (!flag) { CrowdControlMod.Instance.Logger.LogWarning((object)"No spawnPosition provided, using Vector3.up * 2f as fallback"); val = Vector3.up * 2f; } if ((Object)(object)val3 == (Object)null) { CrowdControlMod.Instance.Logger.LogWarning((object)"No valid chase target found, Scoutmaster will not chase anyone"); } Quaternion identity = Quaternion.identity; GameObject scoutmasterObj = PhotonNetwork.InstantiateRoomObject("Character_Scoutmaster", val, identity, (byte)0, (object[])null); CrowdControlMod.Instance.Logger.LogInfo((object)string.Format("Spawned Scoutmaster at {0}, targeting playerId: {1} ({2})", val, targetPlayerId, ((val3 != null) ? ((Object)val3).name : null) ?? "null")); if ((Object)(object)val3 != (Object)null) { ((MonoBehaviour)CrowdControlMod.Instance).StartCoroutine(StartChasingNextFrame(scoutmasterObj, val3)); } return EventResult.SuccessResult($"Successfully spawned Scoutmaster at {val}", new Dictionary<string, object> { ["spawnedScoutmaster"] = true, ["spawnPosition"] = val, ["targetPlayerId"] = targetPlayerId, ["targetPlayerName"] = ((val3 != null) ? ((Object)val3).name : null) ?? "null" }); } catch (Exception ex) { CrowdControlMod.Instance.Logger.LogError((object)("Error in HandleSpawnScoutmaster: " + ex.Message)); CrowdControlMod.Instance.Logger.LogError((object)("Stack trace: " + ex.StackTrace)); return EventResult.FailureResult("Error: " + ex.Message); } } private static EventResult HandleSpawnTornado(Dictionary<string, object> data) { //IL_0080: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) CrowdControlMod.Instance.Logger.LogInfo((object)("[HostEventHandlers] HandleSpawnTornado called with data: " + JsonConvert.SerializeObject((object)data))); try { if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom) { CrowdControlMod.Instance.Logger.LogWarning((object)"Not con