Decompiled source of Project Arrhythmia Multiplayer v1.0.0
patchers/PAMultiplayer/DiscordRPC.dll
Decompiled 3 days 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.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.IO.Pipes; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using DiscordRPC.Converters; using DiscordRPC.Events; using DiscordRPC.Exceptions; using DiscordRPC.Helper; using DiscordRPC.IO; using DiscordRPC.Logging; using DiscordRPC.Message; using DiscordRPC.RPC; using DiscordRPC.RPC.Commands; using DiscordRPC.RPC.Payload; using DiscordRPC.Registry; using Microsoft.Win32; using Newtonsoft.Json; using Newtonsoft.Json.Linq; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Discord RPC")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Discord RPC")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("819d20d6-8d88-45c1-a4d2-aa21f10abd19")] [assembly: AssemblyFileVersion("1.6.1.70")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyVersion("1.6.1.70")] namespace DiscordRPC { public class Configuration { [JsonProperty("api_endpoint")] public string ApiEndpoint { get; set; } [JsonProperty("cdn_host")] public string CdnHost { get; set; } [JsonProperty("environment")] public string Environment { get; set; } } public sealed class DiscordRpcClient : IDisposable { private ILogger _logger; private RpcConnection connection; private bool _shutdownOnly = true; private object _sync = new object(); public bool HasRegisteredUriScheme { get; private set; } public string ApplicationID { get; private set; } public string SteamID { get; private set; } public int ProcessID { get; private set; } public int MaxQueueSize { get; private set; } public bool IsDisposed { get; private set; } public ILogger Logger { get { return _logger; } set { _logger = value; if (connection != null) { connection.Logger = value; } } } public bool AutoEvents { get; private set; } public bool SkipIdenticalPresence { get; set; } public int TargetPipe { get; private set; } public RichPresence CurrentPresence { get; private set; } public EventType Subscription { get; private set; } public User CurrentUser { get; private set; } public Configuration Configuration { get; private set; } public bool IsInitialized { get; private set; } public bool ShutdownOnly { get { return _shutdownOnly; } set { _shutdownOnly = value; if (connection != null) { connection.ShutdownOnly = value; } } } public event OnReadyEvent OnReady; public event OnCloseEvent OnClose; public event OnErrorEvent OnError; public event OnPresenceUpdateEvent OnPresenceUpdate; public event OnSubscribeEvent OnSubscribe; public event OnUnsubscribeEvent OnUnsubscribe; public event OnJoinEvent OnJoin; public event OnSpectateEvent OnSpectate; public event OnJoinRequestedEvent OnJoinRequested; public event OnConnectionEstablishedEvent OnConnectionEstablished; public event OnConnectionFailedEvent OnConnectionFailed; public event OnRpcMessageEvent OnRpcMessage; public DiscordRpcClient(string applicationID) : this(applicationID, -1, null, autoEvents: true, null) { } public DiscordRpcClient(string applicationID, int pipe = -1, ILogger logger = null, bool autoEvents = true, INamedPipeClient client = null) { if (string.IsNullOrEmpty(applicationID)) { throw new ArgumentNullException("applicationID"); } ApplicationID = applicationID.Trim(); TargetPipe = pipe; ProcessID = Process.GetCurrentProcess().Id; HasRegisteredUriScheme = false; AutoEvents = autoEvents; SkipIdenticalPresence = true; _logger = logger ?? new NullLogger(); connection = new RpcConnection(ApplicationID, ProcessID, TargetPipe, client ?? new ManagedNamedPipeClient(), (!autoEvents) ? 128u : 0u) { ShutdownOnly = _shutdownOnly, Logger = _logger }; connection.OnRpcMessage += delegate(object sender, IMessage msg) { if (this.OnRpcMessage != null) { this.OnRpcMessage(this, msg); } if (AutoEvents) { ProcessMessage(msg); } }; } public IMessage[] Invoke() { if (AutoEvents) { Logger.Error("Cannot Invoke client when AutomaticallyInvokeEvents has been set."); return new IMessage[0]; } IMessage[] array = connection.DequeueMessages(); foreach (IMessage message in array) { ProcessMessage(message); } return array; } private void ProcessMessage(IMessage message) { if (message == null) { return; } switch (message.Type) { case MessageType.PresenceUpdate: lock (_sync) { if (message is PresenceMessage presenceMessage) { if (presenceMessage.Presence == null) { CurrentPresence = null; } else if (CurrentPresence == null) { CurrentPresence = new RichPresence().Merge(presenceMessage.Presence); } else { CurrentPresence.Merge(presenceMessage.Presence); } presenceMessage.Presence = CurrentPresence; } } if (this.OnPresenceUpdate != null) { this.OnPresenceUpdate(this, message as PresenceMessage); } break; case MessageType.Ready: if (message is ReadyMessage readyMessage) { lock (_sync) { Configuration = readyMessage.Configuration; CurrentUser = readyMessage.User; } SynchronizeState(); } if (this.OnReady != null) { this.OnReady(this, message as ReadyMessage); } break; case MessageType.Close: if (this.OnClose != null) { this.OnClose(this, message as CloseMessage); } break; case MessageType.Error: if (this.OnError != null) { this.OnError(this, message as ErrorMessage); } break; case MessageType.JoinRequest: if (Configuration != null && message is JoinRequestMessage joinRequestMessage) { joinRequestMessage.User.SetConfiguration(Configuration); } if (this.OnJoinRequested != null) { this.OnJoinRequested(this, message as JoinRequestMessage); } break; case MessageType.Subscribe: lock (_sync) { SubscribeMessage subscribeMessage = message as SubscribeMessage; Subscription |= subscribeMessage.Event; } if (this.OnSubscribe != null) { this.OnSubscribe(this, message as SubscribeMessage); } break; case MessageType.Unsubscribe: lock (_sync) { UnsubscribeMessage unsubscribeMessage = message as UnsubscribeMessage; Subscription &= ~unsubscribeMessage.Event; } if (this.OnUnsubscribe != null) { this.OnUnsubscribe(this, message as UnsubscribeMessage); } break; case MessageType.Join: if (this.OnJoin != null) { this.OnJoin(this, message as JoinMessage); } break; case MessageType.Spectate: if (this.OnSpectate != null) { this.OnSpectate(this, message as SpectateMessage); } break; case MessageType.ConnectionEstablished: if (this.OnConnectionEstablished != null) { this.OnConnectionEstablished(this, message as ConnectionEstablishedMessage); } break; case MessageType.ConnectionFailed: if (this.OnConnectionFailed != null) { this.OnConnectionFailed(this, message as ConnectionFailedMessage); } break; default: Logger.Error("Message was queued with no appropriate handle! {0}", message.Type); break; } } public void Respond(JoinRequestMessage request, bool acceptRequest) { if (IsDisposed) { throw new ObjectDisposedException("Discord IPC Client"); } if (connection == null) { throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized"); } if (!IsInitialized) { throw new UninitializedException(); } connection.EnqueueCommand(new RespondCommand { Accept = acceptRequest, UserID = request.User.ID.ToString() }); } public void SetPresence(RichPresence presence) { if (IsDisposed) { throw new ObjectDisposedException("Discord IPC Client"); } if (connection == null) { throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized"); } if (!IsInitialized) { Logger.Warning("The client is not yet initialized, storing the presence as a state instead."); } if (presence == null) { if (!SkipIdenticalPresence || CurrentPresence != null) { connection.EnqueueCommand(new PresenceCommand { PID = ProcessID, Presence = null }); } } else { if (presence.HasSecrets() && !HasRegisteredUriScheme) { throw new BadPresenceException("Cannot send a presence with secrets as this object has not registered a URI scheme. Please enable the uri scheme registration in the DiscordRpcClient constructor."); } if (presence.HasParty() && presence.Party.Max < presence.Party.Size) { throw new BadPresenceException("Presence maximum party size cannot be smaller than the current size."); } if (presence.HasSecrets() && !presence.HasParty()) { Logger.Warning("The presence has set the secrets but no buttons will show as there is no party available."); } if (!SkipIdenticalPresence || !presence.Matches(CurrentPresence)) { connection.EnqueueCommand(new PresenceCommand { PID = ProcessID, Presence = presence.Clone() }); } } lock (_sync) { CurrentPresence = presence?.Clone(); } } public RichPresence Update(Action<RichPresence> func) { if (!IsInitialized) { throw new UninitializedException(); } RichPresence richPresence; lock (_sync) { richPresence = ((CurrentPresence == null) ? new RichPresence() : CurrentPresence.Clone()); } func(richPresence); SetPresence(richPresence); return richPresence; } public RichPresence UpdateType(ActivityType type) { return Update(delegate(RichPresence p) { p.Type = type; }); } public RichPresence UpdateStatusDisplayType(StatusDisplayType type) { return Update(delegate(RichPresence p) { p.StatusDisplay = type; }); } public RichPresence UpdateButtons(Button[] buttons = null) { return Update(delegate(RichPresence p) { p.Buttons = buttons; }); } public RichPresence SetButton(Button button, int index = 0) { return Update(delegate(RichPresence p) { p.Buttons[index] = button; }); } public RichPresence UpdateDetails(string details) { return Update(delegate(RichPresence p) { p.Details = details; }); } public RichPresence UpdateState(string state) { return Update(delegate(RichPresence p) { p.State = state; }); } public RichPresence UpdateParty(Party party) { return Update(delegate(RichPresence p) { p.Party = party; }); } public RichPresence UpdatePartySize(int size) { return Update(delegate(RichPresence p) { if (p.Party == null) { throw new BadPresenceException("Cannot set the size of the party if the party does not exist"); } p.Party.Size = size; }); } public RichPresence UpdatePartySize(int size, int max) { return Update(delegate(RichPresence p) { if (p.Party == null) { throw new BadPresenceException("Cannot set the size of the party if the party does not exist"); } p.Party.Size = size; p.Party.Max = max; }); } public RichPresence UpdateLargeAsset(string key = null, string tooltip = null) { return Update(delegate(RichPresence p) { if (p.Assets == null) { p.Assets = new Assets(); } p.Assets.LargeImageKey = key ?? p.Assets.LargeImageKey; p.Assets.LargeImageText = tooltip ?? p.Assets.LargeImageText; }); } public RichPresence UpdateSmallAsset(string key = null, string tooltip = null) { return Update(delegate(RichPresence p) { if (p.Assets == null) { p.Assets = new Assets(); } p.Assets.SmallImageKey = key ?? p.Assets.SmallImageKey; p.Assets.SmallImageText = tooltip ?? p.Assets.SmallImageText; }); } public RichPresence UpdateSecrets(Secrets secrets) { return Update(delegate(RichPresence p) { p.Secrets = secrets; }); } public RichPresence UpdateStartTime() { return UpdateStartTime(DateTime.UtcNow); } public RichPresence UpdateStartTime(DateTime time) { return Update(delegate(RichPresence p) { if (p.Timestamps == null) { p.Timestamps = new Timestamps(); } p.Timestamps.Start = time; }); } public RichPresence UpdateEndTime() { return UpdateEndTime(DateTime.UtcNow); } public RichPresence UpdateEndTime(DateTime time) { return Update(delegate(RichPresence p) { if (p.Timestamps == null) { p.Timestamps = new Timestamps(); } p.Timestamps.End = time; }); } public RichPresence UpdateClearTime() { return Update(delegate(RichPresence p) { p.Timestamps = null; }); } public void ClearPresence() { if (IsDisposed) { throw new ObjectDisposedException("Discord IPC Client"); } if (!IsInitialized) { throw new UninitializedException(); } if (connection == null) { throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized"); } SetPresence(null); } public bool RegisterUriScheme(string steamAppID = null, string executable = null) { SchemeInfo schemeInfo = default(SchemeInfo); schemeInfo.ApplicationID = ApplicationID; schemeInfo.SteamAppID = steamAppID; schemeInfo.ExecutablePath = executable ?? Process.GetCurrentProcess().MainModule.FileName; SchemeInfo info = schemeInfo; return HasRegisteredUriScheme = UriScheme.Register(info, _logger); } public void Subscribe(EventType type) { SetSubscription(Subscription | type); } public void Unsubscribe(EventType type) { SetSubscription(Subscription & ~type); } public void SetSubscription(EventType type) { if (IsInitialized) { SubscribeToTypes(Subscription & ~type, isUnsubscribe: true); SubscribeToTypes(~Subscription & type, isUnsubscribe: false); } else { Logger.Warning("Client has not yet initialized, but events are being subscribed too. Storing them as state instead."); } lock (_sync) { Subscription = type; } } private void SubscribeToTypes(EventType type, bool isUnsubscribe) { if (type != 0) { if (IsDisposed) { throw new ObjectDisposedException("Discord IPC Client"); } if (!IsInitialized) { throw new UninitializedException(); } if (connection == null) { throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized"); } if (!HasRegisteredUriScheme) { throw new InvalidConfigurationException("Cannot subscribe/unsubscribe to an event as this application has not registered a URI Scheme. Call RegisterUriScheme()."); } if ((type & EventType.Spectate) == EventType.Spectate) { connection.EnqueueCommand(new SubscribeCommand { Event = ServerEvent.ActivitySpectate, IsUnsubscribe = isUnsubscribe }); } if ((type & EventType.Join) == EventType.Join) { connection.EnqueueCommand(new SubscribeCommand { Event = ServerEvent.ActivityJoin, IsUnsubscribe = isUnsubscribe }); } if ((type & EventType.JoinRequest) == EventType.JoinRequest) { connection.EnqueueCommand(new SubscribeCommand { Event = ServerEvent.ActivityJoinRequest, IsUnsubscribe = isUnsubscribe }); } } } public void SynchronizeState() { if (!IsInitialized) { throw new UninitializedException(); } SetPresence(CurrentPresence); if (HasRegisteredUriScheme) { SubscribeToTypes(Subscription, isUnsubscribe: false); } } public bool Initialize() { if (IsDisposed) { throw new ObjectDisposedException("Discord IPC Client"); } if (IsInitialized) { throw new UninitializedException("Cannot initialize a client that is already initialized"); } if (connection == null) { throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized"); } return IsInitialized = connection.AttemptConnection(); } public void Deinitialize() { if (!IsInitialized) { throw new UninitializedException("Cannot deinitialize a client that has not been initalized."); } connection.Close(); IsInitialized = false; } public void Dispose() { if (!IsDisposed) { if (IsInitialized) { Deinitialize(); } IsDisposed = true; } } } public enum ActivityType { Playing = 0, Listening = 2, Watching = 3, Competing = 5 } [Serializable] public class Assets { private const string EXTERNAL_KEY_PREFIX = "mp:external"; private string _largeimagekey; private string _largeimagetext; private string _largeimageurl; private string _smallimagekey; private string _smallimagetext; private string _smallimageurl; [JsonProperty(/*Could not decode attribute arguments.*/)] public string LargeImageKey { get { return _largeimagekey; } set { if (!BaseRichPresence.ValidateString(value, out _largeimagekey, useBytes: false, 256)) { throw new StringOutOfRangeException(256); } LargeImageID = null; } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string LargeImageText { get { return _largeimagetext; } set { if (!BaseRichPresence.ValidateString(value, out _largeimagetext, useBytes: false, 128)) { throw new StringOutOfRangeException(128); } } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string LargeImageUrl { get { return _largeimageurl; } set { if (!BaseRichPresence.ValidateString(value, out _largeimageurl, useBytes: false, 256)) { throw new StringOutOfRangeException(256); } if (!BaseRichPresence.ValidateUrl(_largeimageurl)) { throw new ArgumentException("Url must be a valid URI"); } } } [JsonIgnore] public string LargeImageID { get; private set; } [JsonIgnore] public bool IsLargeImageKeyExternal { get; private set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public string SmallImageKey { get { return _smallimagekey; } set { if (!BaseRichPresence.ValidateString(value, out _smallimagekey, useBytes: false, 256)) { throw new StringOutOfRangeException(256); } SmallImageID = null; } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string SmallImageText { get { return _smallimagetext; } set { if (!BaseRichPresence.ValidateString(value, out _smallimagetext, useBytes: false, 128)) { throw new StringOutOfRangeException(128); } } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string SmallImageUrl { get { return _smallimageurl; } set { if (!BaseRichPresence.ValidateString(value, out _smallimageurl, useBytes: false, 256)) { throw new StringOutOfRangeException(256); } if (!BaseRichPresence.ValidateUrl(_smallimageurl)) { throw new ArgumentException("Url must be a valid URI"); } } } [JsonIgnore] public string SmallImageID { get; private set; } [JsonIgnore] public bool IsSmallImageKeyExternal { get; private set; } internal void Merge(Assets other) { _smallimagetext = other._smallimagetext; _smallimageurl = other._smallimageurl; _largeimagetext = other._largeimagetext; _largeimageurl = other._largeimageurl; ulong result; if (other._largeimagekey.StartsWith("mp:external")) { IsLargeImageKeyExternal = true; LargeImageID = other._largeimagekey; } else if (ulong.TryParse(other._largeimagekey, out result)) { IsLargeImageKeyExternal = false; LargeImageID = other._largeimagekey; } else { IsLargeImageKeyExternal = false; LargeImageID = null; _largeimagekey = other._largeimagekey; } if (other._smallimagekey.StartsWith("mp:external")) { IsSmallImageKeyExternal = true; SmallImageID = other._smallimagekey; } else if (ulong.TryParse(other._smallimagekey, out result)) { IsSmallImageKeyExternal = false; SmallImageID = other._smallimagekey; } else { IsSmallImageKeyExternal = false; SmallImageID = null; _smallimagekey = other._smallimagekey; } } } public class Button { private string _label; private string _url; [JsonProperty("label")] public string Label { get { return _label; } set { if (!BaseRichPresence.ValidateString(value, out _label, useBytes: true, 31, Encoding.UTF8)) { throw new StringOutOfRangeException(31); } } } [JsonProperty("url")] public string Url { get { return _url; } set { if (!BaseRichPresence.ValidateString(value, out _url, useBytes: false, 512)) { throw new StringOutOfRangeException(512); } if (!BaseRichPresence.ValidateUrl(_url)) { throw new ArgumentException("Url must be a valid URI"); } } } } [Serializable] public class Party { public enum PrivacySetting { Private, Public } private string _partyid; [JsonProperty(/*Could not decode attribute arguments.*/)] public string ID { get { return _partyid; } set { _partyid = value.GetNullOrString(); } } [JsonIgnore] public int Size { get; set; } [JsonIgnore] public int Max { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public PrivacySetting Privacy { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] private int[] _size { get { int num = Math.Max(1, Size); return new int[2] { num, Math.Max(num, Max) }; } set { if (value.Length != 2) { Size = 0; Max = 0; } else { Size = value[0]; Max = value[1]; } } } } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] public class BaseRichPresence { protected internal string _state; protected internal string _stateUrl; protected internal string _details; protected internal string _detailsUrl; [JsonProperty(/*Could not decode attribute arguments.*/)] public string State { get { return _state; } set { if (!ValidateString(value, out _state, useBytes: false, 128)) { throw new StringOutOfRangeException("State", 0, 128); } } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string StateUrl { get { return _stateUrl; } set { if (!ValidateString(value, out _stateUrl, useBytes: false, 256)) { throw new StringOutOfRangeException(256); } if (!ValidateUrl(_stateUrl)) { throw new ArgumentException("Url must be a valid URI"); } } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string Details { get { return _details; } set { if (!ValidateString(value, out _details, useBytes: false, 128)) { throw new StringOutOfRangeException(128); } } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string DetailsUrl { get { return _detailsUrl; } set { if (!ValidateString(value, out _detailsUrl, useBytes: false, 256)) { throw new StringOutOfRangeException(256); } if (!ValidateUrl(_detailsUrl)) { throw new ArgumentException("Url must be a valid URI"); } } } [JsonProperty(/*Could not decode attribute arguments.*/)] public Timestamps Timestamps { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public Assets Assets { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public Party Party { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public Secrets Secrets { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public ActivityType Type { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public StatusDisplayType StatusDisplay { get; set; } public bool HasTimestamps() { if (Timestamps != null) { if (!Timestamps.Start.HasValue) { return Timestamps.End.HasValue; } return true; } return false; } public bool HasAssets() { return Assets != null; } public bool HasParty() { if (Party != null) { return Party.ID != null; } return false; } public bool HasSecrets() { if (Secrets != null) { if (Secrets.JoinSecret == null) { return Secrets.SpectateSecret != null; } return true; } return false; } internal static bool ValidateString(string str, out string result, bool useBytes, int length, Encoding encoding = null) { result = str; if (str == null) { return true; } string text = str.Trim(); if ((useBytes && !text.WithinLength(length, encoding)) || text.Length > length) { return false; } result = text.GetNullOrString(); return true; } internal static bool ValidateUrl(string url) { if (string.IsNullOrEmpty(url)) { return true; } if (!Uri.TryCreate(url, UriKind.Absolute, out Uri _)) { return false; } return true; } public static implicit operator bool(BaseRichPresence presence) { return presence != null; } internal virtual bool Matches(RichPresence other) { if (other == null) { return false; } if (State != other.State || StateUrl != other.StateUrl || Details != other.Details || DetailsUrl != other.DetailsUrl || Type != other.Type) { return false; } if (Timestamps != null) { if (other.Timestamps == null || other.Timestamps.StartUnixMilliseconds != Timestamps.StartUnixMilliseconds || other.Timestamps.EndUnixMilliseconds != Timestamps.EndUnixMilliseconds) { return false; } } else if (other.Timestamps != null) { return false; } if (Secrets != null) { if (other.Secrets == null || other.Secrets.JoinSecret != Secrets.JoinSecret || other.Secrets.SpectateSecret != Secrets.SpectateSecret) { return false; } } else if (other.Secrets != null) { return false; } if (Party != null) { if (other.Party == null || other.Party.ID != Party.ID || other.Party.Max != Party.Max || other.Party.Size != Party.Size || other.Party.Privacy != Party.Privacy) { return false; } } else if (other.Party != null) { return false; } if (Assets != null) { if (other.Assets == null || other.Assets.LargeImageKey != Assets.LargeImageKey || other.Assets.LargeImageText != Assets.LargeImageText || other.Assets.LargeImageUrl != Assets.LargeImageUrl || other.Assets.SmallImageKey != Assets.SmallImageKey || other.Assets.SmallImageText != Assets.SmallImageText || other.Assets.SmallImageUrl != Assets.SmallImageUrl) { return false; } } else if (other.Assets != null) { return false; } return true; } public RichPresence ToRichPresence() { RichPresence richPresence = new RichPresence(); richPresence.State = State; richPresence.StateUrl = StateUrl; richPresence.Details = Details; richPresence.DetailsUrl = DetailsUrl; richPresence.Type = Type; richPresence.StatusDisplay = StatusDisplay; richPresence.Party = ((!HasParty()) ? Party : null); richPresence.Secrets = ((!HasSecrets()) ? Secrets : null); if (HasAssets()) { richPresence.Assets = new Assets { SmallImageKey = Assets.SmallImageKey, SmallImageText = Assets.SmallImageText, SmallImageUrl = Assets.SmallImageUrl, LargeImageKey = Assets.LargeImageKey, LargeImageText = Assets.LargeImageText, LargeImageUrl = Assets.LargeImageUrl }; } if (HasTimestamps()) { richPresence.Timestamps = new Timestamps(); if (Timestamps.Start.HasValue) { richPresence.Timestamps.Start = Timestamps.Start; } if (Timestamps.End.HasValue) { richPresence.Timestamps.End = Timestamps.End; } } return richPresence; } } public sealed class RichPresence : BaseRichPresence { [JsonProperty(/*Could not decode attribute arguments.*/)] public Button[] Buttons { get; set; } public bool HasButtons() { if (Buttons != null) { return Buttons.Length != 0; } return false; } public RichPresence WithState(string state) { base.State = state; return this; } public RichPresence WithStateUrl(string stateUrl) { base.StateUrl = stateUrl; return this; } public RichPresence WithDetails(string details) { base.Details = details; return this; } public RichPresence WithDetailsUrl(string detailsUrl) { base.DetailsUrl = detailsUrl; return this; } public RichPresence WithType(ActivityType type) { base.Type = type; return this; } public RichPresence WithStatusDisplay(StatusDisplayType statusDisplay) { base.StatusDisplay = statusDisplay; return this; } public RichPresence WithTimestamps(Timestamps timestamps) { base.Timestamps = timestamps; return this; } public RichPresence WithAssets(Assets assets) { base.Assets = assets; return this; } public RichPresence WithParty(Party party) { base.Party = party; return this; } public RichPresence WithSecrets(Secrets secrets) { base.Secrets = secrets; return this; } public RichPresence WithButtons(Button topButton, Button bottomButton = null) { if (topButton != null && bottomButton != null) { Buttons = new Button[2] { topButton, bottomButton }; } else if (topButton == null && bottomButton == null) { Buttons = null; } else { Buttons = new Button[1] { topButton ?? bottomButton }; } return this; } public RichPresence Clone() { return new RichPresence { State = ((_state != null) ? (_state.Clone() as string) : null), StateUrl = ((_stateUrl != null) ? (_stateUrl.Clone() as string) : null), Details = ((_details != null) ? (_details.Clone() as string) : null), DetailsUrl = ((_detailsUrl != null) ? (_detailsUrl.Clone() as string) : null), Type = base.Type, StatusDisplay = base.StatusDisplay, Buttons = ((!HasButtons()) ? null : (Buttons.Clone() as Button[])), Secrets = ((!HasSecrets()) ? null : new Secrets { JoinSecret = ((base.Secrets.JoinSecret != null) ? (base.Secrets.JoinSecret.Clone() as string) : null), SpectateSecret = ((base.Secrets.SpectateSecret != null) ? (base.Secrets.SpectateSecret.Clone() as string) : null) }), Timestamps = ((!HasTimestamps()) ? null : new Timestamps { Start = base.Timestamps.Start, End = base.Timestamps.End }), Assets = ((!HasAssets()) ? null : new Assets { LargeImageKey = ((base.Assets.LargeImageKey != null) ? (base.Assets.LargeImageKey.Clone() as string) : null), LargeImageText = ((base.Assets.LargeImageText != null) ? (base.Assets.LargeImageText.Clone() as string) : null), LargeImageUrl = ((base.Assets.LargeImageUrl != null) ? (base.Assets.LargeImageUrl.Clone() as string) : null), SmallImageKey = ((base.Assets.SmallImageKey != null) ? (base.Assets.SmallImageKey.Clone() as string) : null), SmallImageText = ((base.Assets.SmallImageText != null) ? (base.Assets.SmallImageText.Clone() as string) : null), SmallImageUrl = ((base.Assets.SmallImageUrl != null) ? (base.Assets.SmallImageUrl.Clone() as string) : null) }), Party = ((!HasParty()) ? null : new Party { ID = base.Party.ID, Size = base.Party.Size, Max = base.Party.Max, Privacy = base.Party.Privacy }) }; } internal RichPresence Merge(BaseRichPresence presence) { _state = presence.State; _stateUrl = presence.StateUrl; _details = presence.Details; _detailsUrl = presence.DetailsUrl; base.Type = presence.Type; base.StatusDisplay = presence.StatusDisplay; base.Party = presence.Party; base.Timestamps = presence.Timestamps; base.Secrets = presence.Secrets; if (presence.HasAssets()) { if (!HasAssets()) { base.Assets = presence.Assets; } else { base.Assets.Merge(presence.Assets); } } else { base.Assets = null; } return this; } internal override bool Matches(RichPresence other) { if (!base.Matches(other)) { return false; } if ((Buttons == null) ^ (other.Buttons == null)) { return false; } if (Buttons != null) { if (Buttons.Length != other.Buttons.Length) { return false; } for (int i = 0; i < Buttons.Length; i++) { Button button = Buttons[i]; Button button2 = other.Buttons[i]; if (button.Label != button2.Label || button.Url != button2.Url) { return false; } } } return true; } public static implicit operator bool(RichPresence presesnce) { return presesnce != null; } } internal sealed class RichPresenceResponse : BaseRichPresence { [JsonProperty("application_id")] public string ClientID { get; private set; } [JsonProperty("name")] public string Name { get; private set; } } [Serializable] public class Secrets { [Obsolete("This feature has been deprecated my Mason in issue #152 on the offical library. Was originally used as a Notify Me feature, it has been replaced with Join / Spectate.", true)] public string MatchSecret; private string _joinSecret; private string _spectateSecret; [JsonProperty(/*Could not decode attribute arguments.*/)] public string JoinSecret { get { return _joinSecret; } set { if (!BaseRichPresence.ValidateString(value, out _joinSecret, useBytes: false, 128)) { throw new StringOutOfRangeException(128); } } } [JsonProperty(/*Could not decode attribute arguments.*/)] public string SpectateSecret { get { return _spectateSecret; } set { if (!BaseRichPresence.ValidateString(value, out _spectateSecret, useBytes: false, 128)) { throw new StringOutOfRangeException(128); } } } public static Encoding Encoding => Encoding.UTF8; public static int SecretLength => 128; public static string CreateSecret(Random random) { byte[] array = new byte[SecretLength]; random.NextBytes(array); return Encoding.GetString(array); } public static string CreateFriendlySecret(Random random) { string text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < SecretLength; i++) { stringBuilder.Append(text[random.Next(text.Length)]); } return stringBuilder.ToString(); } } public enum StatusDisplayType { Name, State, Details } [Serializable] public class Timestamps { public static Timestamps Now => new Timestamps(DateTime.UtcNow); [JsonIgnore] public DateTime? Start { get; set; } [JsonIgnore] public DateTime? End { get; set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public ulong? StartUnixMilliseconds { get { if (!Start.HasValue) { return null; } return ToUnixMilliseconds(Start.Value); } set { Start = (value.HasValue ? new DateTime?(FromUnixMilliseconds(value.Value)) : null); } } [JsonProperty(/*Could not decode attribute arguments.*/)] public ulong? EndUnixMilliseconds { get { if (!End.HasValue) { return null; } return ToUnixMilliseconds(End.Value); } set { End = (value.HasValue ? new DateTime?(FromUnixMilliseconds(value.Value)) : null); } } public static Timestamps FromTimeSpan(double seconds) { return FromTimeSpan(TimeSpan.FromSeconds(seconds)); } public static Timestamps FromTimeSpan(TimeSpan timespan) { return new Timestamps { Start = DateTime.UtcNow, End = DateTime.UtcNow + timespan }; } public Timestamps() { Start = null; End = null; } public Timestamps(DateTime start) { Start = start; End = null; } public Timestamps(DateTime start, DateTime end) { Start = start; End = end; } public static DateTime FromUnixMilliseconds(ulong unixTime) { return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(Convert.ToDouble(unixTime)); } public static ulong ToUnixMilliseconds(DateTime date) { DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return Convert.ToUInt64((date - dateTime).TotalMilliseconds); } } public class User { public enum AvatarFormat { PNG, JPEG, WebP, GIF } public enum AvatarSize { x16 = 0x10, x32 = 0x20, x64 = 0x40, x128 = 0x80, x256 = 0x100, x512 = 0x200, x1024 = 0x400, x2048 = 0x800 } public struct AvatarDecorationData { [JsonProperty("asset")] public string Asset { get; private set; } [JsonProperty("skuId")] public string SKU { get; private set; } } [Flags] public enum Flag { None = 0, Employee = 1, Partner = 2, HypeSquad = 4, BugHunter = 8, HouseBravery = 0x40, HouseBrilliance = 0x80, HouseBalance = 0x100, EarlySupporter = 0x200, TeamUser = 0x400, BugHunterLevel2 = 0x4000, VerifiedBot = 0x10000, VerifiedDeveloper = 0x20000, CertifiedModerator = 0x40000, BotHttpInteractions = 0x80000, ActiveDeveloper = 0x400000 } public enum PremiumType { None, NitroClassic, Nitro, NitroBasic } [JsonProperty("id")] public ulong ID { get; private set; } [JsonProperty("username")] public string Username { get; private set; } [JsonProperty("discriminator")] [Obsolete("Discord no longer uses discriminators.")] public int Discriminator { get; private set; } [JsonProperty("global_name")] public string DisplayName { get; private set; } [JsonProperty("avatar")] public string Avatar { get; private set; } public bool IsAvatarAnimated { get { if (Avatar != null) { return Avatar.StartsWith("a_"); } return false; } } [JsonProperty("avatar_decoration_data")] public AvatarDecorationData? AvatarDecoration { get; private set; } [JsonProperty("bot")] public bool Bot { get; private set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public Flag Flags { get; private set; } [JsonProperty(/*Could not decode attribute arguments.*/)] public PremiumType Premium { get; private set; } public string CdnEndpoint { get; private set; } internal User() { CdnEndpoint = "cdn.discordapp.com"; } internal void SetConfiguration(Configuration configuration) { CdnEndpoint = configuration.CdnHost; } public string GetAvatarURL() { return GetAvatarURL(AvatarFormat.PNG, AvatarSize.x128); } public string GetAvatarURL(AvatarFormat format) { return GetAvatarURL(format, AvatarSize.x128); } public string GetAvatarURL(AvatarFormat format, AvatarSize size) { string text = $"/avatars/{ID}/{Avatar}"; if (string.IsNullOrEmpty(Avatar)) { if (format != 0) { throw new BadImageFormatException("The user has no avatar and the requested format " + format.ToString() + " is not supported. (Only supports PNG)."); } int num = (int)((ID >> 22) % 6); if (Discriminator > 0) { num = Discriminator % 5; } text = $"/embed/avatars/{num}"; } return $"https://{CdnEndpoint}{text}{GetAvatarExtension(format)}?size={(int)size}&animated=true"; } public string GetAvatarDecorationURL() { return GetAvatarDecorationURL(AvatarFormat.PNG); } public string GetAvatarDecorationURL(AvatarFormat format) { if (!AvatarDecoration.HasValue) { return null; } string arg = "/avatar-decoration-presets/" + AvatarDecoration.Value.Asset; return $"https://{CdnEndpoint}{arg}{GetAvatarExtension(format)}"; } public string GetAvatarExtension(AvatarFormat format) { return "." + format.ToString().ToLowerInvariant(); } public override string ToString() { if (!string.IsNullOrEmpty(DisplayName)) { return DisplayName; } if (Discriminator != 0) { return Username + "#" + Discriminator.ToString("D4"); } return Username; } } [Flags] public enum EventType { None = 0, Spectate = 1, Join = 2, JoinRequest = 4 } } namespace DiscordRPC.RPC { internal class RpcConnection : IDisposable { public static readonly int VERSION = 1; public static readonly int POLL_RATE = 1000; private static readonly bool CLEAR_ON_SHUTDOWN = true; private static readonly bool LOCK_STEP = false; private ILogger _logger; private RpcState _state; private readonly object l_states = new object(); private Configuration _configuration; private readonly object l_config = new object(); private volatile bool aborting; private volatile bool shutdown; private string applicationID; private int processID; private long nonce; private Thread thread; private INamedPipeClient namedPipe; private int targetPipe; private readonly object l_rtqueue = new object(); private readonly uint _maxRtQueueSize; private Queue<ICommand> _rtqueue; private readonly object l_rxqueue = new object(); private readonly uint _maxRxQueueSize; private Queue<IMessage> _rxqueue; private AutoResetEvent queueUpdatedEvent = new AutoResetEvent(initialState: false); private BackoffDelay delay; public ILogger Logger { get { return _logger; } set { _logger = value; if (namedPipe != null) { namedPipe.Logger = value; } } } public RpcState State { get { lock (l_states) { return _state; } } } public Configuration Configuration { get { Configuration configuration = null; lock (l_config) { return _configuration; } } } public bool IsRunning => thread != null; public bool ShutdownOnly { get; set; } public event OnRpcMessageEvent OnRpcMessage; public RpcConnection(string applicationID, int processID, int targetPipe, INamedPipeClient client, uint maxRxQueueSize = 128u, uint maxRtQueueSize = 512u) { this.applicationID = applicationID; this.processID = processID; this.targetPipe = targetPipe; namedPipe = client; ShutdownOnly = true; Logger = new ConsoleLogger(); delay = new BackoffDelay(500, 60000); _maxRtQueueSize = maxRtQueueSize; _rtqueue = new Queue<ICommand>((int)(_maxRtQueueSize + 1)); _maxRxQueueSize = maxRxQueueSize; _rxqueue = new Queue<IMessage>((int)(_maxRxQueueSize + 1)); nonce = 0L; } private long GetNextNonce() { nonce++; return nonce; } internal void EnqueueCommand(ICommand command) { Logger.Trace("Enqueue Command: {0}", command.GetType().FullName); if (aborting || shutdown) { return; } lock (l_rtqueue) { if (_rtqueue.Count == _maxRtQueueSize) { Logger.Error("Too many enqueued commands, dropping oldest one. Maybe you are pushing new presences to fast?"); _rtqueue.Dequeue(); } _rtqueue.Enqueue(command); } } private void EnqueueMessage(IMessage message) { try { if (this.OnRpcMessage != null) { this.OnRpcMessage(this, message); } } catch (Exception ex) { Logger.Error("Unhandled Exception while processing event: {0}", ex.GetType().FullName); Logger.Error(ex.Message); Logger.Error(ex.StackTrace); } if (_maxRxQueueSize == 0) { Logger.Trace("Enqueued Message, but queue size is 0."); return; } Logger.Trace("Enqueue Message: {0}", message.Type); lock (l_rxqueue) { if (_rxqueue.Count == _maxRxQueueSize) { Logger.Warning("Too many enqueued messages, dropping oldest one."); _rxqueue.Dequeue(); } _rxqueue.Enqueue(message); } } internal IMessage DequeueMessage() { lock (l_rxqueue) { if (_rxqueue.Count == 0) { return null; } return _rxqueue.Dequeue(); } } internal IMessage[] DequeueMessages() { lock (l_rxqueue) { IMessage[] result = _rxqueue.ToArray(); _rxqueue.Clear(); return result; } } private void MainLoop() { Logger.Info("RPC Connection Started"); if (Logger.Level <= LogLevel.Trace) { Logger.Trace("============================"); Logger.Trace("Assembly: " + Assembly.GetAssembly(typeof(RichPresence)).FullName); Logger.Trace("Pipe: " + namedPipe.GetType().FullName); Logger.Trace("Platform: " + Environment.OSVersion.ToString()); Logger.Trace("DotNet: " + Environment.Version.ToString()); Logger.Trace("applicationID: " + applicationID); Logger.Trace("targetPipe: " + targetPipe); ILogger logger = Logger; int pOLL_RATE = POLL_RATE; logger.Trace("POLL_RATE: " + pOLL_RATE); ILogger logger2 = Logger; uint maxRtQueueSize = _maxRtQueueSize; logger2.Trace("_maxRtQueueSize: " + maxRtQueueSize); ILogger logger3 = Logger; maxRtQueueSize = _maxRxQueueSize; logger3.Trace("_maxRxQueueSize: " + maxRtQueueSize); Logger.Trace("============================"); } while (!aborting && !shutdown) { try { if (namedPipe == null) { Logger.Error("Something bad has happened with our pipe client!"); aborting = true; return; } Logger.Trace("Connecting to the pipe through the {0}", namedPipe.GetType().FullName); if (namedPipe.Connect(targetPipe)) { Logger.Trace("Connected to the pipe. Attempting to establish handshake..."); EnqueueMessage(new ConnectionEstablishedMessage { ConnectedPipe = namedPipe.ConnectedPipe }); EstablishHandshake(); Logger.Trace("Connection Established. Starting reading loop..."); bool flag = true; while (flag && !aborting && !shutdown && namedPipe.IsConnected) { if (namedPipe.ReadFrame(out var frame)) { Logger.Trace("Read Payload: {0}", frame.Opcode); switch (frame.Opcode) { case Opcode.Close: { ClosePayload @object = frame.GetObject<ClosePayload>(); Logger.Warning("We have been told to terminate by discord: ({0}) {1}", @object.Code, @object.Reason); EnqueueMessage(new CloseMessage { Code = @object.Code, Reason = @object.Reason }); flag = false; break; } case Opcode.Ping: Logger.Trace("PING"); frame.Opcode = Opcode.Pong; namedPipe.WriteFrame(frame); break; case Opcode.Pong: Logger.Trace("PONG"); break; case Opcode.Frame: { if (shutdown) { Logger.Warning("Skipping frame because we are shutting down."); break; } if (frame.Data == null) { Logger.Error("We received no data from the frame so we cannot get the event payload!"); break; } EventPayload eventPayload = null; try { eventPayload = frame.GetObject<EventPayload>(); } catch (Exception ex) { Logger.Error("Failed to parse event! {0}", ex.Message); Logger.Error("Data: {0}", frame.Message); } try { if (eventPayload != null) { ProcessFrame(eventPayload); } } catch (Exception ex2) { Logger.Error("Failed to process event! {0}", ex2.Message); Logger.Error("Data: {0}", frame.Message); } break; } default: Logger.Error("Invalid opcode: {0}", frame.Opcode); flag = false; break; } } if (!aborting && namedPipe.IsConnected) { ProcessCommandQueue(); queueUpdatedEvent.WaitOne(POLL_RATE); } } Logger.Trace("Left main read loop for some reason. Aborting: {0}, Shutting Down: {1}", aborting, shutdown); } else { Logger.Error("Failed to connect for some reason."); EnqueueMessage(new ConnectionFailedMessage { FailedPipe = targetPipe }); } if (!aborting && !shutdown) { long num = delay.NextDelay(); Logger.Trace("Waiting {0}ms before attempting to connect again", num); Thread.Sleep(delay.NextDelay()); } } catch (Exception ex3) { Logger.Error("Unhandled Exception: {0}", ex3.GetType().FullName); Logger.Error(ex3.Message); Logger.Error(ex3.StackTrace); } finally { if (namedPipe.IsConnected) { Logger.Trace("Closing the named pipe."); namedPipe.Close(); } SetConnectionState(RpcState.Disconnected); } } Logger.Trace("Left Main Loop"); if (namedPipe != null) { namedPipe.Dispose(); } Logger.Info("Thread Terminated, no longer performing RPC connection."); } private void ProcessFrame(EventPayload response) { //IL_01c6: Unknown result type (might be due to invalid IL or missing references) Logger.Info("Handling Response. Cmd: {0}, Event: {1}", response.Command, response.Event); if (response.Event.HasValue && response.Event.Value == ServerEvent.Error) { Logger.Error("Error received from the RPC"); ErrorMessage @object = response.GetObject<ErrorMessage>(); Logger.Error("Server responded with an error message: ({0}) {1}", @object.Code.ToString(), @object.Message); EnqueueMessage(@object); } else if (State == RpcState.Connecting && response.Command == Command.Dispatch && response.Event.HasValue && response.Event.Value == ServerEvent.Ready) { Logger.Info("Connection established with the RPC"); SetConnectionState(RpcState.Connected); delay.Reset(); ReadyMessage object2 = response.GetObject<ReadyMessage>(); lock (l_config) { _configuration = object2.Configuration; object2.User.SetConfiguration(_configuration); } EnqueueMessage(object2); } else if (State == RpcState.Connected) { switch (response.Command) { case Command.Dispatch: ProcessDispatch(response); break; case Command.SetActivity: { if (response.Data == null) { EnqueueMessage(new PresenceMessage()); break; } RichPresenceResponse object3 = response.GetObject<RichPresenceResponse>(); EnqueueMessage(new PresenceMessage(object3)); break; } case Command.Subscribe: case Command.Unsubscribe: { ((Collection<JsonConverter>)(object)new JsonSerializer().Converters).Add((JsonConverter)(object)new EnumSnakeCaseConverter()); ServerEvent value = response.GetObject<EventPayload>().Event.Value; if (response.Command == Command.Subscribe) { EnqueueMessage(new SubscribeMessage(value)); } else { EnqueueMessage(new UnsubscribeMessage(value)); } break; } case Command.SendActivityJoinInvite: Logger.Trace("Got invite response ack."); break; case Command.CloseActivityJoinRequest: Logger.Trace("Got invite response reject ack."); break; default: Logger.Error("Unknown frame was received! {0}", response.Command); break; } } else { Logger.Trace("Received a frame while we are disconnected. Ignoring. Cmd: {0}, Event: {1}", response.Command, response.Event); } } private void ProcessDispatch(EventPayload response) { if (response.Command == Command.Dispatch && response.Event.HasValue) { switch (response.Event.Value) { case ServerEvent.ActivitySpectate: { SpectateMessage object3 = response.GetObject<SpectateMessage>(); EnqueueMessage(object3); break; } case ServerEvent.ActivityJoin: { JoinMessage object2 = response.GetObject<JoinMessage>(); EnqueueMessage(object2); break; } case ServerEvent.ActivityJoinRequest: { JoinRequestMessage @object = response.GetObject<JoinRequestMessage>(); EnqueueMessage(@object); break; } default: Logger.Warning("Ignoring {0}", response.Event.Value); break; } } } private void ProcessCommandQueue() { if (State != RpcState.Connected) { return; } if (aborting) { Logger.Warning("We have been told to write a queue but we have also been aborted."); } bool flag = true; ICommand command = null; while (flag && namedPipe.IsConnected) { lock (l_rtqueue) { flag = _rtqueue.Count > 0; if (!flag) { break; } command = _rtqueue.Peek(); } if (shutdown || (!aborting && LOCK_STEP)) { flag = false; } IPayload payload = command.PreparePayload(GetNextNonce()); Logger.Trace("Attempting to send payload: {0}", payload.Command); PipeFrame frame = default(PipeFrame); if (command is CloseCommand) { SendHandwave(); Logger.Trace("Handwave sent, ending queue processing."); lock (l_rtqueue) { _rtqueue.Dequeue(); break; } } if (aborting) { Logger.Warning("- skipping frame because of abort."); lock (l_rtqueue) { _rtqueue.Dequeue(); } continue; } frame.SetObject(Opcode.Frame, payload); Logger.Trace("Sending payload: {0}", payload.Command); if (namedPipe.WriteFrame(frame)) { Logger.Trace("Sent Successfully."); lock (l_rtqueue) { _rtqueue.Dequeue(); } continue; } Logger.Warning("Something went wrong during writing!"); break; } } private void EstablishHandshake() { Logger.Trace("Attempting to establish a handshake..."); if (State != 0) { Logger.Error("State must be disconnected in order to start a handshake!"); return; } Logger.Trace("Sending Handshake..."); if (!namedPipe.WriteFrame(new PipeFrame(Opcode.Handshake, new Handshake { Version = VERSION, ClientID = applicationID }))) { Logger.Error("Failed to write a handshake."); } else { SetConnectionState(RpcState.Connecting); } } private void SendHandwave() { Logger.Info("Attempting to wave goodbye..."); if (State == RpcState.Disconnected) { Logger.Error("State must NOT be disconnected in order to send a handwave!"); } else if (!namedPipe.WriteFrame(new PipeFrame(Opcode.Close, new Handshake { Version = VERSION, ClientID = applicationID }))) { Logger.Error("failed to write a handwave."); } } public bool AttemptConnection() { Logger.Info("Attempting a new connection"); if (thread != null) { Logger.Error("Cannot attempt a new connection as the previous connection thread is not null!"); return false; } if (State != 0) { Logger.Warning("Cannot attempt a new connection as the previous connection hasn't changed state yet."); return false; } if (aborting) { Logger.Error("Cannot attempt a new connection while aborting!"); return false; } thread = new Thread(MainLoop); thread.Name = "Discord IPC Thread"; thread.IsBackground = true; thread.Start(); return true; } private void SetConnectionState(RpcState state) { Logger.Trace("Setting the connection state to {0}", state.ToString().ToSnakeCase().ToUpperInvariant()); lock (l_states) { _state = state; } } public void Shutdown() { Logger.Trace("Initiated shutdown procedure"); shutdown = true; lock (l_rtqueue) { _rtqueue.Clear(); if (CLEAR_ON_SHUTDOWN) { _rtqueue.Enqueue(new PresenceCommand { PID = processID, Presence = null }); } _rtqueue.Enqueue(new CloseCommand()); } queueUpdatedEvent.Set(); } public void Close() { if (thread == null) { Logger.Error("Cannot close as it is not available!"); return; } if (aborting) { Logger.Error("Cannot abort as it has already been aborted"); return; } if (ShutdownOnly) { Shutdown(); return; } Logger.Trace("Updating Abort State..."); aborting = true; queueUpdatedEvent.Set(); } public void Dispose() { ShutdownOnly = false; Close(); } } internal enum RpcState { Disconnected, Connecting, Connected } } namespace DiscordRPC.RPC.Payload { internal class ClosePayload : IPayload { [JsonProperty("code")] public int Code { get; set; } [JsonProperty("message")] public string Reason { get; set; } [JsonConstructor] public ClosePayload() { Code = -1; Reason = ""; } } internal enum Command { [EnumValue("DISPATCH")] Dispatch, [EnumValue("SET_ACTIVITY")] SetActivity, [EnumValue("SUBSCRIBE")] Subscribe, [EnumValue("UNSUBSCRIBE")] Unsubscribe, [EnumValue("SEND_ACTIVITY_JOIN_INVITE")] SendActivityJoinInvite, [EnumValue("CLOSE_ACTIVITY_JOIN_REQUEST")] CloseActivityJoinRequest, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] Authorize, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] Authenticate, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] GetGuild, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] GetGuilds, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] GetChannel, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] GetChannels, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] SetUserVoiceSettings, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] SelectVoiceChannel, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] GetSelectedVoiceChannel, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] SelectTextChannel, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] GetVoiceSettings, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] SetVoiceSettings, [Obsolete("This value is appart of the RPC API and is not supported by this library.", true)] CaptureShortcut } internal abstract class IPayload { [JsonProperty("cmd")] [JsonConverter(typeof(EnumSnakeCaseConverter))] public Command Command { get; set; } [JsonProperty("nonce")] public string Nonce { get; set; } protected IPayload() { } protected IPayload(long nonce) { Nonce = nonce.ToString(); } public override string ToString() { return $"Payload || Command: {Command}, Nonce: {Nonce}"; } } internal class ArgumentPayload : IPayload { [JsonProperty(/*Could not decode attribute arguments.*/)] public JObject Arguments { get; set; } public ArgumentPayload() { Arguments = null; } public ArgumentPayload(long nonce) : base(nonce) { Arguments = null; } public ArgumentPayload(object args, long nonce) : base(nonce) { SetObject(args); } public void SetObject(object obj) { Arguments = JObject.FromObject(obj); } public T GetObject<T>() { return ((JToken)Arguments).ToObject<T>(); } public override string ToString() { return "Argument " + base.ToString(); } } internal class EventPayload : IPayload { [JsonProperty(/*Could not decode attribute arguments.*/)] public JObject Data { get; set; } [JsonProperty("evt")] [JsonConverter(typeof(EnumSnakeCaseConverter))] public ServerEvent? Event { get; set; } public EventPayload() { Data = null; } public EventPayload(long nonce) : base(nonce) { Data = null; } public T GetObject<T>() { if (Data == null) { return default(T); } return ((JToken)Data).ToObject<T>(); } public override string ToString() { return "Event " + base.ToString() + ", Event: " + (Event.HasValue ? Event.ToString() : "N/A"); } } internal enum ServerEvent { [EnumValue("READY")] Ready, [EnumValue("ERROR")] Error, [EnumValue("ACTIVITY_JOIN")] ActivityJoin, [EnumValue("ACTIVITY_SPECTATE")] ActivitySpectate, [EnumValue("ACTIVITY_JOIN_REQUEST")] ActivityJoinRequest } } namespace DiscordRPC.RPC.Commands { internal class CloseCommand : ICommand { [JsonProperty("close_reason")] public string value = "Unity 5.5 doesn't handle thread aborts. Can you please close me discord?"; [JsonProperty("pid")] public int PID { get; set; } public IPayload PreparePayload(long nonce) { return new ArgumentPayload { Command = Command.Dispatch, Nonce = null, Arguments = null }; } } internal interface ICommand { IPayload PreparePayload(long nonce); } internal class PresenceCommand : ICommand { [JsonProperty("pid")] public int PID { get; set; } [JsonProperty("activity")] public RichPresence Presence { get; set; } public IPayload PreparePayload(long nonce) { return new ArgumentPayload(this, nonce) { Command = Command.SetActivity }; } } internal class RespondCommand : ICommand { [JsonProperty("user_id")] public string UserID { get; set; } [JsonIgnore] public bool Accept { get; set; } public IPayload PreparePayload(long nonce) { return new ArgumentPayload(this, nonce) { Command = (Accept ? Command.SendActivityJoinInvite : Command.CloseActivityJoinRequest) }; } } internal class SubscribeCommand : ICommand { public ServerEvent Event { get; set; } public bool IsUnsubscribe { get; set; } public IPayload PreparePayload(long nonce) { return new EventPayload(nonce) { Command = (IsUnsubscribe ? Command.Unsubscribe : Command.Subscribe), Event = Event }; } } } namespace DiscordRPC.Registry { public interface IRegisterUriScheme { bool Register(SchemeInfo info); } public sealed class MacUriScheme : IRegisterUriScheme { private ILogger logger; public MacUriScheme(ILogger logger) { this.logger = logger; } public bool Register(SchemeInfo info) { string executablePath = info.ExecutablePath; if (string.IsNullOrEmpty(executablePath)) { logger.Error("Failed to register because the application could not be located."); return false; } logger.Trace("Registering Steam Command"); string text = executablePath; if (info.UsingSteamApp) { text = "steam://rungameid/" + info.SteamAppID; } else { logger.Warning("This library does not fully support MacOS URI Scheme Registration."); } string text2 = "~/Library/Application Support/discord/games"; if (!Directory.CreateDirectory(text2).Exists) { logger.Error("Failed to register because {0} does not exist", text2); return false; } string text3 = text2 + "/" + info.ApplicationID + ".json"; File.WriteAllText(text3, "{ \"command\": \"" + text + "\" }"); logger.Trace("Registered {0}, {1}", text3, text); return true; } } public sealed class UnixUriScheme : IRegisterUriScheme { private ILogger logger; public UnixUriScheme(ILogger logger) { this.logger = logger; } public bool Register(SchemeInfo info) { string environmentVariable = Environment.GetEnvironmentVariable("HOME"); if (string.IsNullOrEmpty(environmentVariable)) { logger.Error("Failed to register because the HOME variable was not set."); return false; } string executablePath = info.ExecutablePath; if (string.IsNullOrEmpty(executablePath)) { logger.Error("Failed to register because the application was not located."); return false; } string text = null; text = ((!info.UsingSteamApp) ? executablePath : ("xdg-open steam://rungameid/" + info.SteamAppID)); string text2 = $"[Desktop Entry]\nName=Game {info.ApplicationID}\nExec={text} %u\nType=Application\nNoDisplay=true\nCategories=Discord;Games;\nMimeType=x-scheme-handler/discord-{info.ApplicationID}"; string text3 = "/discord-" + info.ApplicationID + ".desktop"; string text4 = environmentVariable + "/.local/share/applications"; if (!Directory.CreateDirectory(text4).Exists) { logger.Error("Failed to register because {0} does not exist", text4); return false; } File.WriteAllText(text4 + text3, text2); if (!RegisterMime(info.ApplicationID)) { logger.Error("Failed to register because the Mime failed."); return false; } logger.Trace("Registered {0}, {1}, {2}", text4 + text3, text2, text); return true; } private bool RegisterMime(string appid) { string arguments = string.Format("default discord-{0}.desktop x-scheme-handler/discord-{0}", appid); Process process = Process.Start("xdg-mime", arguments); process.WaitForExit(); return process.ExitCode >= 0; } } public struct SchemeInfo { public string ApplicationID { get; set; } public string SteamAppID { get; set; } public string ExecutablePath { get; set; } public bool UsingSteamApp => !string.IsNullOrEmpty(SteamAppID); } public static class UriScheme { public static bool Register(SchemeInfo info, ILogger logger = null) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return new WindowsUriScheme(logger).Register(info); } if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { return new UnixUriScheme(logger).Register(info); } if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return new MacUriScheme(logger).Register(info); } logger?.Error("Unknown Platform: {0}", RuntimeInformation.OSDescription); throw new PlatformNotSupportedException("Platform does not support registration."); } } public sealed class WindowsUriScheme : IRegisterUriScheme { private ILogger logger; public WindowsUriScheme(ILogger logger) { this.logger = logger; } public bool Register(SchemeInfo info) { string executablePath = info.ExecutablePath; if (executablePath == null) { logger.Error("Failed to register application because the location was null."); return false; } string scheme = "discord-" + info.ApplicationID; string friendlyName = "Run game " + info.ApplicationID + " protocol"; string defaultIcon = executablePath; string command = executablePath; if (info.UsingSteamApp) { string steamLocation = GetSteamLocation(); if (steamLocation != null) { command = $"\"{steamLocation}\" steam://rungameid/{info.SteamAppID}"; } } CreateUriScheme(scheme, friendlyName, defaultIcon, command); return true; } private void CreateUriScheme(string scheme, string friendlyName, string defaultIcon, string command) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new PlatformNotSupportedException("Requires Windows to use the Registry"); } using (RegistryKey registryKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SOFTWARE\\Classes\\" + scheme)) { registryKey.SetValue("", "URL:" + friendlyName); registryKey.SetValue("URL Protocol", ""); using (RegistryKey registryKey2 = registryKey.CreateSubKey("DefaultIcon")) { registryKey2.SetValue("", defaultIcon); } using RegistryKey registryKey3 = registryKey.CreateSubKey("shell\\open\\command"); registryKey3.SetValue("", command); } logger.Trace("Registered {0}, {1}, {2}", scheme, friendlyName, command); } public string GetSteamLocation() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new PlatformNotSupportedException("Requires Windows to use the Registry"); } using RegistryKey registryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Valve\\Steam"); if (registryKey == null) { return null; } return registryKey.GetValue("SteamExe") as string; } } } namespace DiscordRPC.Message { public class CloseMessage : IMessage { public override MessageType Type => MessageType.Close; public string Reason { get; internal set; } public int Code { get; internal set; } internal CloseMessage() { } internal CloseMessage(string reason) { Reason = reason; } } public class ConnectionEstablishedMessage : IMessage { public override MessageType Type => MessageType.ConnectionEstablished; [Obsolete("The connected pipe is not neccessary information.")] public int ConnectedPipe { get; internal set; } } public class ConnectionFailedMessage : IMessage { public override MessageType Type => MessageType.ConnectionFailed; public int FailedPipe { get; internal set; } } public class ErrorMessage : IMessage { public override MessageType Type => MessageType.Error; [JsonProperty("code")] public ErrorCode Code { get; internal set; } [JsonProperty("message")] public string Message { get; internal set; } } public enum ErrorCode { Success = 0, PipeException = 1, ReadCorrupt = 2, NotImplemented = 10, UnknownError = 1000, InvalidPayload = 4000, InvalidCommand = 4002, InvalidEvent = 4004 } public abstract class IMessage { private DateTime _timecreated; public abstract MessageType Type { get; } public DateTime TimeCreated => _timecreated; public IMessage() { _timecreated = DateTime.Now; } } public class JoinMessage : IMessage { public override MessageType Type => MessageType.Join; [JsonProperty("secret")] public string Secret { get; internal set; } } public class JoinRequestMessage : IMessage { public override MessageType Type => MessageType.JoinRequest; [JsonProperty("user")] public User User { get; internal set; } } public enum MessageType { Ready, Close, Error, PresenceUpdate, Subscribe, Unsubscribe, Join, Spectate, JoinRequest, ConnectionEstablished, ConnectionFailed } public class PresenceMessage : IMessage { public override MessageType Type => MessageType.PresenceUpdate; public BaseRichPresence Presence { get; internal set; } public string Name { get; internal set; } public string ApplicationID { get; internal set; } internal PresenceMessage() : this(null) { } internal PresenceMessage(RichPresenceResponse rpr) { if (rpr == null) { Presence = null; Name = "No Rich Presence"; ApplicationID = ""; } else { Presence = rpr; Name = rpr.Name; ApplicationID = rpr.ClientID; } } } public class ReadyMessage : IMessage { public override MessageType Type => MessageType.Ready; [JsonProperty("config")] public Configuration Configuration { get; set; } [JsonProperty("user")] public User User { get; set; } [JsonProperty("v")] public int Version { get; set; } } public class SpectateMessage : JoinMessage { public override MessageType Type => MessageType.Spectate; } public class SubscribeMessage : IMessage { public override MessageType Type => MessageType.Subscribe; public EventType Event { get; internal set; } internal SubscribeMessage(ServerEvent evt) { switch (evt) { default: Event = EventType.Join; break; case ServerEvent.ActivityJoinRequest: Event = EventType.JoinRequest; break; case ServerEvent.ActivitySpectate: Event = EventType.Spectate; break; } } } public class UnsubscribeMessage : IMessage { public override MessageType Type => MessageType.Unsubscribe; public EventType Event { get; internal set; } internal UnsubscribeMessage(ServerEvent evt) { switch (evt) { default: Event = EventType.Join; break; case ServerEvent.ActivityJoinRequest: Event = EventType.JoinRequest; break; case ServerEvent.ActivitySpectate: Event = EventType.Spectate; break; } } } } namespace DiscordRPC.Logging { public class ConsoleLogger : ILogger { public LogLevel Level { get; set; } public bool Coloured { get; set; } public bool Colored { get { return Coloured; } set { Coloured = value; } } public ConsoleLogger() { Level = LogLevel.Info; Coloured = false; } public ConsoleLogger(LogLevel level) : this() { Level = level; } public ConsoleLogger(LogLevel level, bool coloured) { Level = level; Coloured = coloured; } public void Trace(string message, params object[] args) { if (Level <= LogLevel.Trace) { if (Coloured) { Console.ForegroundColor = ConsoleColor.Gray; } string text = "TRACE: " + message; if (args.Length != 0) { Console.WriteLine(text, args); } else { Console.WriteLine(text); } } } public void Info(string message, params object[] args) { if (Level <= LogLevel.Info) { if (Coloured) { Console.ForegroundColor = ConsoleColor.White; } string text = "INFO: " + message; if (args.Length != 0) { Console.WriteLine(text, args); } else { Console.WriteLine(text); } } } public void Warning(string message, params object[] args) { if (Level <= LogLevel.Warning) { if (Coloured) { Console.ForegroundColor = ConsoleColor.Yellow; } string text = "WARN: " + message; if (args.Length != 0) { Console.WriteLine(text, args); } else { Console.WriteLine(text); } } } public void Error(string message, params object[] args) { if (Level <= LogLevel.Error) { if (Coloured) { Console.ForegroundColor = ConsoleColor.Red; } string text = "ERR : " + message; if (args.Length != 0) { Console.WriteLine(text, args); } else { Console.WriteLine(text); } } } } public class FileLogger : ILogger { private object filelock; public LogLevel Level { get; set; } public string File { get; set; } public FileLogger(string path) : this(path, LogLevel.Info) { } public FileLogger(string path, LogLevel level) { Level = level; File = path; filelock = new object(); } public void Trace(string message, params object[] args) { if (Level > LogLevel.Trace) { return; } lock (filelock) { System.IO.File.AppendAllText(File, "\r\nTRCE: " + ((args.Length != 0) ? string.Format(message, args) : message)); } } public void Info(string message, params object[] args) { if (Level > LogLevel.Info) { return; } lock (filelock) { System.IO.File.AppendAllText(File, "\r\nINFO: " + ((args.Length != 0) ? string.Format(message, args) : message)); } } public void Warning(string message, params object[] args) { if (Level > LogLevel.Warning) { return; } lock (filelock) { System.IO.File.AppendAllText(File, "\r\nWARN: " + ((args.Length != 0) ? string.Format(message, args) : message)); } } public void Error(string message, params object[] args) { if (Level > LogLevel.Error) { return; } lock (filelock) { System.IO.File.AppendAllText(File, "\r\nERR : " + ((args.Length != 0) ? string.Format(message, args) : message)); } } } public interface ILogger { LogLevel Level { get; set; } void Trace(string message, params object[] args); void Info(string message, params object[] args); void Warning(string message, params object[] args); void Error(string message, params object[] args); } public enum LogLevel { Trace = 1, Info = 2, Warning = 3, Error = 4, None = 256 } public class NullLogger : ILogger { public LogLevel Level { get; set; } public void Trace(string message, params object[] args) { } public void Info(string message, params object[] args) { } public void Warning(string message, params object[] args) { } public void Error(string message, params object[] args) { } } } namespace DiscordRPC.IO { internal class Handshake { [JsonProperty("v")] public int Version { get; set; } [JsonProperty("client_id")] public string ClientID { get; set; } } public interface INamedPipeClient : IDisposable { ILogger Logger { get; set; } bool IsConnected { get; } [Obsolete("The connected pipe is not neccessary information.")] int ConnectedPipe { get; } bool Connect(int pipe); bool ReadFrame(out PipeFrame frame); bool WriteFrame(PipeFrame frame); void Close(); } public sealed class ManagedNamedPipeClient : INamedPipeClient, IDisposable { private NamedPipeClientStream _stream; private byte[] _buffer = new byte[PipeFrame.MAX_SIZE]; private Queue<PipeFrame> _framequeue = new Queue<PipeFrame>(); private object _framequeuelock = new object(); private volatile bool _isDisposed; private volatile bool _isClosed = true; private object l_stream = new object(); public ILogger Logger { get; set; } public bool IsConnected { get { if (_isClosed) { return false; } lock (l_stream) { return _stream != null && _stream.IsConnected; } } } public int ConnectedPipe { get; private set; } public ManagedNamedPipeClient() { _buffer = new byte[PipeFrame.MAX_SIZE]; Logger = new NullLogger(); _stream = null; } public bool Connect(int pipe) { Logger.Trace("ManagedNamedPipeClient.Connection({0})", pipe); if (_isDisposed) { throw new ObjectDisposedException("NamedPipe"); } if (pipe > 9) { throw new ArgumentOutOfRangeException("pipe", "Argument cannot be greater than 9"); } int startPipe = 0; if (pipe >= 0) { startPipe = pipe; } foreach (string pipe2 in PipeLocation.GetPipes(startPipe)) { if (AttemptConnection(pipe2)) { BeginReadStream(); return true; } } return false; } private bool AttemptConnection(string pipename) { if (_isDisposed) { throw new ObjectDisposedException("_stream"); } try { lock (l_stream) { Logger.Info("Attempting to connect to '{0}'", pipename); _stream = new NamedPipeClientStream(".", pipename, PipeDirection.InOut, PipeOptions.Asynchronous); _stream.Connect(0); Logger.Trace("Waiting for connection..."); do { Thread.Sleep(10); } while (!_stream.IsConnected); } Logger.Info("Connected to '{0}'", pipename); ConnectedPipe = int.Parse(pipename.Substring(pipename.LastIndexOf('-'))); _isClosed = false; } catch (Exception ex) { Logger.Error("Failed connection to {0}. {1}", pipename, ex.Message); Close(); } Logger.Trace("Done. Result: {0}", _isClosed); return !_isClosed; } private void BeginReadStream() { if (_isClosed) { return; } try { lock (l_stream) { if (_stream != null && _stream.IsConnected) { Logger.Trace("Begining Read of {0} bytes", _buffer.Length); _stream.BeginRead(_buffer, 0, _buffer.Length, EndReadStream, _stream.IsConnected); } } } catch (ObjectDisposedException) { Logger.Warning("Attempted to start reading from a disposed pipe"); } catch (InvalidOperationException) { Logger.Warning("Attempted to start reading from a closed pipe"); } catch (Exception ex3) { Logger.Error("An exception occured while starting to read a stream: {0}", ex3.Message); Logger.Error(ex3.StackTrace); } } private void EndReadStream(IAsyncResult callback) { Logger.Trace("Ending Read"); int num = 0; try { lock (l_stream) { if (_stream == null || !_stream.IsConnected) { return; } num = _stream.EndRead(callback); } } catch (IOException) { Logger.Warning("Attempted to end reading from a closed pipe"); return; } catch (NullReferenceException) { Logger.Warning("Attempted to read from a null pipe"); return; } catch (ObjectDisposedException) { Logger.Warning("Attemped to end reading from a disposed pipe"); return; } catch (Exception ex4) { Logger.Error("An exception occured while ending a read of a stream: {0}", ex4.Message); Logger.Error(ex4.StackTrace); return; } Logger.Trace("Read {0} bytes", num); if (num > 0) { using MemoryStream stream = new MemoryStream(_buffer, 0, num); try { PipeFrame item = default(PipeFrame); if (item.ReadStream(stream)) { Logger.Trace("Read a frame: {0}", item.Opcode); lock (_framequeuelock) { _framequeue.Enqueue(item); } } else { Logger.Error("Pipe failed to read from the data received by the stream."); Close(); } } catch (Exception ex5) { Logger.Error("A exception has occured while trying to parse the pipe data: {0}", ex5.Message); Close(); } } else { Logger.Error("Empty frame was read on {0}, aborting.", Environment.OSVersion); Close(); } if (!_isClosed && IsConnected) { Logger.Trace("Starting another read"); BeginReadStream(); } } public bool ReadFrame(out PipeFrame frame) { if (_isDisposed) { throw new ObjectDisposedException("_stream"); } lock (_framequeuelock) { if (_framequeue.Count == 0) { frame = default(PipeFrame); return false; } frame = _framequeue.Dequeue(); return true; } } public bool WriteFrame(PipeFrame frame) { if (_isDisposed) { throw new ObjectDisposedException("_stream"); } if (_isClosed || !IsConnected) { Logger.Error("Failed to write frame because the stream is closed"); return false; } try { frame.WriteStream(_stream); return true; } catch (IOException ex) { Logger.Error("Failed to write frame because of a IO Exception: {0}", ex.Message); } catch (ObjectDisposedException) { Logger.Warning("Failed to write frame as the stream was already disposed"); } catch (InvalidOperationException) { Logger.Warning("Failed to write frame because of a invalid operation"); } return false; } public void Close() { if (_isClosed) { Logger.Warning("Tried to close a already closed pipe."); return; } try { lock (l_stream) { if (_stream != null) { try { _stream.Flush(); _stream.Dispose(); } catch (Exception) { } _stream = null; _isClosed = true; } else { Logger.Warning("Stream was closed, but no stream was available to begin with!"); } } } catch (ObjectDisposedException) { Logger.Warning("Tried to dispose already disposed stream"); } finally { _isClosed = true; } } public void Dispose() { if (_isDisposed) { return; } if (!_isClosed) { Close(); } lock (l_stream) { if (_stream != null) { _stream.Dispose(); _stream = null; } } _isDisposed = true; } [Obsolete("Use PipePermutation.GetPipes instead", true)] public static string GetPipeName(int pipe) { return string.Empty; } [Obsolete("Use PipePermutation.GetPipes instead", true)] public static string GetPipeName(int pipe, string sandbox) { return string.Empty; } [Obsolete("Use PipePermutation.GetPipes instead", true)] public static string GetPipeSandbox() { return string.Empty; } [Obsolete("Use PipePermutation.GetPipes instead", true)] public static bool IsUnix() { return true; } } public enum Opcode : uint { Handshake, Frame, Close, Ping, Pong } public struct PipeFrame : IEquatable<PipeFrame> { public static readonly int MAX_SIZE = 16384; public Opcode Opcode { get; set; } public uint Length => (uint)Data.Length; public byte[] Data { get; set; } public string Message { get { return GetMessage(); } set { SetMessage(value); } } public Encoding MessageEncoding => Encoding.UTF8; public PipeFrame(Opcode opcode, object data) { Opcode = opcode; Data = null; SetObject(data); } private void SetMessage(string str) { Data = MessageEncoding.GetBytes(str); } private string GetMessage() { return MessageEncoding.GetString(Data); } public void SetObject(object obj) { string message = JsonConvert.SerializeObject(obj); SetMessage(message); } public void SetObject(Opcode opcode, object obj) { Opcode = opcode; SetObject(obj); } public T GetObject<T>() { return JsonConvert.DeserializeObject<T>(GetMessage()); } public bool ReadStream(Stream stream) { if (!TryReadUInt32(stream, out var value)) { return false; } if (!TryReadUInt32(stream, out var value2)) { return false; } uint num = value2; using MemoryStream memoryStream = new MemoryStream(); uint num2 = (uint)Min(2048, value2); byte[] array = new byte[num2]; int count; while ((count = stream.Read(array, 0, Min(array.Length, num))) > 0) { num -= num2; memoryStream.Write(array, 0, count); } byte[] array2 = memoryStream.ToArray(); if (array2.LongLength != value2) { return false; } Opcode = (Opcode)value; Data = array2; return true; } private int Min(int a, uint b) { if (b >= a) { return a; } return (int)b; } private bool TryReadUInt32(Stream stream, out uint value) { byte[] array = new byte[4]; if (stream.Read(array, 0, array.Length) != 4) { value = 0u; return false; } value = BitConverter.ToUInt32(array, 0); return true; } public void WriteStream(Stream stream) { byte[] bytes = BitConverter.GetBytes((uint)Opcode); byte[] bytes2 = BitConverter.GetBytes(Length); byte[] array = new byte[bytes.Length + bytes2.Length + Data.Length]; bytes.CopyTo(array, 0); bytes2.CopyTo(array, bytes.Length); Data.CopyTo(array, bytes.Length + bytes2.Length); stream.Write(array, 0, array.Length); } public bool Equals(PipeFrame other) { if (Opcode == other.Opcode && Length == other.Length) { return Data == other.Data; } return false; } } public static class PipeLocation { [CompilerGenerated] private sealed class <GetUnixPipes>d__5 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private int index; public int <>3__index; private IEnumerator<string> <>7__wrap1; private string <tempDir>5__3; private string[] <>7__wrap3; private int <>7__wrap4; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetUnixPipes>d__5(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = null; <tempDir>5__3 = null; <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = TemporaryDirectories().GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <>7__wrap3 = LinuxPackageManagers; <>7__wrap4 = 0; goto IL_0105; case 2: { <>1__state = -3; <>7__wrap4++; goto IL_0105; } IL_0105: if (<>7__wrap4 < <>7__wrap3.Length) { string path = <>7__wrap3[<>7__wrap4]; <>2__current = Path.Combine(<tempDir>5__3, path, string.Format("{0}{1}", "discord-ipc-", index)); <>1__state = 2; return true; } <>7__wrap3 = null; <tempDir>5__3 = null; break; } if (<>7__wrap1.MoveNext()) { <tempDir>5__3 = <>7__wrap1.Current; <>2__current = Path.Combine(<tempDir>5__3, string.Format("{0}{1}", "discord-ipc-", index)); <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { <GetUnixPipes>d__5 <GetUnixPipes>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetUnixPipes>d__ = this; } else { <GetUnixPipes>d__ = new <GetUnixPipes>d__5(0); } <GetUnixPipes>d__.index = <>3__index; return <GetUnixPipes>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetWindowsPipes>d__4 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private int index; public int <>3__index; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetWindowsPipes>d__4(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = string.Format("{0}{1}", "discord-ipc-", index); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { <GetWindowsPipes>d__4 <GetWindowsPipes>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetWindowsPipes>d__ = this; } else { <GetWindowsPipes>d__ = new <GetWindowsPipes>d__4(0); } <GetWindowsPipes>d__.index = <>3__index; return <GetWindowsPipes>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <TemporaryDirectories>d__6 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TemporaryDirectories>d__6(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { string environmentVariable; switch (<>1__state) { default: return false; case 0: <>1__state = -1; environmentVariable = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); if (environmentVariable != null) { <>2__current = environmentVariable; <>1__state = 1; return true; } goto IL_0053; case 1: <>1__state = -1; goto IL_0053; case 2: <>1__state = -1; goto IL_0078; case 3: <>1__state = -1; goto IL_009d; case 4: <>1__state = -1; goto IL_00c2; case 5: { <>1__state = -1; return false; } IL_009d: environmentVariable = Environment.GetEnvironmentVariable("TEMP"); if (environmentVariable != null) { <>2__current = environmentVariable; <>1__state = 4; return true; } goto IL_00c2; IL_0053: environmentVariable = Environment.GetEnvironmentVariable("TMPDIR"); if (environmentVariable != null) { <>2__current = environmentVariable; <>1__state = 2; return true; } goto IL_0078; IL_0078: environmentVariable = Environment.GetEnvironmentVariable("TMP"); if (environmentVariable != null) { <>2__current = environmentVariable; <>1__state = 3; return true; } goto IL_009d; IL_00c2: <>2__current = "/temp"; <>1__state = 5; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <TemporaryDirectories>d__6(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } private const string DiscordPipePrefix = "discord-ipc-"; private const int MaximumPipeVariations = 10; private static readonly string[] LinuxPackageManagers = new string[2] { "app/com.discordapp.Discord/", "snap.discord/" }; public static IEnumerable<string> GetPipes(int startPipe = 0) { IsOSUnix(); if (IsOSUnix()) { return Enumerable.Range(startPipe, 10).SelectMany(GetUnixPipes); } return Enumerable.Range(startPipe, 10).SelectMany(GetWindowsPipes); } [IteratorStateMachine(typeof(<GetWindowsPipes>d__4))] private static IEnumerable<string> GetWindowsPipes(int index) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetWindowsPipes>d__4(-2) { <>3__index = index }; } [IteratorStateMachine(typeof(<GetUnixPipes>d__5))] private static IEnumerable<string> GetUnixPipes(int index) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetUnixPipes>d__5(-2) { <>3__index = index }; } [IteratorStateMachine(typeof(<TemporaryDirectories>d__6))] private static IEnumerable<string> TemporaryDirectories() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TemporaryDirectories>d__6(-2); } private static bool IsOSUnix() { if (Environment.OSVersion.Platform == PlatformID.Unix) { return true; } return false; } } } namespace DiscordRPC.Helper { internal class BackoffDelay { private int _current; private int _fails; public int Maximum { get; private set; } public int Minimum { get; private set; } public int Current => _current; public int Fails => _fails; public Random Random { get; set; } private BackoffDelay() { } public BackoffDelay(int min, int max) : this(min, max, new Random()) { } public BackoffDelay(int min, int max, Random random) { Minimum = min; Maximum = max; _current = min; _fails = 0; Random = random; } public void Reset() { _fails = 0; _current = Minimum; } public int NextDelay() { _fails++; double num = (float)(Maximum - Minimum) / 100f; _current = (int)Math.Floor(num * (double)_fails) + Minimum; return Math.Min(Math.Max(_current, Minimum), Maximum); } } public static class StringTools { public static string GetNullOrString(this string str) { if (str.Length != 0 && !string.IsNullOrEmpty(str.Trim())) { return str; } return null; } public static bool WithinLength(this string str, int bytes) { return str.WithinLength(bytes, Encoding.UTF8); } public static bool WithinLength(this string str, int bytes, Encoding encoding) { return encoding.GetByteCount(str) <= bytes; } public static string ToCamelCase(this string str) { return (from s in str?.ToLowerInvariant().Split(new string[2] { "_", " " }, StringSplitOptions.RemoveEmptyEntries) select char.ToUpper(s[0]) + s.Substring(1, s.Length - 1)).Aggregate(string.Empty, (string s1, string s2) => s1 + s2); } public static string ToSnakeCase(this string str) { if (str == null) { return null; } return string.Concat(str.Select((char x, int i) => (i <= 0 || !char.IsUpper(x)) ? x.ToString() : ("_" + x)).ToArray()).ToUpperInvariant(); } } } namespace DiscordRPC.Exceptions { public class BadPresenceException : Exception { internal BadPresenceException(string message) : base(message) { } } public class InvalidConfigurationException : Exception { internal InvalidConfigurationException(string message) : base(message) { } } [Obsolete("Not actually used anywhere")] public class InvalidPipeException : Exception { internal InvalidPipeException(string message) : base(message) { } } public class StringOutOfRangeException : Exception { public int MaximumLength { get; private set; } public int MinimumLength { get; private set; } internal StringOutOfRangeException(string message, int min, int max) : base(message) { MinimumLength = min; MaximumLength = max; } internal StringOutOfRangeException(int minumum, int max) : this($"Length of string is out of range. Expected a value between {minumum} and {max}", minumum, max) { } internal StringOutOfRangeException(int max) : this($"Length of string is out of range. Expected a value with a maximum length of {max}", 0, max) { } } public class UninitializedException : Exception { internal UninitializedException(string message) : base(message) { } internal UninitializedException() : this("Cannot perform action because the client has not been initialized yet or has been deinitialized.") { } } } namespace DiscordRPC.Events { public delegate void OnReadyEvent(object sender, ReadyMessage args); public delegate void OnCloseEvent(object sender, CloseMessage args); public delegate void OnErrorEvent(object sender, ErrorMessage args); public delegate void OnPresenceUpdateEvent(object sender, PresenceMessage args); public delegate void OnSubscribeEvent(object sender, SubscribeMessage args); public delegate void OnUnsubscribeEvent(object sender, UnsubscribeMessage args); public delegate void OnJoinEvent(object sender, JoinMessage args); public delegate void OnSpectateEvent(object sender, SpectateMessage args); public delegate void OnJoinRequestedEvent(object sender, JoinRequestMessage args); public delegate void OnConnectionEstablishedEvent(object sender, ConnectionEstablishedMessage args); public delegate void OnConnectionFailedEvent(object sender, ConnectionFailedMessage args); public delegate void OnRpcMessageEvent(object sender, IMessage msg); } namespace DiscordRPC.Converters { internal class EnumSnakeCaseConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType.IsEnum; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.Value == null) { return null; } object obj = null; if (TryParseEnum(objectType, (string)reader.Value, out obj)) { return obj; } return existingValue; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Type type = value.GetType(); string text = Enum.GetName(type, value); MemberInfo[] members = type.GetMembers(BindingFlags.Static | BindingFlags.Public); foreach (MemberInfo memberInfo in members) { if (memberInfo.Name.Equals(text)) { object[] customAttributes = memberInfo.GetCustomAttributes(typeof(EnumValueAttribute), inherit: true); if (customAttributes.Length != 0) { text = ((EnumValueAttribute)customAttributes[0]).Value; } } } writer.WriteValue(text); } pu
patchers/PAMultiplayer/Facepunch.Steamworks.Win64.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Steamworks.Data; using Steamworks.Ugc; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: AssemblyCompany("Garry Newman")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.4.1")] [assembly: AssemblyInformationalVersion("1.0.0+b4d3a65f8686b40bb6ea09241f78ac0aa9f23753")] [assembly: AssemblyProduct("Facepunch.Steamworks.Win64")] [assembly: AssemblyTitle("Facepunch.Steamworks.Win64")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Facepunch/Facepunch.Steamworks.git")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } } namespace Steamworks { internal struct CallResult<T> : INotifyCompletion where T : struct, ICallbackData { private SteamAPICall_t call; private ISteamUtils utils; private bool server; public bool IsCompleted { get { bool pbFailed = false; if (utils.IsAPICallCompleted(call, ref pbFailed) || pbFailed) { return true; } return false; } } public CallResult(SteamAPICall_t call, bool server) { this.call = call; this.server = server; utils = (server ? SteamSharedClass<SteamUtils>.InterfaceServer : SteamSharedClass<SteamUtils>.InterfaceClient) as ISteamUtils; if (utils == null) { utils = SteamSharedClass<SteamUtils>.Interface as ISteamUtils; } } public void OnCompleted(Action continuation) { if (IsCompleted) { continuation(); } else { Dispatch.OnCallComplete<T>(call, continuation, server); } } public T? GetResult() { bool pbFailed = false; if (!utils.IsAPICallCompleted(call, ref pbFailed) || pbFailed) { return null; } T val = default(T); int dataSize = val.DataSize; IntPtr intPtr = Marshal.AllocHGlobal(dataSize); try { if (!utils.GetAPICallResult(call, intPtr, dataSize, (int)val.CallbackType, ref pbFailed) || pbFailed) { Dispatch.OnDebugCallback?.Invoke(val.CallbackType, "!GetAPICallResult or failed", server); return null; } Dispatch.OnDebugCallback?.Invoke(val.CallbackType, Dispatch.CallbackToString(val.CallbackType, intPtr, dataSize), server); return (T)Marshal.PtrToStructure(intPtr, typeof(T)); } finally { Marshal.FreeHGlobal(intPtr); } } internal CallResult<T> GetAwaiter() { return this; } } internal interface ICallbackData { CallbackType CallbackType { get; } int DataSize { get; } } public class AuthTicket : IDisposable { public byte[] Data; public uint Handle; public void Cancel() { if (Handle != 0) { SteamUser.Internal.CancelAuthTicket(Handle); } Handle = 0u; Data = null; } public void Dispose() { Cancel(); } } public static class Dispatch { [StructLayout(LayoutKind.Sequential, Pack = 8)] internal struct CallbackMsg_t { public HSteamUser m_hSteamUser; public CallbackType Type; public IntPtr Data; public int DataSize; } private struct ResultCallback { public Action continuation; public bool server; } private struct Callback { public Action<IntPtr> action; public bool server; } public static Action<CallbackType, string, bool> OnDebugCallback; public static Action<Exception> OnException; private static bool runningFrame = false; private static List<Action<IntPtr>> actionsToCall = new List<Action<IntPtr>>(); private static Dictionary<ulong, ResultCallback> ResultCallbacks = new Dictionary<ulong, ResultCallback>(); private static Dictionary<CallbackType, List<Callback>> Callbacks = new Dictionary<CallbackType, List<Callback>>(); internal static HSteamPipe ClientPipe { get; set; } internal static HSteamPipe ServerPipe { get; set; } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] internal static extern void SteamAPI_ManualDispatch_Init(); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] internal static extern void SteamAPI_ManualDispatch_RunFrame(HSteamPipe pipe); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool SteamAPI_ManualDispatch_GetNextCallback(HSteamPipe pipe, [In][Out] ref CallbackMsg_t msg); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] internal static extern bool SteamAPI_ManualDispatch_FreeLastCallback(HSteamPipe pipe); internal static void Init() { SteamAPI_ManualDispatch_Init(); } internal static void Frame(HSteamPipe pipe) { if (runningFrame) { return; } try { runningFrame = true; SteamAPI_ManualDispatch_RunFrame(pipe); SteamNetworkingUtils.OutputDebugMessages(); CallbackMsg_t msg = default(CallbackMsg_t); while (SteamAPI_ManualDispatch_GetNextCallback(pipe, ref msg)) { try { ProcessCallback(msg, pipe == ServerPipe); } finally { SteamAPI_ManualDispatch_FreeLastCallback(pipe); } } } catch (Exception obj) { OnException?.Invoke(obj); } finally { runningFrame = false; } } private static void ProcessCallback(CallbackMsg_t msg, bool isServer) { OnDebugCallback?.Invoke(msg.Type, CallbackToString(msg.Type, msg.Data, msg.DataSize), isServer); if (msg.Type == CallbackType.SteamAPICallCompleted) { ProcessResult(msg); } else { if (!Callbacks.TryGetValue(msg.Type, out var value)) { return; } actionsToCall.Clear(); foreach (Callback item in value) { if (item.server == isServer) { actionsToCall.Add(item.action); } } foreach (Action<IntPtr> item2 in actionsToCall) { item2(msg.Data); } actionsToCall.Clear(); } } internal static string CallbackToString(CallbackType type, IntPtr data, int expectedsize) { if (!CallbackTypeFactory.All.TryGetValue(type, out var value)) { return $"[{type} not in sdk]"; } object obj = data.ToType(value); if (obj == null) { return "[null]"; } string text = ""; FieldInfo[] fields = value.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (fields.Length == 0) { return "[no fields]"; } int num = fields.Max((FieldInfo x) => x.Name.Length) + 1; if (num < 10) { num = 10; } FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { int num2 = num - fieldInfo.Name.Length; if (num2 < 0) { num2 = 0; } text += $"{new string(' ', num2)}{fieldInfo.Name}: {fieldInfo.GetValue(obj)}\n"; } return text.Trim(new char[1] { '\n' }); } private static void ProcessResult(CallbackMsg_t msg) { SteamAPICallCompleted_t steamAPICallCompleted_t = msg.Data.ToType<SteamAPICallCompleted_t>(); if (!ResultCallbacks.TryGetValue(steamAPICallCompleted_t.AsyncCall, out var value)) { OnDebugCallback?.Invoke((CallbackType)steamAPICallCompleted_t.Callback, "[no callback waiting/required]", arg3: false); return; } ResultCallbacks.Remove(steamAPICallCompleted_t.AsyncCall); value.continuation(); } internal static async void LoopClientAsync() { while (ClientPipe != 0) { Frame(ClientPipe); await Task.Delay(16); } } internal static async void LoopServerAsync() { while (ServerPipe != 0) { Frame(ServerPipe); await Task.Delay(32); } } internal static void OnCallComplete<T>(SteamAPICall_t call, Action continuation, bool server) where T : struct, ICallbackData { ResultCallbacks[call.Value] = new ResultCallback { continuation = continuation, server = server }; } internal static void Install<T>(Action<T> p, bool server = false) where T : ICallbackData { CallbackType callbackType = default(T).CallbackType; if (!Callbacks.TryGetValue(callbackType, out var value)) { value = new List<Callback>(); Callbacks[callbackType] = value; } value.Add(new Callback { action = delegate(IntPtr x) { p(x.ToType<T>()); }, server = server }); } internal static void ShutdownServer() { ServerPipe = 0; foreach (KeyValuePair<CallbackType, List<Callback>> callback in Callbacks) { Callbacks[callback.Key].RemoveAll((Callback x) => x.server); } ResultCallbacks = ResultCallbacks.Where((KeyValuePair<ulong, ResultCallback> x) => !x.Value.server).ToDictionary((KeyValuePair<ulong, ResultCallback> x) => x.Key, (KeyValuePair<ulong, ResultCallback> x) => x.Value); } internal static void ShutdownClient() { ClientPipe = 0; foreach (KeyValuePair<CallbackType, List<Callback>> callback in Callbacks) { Callbacks[callback.Key].RemoveAll((Callback x) => !x.server); } ResultCallbacks = ResultCallbacks.Where((KeyValuePair<ulong, ResultCallback> x) => x.Value.server).ToDictionary((KeyValuePair<ulong, ResultCallback> x) => x.Key, (KeyValuePair<ulong, ResultCallback> x) => x.Value); } } internal static class SteamAPI { internal static class Native { [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] public static extern SteamAPIInitResult SteamInternal_SteamAPI_Init([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszInternalCheckInterfaceVersions, IntPtr pOutErrMsg); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] public static extern void SteamAPI_Shutdown(); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] public static extern HSteamPipe SteamAPI_GetHSteamPipe(); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool SteamAPI_RestartAppIfNecessary(uint unOwnAppID); } internal static SteamAPIInitResult Init(string pszInternalCheckInterfaceVersions, out string pOutErrMsg) { using Helpers.Memory memory = Helpers.Memory.Take(); SteamAPIInitResult result = Native.SteamInternal_SteamAPI_Init(pszInternalCheckInterfaceVersions, memory.Ptr); pOutErrMsg = Helpers.MemoryToString(memory.Ptr); return result; } internal static void Shutdown() { Native.SteamAPI_Shutdown(); } internal static HSteamPipe GetHSteamPipe() { return Native.SteamAPI_GetHSteamPipe(); } internal static bool RestartAppIfNecessary(uint unOwnAppID) { return Native.SteamAPI_RestartAppIfNecessary(unOwnAppID); } } internal static class SteamGameServer { internal static class Native { [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] public static extern void SteamGameServer_RunCallbacks(); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] public static extern void SteamGameServer_Shutdown(); [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] public static extern HSteamPipe SteamGameServer_GetHSteamPipe(); } internal static void RunCallbacks() { Native.SteamGameServer_RunCallbacks(); } internal static void Shutdown() { Native.SteamGameServer_Shutdown(); } internal static HSteamPipe GetHSteamPipe() { return Native.SteamGameServer_GetHSteamPipe(); } } internal static class SteamInternal { internal static class Native { [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] public static extern SteamAPIInitResult SteamInternal_GameServer_Init_V2(uint unIP, ushort usGamePort, ushort usQueryPort, int eServerMode, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersionString, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszInternalCheckInterfaceVersions, IntPtr pOutErrMsg); } internal static SteamAPIInitResult GameServer_Init(uint unIP, ushort usGamePort, ushort usQueryPort, int eServerMode, string pchVersionString, string pszInternalCheckInterfaceVersions, out string pOutErrMsg) { using Helpers.Memory memory = Helpers.Memory.Take(); SteamAPIInitResult result = Native.SteamInternal_GameServer_Init_V2(unIP, usGamePort, usQueryPort, eServerMode, pchVersionString, pszInternalCheckInterfaceVersions, memory.Ptr); pOutErrMsg = Helpers.MemoryToString(memory.Ptr); return result; } } public enum CallbackType { SteamServersConnected = 101, SteamServerConnectFailure = 102, SteamServersDisconnected = 103, ClientGameServerDeny = 113, GSPolicyResponse = 115, IPCFailure = 117, LicensesUpdated = 125, ValidateAuthTicketResponse = 143, MicroTxnAuthorizationResponse = 152, EncryptedAppTicketResponse = 154, GetAuthSessionTicketResponse = 163, GameWebCallback = 164, StoreAuthURLResponse = 165, MarketEligibilityResponse = 166, DurationControl = 167, GetTicketForWebApiResponse = 168, GSClientApprove = 201, GSClientDeny = 202, GSClientKick = 203, GSClientAchievementStatus = 206, GSGameplayStats = 207, GSClientGroupStatus = 208, GSReputation = 209, AssociateWithClanResult = 210, ComputeNewPlayerCompatibilityResult = 211, PersonaStateChange = 304, GameOverlayActivated = 331, GameServerChangeRequested = 332, GameLobbyJoinRequested = 333, AvatarImageLoaded = 334, ClanOfficerListResponse = 335, FriendRichPresenceUpdate = 336, GameRichPresenceJoinRequested = 337, GameConnectedClanChatMsg = 338, GameConnectedChatJoin = 339, GameConnectedChatLeave = 340, DownloadClanActivityCountsResult = 341, JoinClanChatRoomCompletionResult = 342, GameConnectedFriendChatMsg = 343, FriendsGetFollowerCount = 344, FriendsIsFollowing = 345, FriendsEnumerateFollowingList = 346, SetPersonaNameResponse = 347, UnreadChatMessagesChanged = 348, OverlayBrowserProtocolNavigation = 349, EquippedProfileItemsChanged = 350, EquippedProfileItems = 351, FavoritesListChanged = 502, LobbyInvite = 503, LobbyEnter = 504, LobbyDataUpdate = 505, LobbyChatUpdate = 506, LobbyChatMsg = 507, LobbyGameCreated = 509, LobbyMatchList = 510, LobbyKicked = 512, LobbyCreated = 513, PSNGameBootInviteResult = 515, FavoritesListAccountsUpdated = 516, IPCountry = 701, LowBatteryPower = 702, SteamAPICallCompleted = 703, SteamShutdown = 704, CheckFileSignature = 705, GamepadTextInputDismissed = 714, AppResumingFromSuspend = 736, FloatingGamepadTextInputDismissed = 738, FilterTextDictionaryChanged = 739, DlcInstalled = 1005, NewUrlLaunchParameters = 1014, AppProofOfPurchaseKeyResponse = 1021, FileDetailsResult = 1023, TimedTrialStatus = 1030, UserStatsReceived = 1101, UserStatsStored = 1102, UserAchievementStored = 1103, LeaderboardFindResult = 1104, LeaderboardScoresDownloaded = 1105, LeaderboardScoreUploaded = 1106, NumberOfCurrentPlayers = 1107, UserStatsUnloaded = 1108, GSStatsUnloaded = 1108, UserAchievementIconFetched = 1109, GlobalAchievementPercentagesReady = 1110, LeaderboardUGCSet = 1111, GlobalStatsReceived = 1112, P2PSessionRequest = 1202, P2PSessionConnectFail = 1203, SteamNetConnectionStatusChangedCallback = 1221, SteamNetAuthenticationStatus = 1222, SteamNetworkingFakeIPResult = 1223, SteamNetworkingMessagesSessionRequest = 1251, SteamNetworkingMessagesSessionFailed = 1252, SteamRelayNetworkStatus = 1281, RemoteStorageFileShareResult = 1307, RemoteStoragePublishFileResult = 1309, RemoteStorageDeletePublishedFileResult = 1311, RemoteStorageEnumerateUserPublishedFilesResult = 1312, RemoteStorageSubscribePublishedFileResult = 1313, RemoteStorageEnumerateUserSubscribedFilesResult = 1314, RemoteStorageUnsubscribePublishedFileResult = 1315, RemoteStorageUpdatePublishedFileResult = 1316, RemoteStorageDownloadUGCResult = 1317, RemoteStorageGetPublishedFileDetailsResult = 1318, RemoteStorageEnumerateWorkshopFilesResult = 1319, RemoteStorageGetPublishedItemVoteDetailsResult = 1320, RemoteStoragePublishedFileSubscribed = 1321, RemoteStoragePublishedFileUnsubscribed = 1322, RemoteStoragePublishedFileDeleted = 1323, RemoteStorageUpdateUserPublishedItemVoteResult = 1324, RemoteStorageUserVoteDetails = 1325, RemoteStorageEnumerateUserSharedWorkshopFilesResult = 1326, RemoteStorageSetUserPublishedFileActionResult = 1327, RemoteStorageEnumeratePublishedFilesByUserActionResult = 1328, RemoteStoragePublishFileProgress = 1329, RemoteStoragePublishedFileUpdated = 1330, RemoteStorageFileWriteAsyncComplete = 1331, RemoteStorageFileReadAsyncComplete = 1332, RemoteStorageLocalFileChange = 1333, GSStatsReceived = 1800, GSStatsStored = 1801, HTTPRequestCompleted = 2101, HTTPRequestHeadersReceived = 2102, HTTPRequestDataReceived = 2103, ScreenshotReady = 2301, ScreenshotRequested = 2302, SteamInputDeviceConnected = 2801, SteamInputDeviceDisconnected = 2802, SteamInputConfigurationLoaded = 2803, SteamInputGamepadSlotChange = 2804, SteamUGCQueryCompleted = 3401, SteamUGCRequestUGCDetailsResult = 3402, CreateItemResult = 3403, SubmitItemUpdateResult = 3404, ItemInstalled = 3405, DownloadItemResult = 3406, UserFavoriteItemsListChanged = 3407, SetUserItemVoteResult = 3408, GetUserItemVoteResult = 3409, StartPlaytimeTrackingResult = 3410, StopPlaytimeTrackingResult = 3411, AddUGCDependencyResult = 3412, RemoveUGCDependencyResult = 3413, AddAppDependencyResult = 3414, RemoveAppDependencyResult = 3415, GetAppDependenciesResult = 3416, DeleteItemResult = 3417, UserSubscribedItemsListChanged = 3418, WorkshopEULAStatus = 3420, PlaybackStatusHasChanged = 4001, VolumeHasChanged = 4002, MusicPlayerWantsVolume = 4011, MusicPlayerSelectsQueueEntry = 4012, MusicPlayerSelectsPlaylistEntry = 4013, MusicPlayerRemoteWillActivate = 4101, MusicPlayerRemoteWillDeactivate = 4102, MusicPlayerRemoteToFront = 4103, MusicPlayerWillQuit = 4104, MusicPlayerWantsPlay = 4105, MusicPlayerWantsPause = 4106, MusicPlayerWantsPlayPrevious = 4107, MusicPlayerWantsPlayNext = 4108, MusicPlayerWantsShuffled = 4109, MusicPlayerWantsLooped = 4110, MusicPlayerWantsPlayingRepeatStatus = 4114, HTML_BrowserReady = 4501, HTML_NeedsPaint = 4502, HTML_StartRequest = 4503, HTML_CloseBrowser = 4504, HTML_URLChanged = 4505, HTML_FinishedRequest = 4506, HTML_OpenLinkInNewTab = 4507, HTML_ChangedTitle = 4508, HTML_SearchResults = 4509, HTML_CanGoBackAndForward = 4510, HTML_HorizontalScroll = 4511, HTML_VerticalScroll = 4512, HTML_LinkAtPosition = 4513, HTML_JSAlert = 4514, HTML_JSConfirm = 4515, HTML_FileOpenDialog = 4516, HTML_NewWindow = 4521, HTML_SetCursor = 4522, HTML_StatusText = 4523, HTML_ShowToolTip = 4524, HTML_UpdateToolTip = 4525, HTML_HideToolTip = 4526, HTML_BrowserRestarted = 4527, BroadcastUploadStart = 4604, BroadcastUploadStop = 4605, GetVideoURLResult = 4611, GetOPFSettingsResult = 4624, SteamInventoryResultReady = 4700, SteamInventoryFullUpdate = 4701, SteamInventoryDefinitionUpdate = 4702, SteamInventoryEligiblePromoItemDefIDs = 4703, SteamInventoryStartPurchaseResult = 4704, SteamInventoryRequestPricesResult = 4705, SteamParentalSettingsChanged = 5001, SearchForGameProgressCallback = 5201, SearchForGameResultCallback = 5202, RequestPlayersForGameProgressCallback = 5211, RequestPlayersForGameResultCallback = 5212, RequestPlayersForGameFinalResultCallback = 5213, SubmitPlayerResultResultCallback = 5214, EndGameResultCallback = 5215, JoinPartyCallback = 5301, CreateBeaconCallback = 5302, ReservationNotificationCallback = 5303, ChangeNumOpenSlotsCallback = 5304, AvailableBeaconLocationsUpdated = 5305, ActiveBeaconsUpdated = 5306, SteamRemotePlaySessionConnected = 5701, SteamRemotePlaySessionDisconnected = 5702, SteamRemotePlayTogetherGuestInvite = 5703, SteamTimelineGamePhaseRecordingExists = 6001, SteamTimelineEventRecordingExists = 6002 } internal static class CallbackTypeFactory { internal static Dictionary<CallbackType, Type> All = new Dictionary<CallbackType, Type> { { CallbackType.SteamServersConnected, typeof(SteamServersConnected_t) }, { CallbackType.SteamServerConnectFailure, typeof(SteamServerConnectFailure_t) }, { CallbackType.SteamServersDisconnected, typeof(SteamServersDisconnected_t) }, { CallbackType.ClientGameServerDeny, typeof(ClientGameServerDeny_t) }, { CallbackType.GSPolicyResponse, typeof(GSPolicyResponse_t) }, { CallbackType.IPCFailure, typeof(IPCFailure_t) }, { CallbackType.LicensesUpdated, typeof(LicensesUpdated_t) }, { CallbackType.ValidateAuthTicketResponse, typeof(ValidateAuthTicketResponse_t) }, { CallbackType.MicroTxnAuthorizationResponse, typeof(MicroTxnAuthorizationResponse_t) }, { CallbackType.EncryptedAppTicketResponse, typeof(EncryptedAppTicketResponse_t) }, { CallbackType.GetAuthSessionTicketResponse, typeof(GetAuthSessionTicketResponse_t) }, { CallbackType.GameWebCallback, typeof(GameWebCallback_t) }, { CallbackType.StoreAuthURLResponse, typeof(StoreAuthURLResponse_t) }, { CallbackType.MarketEligibilityResponse, typeof(MarketEligibilityResponse_t) }, { CallbackType.DurationControl, typeof(DurationControl_t) }, { CallbackType.GetTicketForWebApiResponse, typeof(GetTicketForWebApiResponse_t) }, { CallbackType.GSClientApprove, typeof(GSClientApprove_t) }, { CallbackType.GSClientDeny, typeof(GSClientDeny_t) }, { CallbackType.GSClientKick, typeof(GSClientKick_t) }, { CallbackType.GSClientAchievementStatus, typeof(GSClientAchievementStatus_t) }, { CallbackType.GSGameplayStats, typeof(GSGameplayStats_t) }, { CallbackType.GSClientGroupStatus, typeof(GSClientGroupStatus_t) }, { CallbackType.GSReputation, typeof(GSReputation_t) }, { CallbackType.AssociateWithClanResult, typeof(AssociateWithClanResult_t) }, { CallbackType.ComputeNewPlayerCompatibilityResult, typeof(ComputeNewPlayerCompatibilityResult_t) }, { CallbackType.PersonaStateChange, typeof(PersonaStateChange_t) }, { CallbackType.GameOverlayActivated, typeof(GameOverlayActivated_t) }, { CallbackType.GameServerChangeRequested, typeof(GameServerChangeRequested_t) }, { CallbackType.GameLobbyJoinRequested, typeof(GameLobbyJoinRequested_t) }, { CallbackType.AvatarImageLoaded, typeof(AvatarImageLoaded_t) }, { CallbackType.ClanOfficerListResponse, typeof(ClanOfficerListResponse_t) }, { CallbackType.FriendRichPresenceUpdate, typeof(FriendRichPresenceUpdate_t) }, { CallbackType.GameRichPresenceJoinRequested, typeof(GameRichPresenceJoinRequested_t) }, { CallbackType.GameConnectedClanChatMsg, typeof(GameConnectedClanChatMsg_t) }, { CallbackType.GameConnectedChatJoin, typeof(GameConnectedChatJoin_t) }, { CallbackType.GameConnectedChatLeave, typeof(GameConnectedChatLeave_t) }, { CallbackType.DownloadClanActivityCountsResult, typeof(DownloadClanActivityCountsResult_t) }, { CallbackType.JoinClanChatRoomCompletionResult, typeof(JoinClanChatRoomCompletionResult_t) }, { CallbackType.GameConnectedFriendChatMsg, typeof(GameConnectedFriendChatMsg_t) }, { CallbackType.FriendsGetFollowerCount, typeof(FriendsGetFollowerCount_t) }, { CallbackType.FriendsIsFollowing, typeof(FriendsIsFollowing_t) }, { CallbackType.FriendsEnumerateFollowingList, typeof(FriendsEnumerateFollowingList_t) }, { CallbackType.SetPersonaNameResponse, typeof(SetPersonaNameResponse_t) }, { CallbackType.UnreadChatMessagesChanged, typeof(UnreadChatMessagesChanged_t) }, { CallbackType.OverlayBrowserProtocolNavigation, typeof(OverlayBrowserProtocolNavigation_t) }, { CallbackType.EquippedProfileItemsChanged, typeof(EquippedProfileItemsChanged_t) }, { CallbackType.EquippedProfileItems, typeof(EquippedProfileItems_t) }, { CallbackType.FavoritesListChanged, typeof(FavoritesListChanged_t) }, { CallbackType.LobbyInvite, typeof(LobbyInvite_t) }, { CallbackType.LobbyEnter, typeof(LobbyEnter_t) }, { CallbackType.LobbyDataUpdate, typeof(LobbyDataUpdate_t) }, { CallbackType.LobbyChatUpdate, typeof(LobbyChatUpdate_t) }, { CallbackType.LobbyChatMsg, typeof(LobbyChatMsg_t) }, { CallbackType.LobbyGameCreated, typeof(LobbyGameCreated_t) }, { CallbackType.LobbyMatchList, typeof(LobbyMatchList_t) }, { CallbackType.LobbyKicked, typeof(LobbyKicked_t) }, { CallbackType.LobbyCreated, typeof(LobbyCreated_t) }, { CallbackType.PSNGameBootInviteResult, typeof(PSNGameBootInviteResult_t) }, { CallbackType.FavoritesListAccountsUpdated, typeof(FavoritesListAccountsUpdated_t) }, { CallbackType.IPCountry, typeof(IPCountry_t) }, { CallbackType.LowBatteryPower, typeof(LowBatteryPower_t) }, { CallbackType.SteamAPICallCompleted, typeof(SteamAPICallCompleted_t) }, { CallbackType.SteamShutdown, typeof(SteamShutdown_t) }, { CallbackType.CheckFileSignature, typeof(CheckFileSignature_t) }, { CallbackType.GamepadTextInputDismissed, typeof(GamepadTextInputDismissed_t) }, { CallbackType.AppResumingFromSuspend, typeof(AppResumingFromSuspend_t) }, { CallbackType.FloatingGamepadTextInputDismissed, typeof(FloatingGamepadTextInputDismissed_t) }, { CallbackType.FilterTextDictionaryChanged, typeof(FilterTextDictionaryChanged_t) }, { CallbackType.DlcInstalled, typeof(DlcInstalled_t) }, { CallbackType.NewUrlLaunchParameters, typeof(NewUrlLaunchParameters_t) }, { CallbackType.AppProofOfPurchaseKeyResponse, typeof(AppProofOfPurchaseKeyResponse_t) }, { CallbackType.FileDetailsResult, typeof(FileDetailsResult_t) }, { CallbackType.TimedTrialStatus, typeof(TimedTrialStatus_t) }, { CallbackType.UserStatsReceived, typeof(UserStatsReceived_t) }, { CallbackType.UserStatsStored, typeof(UserStatsStored_t) }, { CallbackType.UserAchievementStored, typeof(UserAchievementStored_t) }, { CallbackType.LeaderboardFindResult, typeof(LeaderboardFindResult_t) }, { CallbackType.LeaderboardScoresDownloaded, typeof(LeaderboardScoresDownloaded_t) }, { CallbackType.LeaderboardScoreUploaded, typeof(LeaderboardScoreUploaded_t) }, { CallbackType.NumberOfCurrentPlayers, typeof(NumberOfCurrentPlayers_t) }, { CallbackType.UserStatsUnloaded, typeof(UserStatsUnloaded_t) }, { CallbackType.UserAchievementIconFetched, typeof(UserAchievementIconFetched_t) }, { CallbackType.GlobalAchievementPercentagesReady, typeof(GlobalAchievementPercentagesReady_t) }, { CallbackType.LeaderboardUGCSet, typeof(LeaderboardUGCSet_t) }, { CallbackType.GlobalStatsReceived, typeof(GlobalStatsReceived_t) }, { CallbackType.P2PSessionRequest, typeof(P2PSessionRequest_t) }, { CallbackType.P2PSessionConnectFail, typeof(P2PSessionConnectFail_t) }, { CallbackType.SteamNetConnectionStatusChangedCallback, typeof(SteamNetConnectionStatusChangedCallback_t) }, { CallbackType.SteamNetAuthenticationStatus, typeof(SteamNetAuthenticationStatus_t) }, { CallbackType.SteamNetworkingFakeIPResult, typeof(SteamNetworkingFakeIPResult_t) }, { CallbackType.SteamNetworkingMessagesSessionRequest, typeof(SteamNetworkingMessagesSessionRequest_t) }, { CallbackType.SteamNetworkingMessagesSessionFailed, typeof(SteamNetworkingMessagesSessionFailed_t) }, { CallbackType.SteamRelayNetworkStatus, typeof(SteamRelayNetworkStatus_t) }, { CallbackType.RemoteStorageFileShareResult, typeof(RemoteStorageFileShareResult_t) }, { CallbackType.RemoteStoragePublishFileResult, typeof(RemoteStoragePublishFileResult_t) }, { CallbackType.RemoteStorageDeletePublishedFileResult, typeof(RemoteStorageDeletePublishedFileResult_t) }, { CallbackType.RemoteStorageEnumerateUserPublishedFilesResult, typeof(RemoteStorageEnumerateUserPublishedFilesResult_t) }, { CallbackType.RemoteStorageSubscribePublishedFileResult, typeof(RemoteStorageSubscribePublishedFileResult_t) }, { CallbackType.RemoteStorageEnumerateUserSubscribedFilesResult, typeof(RemoteStorageEnumerateUserSubscribedFilesResult_t) }, { CallbackType.RemoteStorageUnsubscribePublishedFileResult, typeof(RemoteStorageUnsubscribePublishedFileResult_t) }, { CallbackType.RemoteStorageUpdatePublishedFileResult, typeof(RemoteStorageUpdatePublishedFileResult_t) }, { CallbackType.RemoteStorageDownloadUGCResult, typeof(RemoteStorageDownloadUGCResult_t) }, { CallbackType.RemoteStorageGetPublishedFileDetailsResult, typeof(RemoteStorageGetPublishedFileDetailsResult_t) }, { CallbackType.RemoteStorageEnumerateWorkshopFilesResult, typeof(RemoteStorageEnumerateWorkshopFilesResult_t) }, { CallbackType.RemoteStorageGetPublishedItemVoteDetailsResult, typeof(RemoteStorageGetPublishedItemVoteDetailsResult_t) }, { CallbackType.RemoteStoragePublishedFileSubscribed, typeof(RemoteStoragePublishedFileSubscribed_t) }, { CallbackType.RemoteStoragePublishedFileUnsubscribed, typeof(RemoteStoragePublishedFileUnsubscribed_t) }, { CallbackType.RemoteStoragePublishedFileDeleted, typeof(RemoteStoragePublishedFileDeleted_t) }, { CallbackType.RemoteStorageUpdateUserPublishedItemVoteResult, typeof(RemoteStorageUpdateUserPublishedItemVoteResult_t) }, { CallbackType.RemoteStorageUserVoteDetails, typeof(RemoteStorageUserVoteDetails_t) }, { CallbackType.RemoteStorageEnumerateUserSharedWorkshopFilesResult, typeof(RemoteStorageEnumerateUserSharedWorkshopFilesResult_t) }, { CallbackType.RemoteStorageSetUserPublishedFileActionResult, typeof(RemoteStorageSetUserPublishedFileActionResult_t) }, { CallbackType.RemoteStorageEnumeratePublishedFilesByUserActionResult, typeof(RemoteStorageEnumeratePublishedFilesByUserActionResult_t) }, { CallbackType.RemoteStoragePublishFileProgress, typeof(RemoteStoragePublishFileProgress_t) }, { CallbackType.RemoteStoragePublishedFileUpdated, typeof(RemoteStoragePublishedFileUpdated_t) }, { CallbackType.RemoteStorageFileWriteAsyncComplete, typeof(RemoteStorageFileWriteAsyncComplete_t) }, { CallbackType.RemoteStorageFileReadAsyncComplete, typeof(RemoteStorageFileReadAsyncComplete_t) }, { CallbackType.RemoteStorageLocalFileChange, typeof(RemoteStorageLocalFileChange_t) }, { CallbackType.GSStatsReceived, typeof(GSStatsReceived_t) }, { CallbackType.GSStatsStored, typeof(GSStatsStored_t) }, { CallbackType.HTTPRequestCompleted, typeof(HTTPRequestCompleted_t) }, { CallbackType.HTTPRequestHeadersReceived, typeof(HTTPRequestHeadersReceived_t) }, { CallbackType.HTTPRequestDataReceived, typeof(HTTPRequestDataReceived_t) }, { CallbackType.ScreenshotReady, typeof(ScreenshotReady_t) }, { CallbackType.ScreenshotRequested, typeof(ScreenshotRequested_t) }, { CallbackType.SteamInputDeviceConnected, typeof(SteamInputDeviceConnected_t) }, { CallbackType.SteamInputDeviceDisconnected, typeof(SteamInputDeviceDisconnected_t) }, { CallbackType.SteamInputConfigurationLoaded, typeof(SteamInputConfigurationLoaded_t) }, { CallbackType.SteamInputGamepadSlotChange, typeof(SteamInputGamepadSlotChange_t) }, { CallbackType.SteamUGCQueryCompleted, typeof(SteamUGCQueryCompleted_t) }, { CallbackType.SteamUGCRequestUGCDetailsResult, typeof(SteamUGCRequestUGCDetailsResult_t) }, { CallbackType.CreateItemResult, typeof(CreateItemResult_t) }, { CallbackType.SubmitItemUpdateResult, typeof(SubmitItemUpdateResult_t) }, { CallbackType.ItemInstalled, typeof(ItemInstalled_t) }, { CallbackType.DownloadItemResult, typeof(DownloadItemResult_t) }, { CallbackType.UserFavoriteItemsListChanged, typeof(UserFavoriteItemsListChanged_t) }, { CallbackType.SetUserItemVoteResult, typeof(SetUserItemVoteResult_t) }, { CallbackType.GetUserItemVoteResult, typeof(GetUserItemVoteResult_t) }, { CallbackType.StartPlaytimeTrackingResult, typeof(StartPlaytimeTrackingResult_t) }, { CallbackType.StopPlaytimeTrackingResult, typeof(StopPlaytimeTrackingResult_t) }, { CallbackType.AddUGCDependencyResult, typeof(AddUGCDependencyResult_t) }, { CallbackType.RemoveUGCDependencyResult, typeof(RemoveUGCDependencyResult_t) }, { CallbackType.AddAppDependencyResult, typeof(AddAppDependencyResult_t) }, { CallbackType.RemoveAppDependencyResult, typeof(RemoveAppDependencyResult_t) }, { CallbackType.GetAppDependenciesResult, typeof(GetAppDependenciesResult_t) }, { CallbackType.DeleteItemResult, typeof(DeleteItemResult_t) }, { CallbackType.UserSubscribedItemsListChanged, typeof(UserSubscribedItemsListChanged_t) }, { CallbackType.WorkshopEULAStatus, typeof(WorkshopEULAStatus_t) }, { CallbackType.PlaybackStatusHasChanged, typeof(PlaybackStatusHasChanged_t) }, { CallbackType.VolumeHasChanged, typeof(VolumeHasChanged_t) }, { CallbackType.MusicPlayerWantsVolume, typeof(MusicPlayerWantsVolume_t) }, { CallbackType.MusicPlayerSelectsQueueEntry, typeof(MusicPlayerSelectsQueueEntry_t) }, { CallbackType.MusicPlayerSelectsPlaylistEntry, typeof(MusicPlayerSelectsPlaylistEntry_t) }, { CallbackType.MusicPlayerRemoteWillActivate, typeof(MusicPlayerRemoteWillActivate_t) }, { CallbackType.MusicPlayerRemoteWillDeactivate, typeof(MusicPlayerRemoteWillDeactivate_t) }, { CallbackType.MusicPlayerRemoteToFront, typeof(MusicPlayerRemoteToFront_t) }, { CallbackType.MusicPlayerWillQuit, typeof(MusicPlayerWillQuit_t) }, { CallbackType.MusicPlayerWantsPlay, typeof(MusicPlayerWantsPlay_t) }, { CallbackType.MusicPlayerWantsPause, typeof(MusicPlayerWantsPause_t) }, { CallbackType.MusicPlayerWantsPlayPrevious, typeof(MusicPlayerWantsPlayPrevious_t) }, { CallbackType.MusicPlayerWantsPlayNext, typeof(MusicPlayerWantsPlayNext_t) }, { CallbackType.MusicPlayerWantsShuffled, typeof(MusicPlayerWantsShuffled_t) }, { CallbackType.MusicPlayerWantsLooped, typeof(MusicPlayerWantsLooped_t) }, { CallbackType.MusicPlayerWantsPlayingRepeatStatus, typeof(MusicPlayerWantsPlayingRepeatStatus_t) }, { CallbackType.HTML_BrowserReady, typeof(HTML_BrowserReady_t) }, { CallbackType.HTML_NeedsPaint, typeof(HTML_NeedsPaint_t) }, { CallbackType.HTML_StartRequest, typeof(HTML_StartRequest_t) }, { CallbackType.HTML_CloseBrowser, typeof(HTML_CloseBrowser_t) }, { CallbackType.HTML_URLChanged, typeof(HTML_URLChanged_t) }, { CallbackType.HTML_FinishedRequest, typeof(HTML_FinishedRequest_t) }, { CallbackType.HTML_OpenLinkInNewTab, typeof(HTML_OpenLinkInNewTab_t) }, { CallbackType.HTML_ChangedTitle, typeof(HTML_ChangedTitle_t) }, { CallbackType.HTML_SearchResults, typeof(HTML_SearchResults_t) }, { CallbackType.HTML_CanGoBackAndForward, typeof(HTML_CanGoBackAndForward_t) }, { CallbackType.HTML_HorizontalScroll, typeof(HTML_HorizontalScroll_t) }, { CallbackType.HTML_VerticalScroll, typeof(HTML_VerticalScroll_t) }, { CallbackType.HTML_LinkAtPosition, typeof(HTML_LinkAtPosition_t) }, { CallbackType.HTML_JSAlert, typeof(HTML_JSAlert_t) }, { CallbackType.HTML_JSConfirm, typeof(HTML_JSConfirm_t) }, { CallbackType.HTML_FileOpenDialog, typeof(HTML_FileOpenDialog_t) }, { CallbackType.HTML_NewWindow, typeof(HTML_NewWindow_t) }, { CallbackType.HTML_SetCursor, typeof(HTML_SetCursor_t) }, { CallbackType.HTML_StatusText, typeof(HTML_StatusText_t) }, { CallbackType.HTML_ShowToolTip, typeof(HTML_ShowToolTip_t) }, { CallbackType.HTML_UpdateToolTip, typeof(HTML_UpdateToolTip_t) }, { CallbackType.HTML_HideToolTip, typeof(HTML_HideToolTip_t) }, { CallbackType.HTML_BrowserRestarted, typeof(HTML_BrowserRestarted_t) }, { CallbackType.BroadcastUploadStart, typeof(BroadcastUploadStart_t) }, { CallbackType.BroadcastUploadStop, typeof(BroadcastUploadStop_t) }, { CallbackType.GetVideoURLResult, typeof(GetVideoURLResult_t) }, { CallbackType.GetOPFSettingsResult, typeof(GetOPFSettingsResult_t) }, { CallbackType.SteamInventoryResultReady, typeof(SteamInventoryResultReady_t) }, { CallbackType.SteamInventoryFullUpdate, typeof(SteamInventoryFullUpdate_t) }, { CallbackType.SteamInventoryDefinitionUpdate, typeof(SteamInventoryDefinitionUpdate_t) }, { CallbackType.SteamInventoryEligiblePromoItemDefIDs, typeof(SteamInventoryEligiblePromoItemDefIDs_t) }, { CallbackType.SteamInventoryStartPurchaseResult, typeof(SteamInventoryStartPurchaseResult_t) }, { CallbackType.SteamInventoryRequestPricesResult, typeof(SteamInventoryRequestPricesResult_t) }, { CallbackType.SteamParentalSettingsChanged, typeof(SteamParentalSettingsChanged_t) }, { CallbackType.SearchForGameProgressCallback, typeof(SearchForGameProgressCallback_t) }, { CallbackType.SearchForGameResultCallback, typeof(SearchForGameResultCallback_t) }, { CallbackType.RequestPlayersForGameProgressCallback, typeof(RequestPlayersForGameProgressCallback_t) }, { CallbackType.RequestPlayersForGameResultCallback, typeof(RequestPlayersForGameResultCallback_t) }, { CallbackType.RequestPlayersForGameFinalResultCallback, typeof(RequestPlayersForGameFinalResultCallback_t) }, { CallbackType.SubmitPlayerResultResultCallback, typeof(SubmitPlayerResultResultCallback_t) }, { CallbackType.EndGameResultCallback, typeof(EndGameResultCallback_t) }, { CallbackType.JoinPartyCallback, typeof(JoinPartyCallback_t) }, { CallbackType.CreateBeaconCallback, typeof(CreateBeaconCallback_t) }, { CallbackType.ReservationNotificationCallback, typeof(ReservationNotificationCallback_t) }, { CallbackType.ChangeNumOpenSlotsCallback, typeof(ChangeNumOpenSlotsCallback_t) }, { CallbackType.AvailableBeaconLocationsUpdated, typeof(AvailableBeaconLocationsUpdated_t) }, { CallbackType.ActiveBeaconsUpdated, typeof(ActiveBeaconsUpdated_t) }, { CallbackType.SteamRemotePlaySessionConnected, typeof(SteamRemotePlaySessionConnected_t) }, { CallbackType.SteamRemotePlaySessionDisconnected, typeof(SteamRemotePlaySessionDisconnected_t) }, { CallbackType.SteamRemotePlayTogetherGuestInvite, typeof(SteamRemotePlayTogetherGuestInvite_t) }, { CallbackType.SteamTimelineGamePhaseRecordingExists, typeof(SteamTimelineGamePhaseRecordingExists_t) }, { CallbackType.SteamTimelineEventRecordingExists, typeof(SteamTimelineEventRecordingExists_t) } }; } internal class ISteamAppList : SteamInterface { internal ISteamAppList(bool IsGameServer) { SetupInterface(IsGameServer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr SteamAPI_SteamAppList_v001(); public override IntPtr GetUserInterfacePointer() { return SteamAPI_SteamAppList_v001(); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamAppList_GetNumInstalledApps")] private static extern uint _GetNumInstalledApps(IntPtr self); internal uint GetNumInstalledApps() { return _GetNumInstalledApps(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamAppList_GetInstalledApps")] private static extern uint _GetInstalledApps(IntPtr self, [In][Out] AppId[] pvecAppID, uint unMaxAppIDs); internal uint GetInstalledApps([In][Out] AppId[] pvecAppID, uint unMaxAppIDs) { return _GetInstalledApps(Self, pvecAppID, unMaxAppIDs); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamAppList_GetAppName")] private static extern int _GetAppName(IntPtr self, AppId nAppID, IntPtr pchName, int cchNameMax); internal int GetAppName(AppId nAppID, out string pchName) { Helpers.Memory m = Helpers.TakeMemory(); try { int result = _GetAppName(Self, nAppID, m, 32768); pchName = Helpers.MemoryToString(m); return result; } finally { ((IDisposable)m).Dispose(); } } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamAppList_GetAppInstallDir")] private static extern int _GetAppInstallDir(IntPtr self, AppId nAppID, IntPtr pchDirectory, int cchNameMax); internal int GetAppInstallDir(AppId nAppID, out string pchDirectory) { Helpers.Memory m = Helpers.TakeMemory(); try { int result = _GetAppInstallDir(Self, nAppID, m, 32768); pchDirectory = Helpers.MemoryToString(m); return result; } finally { ((IDisposable)m).Dispose(); } } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamAppList_GetAppBuildId")] private static extern int _GetAppBuildId(IntPtr self, AppId nAppID); internal int GetAppBuildId(AppId nAppID) { return _GetAppBuildId(Self, nAppID); } } internal class ISteamApps : SteamInterface { public const string Version = "STEAMAPPS_INTERFACE_VERSION008"; internal ISteamApps(bool IsGameServer) { SetupInterface(IsGameServer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr SteamAPI_SteamApps_v008(); public override IntPtr GetUserInterfacePointer() { return SteamAPI_SteamApps_v008(); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsSubscribed")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsSubscribed(IntPtr self); internal bool BIsSubscribed() { return _BIsSubscribed(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsLowViolence")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsLowViolence(IntPtr self); internal bool BIsLowViolence() { return _BIsLowViolence(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsCybercafe")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsCybercafe(IntPtr self); internal bool BIsCybercafe() { return _BIsCybercafe(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsVACBanned")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsVACBanned(IntPtr self); internal bool BIsVACBanned() { return _BIsVACBanned(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetCurrentGameLanguage")] private static extern Utf8StringPointer _GetCurrentGameLanguage(IntPtr self); internal string GetCurrentGameLanguage() { return _GetCurrentGameLanguage(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetAvailableGameLanguages")] private static extern Utf8StringPointer _GetAvailableGameLanguages(IntPtr self); internal string GetAvailableGameLanguages() { return _GetAvailableGameLanguages(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsSubscribedApp")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsSubscribedApp(IntPtr self, AppId appID); internal bool BIsSubscribedApp(AppId appID) { return _BIsSubscribedApp(Self, appID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsDlcInstalled")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsDlcInstalled(IntPtr self, AppId appID); internal bool BIsDlcInstalled(AppId appID) { return _BIsDlcInstalled(Self, appID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetEarliestPurchaseUnixTime")] private static extern uint _GetEarliestPurchaseUnixTime(IntPtr self, AppId nAppID); internal uint GetEarliestPurchaseUnixTime(AppId nAppID) { return _GetEarliestPurchaseUnixTime(Self, nAppID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsSubscribedFromFreeWeekend")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsSubscribedFromFreeWeekend(IntPtr self); internal bool BIsSubscribedFromFreeWeekend() { return _BIsSubscribedFromFreeWeekend(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetDLCCount")] private static extern int _GetDLCCount(IntPtr self); internal int GetDLCCount() { return _GetDLCCount(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BGetDLCDataByIndex")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BGetDLCDataByIndex(IntPtr self, int iDLC, ref AppId pAppID, [MarshalAs(UnmanagedType.U1)] ref bool pbAvailable, IntPtr pchName, int cchNameBufferSize); internal bool BGetDLCDataByIndex(int iDLC, ref AppId pAppID, [MarshalAs(UnmanagedType.U1)] ref bool pbAvailable, out string pchName) { Helpers.Memory m = Helpers.TakeMemory(); try { bool result = _BGetDLCDataByIndex(Self, iDLC, ref pAppID, ref pbAvailable, m, 32768); pchName = Helpers.MemoryToString(m); return result; } finally { ((IDisposable)m).Dispose(); } } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_InstallDLC")] private static extern void _InstallDLC(IntPtr self, AppId nAppID); internal void InstallDLC(AppId nAppID) { _InstallDLC(Self, nAppID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_UninstallDLC")] private static extern void _UninstallDLC(IntPtr self, AppId nAppID); internal void UninstallDLC(AppId nAppID) { _UninstallDLC(Self, nAppID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_RequestAppProofOfPurchaseKey")] private static extern void _RequestAppProofOfPurchaseKey(IntPtr self, AppId nAppID); internal void RequestAppProofOfPurchaseKey(AppId nAppID) { _RequestAppProofOfPurchaseKey(Self, nAppID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetCurrentBetaName")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _GetCurrentBetaName(IntPtr self, IntPtr pchName, int cchNameBufferSize); internal bool GetCurrentBetaName(out string pchName) { Helpers.Memory m = Helpers.TakeMemory(); try { bool result = _GetCurrentBetaName(Self, m, 32768); pchName = Helpers.MemoryToString(m); return result; } finally { ((IDisposable)m).Dispose(); } } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_MarkContentCorrupt")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _MarkContentCorrupt(IntPtr self, [MarshalAs(UnmanagedType.U1)] bool bMissingFilesOnly); internal bool MarkContentCorrupt([MarshalAs(UnmanagedType.U1)] bool bMissingFilesOnly) { return _MarkContentCorrupt(Self, bMissingFilesOnly); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetInstalledDepots")] private static extern uint _GetInstalledDepots(IntPtr self, AppId appID, [In][Out] DepotId_t[] pvecDepots, uint cMaxDepots); internal uint GetInstalledDepots(AppId appID, [In][Out] DepotId_t[] pvecDepots, uint cMaxDepots) { return _GetInstalledDepots(Self, appID, pvecDepots, cMaxDepots); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetAppInstallDir")] private static extern uint _GetAppInstallDir(IntPtr self, AppId appID, IntPtr pchFolder, uint cchFolderBufferSize); internal uint GetAppInstallDir(AppId appID, out string pchFolder) { Helpers.Memory m = Helpers.TakeMemory(); try { uint result = _GetAppInstallDir(Self, appID, m, 32768u); pchFolder = Helpers.MemoryToString(m); return result; } finally { ((IDisposable)m).Dispose(); } } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsAppInstalled")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsAppInstalled(IntPtr self, AppId appID); internal bool BIsAppInstalled(AppId appID) { return _BIsAppInstalled(Self, appID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetAppOwner")] private static extern SteamId _GetAppOwner(IntPtr self); internal SteamId GetAppOwner() { return _GetAppOwner(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetLaunchQueryParam")] private static extern Utf8StringPointer _GetLaunchQueryParam(IntPtr self, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchKey); internal string GetLaunchQueryParam([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchKey) { return _GetLaunchQueryParam(Self, pchKey); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetDlcDownloadProgress")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _GetDlcDownloadProgress(IntPtr self, AppId nAppID, ref ulong punBytesDownloaded, ref ulong punBytesTotal); internal bool GetDlcDownloadProgress(AppId nAppID, ref ulong punBytesDownloaded, ref ulong punBytesTotal) { return _GetDlcDownloadProgress(Self, nAppID, ref punBytesDownloaded, ref punBytesTotal); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetAppBuildId")] private static extern int _GetAppBuildId(IntPtr self); internal int GetAppBuildId() { return _GetAppBuildId(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_RequestAllProofOfPurchaseKeys")] private static extern void _RequestAllProofOfPurchaseKeys(IntPtr self); internal void RequestAllProofOfPurchaseKeys() { _RequestAllProofOfPurchaseKeys(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetFileDetails")] private static extern SteamAPICall_t _GetFileDetails(IntPtr self, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszFileName); internal CallResult<FileDetailsResult_t> GetFileDetails([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszFileName) { return new CallResult<FileDetailsResult_t>(_GetFileDetails(Self, pszFileName), base.IsServer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetLaunchCommandLine")] private static extern int _GetLaunchCommandLine(IntPtr self, IntPtr pszCommandLine, int cubCommandLine); internal int GetLaunchCommandLine(out string pszCommandLine) { Helpers.Memory m = Helpers.TakeMemory(); try { int result = _GetLaunchCommandLine(Self, m, 32768); pszCommandLine = Helpers.MemoryToString(m); return result; } finally { ((IDisposable)m).Dispose(); } } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsSubscribedFromFamilySharing")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsSubscribedFromFamilySharing(IntPtr self); internal bool BIsSubscribedFromFamilySharing() { return _BIsSubscribedFromFamilySharing(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_BIsTimedTrial")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BIsTimedTrial(IntPtr self, ref uint punSecondsAllowed, ref uint punSecondsPlayed); internal bool BIsTimedTrial(ref uint punSecondsAllowed, ref uint punSecondsPlayed) { return _BIsTimedTrial(Self, ref punSecondsAllowed, ref punSecondsPlayed); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_SetDlcContext")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _SetDlcContext(IntPtr self, AppId nAppID); internal bool SetDlcContext(AppId nAppID) { return _SetDlcContext(Self, nAppID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetNumBetas")] private static extern int _GetNumBetas(IntPtr self, ref int pnAvailable, ref int pnPrivate); internal int GetNumBetas(ref int pnAvailable, ref int pnPrivate) { return _GetNumBetas(Self, ref pnAvailable, ref pnPrivate); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_GetBetaInfo")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _GetBetaInfo(IntPtr self, int iBetaIndex, ref uint punFlags, ref uint punBuildID, IntPtr pchBetaName, int cchBetaName, IntPtr pchDescription, int cchDescription); internal bool GetBetaInfo(int iBetaIndex, ref uint punFlags, ref uint punBuildID, out string pchBetaName, out string pchDescription) { Helpers.Memory m = Helpers.TakeMemory(); try { Helpers.Memory m2 = Helpers.TakeMemory(); try { bool result = _GetBetaInfo(Self, iBetaIndex, ref punFlags, ref punBuildID, m, 32768, m2, 32768); pchBetaName = Helpers.MemoryToString(m); pchDescription = Helpers.MemoryToString(m2); return result; } finally { ((IDisposable)m2).Dispose(); } } finally { ((IDisposable)m).Dispose(); } } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamApps_SetActiveBeta")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _SetActiveBeta(IntPtr self, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchBetaName); internal bool SetActiveBeta([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchBetaName) { return _SetActiveBeta(Self, pchBetaName); } } internal class ISteamClient : SteamInterface { internal ISteamClient(bool IsGameServer) { SetupInterface(IsGameServer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_CreateSteamPipe")] private static extern HSteamPipe _CreateSteamPipe(IntPtr self); internal HSteamPipe CreateSteamPipe() { return _CreateSteamPipe(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_BReleaseSteamPipe")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BReleaseSteamPipe(IntPtr self, HSteamPipe hSteamPipe); internal bool BReleaseSteamPipe(HSteamPipe hSteamPipe) { return _BReleaseSteamPipe(Self, hSteamPipe); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_ConnectToGlobalUser")] private static extern HSteamUser _ConnectToGlobalUser(IntPtr self, HSteamPipe hSteamPipe); internal HSteamUser ConnectToGlobalUser(HSteamPipe hSteamPipe) { return _ConnectToGlobalUser(Self, hSteamPipe); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_CreateLocalUser")] private static extern HSteamUser _CreateLocalUser(IntPtr self, ref HSteamPipe phSteamPipe, AccountType eAccountType); internal HSteamUser CreateLocalUser(ref HSteamPipe phSteamPipe, AccountType eAccountType) { return _CreateLocalUser(Self, ref phSteamPipe, eAccountType); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_ReleaseUser")] private static extern void _ReleaseUser(IntPtr self, HSteamPipe hSteamPipe, HSteamUser hUser); internal void ReleaseUser(HSteamPipe hSteamPipe, HSteamUser hUser) { _ReleaseUser(Self, hSteamPipe, hUser); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamUser")] private static extern IntPtr _GetISteamUser(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamUser(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamUser(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamGameServer")] private static extern IntPtr _GetISteamGameServer(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamGameServer(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamGameServer(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_SetLocalIPBinding")] private static extern void _SetLocalIPBinding(IntPtr self, ref SteamIPAddress unIP, ushort usPort); internal void SetLocalIPBinding(ref SteamIPAddress unIP, ushort usPort) { _SetLocalIPBinding(Self, ref unIP, usPort); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamFriends")] private static extern IntPtr _GetISteamFriends(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamFriends(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamFriends(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamUtils")] private static extern IntPtr _GetISteamUtils(IntPtr self, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamUtils(HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamUtils(Self, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamMatchmaking")] private static extern IntPtr _GetISteamMatchmaking(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamMatchmaking(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamMatchmaking(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamMatchmakingServers")] private static extern IntPtr _GetISteamMatchmakingServers(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamMatchmakingServers(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamMatchmakingServers(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamGenericInterface")] private static extern IntPtr _GetISteamGenericInterface(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamGenericInterface(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamGenericInterface(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamUserStats")] private static extern IntPtr _GetISteamUserStats(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamUserStats(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamUserStats(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamGameServerStats")] private static extern IntPtr _GetISteamGameServerStats(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamGameServerStats(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamGameServerStats(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamApps")] private static extern IntPtr _GetISteamApps(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamApps(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamApps(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamNetworking")] private static extern IntPtr _GetISteamNetworking(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamNetworking(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamNetworking(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamRemoteStorage")] private static extern IntPtr _GetISteamRemoteStorage(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamRemoteStorage(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamRemoteStorage(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamScreenshots")] private static extern IntPtr _GetISteamScreenshots(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamScreenshots(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamScreenshots(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamGameSearch")] private static extern IntPtr _GetISteamGameSearch(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamGameSearch(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamGameSearch(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetIPCCallCount")] private static extern uint _GetIPCCallCount(IntPtr self); internal uint GetIPCCallCount() { return _GetIPCCallCount(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_SetWarningMessageHook")] private static extern void _SetWarningMessageHook(IntPtr self, IntPtr pFunction); internal void SetWarningMessageHook(IntPtr pFunction) { _SetWarningMessageHook(Self, pFunction); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_BShutdownIfAllPipesClosed")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _BShutdownIfAllPipesClosed(IntPtr self); internal bool BShutdownIfAllPipesClosed() { return _BShutdownIfAllPipesClosed(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamHTTP")] private static extern IntPtr _GetISteamHTTP(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamHTTP(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamHTTP(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamController")] private static extern IntPtr _GetISteamController(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamController(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamController(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamUGC")] private static extern IntPtr _GetISteamUGC(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamUGC(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamUGC(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamMusic")] private static extern IntPtr _GetISteamMusic(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamMusic(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamMusic(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamMusicRemote")] private static extern IntPtr _GetISteamMusicRemote(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamMusicRemote(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamMusicRemote(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamHTMLSurface")] private static extern IntPtr _GetISteamHTMLSurface(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamHTMLSurface(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamHTMLSurface(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamInventory")] private static extern IntPtr _GetISteamInventory(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamInventory(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamInventory(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamVideo")] private static extern IntPtr _GetISteamVideo(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamVideo(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamVideo(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamParentalSettings")] private static extern IntPtr _GetISteamParentalSettings(IntPtr self, HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamParentalSettings(HSteamUser hSteamuser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamParentalSettings(Self, hSteamuser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamInput")] private static extern IntPtr _GetISteamInput(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamInput(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamInput(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamParties")] private static extern IntPtr _GetISteamParties(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamParties(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamParties(Self, hSteamUser, hSteamPipe, pchVersion); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamClient_GetISteamRemotePlay")] private static extern IntPtr _GetISteamRemotePlay(IntPtr self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion); internal IntPtr GetISteamRemotePlay(HSteamUser hSteamUser, HSteamPipe hSteamPipe, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchVersion) { return _GetISteamRemotePlay(Self, hSteamUser, hSteamPipe, pchVersion); } } internal class ISteamController : SteamInterface { public const string Version = "SteamController008"; internal ISteamController(bool IsGameServer) { SetupInterface(IsGameServer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr SteamAPI_SteamController_v008(); public override IntPtr GetUserInterfacePointer() { return SteamAPI_SteamController_v008(); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_Init")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _Init(IntPtr self); internal bool Init() { return _Init(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_Shutdown")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _Shutdown(IntPtr self); internal bool Shutdown() { return _Shutdown(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_RunFrame")] private static extern void _RunFrame(IntPtr self); internal void RunFrame() { _RunFrame(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetConnectedControllers")] private static extern int _GetConnectedControllers(IntPtr self, [In][Out] ControllerHandle_t[] handlesOut); internal int GetConnectedControllers([In][Out] ControllerHandle_t[] handlesOut) { return _GetConnectedControllers(Self, handlesOut); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetActionSetHandle")] private static extern ControllerActionSetHandle_t _GetActionSetHandle(IntPtr self, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszActionSetName); internal ControllerActionSetHandle_t GetActionSetHandle([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszActionSetName) { return _GetActionSetHandle(Self, pszActionSetName); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_ActivateActionSet")] private static extern void _ActivateActionSet(IntPtr self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle); internal void ActivateActionSet(ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle) { _ActivateActionSet(Self, controllerHandle, actionSetHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetCurrentActionSet")] private static extern ControllerActionSetHandle_t _GetCurrentActionSet(IntPtr self, ControllerHandle_t controllerHandle); internal ControllerActionSetHandle_t GetCurrentActionSet(ControllerHandle_t controllerHandle) { return _GetCurrentActionSet(Self, controllerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_ActivateActionSetLayer")] private static extern void _ActivateActionSetLayer(IntPtr self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle); internal void ActivateActionSetLayer(ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle) { _ActivateActionSetLayer(Self, controllerHandle, actionSetLayerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_DeactivateActionSetLayer")] private static extern void _DeactivateActionSetLayer(IntPtr self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle); internal void DeactivateActionSetLayer(ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle) { _DeactivateActionSetLayer(Self, controllerHandle, actionSetLayerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_DeactivateAllActionSetLayers")] private static extern void _DeactivateAllActionSetLayers(IntPtr self, ControllerHandle_t controllerHandle); internal void DeactivateAllActionSetLayers(ControllerHandle_t controllerHandle) { _DeactivateAllActionSetLayers(Self, controllerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetActiveActionSetLayers")] private static extern int _GetActiveActionSetLayers(IntPtr self, ControllerHandle_t controllerHandle, [In][Out] ControllerActionSetHandle_t[] handlesOut); internal int GetActiveActionSetLayers(ControllerHandle_t controllerHandle, [In][Out] ControllerActionSetHandle_t[] handlesOut) { return _GetActiveActionSetLayers(Self, controllerHandle, handlesOut); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetDigitalActionHandle")] private static extern ControllerDigitalActionHandle_t _GetDigitalActionHandle(IntPtr self, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszActionName); internal ControllerDigitalActionHandle_t GetDigitalActionHandle([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszActionName) { return _GetDigitalActionHandle(Self, pszActionName); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetDigitalActionData")] private static extern DigitalState _GetDigitalActionData(IntPtr self, ControllerHandle_t controllerHandle, ControllerDigitalActionHandle_t digitalActionHandle); internal DigitalState GetDigitalActionData(ControllerHandle_t controllerHandle, ControllerDigitalActionHandle_t digitalActionHandle) { return _GetDigitalActionData(Self, controllerHandle, digitalActionHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetDigitalActionOrigins")] private static extern int _GetDigitalActionOrigins(IntPtr self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerDigitalActionHandle_t digitalActionHandle, ref ControllerActionOrigin originsOut); internal int GetDigitalActionOrigins(ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerDigitalActionHandle_t digitalActionHandle, ref ControllerActionOrigin originsOut) { return _GetDigitalActionOrigins(Self, controllerHandle, actionSetHandle, digitalActionHandle, ref originsOut); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetAnalogActionHandle")] private static extern ControllerAnalogActionHandle_t _GetAnalogActionHandle(IntPtr self, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszActionName); internal ControllerAnalogActionHandle_t GetAnalogActionHandle([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pszActionName) { return _GetAnalogActionHandle(Self, pszActionName); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetAnalogActionData")] private static extern AnalogState _GetAnalogActionData(IntPtr self, ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t analogActionHandle); internal AnalogState GetAnalogActionData(ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t analogActionHandle) { return _GetAnalogActionData(Self, controllerHandle, analogActionHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetAnalogActionOrigins")] private static extern int _GetAnalogActionOrigins(IntPtr self, ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerAnalogActionHandle_t analogActionHandle, ref ControllerActionOrigin originsOut); internal int GetAnalogActionOrigins(ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerAnalogActionHandle_t analogActionHandle, ref ControllerActionOrigin originsOut) { return _GetAnalogActionOrigins(Self, controllerHandle, actionSetHandle, analogActionHandle, ref originsOut); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetGlyphForActionOrigin")] private static extern Utf8StringPointer _GetGlyphForActionOrigin(IntPtr self, ControllerActionOrigin eOrigin); internal string GetGlyphForActionOrigin(ControllerActionOrigin eOrigin) { return _GetGlyphForActionOrigin(Self, eOrigin); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetStringForActionOrigin")] private static extern Utf8StringPointer _GetStringForActionOrigin(IntPtr self, ControllerActionOrigin eOrigin); internal string GetStringForActionOrigin(ControllerActionOrigin eOrigin) { return _GetStringForActionOrigin(Self, eOrigin); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_StopAnalogActionMomentum")] private static extern void _StopAnalogActionMomentum(IntPtr self, ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t eAction); internal void StopAnalogActionMomentum(ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t eAction) { _StopAnalogActionMomentum(Self, controllerHandle, eAction); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetMotionData")] private static extern MotionState _GetMotionData(IntPtr self, ControllerHandle_t controllerHandle); internal MotionState GetMotionData(ControllerHandle_t controllerHandle) { return _GetMotionData(Self, controllerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_TriggerHapticPulse")] private static extern void _TriggerHapticPulse(IntPtr self, ControllerHandle_t controllerHandle, SteamControllerPad eTargetPad, ushort usDurationMicroSec); internal void TriggerHapticPulse(ControllerHandle_t controllerHandle, SteamControllerPad eTargetPad, ushort usDurationMicroSec) { _TriggerHapticPulse(Self, controllerHandle, eTargetPad, usDurationMicroSec); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_TriggerRepeatedHapticPulse")] private static extern void _TriggerRepeatedHapticPulse(IntPtr self, ControllerHandle_t controllerHandle, SteamControllerPad eTargetPad, ushort usDurationMicroSec, ushort usOffMicroSec, ushort unRepeat, uint nFlags); internal void TriggerRepeatedHapticPulse(ControllerHandle_t controllerHandle, SteamControllerPad eTargetPad, ushort usDurationMicroSec, ushort usOffMicroSec, ushort unRepeat, uint nFlags) { _TriggerRepeatedHapticPulse(Self, controllerHandle, eTargetPad, usDurationMicroSec, usOffMicroSec, unRepeat, nFlags); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_TriggerVibration")] private static extern void _TriggerVibration(IntPtr self, ControllerHandle_t controllerHandle, ushort usLeftSpeed, ushort usRightSpeed); internal void TriggerVibration(ControllerHandle_t controllerHandle, ushort usLeftSpeed, ushort usRightSpeed) { _TriggerVibration(Self, controllerHandle, usLeftSpeed, usRightSpeed); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_SetLEDColor")] private static extern void _SetLEDColor(IntPtr self, ControllerHandle_t controllerHandle, byte nColorR, byte nColorG, byte nColorB, uint nFlags); internal void SetLEDColor(ControllerHandle_t controllerHandle, byte nColorR, byte nColorG, byte nColorB, uint nFlags) { _SetLEDColor(Self, controllerHandle, nColorR, nColorG, nColorB, nFlags); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_ShowBindingPanel")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _ShowBindingPanel(IntPtr self, ControllerHandle_t controllerHandle); internal bool ShowBindingPanel(ControllerHandle_t controllerHandle) { return _ShowBindingPanel(Self, controllerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetInputTypeForHandle")] private static extern InputType _GetInputTypeForHandle(IntPtr self, ControllerHandle_t controllerHandle); internal InputType GetInputTypeForHandle(ControllerHandle_t controllerHandle) { return _GetInputTypeForHandle(Self, controllerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetControllerForGamepadIndex")] private static extern ControllerHandle_t _GetControllerForGamepadIndex(IntPtr self, int nIndex); internal ControllerHandle_t GetControllerForGamepadIndex(int nIndex) { return _GetControllerForGamepadIndex(Self, nIndex); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetGamepadIndexForController")] private static extern int _GetGamepadIndexForController(IntPtr self, ControllerHandle_t ulControllerHandle); internal int GetGamepadIndexForController(ControllerHandle_t ulControllerHandle) { return _GetGamepadIndexForController(Self, ulControllerHandle); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetStringForXboxOrigin")] private static extern Utf8StringPointer _GetStringForXboxOrigin(IntPtr self, XboxOrigin eOrigin); internal string GetStringForXboxOrigin(XboxOrigin eOrigin) { return _GetStringForXboxOrigin(Self, eOrigin); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetGlyphForXboxOrigin")] private static extern Utf8StringPointer _GetGlyphForXboxOrigin(IntPtr self, XboxOrigin eOrigin); internal string GetGlyphForXboxOrigin(XboxOrigin eOrigin) { return _GetGlyphForXboxOrigin(Self, eOrigin); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetActionOriginFromXboxOrigin")] private static extern ControllerActionOrigin _GetActionOriginFromXboxOrigin(IntPtr self, ControllerHandle_t controllerHandle, XboxOrigin eOrigin); internal ControllerActionOrigin GetActionOriginFromXboxOrigin(ControllerHandle_t controllerHandle, XboxOrigin eOrigin) { return _GetActionOriginFromXboxOrigin(Self, controllerHandle, eOrigin); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_TranslateActionOrigin")] private static extern ControllerActionOrigin _TranslateActionOrigin(IntPtr self, InputType eDestinationInputType, ControllerActionOrigin eSourceOrigin); internal ControllerActionOrigin TranslateActionOrigin(InputType eDestinationInputType, ControllerActionOrigin eSourceOrigin) { return _TranslateActionOrigin(Self, eDestinationInputType, eSourceOrigin); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamController_GetControllerBindingRevision")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _GetControllerBindingRevision(IntPtr self, ControllerHandle_t controllerHandle, ref int pMajor, ref int pMinor); internal bool GetControllerBindingRevision(ControllerHandle_t controllerHandle, ref int pMajor, ref int pMinor) { return _GetControllerBindingRevision(Self, controllerHandle, ref pMajor, ref pMinor); } } internal class ISteamFriends : SteamInterface { public const string Version = "SteamFriends017"; internal ISteamFriends(bool IsGameServer) { SetupInterface(IsGameServer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr SteamAPI_SteamFriends_v017(); public override IntPtr GetUserInterfacePointer() { return SteamAPI_SteamFriends_v017(); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetPersonaName")] private static extern Utf8StringPointer _GetPersonaName(IntPtr self); internal string GetPersonaName() { return _GetPersonaName(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_SetPersonaName")] private static extern SteamAPICall_t _SetPersonaName(IntPtr self, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchPersonaName); internal CallResult<SetPersonaNameResponse_t> SetPersonaName([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "Steamworks.Utf8StringToNative")] string pchPersonaName) { return new CallResult<SetPersonaNameResponse_t>(_SetPersonaName(Self, pchPersonaName), base.IsServer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetPersonaState")] private static extern FriendState _GetPersonaState(IntPtr self); internal FriendState GetPersonaState() { return _GetPersonaState(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendCount")] private static extern int _GetFriendCount(IntPtr self, int iFriendFlags); internal int GetFriendCount(int iFriendFlags) { return _GetFriendCount(Self, iFriendFlags); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendByIndex")] private static extern SteamId _GetFriendByIndex(IntPtr self, int iFriend, int iFriendFlags); internal SteamId GetFriendByIndex(int iFriend, int iFriendFlags) { return _GetFriendByIndex(Self, iFriend, iFriendFlags); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendRelationship")] private static extern Relationship _GetFriendRelationship(IntPtr self, SteamId steamIDFriend); internal Relationship GetFriendRelationship(SteamId steamIDFriend) { return _GetFriendRelationship(Self, steamIDFriend); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendPersonaState")] private static extern FriendState _GetFriendPersonaState(IntPtr self, SteamId steamIDFriend); internal FriendState GetFriendPersonaState(SteamId steamIDFriend) { return _GetFriendPersonaState(Self, steamIDFriend); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendPersonaName")] private static extern Utf8StringPointer _GetFriendPersonaName(IntPtr self, SteamId steamIDFriend); internal string GetFriendPersonaName(SteamId steamIDFriend) { return _GetFriendPersonaName(Self, steamIDFriend); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendGamePlayed")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _GetFriendGamePlayed(IntPtr self, SteamId steamIDFriend, ref FriendGameInfo_t pFriendGameInfo); internal bool GetFriendGamePlayed(SteamId steamIDFriend, ref FriendGameInfo_t pFriendGameInfo) { return _GetFriendGamePlayed(Self, steamIDFriend, ref pFriendGameInfo); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendPersonaNameHistory")] private static extern Utf8StringPointer _GetFriendPersonaNameHistory(IntPtr self, SteamId steamIDFriend, int iPersonaName); internal string GetFriendPersonaNameHistory(SteamId steamIDFriend, int iPersonaName) { return _GetFriendPersonaNameHistory(Self, steamIDFriend, iPersonaName); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendSteamLevel")] private static extern int _GetFriendSteamLevel(IntPtr self, SteamId steamIDFriend); internal int GetFriendSteamLevel(SteamId steamIDFriend) { return _GetFriendSteamLevel(Self, steamIDFriend); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetPlayerNickname")] private static extern Utf8StringPointer _GetPlayerNickname(IntPtr self, SteamId steamIDPlayer); internal string GetPlayerNickname(SteamId steamIDPlayer) { return _GetPlayerNickname(Self, steamIDPlayer); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendsGroupCount")] private static extern int _GetFriendsGroupCount(IntPtr self); internal int GetFriendsGroupCount() { return _GetFriendsGroupCount(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendsGroupIDByIndex")] private static extern FriendsGroupID_t _GetFriendsGroupIDByIndex(IntPtr self, int iFG); internal FriendsGroupID_t GetFriendsGroupIDByIndex(int iFG) { return _GetFriendsGroupIDByIndex(Self, iFG); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendsGroupName")] private static extern Utf8StringPointer _GetFriendsGroupName(IntPtr self, FriendsGroupID_t friendsGroupID); internal string GetFriendsGroupName(FriendsGroupID_t friendsGroupID) { return _GetFriendsGroupName(Self, friendsGroupID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendsGroupMembersCount")] private static extern int _GetFriendsGroupMembersCount(IntPtr self, FriendsGroupID_t friendsGroupID); internal int GetFriendsGroupMembersCount(FriendsGroupID_t friendsGroupID) { return _GetFriendsGroupMembersCount(Self, friendsGroupID); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetFriendsGroupMembersList")] private static extern void _GetFriendsGroupMembersList(IntPtr self, FriendsGroupID_t friendsGroupID, [In][Out] SteamId[] pOutSteamIDMembers, int nMembersCount); internal void GetFriendsGroupMembersList(FriendsGroupID_t friendsGroupID, [In][Out] SteamId[] pOutSteamIDMembers, int nMembersCount) { _GetFriendsGroupMembersList(Self, friendsGroupID, pOutSteamIDMembers, nMembersCount); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_HasFriend")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _HasFriend(IntPtr self, SteamId steamIDFriend, int iFriendFlags); internal bool HasFriend(SteamId steamIDFriend, int iFriendFlags) { return _HasFriend(Self, steamIDFriend, iFriendFlags); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetClanCount")] private static extern int _GetClanCount(IntPtr self); internal int GetClanCount() { return _GetClanCount(Self); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetClanByIndex")] private static extern SteamId _GetClanByIndex(IntPtr self, int iClan); internal SteamId GetClanByIndex(int iClan) { return _GetClanByIndex(Self, iClan); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetClanName")] private static extern Utf8StringPointer _GetClanName(IntPtr self, SteamId steamIDClan); internal string GetClanName(SteamId steamIDClan) { return _GetClanName(Self, steamIDClan); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetClanTag")] private static extern Utf8StringPointer _GetClanTag(IntPtr self, SteamId steamIDClan); internal string GetClanTag(SteamId steamIDClan) { return _GetClanTag(Self, steamIDClan); } [DllImport("steam_api64", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamFriends_GetClanActivityCounts")] [return: MarshalAs(UnmanagedType.I1)] private static extern bool _GetClanActivityCounts(IntPtr self, SteamId steamIDClan, ref int pnOnline, ref int pnInGame, ref int pnChatting); internal bool GetClanActivityCounts(SteamId steamIDClan, ref int pnOnline, ref int pnInGame, ref int pnChatting) { return _GetClanActivityCounts(Self, steamIDClan, ref pnOnline, ref pnInGame, ref pnChatting); } [DllIm
patchers/PAMultiplayer/PAMultiplayer.Preloader.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx.Logging; using Mono.Cecil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("PAMultiplayer.Preloader")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e7b02a7e8158d7350b511b806d3dc491b122ddb2")] [assembly: AssemblyProduct("PAMultiplayer.Preloader")] [assembly: AssemblyTitle("PAMultiplayer.Preloader")] [assembly: AssemblyVersion("1.0.0.0")] namespace PAMultiplayer.Preloader; public static class Patcher { public static IEnumerable<string> TargetDLLs { get; } = new string[2] { "Facepunch.Steamworks.Win64.dll", "DiscordRPC.dll" }; public static void Patch(ref AssemblyDefinition assembly) { switch (((AssemblyNameReference)assembly.Name).Name) { case "DiscordRPC": assembly = AssemblyDefinition.ReadAssembly(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DiscordRPC.dll"); break; case "Facepunch.Steamworks.Win64": assembly = AssemblyDefinition.ReadAssembly(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\Facepunch.Steamworks.Win64.dll"); PatchFacepunch(assembly); break; } } private static void PatchFacepunch(AssemblyDefinition assembly) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) ManualLogSource val = Logger.CreateLogSource("me.ytarame.multiplayer.preloader"); string name = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\steam_api64.dll"; Enumerator<ModuleDefinition> enumerator = assembly.Modules.GetEnumerator(); try { while (enumerator.MoveNext()) { ModuleDefinition current = enumerator.Current; Enumerator<TypeDefinition> enumerator2 = current.Types.GetEnumerator(); try { while (enumerator2.MoveNext()) { TypeDefinition current2 = enumerator2.Current; Enumerator<MethodDefinition> enumerator3 = current2.Methods.GetEnumerator(); try { while (enumerator3.MoveNext()) { MethodDefinition current3 = enumerator3.Current; if (!current3.IsPInvokeImpl || current3.PInvokeInfo == null || current3.PInvokeInfo.Module.Name != "steam_api64") { continue; } val.LogInfo((object)"Found steam_api64 import"); current3.PInvokeInfo.Module.Name = name; return; } } finally { ((IDisposable)enumerator3).Dispose(); } } } finally { ((IDisposable)enumerator2).Dispose(); } } } finally { ((IDisposable)enumerator).Dispose(); } val.Dispose(); } }
plugins/PAMultiplayer/AttributeNetworkWrapperV2.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Aiden")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6ab9188a1d8b56f81ab965331a4ef8df7cf151b2")] [assembly: AssemblyProduct("AttributeNetworkWrapperV2")] [assembly: AssemblyTitle("AttributeNetworkWrapperV2")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Aiden-ytarame/AttributeNetworkWrapperV2/")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AttributeNetworkWrapperV2 { public enum SendType : ushort { Reliable, Unreliable } [AttributeUsage(AttributeTargets.Method)] public class ServerRpcAttribute : Attribute { private SendType sendType; public ServerRpcAttribute(SendType sendType = SendType.Reliable) { this.sendType = sendType; } } [AttributeUsage(AttributeTargets.Method)] public class ClientRpcAttribute : Attribute { private SendType sendType; public ClientRpcAttribute(SendType sendType = SendType.Reliable) { this.sendType = sendType; } } [AttributeUsage(AttributeTargets.Method)] public class MultiRpcAttribute : Attribute { private SendType sendType; public MultiRpcAttribute(SendType sendType = SendType.Reliable) { this.sendType = sendType; } } public class NullServerException : Exception { public NullServerException(string message) : base(message) { } } public static class Extensions { public static ushort GetStableHashCode(this string text) { uint num = 2166136261u; uint num2 = 16777619u; foreach (char c in text) { byte b = (byte)c; num ^= b; num *= num2; } return (ushort)((num >> 16) ^ num); } } public abstract class NetworkConnection { public readonly int ConnectionId = 0; public string Address { get; private set; } internal NetworkConnection() { } internal NetworkConnection(int connectionId, string address) { ConnectionId = connectionId; Address = address; } public abstract void SendRpcToTransport(ArraySegment<byte> data, SendType sendType = SendType.Reliable); public abstract void Disconnect(); } public class ServerNetworkConnection : NetworkConnection { public ServerNetworkConnection(string address) : base(0, address) { } public override void SendRpcToTransport(ArraySegment<byte> data, SendType sendType = SendType.Reliable) { Transport.Instance?.SendMessageToServer(data, sendType); } public override void Disconnect() { NetworkManager.Instance?.Disconnect(); } } public class ClientNetworkConnection : NetworkConnection { public ClientNetworkConnection(int connectionId, string address) : base(connectionId, address) { } public override void SendRpcToTransport(ArraySegment<byte> data, SendType sendType = SendType.Reliable) { Transport.Instance?.SendMessageToClient(ConnectionId, data, sendType); } public override void Disconnect() { NetworkManager.Instance?.KickClient(ConnectionId); } } public class NetworkManager { protected ServerNetworkConnection? ServerConnection; protected Dictionary<int, ClientNetworkConnection> ClientConnections = new Dictionary<int, ClientNetworkConnection>(); private bool _eventsSet = false; public static NetworkManager? Instance { get; private set; } public bool TransportActive => Transport.IsActive; public bool Server => Transport.IsServer; public bool PeerServer { get; protected set; } public ClientNetworkConnection? ServerSelfPeerConnection { get; protected set; } protected Transport Transport => AttributeNetworkWrapperV2.Transport.Instance; public bool Init(Transport transport) { if (Instance != null) { return false; } Instance = this; AttributeNetworkWrapperV2.Transport.Instance = transport; SetupEvents(); return true; } public void Shutdown() { if (this == Instance) { DeSetupEvents(); Instance = null; AttributeNetworkWrapperV2.Transport.Instance = null; } } private void SetupEvents() { if (!_eventsSet) { Transport transport = Transport; transport.OnClientConnected = (Action<ServerNetworkConnection>)Delegate.Combine(transport.OnClientConnected, new Action<ServerNetworkConnection>(OnClientConnected)); Transport transport2 = Transport; transport2.OnServerStarted = (Action)Delegate.Combine(transport2.OnServerStarted, new Action(OnServerStarted)); Transport transport3 = Transport; transport3.OnClientDisconnected = (Action)Delegate.Combine(transport3.OnClientDisconnected, new Action(OnClientDisconnected)); Transport transport4 = Transport; transport4.OnServerClientConnected = (Action<ClientNetworkConnection>)Delegate.Combine(transport4.OnServerClientConnected, new Action<ClientNetworkConnection>(OnServerClientConnected)); Transport transport5 = Transport; transport5.OnServerClientDisconnected = (Action<ClientNetworkConnection>)Delegate.Combine(transport5.OnServerClientDisconnected, new Action<ClientNetworkConnection>(OnServerClientDisconnected)); Transport transport6 = Transport; transport6.OnServerDataReceived = (Action<ClientNetworkConnection, ArraySegment<byte>>)Delegate.Combine(transport6.OnServerDataReceived, new Action<ClientNetworkConnection, ArraySegment<byte>>(OnServerTransportDataReceived)); Transport transport7 = Transport; transport7.OnClientDataReceived = (Action<ArraySegment<byte>>)Delegate.Combine(transport7.OnClientDataReceived, new Action<ArraySegment<byte>>(OnClientTransportDataReceived)); _eventsSet = true; } } private void DeSetupEvents() { if (_eventsSet) { Transport transport = Transport; transport.OnClientConnected = (Action<ServerNetworkConnection>)Delegate.Remove(transport.OnClientConnected, new Action<ServerNetworkConnection>(OnClientConnected)); Transport transport2 = Transport; transport2.OnServerStarted = (Action)Delegate.Remove(transport2.OnServerStarted, new Action(OnServerStarted)); Transport transport3 = Transport; transport3.OnClientDisconnected = (Action)Delegate.Remove(transport3.OnClientDisconnected, new Action(OnClientDisconnected)); Transport transport4 = Transport; transport4.OnServerClientConnected = (Action<ClientNetworkConnection>)Delegate.Remove(transport4.OnServerClientConnected, new Action<ClientNetworkConnection>(OnServerClientConnected)); Transport transport5 = Transport; transport5.OnServerClientDisconnected = (Action<ClientNetworkConnection>)Delegate.Remove(transport5.OnServerClientDisconnected, new Action<ClientNetworkConnection>(OnServerClientDisconnected)); Transport transport6 = Transport; transport6.OnServerDataReceived = (Action<ClientNetworkConnection, ArraySegment<byte>>)Delegate.Remove(transport6.OnServerDataReceived, new Action<ClientNetworkConnection, ArraySegment<byte>>(OnServerTransportDataReceived)); Transport transport7 = Transport; transport7.OnClientDataReceived = (Action<ArraySegment<byte>>)Delegate.Remove(transport7.OnClientDataReceived, new Action<ArraySegment<byte>>(OnClientTransportDataReceived)); _eventsSet = false; } } public virtual void ConnectToServer(string address) { Transport.ConnectClient(address); } public virtual void Disconnect() { Transport.StopClient(); } public virtual void KickClient(int clientId) { Transport.KickConnection(clientId); } public virtual void OnClientConnected(ServerNetworkConnection connection) { ServerConnection = connection; } public virtual void OnClientDisconnected() { ServerConnection = null; } public virtual void SendToServer(ArraySegment<byte> data, SendType sendType) { if (ServerConnection == null || Transport == null || !Transport.IsActive) { throw new NullServerException("Tried calling a server rpc while server is Null!"); } ServerConnection.SendRpcToTransport(data, sendType); } internal static void OnClientTransportDataReceived(ArraySegment<byte> data) { using NetworkReader reader = new NetworkReader(data); if (data.Count < 2) { Console.WriteLine("Data was too small, idk what we do for now"); return; } ushort hash = reader.ReadUInt16(); if (RpcHandler.TryGetRpcInvoker(hash, out var invoker)) { if (invoker.CallType != 0) { invoker.RpcFunc(null, reader); } else { Console.WriteLine("Received server rcp as a client!"); } } else { Console.WriteLine("Received invalid id!"); } } public virtual void StartServer(bool serverIsPeer) { ClientConnections.Clear(); PeerServer = serverIsPeer; ServerSelfPeerConnection = new ClientNetworkConnection(0, "addr"); ClientConnections.Add(0, ServerSelfPeerConnection); Transport.StartServer(); } public virtual void EndServer() { PeerServer = false; ClientConnections.Clear(); ServerSelfPeerConnection = null; Transport.StopServer(); } public virtual void OnServerClientDisconnected(ClientNetworkConnection connection) { ClientConnections.Remove(connection.ConnectionId); } public virtual void OnServerClientConnected(ClientNetworkConnection connection) { ClientConnections.Add(connection.ConnectionId, connection); } public virtual void OnServerStarted() { } public virtual void SendToClient(ClientNetworkConnection connection, ArraySegment<byte> data, SendType sendType) { if (Transport == null || !Transport.IsActive) { throw new NullServerException("Tried calling a Client rpc while transport is Null!"); } if (connection != null) { connection.SendRpcToTransport(data, sendType); return; } throw new ArgumentException("Tried to send rpc to invalid connection ID!"); } public virtual void SendToAllClients(ArraySegment<byte> data, SendType sendType) { if (Transport == null || !Transport.IsActive) { throw new NullServerException("Tried calling a Client rpc while transport is Null!"); } foreach (KeyValuePair<int, ClientNetworkConnection> clientConnection in ClientConnections) { if (!PeerServer || ServerSelfPeerConnection != clientConnection.Value) { clientConnection.Value.SendRpcToTransport(data, sendType); } } } internal static void OnServerTransportDataReceived(ClientNetworkConnection connection, ArraySegment<byte> data) { using NetworkReader reader = new NetworkReader(data); if (data.Count < 2) { Console.WriteLine("Data was too small, idk what we do for now"); return; } ushort hash = reader.ReadUInt16(); if (RpcHandler.TryGetRpcInvoker(hash, out var invoker)) { if (invoker.CallType == RpcHandler.CallType.Server) { invoker.RpcFunc(connection, reader); } else { Console.WriteLine("Received client rcp as a server!"); } } else { Console.WriteLine("Received invalid id!"); } } } public class NetworkReader : IDisposable { public readonly BinaryReader BinaryReader; public NetworkReader(Stream stream) { BinaryReader = new BinaryReader(stream); } public NetworkReader(ArraySegment<byte> data) : this(new MemoryStream(Enumerable.ToArray(data))) { } public void Dispose() { BinaryReader.Dispose(); GC.SuppressFinalize(this); } } public static class NetReaderExtensions { public static bool ReadBoolean(this NetworkReader reader) { return reader.BinaryReader.ReadBoolean(); } public static byte ReadByte(this NetworkReader reader) { return reader.BinaryReader.ReadByte(); } public static sbyte ReadSByte(this NetworkReader reader) { return reader.BinaryReader.ReadSByte(); } public static short ReadInt16(this NetworkReader reader) { return reader.BinaryReader.ReadInt16(); } public static ushort ReadUInt16(this NetworkReader reader) { return reader.BinaryReader.ReadUInt16(); } public static int ReadInt32(this NetworkReader reader) { return reader.BinaryReader.ReadInt32(); } public static uint ReadUInt32(this NetworkReader reader) { return reader.BinaryReader.ReadUInt32(); } public static long ReadInt64(this NetworkReader reader) { return reader.BinaryReader.ReadInt64(); } public static ulong ReadUInt64(this NetworkReader reader) { return reader.BinaryReader.ReadUInt64(); } public static float ReadSingle(this NetworkReader reader) { return reader.BinaryReader.ReadSingle(); } public static double ReadDouble(this NetworkReader reader) { return reader.BinaryReader.ReadDouble(); } public static char ReadChar(this NetworkReader reader) { return reader.BinaryReader.ReadChar(); } public static string ReadString(this NetworkReader reader) { return reader.BinaryReader.ReadString(); } } public static class RpcHandler { public enum CallType { Server, Client, Multi } public struct Invoker { public CallType CallType; public RpcDelegate RpcFunc; public Invoker(CallType callType, RpcDelegate func) { CallType = callType; RpcFunc = func; } } public delegate void RpcDelegate(ClientNetworkConnection conn, NetworkReader reader); private static Dictionary<ushort, Invoker> RpcInvokers; static RpcHandler() { RpcInvokers = new Dictionary<ushort, Invoker>(); Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type = assembly.GetType("AttributeNetworkWrapperV2.RpcFuncRegistersGenerated"); if (type != null) { break; } } if (type == null) { throw new ApplicationException("RpcFuncRegistersGenerated wasn't found, something terrible went wrong"); } RuntimeHelpers.RunClassConstructor(type.TypeHandle); } public static bool TryGetRpcInvoker(ushort hash, out Invoker invoker) { return RpcInvokers.TryGetValue(hash, out invoker); } public static void RegisterRpc(ushort hash, RpcDelegate rpcDelegate, CallType callType) { if (TryGetRpcInvoker(hash, out var invoker)) { throw new ArgumentException($"Tried to register RPC with hash {hash}, but it already exists.\n" + "Tried to Add [" + rpcDelegate.Method.DeclaringType?.Name + "." + rpcDelegate.Method.Name + "] but [" + invoker.RpcFunc.Method.DeclaringType?.Name + "." + invoker.RpcFunc.Method.Name + "] already exists. Consider renaming the RPC."); } RpcInvokers.Add(hash, new Invoker(callType, rpcDelegate)); } } public abstract class Transport { public Action<ArraySegment<byte>> OnClientDataReceived; public Action<ServerNetworkConnection> OnClientConnected; public Action OnClientDisconnected; public Action<ClientNetworkConnection, ArraySegment<byte>> OnServerDataReceived; public Action<ClientNetworkConnection> OnServerClientConnected; public Action<ClientNetworkConnection> OnServerClientDisconnected; public Action OnServerStarted; public static Transport? Instance { get; set; } public bool IsActive { get; protected set; } public bool IsServer { get; protected set; } public abstract void ConnectClient(string address); public abstract void StopClient(); public abstract void StartServer(); public abstract void StopServer(); public abstract void KickConnection(int connectionId); public abstract void SendMessageToServer(ArraySegment<byte> data, SendType sendType = SendType.Reliable); public abstract void SendMessageToClient(int connectionId, ArraySegment<byte> data, SendType sendType = SendType.Reliable); public abstract void Shutdown(); } public class NetworkWriter : IDisposable { private static MemoryStream _memoryStream = new MemoryStream(1024); public readonly BinaryWriter BinaryWriter = new BinaryWriter(_memoryStream, Encoding.UTF8, leaveOpen: true); public NetworkWriter() { _memoryStream.Position = 0L; } public ArraySegment<byte> GetData() { return new ArraySegment<byte>(_memoryStream.GetBuffer(), 0, (int)_memoryStream.Position); } public void Dispose() { BinaryWriter.Dispose(); GC.SuppressFinalize(this); } } public static class NetWriterExtensions { public static void Write(this NetworkWriter nw, bool value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, byte value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, sbyte value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, short value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, ushort value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, int value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, uint value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, long value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, ulong value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, float value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, double value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, char value) { nw.BinaryWriter.Write(value); } public static void Write(this NetworkWriter nw, string value) { nw.BinaryWriter.Write(value); } } }
plugins/PAMultiplayer/PAMultiplayer.dll
Decompiled 3 days 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.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using System.Threading.Tasks; using Systems.SceneManagement; using AttributeNetworkWrapperV2; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Crosstales; using DiscordRPC; using DiscordRPC.Events; using DiscordRPC.IO; using DiscordRPC.Logging; using DiscordRPC.Message; using Eflatun.SceneReference; using HarmonyLib; using Lachee.Discord; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using PAMultiplayer.AttributeNetworkWrapperOverrides; using PAMultiplayer.Managers; using PAMultiplayer.Patch; using PaApi; using Rewired; using SimpleJSON; using Steamworks; using Steamworks.Data; using Steamworks.Ugc; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Localization.PropertyVariants; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; using VGFunctions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PAMultiplayer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Multiplayer Mod")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e7b02a7e8158d7350b511b806d3dc491b122ddb2")] [assembly: AssemblyProduct("PAMultiplayer")] [assembly: AssemblyTitle("PAMultiplayer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AttributeNetworkWrapperV2 { public static class RpcFuncRegistersGenerated { static RpcFuncRegistersGenerated() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Expected O, but got Unknown //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Expected O, but got Unknown //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Expected O, but got Unknown //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown RpcHandler.RegisterRpc((ushort)58818, new RpcDelegate(PaMNetworkManager.Deserialize_Server_SendModVer_58818), (CallType)0); RpcHandler.RegisterRpc((ushort)34771, new RpcDelegate(ChallengeManager.Deserialize_Server_UnknownLevelIds_34771), (CallType)0); RpcHandler.RegisterRpc((ushort)7811, new RpcDelegate(VoterCell.Deserialize_Server_LevelVoted_7811), (CallType)0); RpcHandler.RegisterRpc((ushort)65336, new RpcDelegate(NetworkManager.Deserialize_Server_PlayerPos_65336), (CallType)0); RpcHandler.RegisterRpc((ushort)28267, new RpcDelegate(PointsManager.Deserialize_Client_SendResults_28267), (CallType)0); RpcHandler.RegisterRpc((ushort)34247, new RpcDelegate(GameManagerPatch.Deserialize_Server_RequestLobbyState_34247), (CallType)0); RpcHandler.RegisterRpc((ushort)54552, new RpcDelegate(Player_Patch.Deserialize_Server_PlayerDamaged_54552), (CallType)0); RpcHandler.RegisterRpc((ushort)59657, new RpcDelegate(Player_Patch.Deserialize_Server_PlayerBoost_59657), (CallType)0); RpcHandler.RegisterRpc((ushort)42018, new RpcDelegate(PaMNetworkManager.Deserialize_Client_RegisterPlayerId_42018), (CallType)1); RpcHandler.RegisterRpc((ushort)37620, new RpcDelegate(PaMNetworkManager.Deserialize_Client_AskForMod_37620), (CallType)1); RpcHandler.RegisterRpc((ushort)8766, new RpcDelegate(PaMNetworkManager.Deserialize_Client_MissingMod_8766), (CallType)1); RpcHandler.RegisterRpc((ushort)56878, new RpcDelegate(ChallengeManager.Deserialize_Client_AudioData_56878), (CallType)1); RpcHandler.RegisterRpc((ushort)11993, new RpcDelegate(GameManagerPatch.Deserialize_Client_LobbyState_11993), (CallType)1); RpcHandler.RegisterRpc((ushort)22680, new RpcDelegate(PaMNetworkManager.Deserialize_Multi_RegisterJoinedPlayerId_22680), (CallType)2); RpcHandler.RegisterRpc((ushort)18518, new RpcDelegate(PaMNetworkManager.Deserialize_Multi_PlayerLeft_18518), (CallType)2); RpcHandler.RegisterRpc((ushort)27550, new RpcDelegate(ChallengeManager.Deserialize_Multi_VoteWinner_27550), (CallType)2); RpcHandler.RegisterRpc((ushort)47253, new RpcDelegate(ChallengeManager.Deserialize_Multi_CheckLevelIds_47253), (CallType)2); RpcHandler.RegisterRpc((ushort)13413, new RpcDelegate(NetworkManager.Deserialize_Multi_PlayerPos_13413), (CallType)2); RpcHandler.RegisterRpc((ushort)49432, new RpcDelegate(PointsManager.Deserialize_Multi_SetPlayerResults_49432), (CallType)2); RpcHandler.RegisterRpc((ushort)10245, new RpcDelegate(GameManagerPatch.Deserialize_Multi_LatePlayerJoin_10245), (CallType)2); RpcHandler.RegisterRpc((ushort)62198, new RpcDelegate(GameManagerPatch.Deserialize_Multi_NextQueueLevel_62198), (CallType)2); RpcHandler.RegisterRpc((ushort)65142, new RpcDelegate(GameManagerPatch.Deserialize_Multi_OpenChallenge_65142), (CallType)2); RpcHandler.RegisterRpc((ushort)40080, new RpcDelegate(Player_Patch.Deserialize_Multi_PlayerDamaged_40080), (CallType)2); RpcHandler.RegisterRpc((ushort)5034, new RpcDelegate(Player_Patch.Deserialize_Multi_DamageAll_5034), (CallType)2); RpcHandler.RegisterRpc((ushort)29337, new RpcDelegate(Player_Patch.Deserialize_Multi_PlayerBoost_29337), (CallType)2); RpcHandler.RegisterRpc((ushort)16372, new RpcDelegate(CheckpointHandler.Deserialize_Multi_CheckpointHit_16372), (CallType)2); RpcHandler.RegisterRpc((ushort)11649, new RpcDelegate(RewindHandler.Deserialize_Multi_RewindToCheckpoint_11649), (CallType)2); RpcHandler.RegisterRpc((ushort)34174, new RpcDelegate(PauseLobbyPatch.Deserialize_Multi_StartLevel_34174), (CallType)2); } } } namespace PAMultiplayer { [BepInPlugin("me.ytarame.Multiplayer", "Multiplayer", "1.1.0")] [BepInProcess("Project Arrhythmia.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class PAM : BaseUnityPlugin { public static PAM Inst; internal static ManualLogSource Logger; private Harmony harmony; public const string Guid = "me.ytarame.Multiplayer"; private const string Name = "Multiplayer"; public const string Version = "1.1.0"; private void Awake() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; Inst = this; harmony = new Harmony("me.ytarame.Multiplayer"); harmony.PatchAll(); Settings.Initialize(((BaseUnityPlugin)this).Config); SettingsHelper.RegisterModSettings("me.ytarame.Multiplayer", "Multiplayer", (Color?)Color.red, ((BaseUnityPlugin)this).Config, (Action<SettingsBuilder>)delegate(SettingsBuilder builder) { builder.Label("<b>TRANSPARENT NANOS</b> - and related settings"); builder.Toggle("Transparent Nanos", Settings.Transparent, (Action<bool>)null); builder.Slider("Transparent Opacity", Settings.TransparentAlpha, (VisualType)1, new string[3] { "35%", "50%", "85%" }); builder.Spacer(); builder.Label("<b>MISCELLANEOUS</b> - other settings"); builder.Slider("No Repeats in Challenge", Settings.NoRepeat, (VisualType)1, new string[5] { "0 Rounds", "1 Round", "2 Rounds", "3 Rounds", "Infinite" }); builder.Toggle("Chat Enabled", Settings.Chat, (Action<bool>)null); builder.Toggle("Linked Health Hit Popup", Settings.Linked, (Action<bool>)null); builder.Toggle("Allow hidden workshop levels", Settings.AllowNonPublicLevels, (Action<bool>)null); }); Logger.LogFatal((object)"Multiplayer has loaded!"); } } internal static class Settings { public static ConfigEntry<int> WarpSfx { get; private set; } public static ConfigEntry<int> HitSfx { get; private set; } public static ConfigEntry<bool> Transparent { get; private set; } public static ConfigEntry<int> TransparentAlpha { get; private set; } public static ConfigEntry<int> NoRepeat { get; private set; } public static ConfigEntry<bool> Chat { get; private set; } public static ConfigEntry<bool> Linked { get; private set; } public static ConfigEntry<bool> AllowNonPublicLevels { get; private set; } public static ConfigEntry<int> Score { get; private set; } internal static void Initialize(ConfigFile config) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_0121: Expected O, but got Unknown if (WarpSfx == null) { WarpSfx = config.Bind<int>(new ConfigDefinition("General", "Player Warp SFX"), 1, (ConfigDescription)null); HitSfx = config.Bind<int>(new ConfigDefinition("General", "Player Hit SFX"), 0, (ConfigDescription)null); Transparent = config.Bind<bool>(new ConfigDefinition("General", "Transparent Nanos"), true, (ConfigDescription)null); TransparentAlpha = config.Bind<int>(new ConfigDefinition("General", "Transparent Alpha"), 0, (ConfigDescription)null); NoRepeat = config.Bind<int>(new ConfigDefinition("General", "No Repeat"), 0, (ConfigDescription)null); Chat = config.Bind<bool>(new ConfigDefinition("General", "Chat Enabled"), true, (ConfigDescription)null); Linked = config.Bind<bool>(new ConfigDefinition("General", "Linked Health Popup"), true, (ConfigDescription)null); AllowNonPublicLevels = config.Bind<bool>(new ConfigDefinition("General", "Allow Private Levels"), false, (ConfigDescription)null); Score = config.Bind<int>(new ConfigDefinition("General", "Score"), 0, new ConfigDescription("I know you're thinking about it, dont do it... be legitimate...", (AcceptableValueBase)null, Array.Empty<object>())); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "PAMultiplayer"; public const string PLUGIN_NAME = "PAMultiplayer"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace PAMultiplayer.Patch { [HarmonyPatch(typeof(DebugController))] public static class DebugControllerPatch { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void PostAwake(DebugController __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown DebugCommand item = new DebugCommand("Kill_All", "Kills all players (multiplayer mod, any)", (Action)delegate { if (GlobalsManager.IsMultiplayer) { if (GlobalsManager.IsHosting) { __instance.AddLog("Is host, Killing all players."); int index = 0; if (DataManager.inst.GetSettingEnum("ArcadeHealthMod", 0) <= 1) { index = SingletonBase<GameManager>.Inst.currentCheckpointIndex; } RewindHandler.CallRpc_Multi_RewindToCheckpoint(index); } else { __instance.AddLog("Is client, Killing self only."); if (GlobalsManager.LocalPlayerObj.IsValidPlayer()) { GlobalsManager.LocalPlayerObj.Health = 1; GlobalsManager.LocalPlayerObj.PlayerHit(); } } return; } __instance.AddLog("Killing All Players."); foreach (VGPlayerData player in SingletonBase<VGPlayerManager>.Inst.players) { if (player.PlayerObject.IsValidPlayer()) { player.PlayerObject.Health = 1; player.PlayerObject.PlayerHit(); } } }); __instance.CommandList.Add(item); DebugCommand item2 = new DebugCommand("Force_Disconnect", "Disconnects you from the lobby (multiplayer mod, any)", (Action)delegate { __instance.AddLog("Attempting to disconnect from the lobby."); GlobalsManager.LocalPlayerObjectId = 0; SteamManager.Inst.EndServer(); SteamManager.Inst.EndClient(); GlobalsManager.Players.Clear(); }); __instance.CommandList.Add(item2); Action<string> action = delegate(string message) { __instance.OnToggleDebug(); if (!GlobalsManager.IsMultiplayer) { __instance.AddLog("Not currently in a lobby."); } else { __instance.AddLog("Sending message: [" + message + "]"); if (message.Length > 25) { __instance.AddLog("Message is longer than 25 characters. Cutting message."); message = message.Substring(0, 25); } ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SendChatString(message); } }; DebugCommand<string> item3 = new DebugCommand<string>("chat", "Makes your Nano say something. (multiplayer mod, any)", "string(message)", action); __instance.CommandList.Add(item3); DebugCommand<string> item4 = new DebugCommand<string>("c", "Same as Chat (multiplayer mod, any)", "string(message)", action); __instance.CommandList.Add(item4); DebugCommand<string> item5 = new DebugCommand<string>("add_queue", "Adds a level to the queue, the level has to be downloaded. (multiplayer mod, host)", "string(level_id)", (Action<string>)delegate(string levelId) { if (GlobalsManager.IsMultiplayer && !GlobalsManager.IsHosting) { __instance.AddLog("You're not the host."); } else if (Object.op_Implicit((Object)(object)SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(levelId.ToString()))) { GlobalsManager.Queue.Add(levelId); __instance.AddLog("Adding level with id [" + levelId + "] to queue."); List<string> list = new List<string> { ((Object)SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel).name }; foreach (string item12 in GlobalsManager.Queue) { VGLevel localCustomLevel = SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(item12); list.Add(localCustomLevel.TrackName); } ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetData("LevelQueue", JsonConvert.SerializeObject((object)list)); } else { __instance.AddLog("Level with id [" + levelId + "] wasn't found downloaded."); } }); __instance.CommandList.Add(item5); DebugCommand item6 = new DebugCommand("toggle_transparency", "toggles Transparent Nanos. (multiplayer mod, any)", (Action)delegate { if (!GlobalsManager.IsMultiplayer) { __instance.AddLog("Not in multiplayer, not toggling transparency."); } else { bool flag2 = !Settings.Transparent.Value; Settings.Transparent.Value = flag2; foreach (VGPlayerData player2 in SingletonBase<VGPlayerManager>.Inst.players) { if (player2.PlayerObject.IsValidPlayer() && !player2.PlayerObject.IsLocalPlayer()) { foreach (PlayerTrailReference item13 in player2.PlayerObject.Player_Trail.Trail) { ((Renderer)item13.Render_Trail).enabled = flag2; } } } __instance.AddLog($"Toggle Transparency to [{flag2}]."); } }); __instance.CommandList.Add(item6); DebugCommand item7 = new DebugCommand("toggle_linked", "Toggles the modifier Linked Health. (multiplayer mod, host)", (Action)delegate { bool flag = !DataManager.inst.GetSettingBool("mp_linkedHealth", false); DataManager.inst.UpdateSettingBool("mp_linkedHealth", flag); if (GlobalsManager.IsMultiplayer) { ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetData("LinkedMod", flag.ToString()); } __instance.AddLog($"Toggle Linked Health to [{flag}]."); }); __instance.CommandList.Add(item7); DebugCommand item8 = new DebugCommand("player_list", "shows all player ids. (multiplayer mod, any)", (Action)delegate { if (!GlobalsManager.IsMultiplayer) { __instance.AddLog("Not in multiplayer."); return; } __instance.AddLog("Showing all players."); if (GlobalsManager.IsHosting) { foreach (KeyValuePair<ulong, int> item14 in PaMNetworkManager.PamInstance.SteamIdToNetId) { __instance.AddLog($"ID [{item14.Value}], Name [{GlobalsManager.Players[item14.Key].Name}]"); } return; } foreach (KeyValuePair<ulong, PlayerData> player3 in GlobalsManager.Players) { __instance.AddLog(player3.Value.Name); } }); __instance.CommandList.Add(item8); DebugCommand<int> item9 = new DebugCommand<int>("kick", "attempts to kick a player from the lobby. (multiplayer mod, host)", "int(player_id)", (Action<int>)delegate(int playerId) { if (!GlobalsManager.IsMultiplayer || !GlobalsManager.IsHosting) { __instance.AddLog("Not in multiplayer or not the host. not kicking player."); } else { ((NetworkManager)PaMNetworkManager.PamInstance).KickClient(playerId); __instance.AddLog("Attempting to kick player from server."); } }); __instance.CommandList.Add(item9); DebugCommand<string> item10 = new DebugCommand<string>("set_Lobby_Privacy", "set the lobby privacy setting. (multiplayer mod, host)", "bool(private)", (Action<string>)delegate(string isPrivateStr) { if (!bool.TryParse(isPrivateStr.ToLower(), out var result)) { __instance.AddLog("Invalid parameter, pass \"true\" or \"false\"."); } else if (!GlobalsManager.IsMultiplayer || !GlobalsManager.IsHosting) { __instance.AddLog("Not in multiplayer or not the host."); } else if (result) { ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetFriendsOnly(); __instance.AddLog("Lobby was made private."); } else { ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetPublic(); __instance.AddLog("Lobby was made public."); } }); __instance.CommandList.Add(item10); DebugCommand<int> item11 = new DebugCommand<int>("set_lobby_size", "attempts to change the lobby size. (multiplayer mod, host) | 1 - 4 players. | 2 - 8 players. | 3 - 12 players. | 4 - 16 players.", "int(player_count)", (Action<int>)delegate(int playerCount) { if (!GlobalsManager.IsMultiplayer || !GlobalsManager.IsHosting) { __instance.AddLog("Not in multiplayer or not the host."); } else { playerCount = Mathf.Clamp(playerCount * 4, 4, 16); if (((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).MemberCount < playerCount) { __instance.AddLog("Tried to set lobby size to less than the lobby player count."); } else { ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).MaxMembers = playerCount; LobbyCreationManager.Instance.PlayerCount = playerCount; __instance.AddLog($"Set lobby max players to [{playerCount}]"); } } }); __instance.CommandList.Add(item11); } [HarmonyPatch("HandleInput")] [HarmonyPrefix] private static void PreHandleInput(ref string _input) { if (_input.Length >= 5 && _input.ToLower().Substring(0, 5) == "chat ") { _input = "chat " + _input.Substring(5).Replace(' ', '_'); } if (_input.Length >= 2 && _input.ToLower().Substring(0, 2) == "c ") { _input = "c " + _input.Substring(2).Replace(' ', '_'); } } } [HarmonyPatch(typeof(DiscordManager))] public static class DiscordManagerPatch { [HarmonyPatch("Awake")] [HarmonyPrefix] private static void stopPresence(DiscordManager __instance) { JsonConvert.DefaultSettings = null; ((Component)__instance).gameObject.AddComponent<MultiplayerDiscordManager>(); Object.Destroy((Object)(object)__instance); } } [HarmonyPatch(typeof(GameManager))] public class GameManagerPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__0_0; public static UnityAction <>9__0_1; public static Func<Task> <>9__0_2; public static Func<Task> <>9__0_3; public static Func<Task> <>9__0_4; public static Func<bool> <>9__11_0; public static Func<bool> <>9__11_1; public static Func<bool> <>9__11_2; public static Func<Task> <>9__11_3; public static Func<bool> <>9__11_4; public static Func<Task> <>9__11_5; public static Func<Task> <>9__11_7; public static Func<bool> <>9__11_8; public static Comparison<Checkpoint> <>9__11_6; internal void <PostStart>b__0_0() { GlobalsManager.IsReloadingLobby = true; } internal void <PostStart>b__0_1() { SingletonBase<PauseUIManager>.Inst.CloseUI(); GlobalsManager.IsReloadingLobby = true; if (GlobalsManager.IsMultiplayer) { SteamLobbyManager.Inst.UnloadAll(); } if (GlobalsManager.IsChallenge) { if (GlobalsManager.IsMultiplayer && GlobalsManager.IsHosting) { CallRpc_Multi_OpenChallenge(); } SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Challenge"); } else { string text = GlobalsManager.Queue[0]; SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel = SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(text); GlobalsManager.LevelId = text; SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Arcade_Level"); PAM.Logger.LogInfo((object)"Skipping to next level in queue!"); } } internal async Task <PostStart>b__0_2() { while (!SteamLobbyManager.Inst.InLobby) { PAM.Logger.LogError((object)"waiting"); await Task.Delay(100); } } internal async Task <PostStart>b__0_3() { while (PaMNetworkManager.PamInstance == null || !NetworkManager.Instance.TransportActive) { await Task.Delay(100); } } internal async Task <PostStart>b__0_4() { while (!GlobalsManager.HasLoadedAllInfo) { await Task.Delay(100); } } internal bool <CustomLoadGame>b__11_0() { return SteamLobbyManager.Inst.InLobby; } internal bool <CustomLoadGame>b__11_1() { return NetworkManager.Instance.TransportActive; } internal bool <CustomLoadGame>b__11_2() { return GlobalsManager.HasLoadedAllInfo; } internal async Task <CustomLoadGame>b__11_3() { while (GlobalsManager.LobbyState == SteamLobbyManager.LobbyState.Challenge) { await Task.Delay(100); } } internal bool <CustomLoadGame>b__11_4() { return GlobalsManager.LobbyState != SteamLobbyManager.LobbyState.Challenge; } internal async Task <CustomLoadGame>b__11_5() { while (!GlobalsManager.HasLoadedLobbyInfo) { await Task.Delay(100); } } internal async Task <CustomLoadGame>b__11_7() { while (GlobalsManager.IsDownloading) { await Task.Delay(100); } } internal bool <CustomLoadGame>b__11_8() { return !GlobalsManager.IsDownloading; } internal int <CustomLoadGame>b__11_6(Checkpoint x, Checkpoint y) { return x.time.CompareTo(y.time); } } [CompilerGenerated] private sealed class <CustomLoadGame>d__11 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public VGLevel _level; private GameManager <gm>5__1; private Comparison<Checkpoint> <comparision>5__2; private VGLevel <levelTest>5__3; private Task<Item> <item>5__4; private Item <result>5__5; private VGLevel <vgLevel>5__6; private bool <skipLevel>5__7; private ulong <nextQueueId>5__8; private Task<Item?> <result>5__9; private Item? <levelItem>5__10; private bool <allowHiddenLevel>5__11; private string <id>5__12; private List<string> <levelNames>5__13; private List<string>.Enumerator <>s__14; private string <id>5__15; private VGLevel <level>5__16; private int <seed>5__17; private Exception <e>5__18; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CustomLoadGame>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) <gm>5__1 = null; <comparision>5__2 = null; <levelTest>5__3 = null; <item>5__4 = null; <result>5__5 = default(Item); <vgLevel>5__6 = null; <result>5__9 = null; <levelItem>5__10 = null; <id>5__12 = null; <levelNames>5__13 = null; <>s__14 = default(List<string>.Enumerator); <id>5__15 = null; <level>5__16 = null; <e>5__18 = null; <>1__state = -2; } private bool MoveNext() { //IL_040c: 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_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Expected O, but got Unknown //IL_05f1: 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_060e: Expected O, but got Unknown //IL_0bc6: Unknown result type (might be due to invalid IL or missing references) //IL_0bcb: Unknown result type (might be due to invalid IL or missing references) //IL_0bd2: Unknown result type (might be due to invalid IL or missing references) //IL_0bde: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_0755: Unknown result type (might be due to invalid IL or missing references) //IL_075f: Expected O, but got Unknown //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_0671: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Invalid comparison between Unknown and I4 //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Expected O, but got Unknown //IL_0689: Unknown result type (might be due to invalid IL or missing references) //IL_068e: Unknown result type (might be due to invalid IL or missing references) //IL_06a6: Unknown result type (might be due to invalid IL or missing references) //IL_06ab: Unknown result type (might be due to invalid IL or missing references) //IL_06bc: Unknown result type (might be due to invalid IL or missing references) //IL_06c1: Unknown result type (might be due to invalid IL or missing references) PublishedFileId id; switch (<>1__state) { default: return false; case 0: <>1__state = -1; <gm>5__1 = SingletonBase<GameManager>.Inst; <gm>5__1.LoadTimer = new Stopwatch(); <gm>5__1.LoadTimer.Start(); if (!GlobalsManager.IsReloadingLobby) { if (GlobalsManager.IsHosting) { SteamLobbyManager.Inst.CreateLobby(); <>2__current = (object)new WaitUntil((Func<bool>)(() => SteamLobbyManager.Inst.InLobby)); <>1__state = 1; return true; } SteamManager.Inst.StartClient(((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).Owner.Id); <>2__current = (object)new WaitUntil((Func<bool>)(() => NetworkManager.Instance.TransportActive)); <>1__state = 2; return true; } goto IL_02ef; case 1: <>1__state = -1; GlobalsManager.HasLoadedLobbyInfo = true; ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetData("LobbyState", ((ushort)0).ToString()); goto IL_02ef; case 2: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => GlobalsManager.HasLoadedAllInfo)); <>1__state = 3; return true; case 3: <>1__state = -1; if (GlobalsManager.LobbyState == SteamLobbyManager.LobbyState.Challenge) { ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetMemberData("IsLoaded", "1"); SingletonBase<SceneLoader>.Inst.manager.AddToLoadingTasks("Challenge Level Vote", Task.Run(async delegate { while (GlobalsManager.LobbyState == SteamLobbyManager.LobbyState.Challenge) { await Task.Delay(100); } }), (string)null, (string)null, (Func<string>)null); <>2__current = (object)new WaitUntil((Func<bool>)(() => GlobalsManager.LobbyState != SteamLobbyManager.LobbyState.Challenge)); <>1__state = 4; return true; } if (GlobalsManager.LobbyState == SteamLobbyManager.LobbyState.Playing) { GlobalsManager.HasLoadedLobbyInfo = false; GlobalsManager.JoinedMidLevel = true; SingletonBase<SceneLoader>.Inst.manager.AddToLoadingTasks("Lobby State", Task.Run(async delegate { while (!GlobalsManager.HasLoadedLobbyInfo) { await Task.Delay(100); } }), (string)null, (string)null, (Func<string>)null); } else { GlobalsManager.JoinedMidLevel = false; } goto IL_02ef; case 4: <>1__state = -1; return false; case 5: <>1__state = -1; if (SteamWorkshopFacepunch.inst.isLoadingLevels) { goto IL_02fe; } goto IL_0359; case 6: { <>1__state = -1; <result>5__5 = <item>5__4.Result; if (((Item)(ref <result>5__5)).Id == PublishedFileId.op_Implicit(0uL)) { return false; } <vgLevel>5__6 = ScriptableObject.CreateInstance<VGLevel>(); <vgLevel>5__6.InitArcadeData(((Item)(ref <result>5__5)).Directory); InitSteamInfo(ref <vgLevel>5__6, ((Item)(ref <result>5__5)).Id, ((Item)(ref <result>5__5)).Directory, <result>5__5); SingletonBase<ArcadeLevelDataManager>.Inst.ArcadeLevels.Add(<vgLevel>5__6); GameManager obj2 = <gm>5__1; FileManager inst2 = FileManager.inst; id = ((Item)(ref <result>5__5)).Id; <>2__current = ((MonoBehaviour)obj2).StartCoroutine(inst2.LoadAlbumArt(((object)(PublishedFileId)(ref id)).ToString(), ((Item)(ref <result>5__5)).Directory)); <>1__state = 7; return true; } case 7: { <>1__state = -1; GameManager obj = <gm>5__1; FileManager inst = FileManager.inst; id = ((Item)(ref <result>5__5)).Id; <>2__current = ((MonoBehaviour)obj).StartCoroutine(inst.LoadMusic(((object)(PublishedFileId)(ref id)).ToString(), ((Item)(ref <result>5__5)).Directory)); <>1__state = 8; return true; } case 8: <>1__state = -1; _level = <vgLevel>5__6; SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel = <vgLevel>5__6; <item>5__4 = null; <result>5__5 = default(Item); <vgLevel>5__6 = null; goto IL_056d; case 9: <>1__state = -1; if (GlobalsManager.IsHosting) { <skipLevel>5__7 = true; if (ulong.TryParse(GlobalsManager.LevelId, out <nextQueueId>5__8)) { <result>5__9 = SteamUGC.QueryFileAsync(PublishedFileId.op_Implicit(<nextQueueId>5__8)); goto IL_0620; } goto IL_070e; } if (int.TryParse(((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).GetData("seed"), out <seed>5__17)) { SteamLobbyManager.Inst.RandSeed = <seed>5__17; } RNGSync.Seed = SteamLobbyManager.Inst.RandSeed; ObjectManager.inst.seed = SteamLobbyManager.Inst.RandSeed; goto IL_0a41; case 10: <>1__state = -1; goto IL_0620; case 11: <>1__state = -1; if (GlobalsManager.IsChallenge) { CallRpc_Multi_OpenChallenge(); SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Challenge"); } else { GlobalsManager.Queue.Remove(GlobalsManager.LevelId); if (GlobalsManager.Queue.Count == 0) { SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Arcade"); SteamManager.Inst.EndServer(); return false; } <id>5__12 = GlobalsManager.Queue[0]; SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel = SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(<id>5__12); GlobalsManager.LevelId = <id>5__12; <id>5__12 = null; } SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Arcade_Level"); return false; case 12: <>1__state = -1; <>2__current = ((MonoBehaviour)<gm>5__1).StartCoroutine(<gm>5__1.LoadObjects(_level)); <>1__state = 13; return true; case 13: <>1__state = -1; <>2__current = ((MonoBehaviour)<gm>5__1).StartCoroutine(<gm>5__1.LoadTweens()); <>1__state = 14; return true; case 14: { <>1__state = -1; <comparision>5__2 = (Checkpoint x, Checkpoint y) => x.time.CompareTo(y.time); DataManager.inst.gameData.beatmapData.checkpoints.Sort(<comparision>5__2); if (SingletonBase<VGPlayerManager>.Inst.players.Count == 0) { SingletonBase<VGPlayerManager>.Inst.players.Add(new VGPlayerData { PlayerID = 0, ControllerID = 0 }); } <gm>5__1.PlayGame(); return false; } IL_06fa: <result>5__9 = null; <levelItem>5__10 = null; goto IL_070e; IL_02ef: if (GlobalsManager.IsDownloading) { goto IL_02fe; } goto IL_0575; IL_070e: if (<skipLevel>5__7) { PAM.Logger.LogError((object)"tried playing local or non public level while [Allow hidden levels] is disabled"); GlobalsManager.IsReloadingLobby = true; SteamLobbyManager.Inst.UnloadAll(); SingletonBase<SceneLoader>.Inst.manager.ClearLoadingTasks(); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 11; return true; } PAM.Logger.LogError((object)Random.seed.ToString()); SteamLobbyManager.Inst.RandSeed = Random.seed; ObjectManager.inst.seed = Random.seed; RNGSync.Seed = SteamLobbyManager.Inst.RandSeed; if (GlobalsManager.IsReloadingLobby) { ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetData("LevelId", GlobalsManager.LevelId); ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetData("seed", SteamLobbyManager.Inst.RandSeed.ToString()); ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetData("LobbyState", ((ushort)0).ToString()); if (!GlobalsManager.IsChallenge) { <levelNames>5__13 = new List<string>(); <>s__14 = GlobalsManager.Queue.GetEnumerator(); try { while (<>s__14.MoveNext()) { <id>5__15 = <>s__14.Current; <level>5__16 = SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(<id>5__15); <levelNames>5__13.Add(<level>5__16.TrackName); <level>5__16 = null; <id>5__15 = null; } } finally { ((IDisposable)<>s__14).Dispose(); } <>s__14 = default(List<string>.Enumerator); ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetData("LevelQueue", JsonConvert.SerializeObject((object)<levelNames>5__13)); <levelNames>5__13 = null; } PAM.Logger.LogError((object)SteamLobbyManager.Inst.RandSeed); CallRpc_Multi_NextQueueLevel(<nextQueueId>5__8, SteamLobbyManager.Inst.RandSeed); } goto IL_0a41; IL_02fe: <levelTest>5__3 = SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(GlobalsManager.LevelId); if (Object.op_Implicit((Object)(object)<levelTest>5__3)) { goto IL_0359; } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 5; return true; IL_056d: <levelTest>5__3 = null; goto IL_0575; IL_0a41: try { <gm>5__1.LoadData(_level); } catch (Exception ex) { <e>5__18 = ex; PAM.Logger.LogFatal((object)"LEVEL FAILED TO LOAD, going back to menu"); PAM.Logger.LogDebug((object)<e>5__18); GlobalsManager.IsReloadingLobby = false; if (!GlobalsManager.IsHosting) { SteamManager.Inst.EndClient(); } SingletonBase<SceneLoader>.Inst.manager.ClearLoadingTasks(); SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Menu"); return false; } <>2__current = ((MonoBehaviour)<gm>5__1).StartCoroutine(<gm>5__1.LoadBackgrounds(_level)); <>1__state = 12; return true; IL_0620: if (!<result>5__9.IsCompleted) { <>2__current = (object)new WaitForUpdate(); <>1__state = 10; return true; } <levelItem>5__10 = <result>5__9.Result; <allowHiddenLevel>5__11 = Settings.AllowNonPublicLevels.Value; if (<levelItem>5__10.HasValue) { Item value = <levelItem>5__10.Value; if ((int)((Item)(ref value)).Result == 1) { value = <levelItem>5__10.Value; if (((Item)(ref value)).IsPublic | <allowHiddenLevel>5__11) { goto IL_06d9; } value = <levelItem>5__10.Value; if (!((Item)(ref value)).IsFriendsOnly) { value = <levelItem>5__10.Value; if (!((Item)(ref value)).IsPrivate) { goto IL_06d9; } } goto IL_06fa; } } if (<allowHiddenLevel>5__11) { <skipLevel>5__7 = false; } goto IL_06fa; IL_0359: if (Object.op_Implicit((Object)(object)<levelTest>5__3)) { GlobalsManager.IsDownloading = false; _level = <levelTest>5__3; goto IL_056d; } SingletonBase<SceneLoader>.Inst.manager.AddToLoadingTasks("Downloading Level", Task.Run(async delegate { while (GlobalsManager.IsDownloading) { await Task.Delay(100); } }), (string)null, (string)null, (Func<string>)null); <item>5__4 = DownloadLevel(); <>2__current = (object)new WaitUntil((Func<bool>)(() => !GlobalsManager.IsDownloading)); <>1__state = 6; return true; IL_0575: <gm>5__1.LoadMetadata(_level); <>2__current = ((MonoBehaviour)<gm>5__1).StartCoroutine(<gm>5__1.LoadAudio(_level)); <>1__state = 9; return true; IL_06d9: <skipLevel>5__7 = false; goto IL_06fa; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <FetchExternalData>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private UnityWebRequest <webRequest>5__1; private JSONNode <nameColors>5__2; private Dictionary<ulong, string> <newColors>5__3; private Enumerator <>s__4; private KeyValuePair<string, JSONNode> <playerColor>5__5; private ulong <id>5__6; private string <color>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FetchExternalData>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) <webRequest>5__1 = null; <nameColors>5__2 = null; <newColors>5__3 = null; <>s__4 = default(Enumerator); <playerColor>5__5 = default(KeyValuePair<string, JSONNode>); <color>5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <webRequest>5__1 = UnityWebRequest.Get("https://raw.githubusercontent.com/aiden-ytarame/PAMultiplayer/master/ColoredNames.json"); <>2__current = <webRequest>5__1.SendWebRequest(); <>1__state = 1; return true; case 1: <>1__state = -1; if ((int)<webRequest>5__1.result != 1) { PAM.Logger.LogError((object)"Failed to fetch external data :("); return false; } <nameColors>5__2 = JSON.Parse(<webRequest>5__1.downloadHandler.text); <newColors>5__3 = new Dictionary<ulong, string>(); <>s__4 = <nameColors>5__2.GetEnumerator(); while (((Enumerator)(ref <>s__4)).MoveNext()) { <playerColor>5__5 = ((Enumerator)(ref <>s__4)).Current; if (ulong.TryParse(<playerColor>5__5.Key, out <id>5__6)) { <color>5__7 = JSONNode.op_Implicit(<playerColor>5__5.Value["color"]); if (<color>5__7 != null) { PAM.Logger.LogInfo((object)("Loaded custom color for " + <playerColor>5__5.Value["name"].Value)); <newColors>5__3.Add(<id>5__6, <color>5__7); } <color>5__7 = null; <playerColor>5__5 = default(KeyValuePair<string, JSONNode>); } } <>s__4 = default(Enumerator); LobbyScreenManager.SpecialColors = <newColors>5__3; GlobalsManager.HasLoadedExternalInfo = true; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <NextQueueLevelIEnu>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ulong levelID; public int seed; private VGLevel <level>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <NextQueueLevelIEnu>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <level>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; SingletonBase<SceneLoader>.Inst.manager.ClearLoadingTasks(); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; <level>5__1 = SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(GlobalsManager.LevelId); if (Object.op_Implicit((Object)(object)<level>5__1)) { SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel = <level>5__1; SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Arcade_Level"); return false; } GlobalsManager.IsDownloading = true; PAM.Logger.LogError((object)"You did not have the lobby's level downloaded!, Downloading Level..."); SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Arcade_Level"); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static bool paused; [HarmonyPatch("Start")] [HarmonyPostfix] private static void PostStart(ref GameManager __instance) { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown if (!__instance.IsArcade) { return; } Transform val = ((Component)SingletonBase<PauseUIManager>.Inst).transform.Find("Pause Menu"); Transform val2 = val.Find("Restart"); Transform val3 = val.Find("Skip Queue Level"); if (!Object.op_Implicit((Object)(object)val3)) { val3 = Object.Instantiate<Transform>(val2, val); ((Object)val3).name = "Skip Queue Level"; val3.SetSiblingIndex(2); SingletonBase<UIStateManager>.Inst.RefreshTextCache(((Component)val3.Find("Title Wrapper/Title")).GetComponent<TextMeshProUGUI>(), "Skip Level"); SingletonBase<UIStateManager>.Inst.RefreshTextCache(((Component)val3.Find("Content/Text")).GetComponent<TextMeshProUGUI>(), "Skips the current level in queue"); ((SerializableDictionary<string, UIView>)(object)SingletonBase<PauseUIManager>.Inst.PauseMenu.AllViews)["main"].Elements.Add((UIElement)(object)((Component)val3).GetComponent<UI_Button>()); ButtonClickedEvent onClick = ((Button)((Component)val2).GetComponent<MultiElementButton>()).onClick; object obj = <>c.<>9__0_0; if (obj == null) { UnityAction val4 = delegate { GlobalsManager.IsReloadingLobby = true; }; <>c.<>9__0_0 = val4; obj = (object)val4; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } MultiElementButton component = ((Component)val3).GetComponent<MultiElementButton>(); ((Button)component).onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick2 = ((Button)component).onClick; object obj2 = <>c.<>9__0_1; if (obj2 == null) { UnityAction val5 = delegate { SingletonBase<PauseUIManager>.Inst.CloseUI(); GlobalsManager.IsReloadingLobby = true; if (GlobalsManager.IsMultiplayer) { SteamLobbyManager.Inst.UnloadAll(); } if (GlobalsManager.IsChallenge) { if (GlobalsManager.IsMultiplayer && GlobalsManager.IsHosting) { CallRpc_Multi_OpenChallenge(); } SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Challenge"); } else { string text = GlobalsManager.Queue[0]; SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel = SingletonBase<ArcadeLevelDataManager>.Inst.GetLocalCustomLevel(text); GlobalsManager.LevelId = text; SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Arcade_Level"); PAM.Logger.LogInfo((object)"Skipping to next level in queue!"); } }; <>c.<>9__0_1 = val5; obj2 = (object)val5; } ((UnityEvent)onClick2).AddListener((UnityAction)obj2); ((Component)val3).gameObject.SetActive(GlobalsManager.Queue.Count >= 2 || GlobalsManager.IsChallenge); ((Component)__instance).gameObject.AddComponent<PointsManager>(); if (!GlobalsManager.IsMultiplayer) { ((Component)val2).gameObject.SetActive(true); return; } ((Component)val2).gameObject.SetActive(false); if ((Object)(object)Player_Patch.CircleMesh == (Object)null) { Mesh[] array = Resources.FindObjectsOfTypeAll<Mesh>(); foreach (Mesh val6 in array) { if (((Object)val6).name == "circle") { Player_Patch.CircleMesh = val6; } if (((Object)val6).name == "full_arrow") { Player_Patch.ArrowMesh = val6; } if (((Object)val6).name == "triangle") { Player_Patch.TriangleMesh = val6; } } } ((Component)__instance).gameObject.AddComponent<NetworkManager>(); ((MonoBehaviour)__instance).StartCoroutine(FetchExternalData()); if (GlobalsManager.IsHosting) { SingletonBase<SceneLoader>.Inst.manager.AddToLoadingTasks("Creating Lobby", Task.Run(async delegate { while (!SteamLobbyManager.Inst.InLobby) { PAM.Logger.LogError((object)"waiting"); await Task.Delay(100); } }), (string)null, (string)null, (Func<string>)null); return; } SingletonBase<SceneLoader>.Inst.manager.AddToLoadingTasks("Connecting to Server", Task.Run(async delegate { while (PaMNetworkManager.PamInstance == null || !NetworkManager.Instance.TransportActive) { await Task.Delay(100); } }), (string)null, (string)null, (Func<string>)null); SingletonBase<SceneLoader>.Inst.manager.AddToLoadingTasks("Server Info", Task.Run(async delegate { while (!GlobalsManager.HasLoadedAllInfo) { await Task.Delay(100); } }), (string)null, (string)null, (Func<string>)null); ((Component)val3).gameObject.SetActive(false); } [HarmonyPatch("OnDestroy")] [HarmonyPostfix] private static void PostDestroy() { for (int i = 0; i < SingletonBase<CameraDB>.Inst.CameraParentedRoot.childCount; i++) { Object.Destroy((Object)(object)((Component)SingletonBase<CameraDB>.Inst.CameraParentedRoot.GetChild(i)).gameObject); } if (!GlobalsManager.IsReloadingLobby) { GlobalsManager.IsChallenge = false; GlobalsManager.IsMultiplayer = false; } } [IteratorStateMachine(typeof(<FetchExternalData>d__2))] private static IEnumerator FetchExternalData() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FetchExternalData>d__2(0); } [HarmonyPatch("Pause")] [HarmonyPrefix] private static bool PrePause(ref GameManager __instance, bool _showUI) { if (!GlobalsManager.IsMultiplayer) { return true; } if (!GlobalsManager.HasStarted) { return true; } if (paused) { __instance.UnPause(); paused = false; return false; } __instance.Paused = false; paused = true; return false; } [HarmonyPatch("UnPause")] [HarmonyPostfix] private static void PostUnPause() { if (GlobalsManager.IsMultiplayer) { paused = false; } } [HarmonyPatch("OnDestroy")] [HarmonyPostfix] private static void PostOnDestroy() { if (MultiplayerDiscordManager.IsInitialized) { MultiplayerDiscordManager.Instance.SetMenuPresence(); } } [HarmonyPatch("PlayGame")] [HarmonyPostfix] private static void PostPlay(GameManager __instance) { //IL_01a0: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) GlobalsManager.IsReloadingLobby = false; GlobalsManager.Queue.Remove(GlobalsManager.LevelId); if (!GlobalsManager.IsMultiplayer) { if (MultiplayerDiscordManager.IsInitialized) { if (SingletonBase<GameManager>.Inst.IsEditor) { MultiplayerDiscordManager.Instance.SetLevelPresence("Editing " + SingletonBase<GameManager>.Inst.TrackName, "", "palogo"); } else if (!__instance.IsArcade) { MultiplayerDiscordManager.Instance.SetLevelPresence("Playing Story Mode!", SingletonBase<GameManager>.Inst.TrackName + " by " + SingletonBase<GameManager>.Inst.ArtistName, "palogo"); } else { setupLevelPresence("Playing Singleplayer!"); } } return; } if (GlobalsManager.LobbyState != SteamLobbyManager.LobbyState.Playing) { __instance.Pause(false); __instance.Paused = true; ((Component)__instance).gameObject.AddComponent<LobbyScreenManager>(); } else { __instance.Pause(false); __instance.Paused = true; GlobalsManager.HasStarted = true; } EventManager.inst.HasJiggle = false; foreach (VGPlayerData player in SingletonBase<VGPlayerManager>.Inst.players) { VGPlayer playerObject = player.PlayerObject; if (playerObject != null) { playerObject.PlayerDeath(0f); } } SingletonBase<VGPlayerManager>.Inst.players.Clear(); if (GlobalsManager.IsHosting) { if (GlobalsManager.Players.Count == 0) { VGPlayerData val = new VGPlayerData { PlayerID = 0, ControllerID = 0 }; SingletonBase<VGPlayerManager>.Inst.players.Add(val); GlobalsManager.Players.TryAdd(SteamId.op_Implicit(GlobalsManager.LocalPlayerId), new PlayerData(val, SteamClient.Name)); } else { foreach (KeyValuePair<ulong, PlayerData> player2 in GlobalsManager.Players) { SingletonBase<VGPlayerManager>.Inst.players.Add(player2.Value.VGPlayerData); } } ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetMemberData("IsLoaded", "1"); } else { if (NetworkManager.Instance == null) { SingletonBase<SceneLoader>.Inst.manager.ClearLoadingTasks(); SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Menu"); return; } ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetMemberData("IsLoaded", "1"); foreach (KeyValuePair<ulong, PlayerData> player3 in GlobalsManager.Players) { SingletonBase<VGPlayerManager>.Inst.players.Add(player3.Value.VGPlayerData); } if (GlobalsManager.LobbyState != SteamLobbyManager.LobbyState.Playing) { GlobalsManager.HasLoadedLobbyInfo = true; SingletonBase<VGPlayerManager>.Inst.RespawnPlayers(); } else { CallRpc_Server_RequestLobbyState(); } } if (MultiplayerDiscordManager.IsInitialized) { setupLevelPresence("Playing Multiplayer!"); } static async void setupLevelPresence(string state) { if (Object.op_Implicit((Object)(object)SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel)) { Item? val2; Item value; if (SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel.SteamInfo != null) { val2 = await SteamUGC.QueryFileAsync(SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel.SteamInfo.ItemID); } else { value = default(Item); val2 = value; } Item? item = val2; string levelCover = "null_level"; int num; if (item.HasValue) { value = item.Value; num = (((int)((Item)(ref value)).Result == 1) ? 1 : 0); } else { num = 0; } if (num != 0) { value = item.Value; levelCover = ((Item)(ref value)).PreviewImageUrl; } MultiplayerDiscordManager.Instance.SetLevelPresence(state, SingletonBase<GameManager>.Inst.TrackName + " by " + SingletonBase<GameManager>.Inst.ArtistName, levelCover); } } } [ServerRpc(/*Could not decode attribute arguments.*/)] private static async void Server_RequestLobbyState(ClientNetworkConnection conn) { try { LevelEndScreen endScreen = Object.FindFirstObjectByType<LevelEndScreen>(); if (!Object.op_Implicit((Object)(object)endScreen)) { return; } while ((int)SingletonBase<GameManager>.Inst.CurGameState == 2) { await Task.Delay(200); } List<ulong> playerIds = new List<ulong>(); List<short> healths = new List<short>(); foreach (KeyValuePair<ulong, PlayerData> playerDataPair in GlobalsManager.Players) { playerIds.Add(playerDataPair.Key); if (Object.op_Implicit((Object)(object)playerDataPair.Value.VGPlayerData.PlayerObject)) { healths.Add((short)playerDataPair.Value.VGPlayerData.PlayerObject.Health); } else { healths.Add(0); } } CallRpc_Client_LobbyState(conn, endScreen.Hits.Count, SingletonBase<GameManager>.Inst.CurrentSongTime, playerIds, healths.ToArray()); if (conn.TryGetSteamId(out var id)) { CallRpc_Multi_LatePlayerJoin(id); } } catch (Exception ex) { Exception e = ex; PAM.Logger.LogError((object)e); } } [ClientRpc(/*Could not decode attribute arguments.*/)] private static void Client_LobbyState(int hitCount, float currentTime, List<ulong> playerIds, Span<short> healths) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) ActionMoment item = default(ActionMoment); item.position = Vector3.zero; item.time = currentTime; LevelEndScreen val = Object.FindFirstObjectByType<LevelEndScreen>(); if (!Object.op_Implicit((Object)(object)val)) { return; } for (int i = 0; i < hitCount; i++) { val.Hits.Add(item); } if (GlobalsManager.HasLoadedLobbyInfo) { return; } GlobalsManager.HasLoadedLobbyInfo = true; SingletonBase<GameManager>.Inst.UnPause(); SingletonBase<AudioManager>.Inst.CurrentAudioSource.time = currentTime; SingletonBase<VGPlayerManager>.inst.RespawnPlayers(); for (int j = 0; j < playerIds.Count; j++) { ulong key = playerIds[j]; short num = healths[j]; if (GlobalsManager.Players.TryGetValue(key, out var value)) { value.VGPlayerData.PlayerObject.Health = num; if (num <= 0) { Object.Destroy((Object)(object)value.VGPlayerData.PlayerObject); } } } } [MultiRpc(/*Could not decode attribute arguments.*/)] private static void Multi_LatePlayerJoin(SteamId playerId) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!SingletonBase<VGPlayerManager>.Inst.players.Contains(GlobalsManager.Players[SteamId.op_Implicit(playerId)].VGPlayerData)) { SingletonBase<VGPlayerManager>.Inst.players.Add(GlobalsManager.Players[SteamId.op_Implicit(playerId)].VGPlayerData); } } [IteratorStateMachine(typeof(<CustomLoadGame>d__11))] private static IEnumerator CustomLoadGame(VGLevel _level) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CustomLoadGame>d__11(0) { _level = _level }; } [MultiRpc(/*Could not decode attribute arguments.*/)] private static void Multi_NextQueueLevel(ulong levelID, int seed) { if (!GlobalsManager.IsHosting) { PAM.Logger.LogInfo((object)$"New random seed : {seed}"); GlobalsManager.LevelId = levelID.ToString(); SteamLobbyManager.Inst.RandSeed = seed; GlobalsManager.IsReloadingLobby = true; GlobalsManager.LobbyState = SteamLobbyManager.LobbyState.Lobby; GlobalsManager.HasLoadedLobbyInfo = true; ((MonoBehaviour)DataManager.inst).StartCoroutine(NextQueueLevelIEnu(levelID, seed)); } } [IteratorStateMachine(typeof(<NextQueueLevelIEnu>d__13))] private static IEnumerator NextQueueLevelIEnu(ulong levelID, int seed) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <NextQueueLevelIEnu>d__13(0) { levelID = levelID, seed = seed }; } [MultiRpc(/*Could not decode attribute arguments.*/)] public static void Multi_OpenChallenge() { if (!GlobalsManager.IsHosting) { ((Lobby)(ref SteamLobbyManager.Inst.CurrentLobby)).SetMemberData("IsLoaded", "0"); GlobalsManager.IsReloadingLobby = true; GlobalsManager.HasLoadedLobbyInfo = true; SingletonBase<SceneLoader>.Inst.manager.ClearLoadingTasks(); SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Challenge"); } } private static void InitSteamInfo(ref VGLevel _level, PublishedFileId _id, string _folder, Item _item) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_002d: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown if (!string.IsNullOrEmpty(_folder)) { LevelDataBase val = new LevelDataBase { LevelID = ((object)(PublishedFileId)(ref _id)).ToString(), LocalFolder = _folder }; ((Object)_level).name = _id.Value.ToString(); _level.LevelData = val; _level.BaseLevelData = val; _level.SteamInfo = new SteamData { ItemID = _id }; } } private static async Task<Item> DownloadLevel() { if (!ulong.TryParse(GlobalsManager.LevelId, out var id)) { FailLoad("Invalid level ID to download"); return default(Item); } Item? item = await SteamUGC.QueryFileAsync(PublishedFileId.op_Implicit(id)); if (!item.HasValue) { FailLoad("Level not found, is it deleted from the workshop?"); return default(Item); } Item level = item.Value; if (AppId.op_Implicit(((Item)(ref level)).ConsumerApp) != 440310) { FailLoad("Workshop item is not from PA"); return default(Item); } ManualLogSource logger = PAM.Logger; string[] obj = new string[5] { "Downloading [", ((Item)(ref level)).Title, "] created by [", null, null }; Friend owner = ((Item)(ref level)).Owner; obj[3] = ((Friend)(ref owner)).Name; obj[4] = "]"; logger.LogInfo((object)string.Concat(obj)); if (string.IsNullOrEmpty(((Item)(ref level)).Directory)) { await ((Item)(ref level)).Subscribe(); for (int i = 0; i < 3; i++) { if (await ((Item)(ref level)).DownloadAsync((Action<float>)null, 60, default(CancellationToken))) { break; } PAM.Logger.LogWarning((object)$"Failed to to download level, retrying.. [{i + 1}/3]"); await Task.Delay(1000); } } if (!((Item)(ref level)).IsInstalled) { FailLoad("Failed to download level"); return default(Item); } GlobalsManager.IsDownloading = false; return level; static void FailLoad(string errorMessage) { PAM.Logger.LogError((object)errorMessage); GlobalsManager.IsDownloading = false; SingletonBase<SceneLoader>.Inst.manager.ClearLoadingTasks(); SingletonBase<SceneLoader>.Inst.LoadSceneGroup("Menu"); } } [HarmonyPrefix] [HarmonyPatch("LoadGame")] public static bool OverrideLoadGame(ref IEnumerator __result) { if (!SingletonBase<GameManager>.Inst.IsArcade || !GlobalsManager.IsMultiplayer) { return true; } ((MonoBehaviour)SingletonBase<GameManager>.Inst).StartCoroutine(CustomLoadGame(SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel)); return false; } private static void CallRpc_Server_RequestLobbyState() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Server_RequestLobbyState(NetworkManager.Instance.ServerSelfPeerConnection); return; } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)34247); NetworkManager.Instance.SendToServer(val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Server_RequestLobbyState_34247(ClientNetworkConnection senderConn, NetworkReader reader) { Server_RequestLobbyState(senderConn); } private static void CallRpc_Client_LobbyState(ClientNetworkConnection target, int hitCount, float currentTime, List<ulong> playerIds, Span<short> healths) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer && target == NetworkManager.Instance.ServerSelfPeerConnection) { Client_LobbyState(hitCount, currentTime, playerIds, healths); return; } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)11993); NetWriterExtensions.Write(val, hitCount); NetWriterExtensions.Write(val, currentTime); val.WriteUlongs(playerIds); val.WriteSongData(healths); NetworkManager.Instance.SendToClient(target, val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Client_LobbyState_11993(ClientNetworkConnection senderConn, NetworkReader reader) { Client_LobbyState(NetReaderExtensions.ReadInt32(reader), NetReaderExtensions.ReadSingle(reader), reader.ReadUlongs(), reader.ReadSongData()); } private static void CallRpc_Multi_LatePlayerJoin(SteamId playerId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Multi_LatePlayerJoin(playerId); } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)10245); val.WriteSteamId(playerId); NetworkManager.Instance.SendToAllClients(val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Multi_LatePlayerJoin_10245(ClientNetworkConnection senderConn, NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Multi_LatePlayerJoin(reader.ReadSteamId()); } private static void CallRpc_Multi_NextQueueLevel(ulong levelID, int seed) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Multi_NextQueueLevel(levelID, seed); } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)62198); NetWriterExtensions.Write(val, levelID); NetWriterExtensions.Write(val, seed); NetworkManager.Instance.SendToAllClients(val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Multi_NextQueueLevel_62198(ClientNetworkConnection senderConn, NetworkReader reader) { Multi_NextQueueLevel(NetReaderExtensions.ReadUInt64(reader), NetReaderExtensions.ReadInt32(reader)); } public static void CallRpc_Multi_OpenChallenge() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Multi_OpenChallenge(); } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)65142); NetworkManager.Instance.SendToAllClients(val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Multi_OpenChallenge_65142(ClientNetworkConnection senderConn, NetworkReader reader) { Multi_OpenChallenge(); } } [HarmonyPatch(typeof(ObjectManager))] public static class RNGSync { public static int Seed; [HarmonyPatch("CreateObjectData")] [HarmonyPostfix] public static void PostCreateData(int _i, ref GameObjectRef __result) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (GlobalsManager.IsMultiplayer) { Random.InitState(Seed); __result.sequence.randomState = Random.state; Seed = Random.RandomRangeInt(int.MinValue, int.MaxValue); } } } [HarmonyPatch(typeof(VGPlayer))] public class Player_Patch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static CloseCallDelegate <>9__14_0; public static HitDelegate <>9__14_1; public static DeathDelegate <>9__14_2; internal void <PostSpawn>b__14_0(Vector3 _) { PointsManager.Inst.AddCloseCall(); } internal void <PostSpawn>b__14_1(int _, Vector3 _) { PointsManager.Inst.AddHit(); } internal void <PostSpawn>b__14_2(Vector3 _) { PointsManager.Inst.AddDeath(); } } public static bool IsDamageAll; public static Mesh CircleMesh; public static Mesh ArrowMesh; public static Mesh TriangleMesh; private static float _holdingBoost; [HarmonyPatch("CheckForObjectCollision")] [HarmonyPrefix] private static bool PreCollision(VGPlayer __instance, Collider2D _other, ref bool __result) { if (!GlobalsManager.IsMultiplayer) { return true; } if (!__instance.IsLocalPlayer()) { __result = false; return false; } return true; } [HarmonyPatch("PlayerHit")] [HarmonyPrefix] private static bool Hit_Pre(ref VGPlayer __instance) { //IL_00dc: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) if (!SingletonBase<GameManager>.Inst.IsArcade || SingletonBase<GameManager>.Inst.IsEditor) { return true; } if (SingletonBase<GameManager>.Inst.Paused) { return false; } if (DataManager.inst.GetSettingEnum("ArcadeHealthMod", 0) == 1) { return false; } VGPlayer val = __instance; bool flag = !GlobalsManager.IsMultiplayer || val.IsLocalPlayer(); if (flag) { bool settingBool = DataManager.inst.GetSettingBool("mp_linkedHealth", false); if (GlobalsManager.IsMultiplayer) { if (GlobalsManager.IsHosting) { if (settingBool) { if (!IsDamageAll) { CallRpc_Multi_DamageAll(val.Health, GlobalsManager.LocalPlayerId); return false; } } else { CallRpc_Multi_PlayerDamaged(GlobalsManager.LocalPlayerId, val.Health); } } else if (!settingBool || !IsDamageAll) { CallRpc_Server_PlayerDamaged(val.Health); } IsDamageAll = false; val.Health--; } else { val.Health--; if (settingBool) { foreach (VGPlayerData player in SingletonBase<VGPlayerManager>.Inst.players) { if (player.PlayerObject.IsValidPlayer() && (Object)(object)player.PlayerObject != (Object)(object)__instance && player.PlayerObject.Health > val.Health) { player.PlayerObject.PlayerHit(); } } } } } else { val.Health--; } ((MonoBehaviour)val).StopCoroutine("RegisterCloseCall"); if (EventHelper.GetDeathEvent(val) != null && val.Health <= 0) { EventHelper.GetDeathEvent(val).Invoke(val.Player_Wrapper.position); } else if (EventHelper.GetHitEvent(val) != null) { EventHelper.GetHitEvent(val).Invoke(val.Health, val.Player_Wrapper.position); } if (val.Health > 0) { val.StartHurtDecay(); int value = Settings.WarpSfx.Value; if (value == 0 || (value == 1 && val.IsLocalPlayer())) { SingletonBase<AudioManager>.Inst.ApplyLowPass(0.05f, 0.8f, 1.5f); SingletonBase<AudioManager>.Inst.ApplyLowPassResonance(0f, 0.6f, 0.2f); } int value2 = Settings.HitSfx.Value; if (value2 == 0 || (value2 == 1 && val.IsLocalPlayer())) { SingletonBase<AudioManager>.Inst.PlaySound("HurtPlayer", 0.6f); } if (flag) { val.PlayerHitAnimation(); } else { val.PlayParticles((ParticleTypes)2); } } else { val.PlayerDeath(0.2f); if (flag) { val.PlayerDeathAnimation(); } else { val.PlayParticles((ParticleTypes)3); } } return false; } [ServerRpc(/*Could not decode attribute arguments.*/)] private static void Server_PlayerDamaged(ClientNetworkConnection conn, int healthPreHit) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!conn.TryGetSteamId(out var steamId)) { return; } if (DataManager.inst.GetSettingBool("mp_linkedHealth", false)) { if (GlobalsManager.LocalPlayerObj.Health >= healthPreHit) { CallRpc_Multi_DamageAll(healthPreHit, steamId); } } else { CallRpc_Multi_PlayerDamaged(steamId, healthPreHit); } } [MultiRpc(/*Could not decode attribute arguments.*/)] private static void Multi_PlayerDamaged(SteamId steamID, int healthPreHit) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (healthPreHit == 1) { PointsManager.Inst?.PlayerHasDied(SteamId.op_Implicit(steamID)); } PAM.Logger.LogDebug((object)$"Damaging player {steamID}"); if (!steamID.IsLocalPlayer() && GlobalsManager.Players.TryGetValue(SteamId.op_Implicit(steamID), out var value) && value.VGPlayerData.PlayerObject.IsValidPlayer()) { value.VGPlayerData.PlayerObject.Health = healthPreHit; value.VGPlayerData.PlayerObject.PlayerHit(); } } [MultiRpc(/*Could not decode attribute arguments.*/)] private static void Multi_DamageAll(int healthPreHit, SteamId playerHit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) DamageAll(healthPreHit, SteamId.op_Implicit(playerHit)); } private static void DamageAll(int healthPreHit, ulong hitPlayerId) { if (Settings.Linked.Value && GlobalsManager.Players.TryGetValue(hitPlayerId, out var value)) { string playerColorHex = SingletonBase<VGPlayerManager>.Inst.GetPlayerColorHex(value.VGPlayerData.PlayerID); SingletonBase<VGPlayerManager>.Inst.DisplayNotification("Nano [<color=#" + playerColorHex + ">" + value.Name + "</color>] got hit!", 1f); } foreach (KeyValuePair<ulong, PlayerData> player in GlobalsManager.Players) { VGPlayer playerObject = player.Value.VGPlayerData.PlayerObject; if (!playerObject.IsValidPlayer()) { continue; } if (playerObject.Health < healthPreHit) { PAM.Logger.LogWarning((object)"Old message"); continue; } if (playerObject.IsLocalPlayer()) { IsDamageAll = true; } playerObject.Health = healthPreHit; playerObject.PlayerHit(); } } [HarmonyPatch("HandleBoost")] [HarmonyPrefix] private static bool Boost_Pre(ref VGPlayer __instance) { if (!GlobalsManager.IsMultiplayer) { return true; } return __instance.IsLocalPlayer(); } [HarmonyPatch("PlayParticles")] [HarmonyPrefix] private static bool BoostParticle_Post(ref VGPlayer __instance, ParticleTypes _type) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected I4, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_00df: Unknown result type (might be due to invalid IL or missing references) ParticleSystem val = null; Quaternion rotation = __instance.Player_Wrapper.rotation; Quaternion val2 = Quaternion.Euler(0f, 0f, ((Quaternion)(ref rotation)).eulerAngles.z - 90f); BeatmapTheme val3 = (Object.op_Implicit((Object)(object)SingletonBase<GameManager>.Inst) ? SingletonBase<GameManager>.Inst.LiveTheme : ChallengeManager.Inst.ChallengeTheme); switch ((int)_type) { case 0: { val = Object.Instantiate<ParticleSystem>(__instance.PS_Spawn, __instance.Player_Wrapper.position, val2); MainModule main4 = val.main; ((MainModule)(ref main4)).startColor = new MinMaxGradient(val3.GetPlayerColor(__instance.PlayerID)); break; } case 1: { if (GlobalsManager.IsMultiplayer && __instance.IsLocalPlayer()) { if (GlobalsManager.IsHosting) { CallRpc_Multi_PlayerBoost(GlobalsManager.LocalPlayerId); } else { CallRpc_Server_PlayerBoost(); } } val = Object.Instantiate<ParticleSystem>(__instance.PS_Boost, __instance.Player_Wrapper.position, val2); ((Component)val).transform.SetParent(__instance.Player_Wrapper); MainModule main3 = val.main; ((MainModule)(ref main3)).startColor = new MinMaxGradient(val3.GetPlayerColor(__instance.PlayerID)); break; } case 2: { val = Object.Instantiate<ParticleSystem>(__instance.PS_Hit, __instance.Player_Wrapper.position, val2); MainModule main2 = val.main; ((MainModule)(ref main2)).startColor = new MinMaxGradient(val3.guiAccent); break; } case 3: { val = Object.Instantiate<ParticleSystem>(__instance.PS_Die, __instance.Player_Wrapper.position, val2); MainModule main = val.main; ((MainModule)(ref main)).startColor = new MinMaxGradient(val3.guiAccent); break; } } if (Object.op_Implicit((Object)(object)val)) { val.Play(); ((MonoBehaviour)SystemManager.inst).StartCoroutine(__instance.KillParticleSystem(val)); } return false; } [ServerRpc(/*Could not decode attribute arguments.*/)] public static void Server_PlayerBoost(ClientNetworkConnection conn) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (conn.TryGetSteamId(out var steamId)) { if (GlobalsManager.Players.TryGetValue(SteamId.op_Implicit(steamId), out var value) && Object.op_Implicit((Object)(object)value.VGPlayerData.PlayerObject) && !value.VGPlayerData.PlayerObject.isDead) { value.VGPlayerData.PlayerObject.PlayParticles((ParticleTypes)1); } CallRpc_Multi_PlayerBoost(steamId); } } [MultiRpc(/*Could not decode attribute arguments.*/)] public static void Multi_PlayerBoost(SteamId steamID) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!steamID.IsLocalPlayer() && GlobalsManager.Players.TryGetValue(SteamId.op_Implicit(steamID), out var value) && Object.op_Implicit((Object)(object)value.VGPlayerData.PlayerObject) && !value.VGPlayerData.PlayerObject.isDead) { value.VGPlayerData.PlayerObject.PlayParticles((ParticleTypes)1); } } [HarmonyPatch("Init", new Type[] { })] [HarmonyPostfix] private static void PostSpawn(ref VGPlayer __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0088: 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_0093: Expected O, but got Unknown //IL_021c: 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_0249: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) if (__instance.RPlayer.id == 0 && Object.op_Implicit((Object)(object)PointsManager.Inst)) { VGPlayer obj = __instance; object obj2 = <>c.<>9__14_0; if (obj2 == null) { CloseCallDelegate val = delegate { PointsManager.Inst.AddCloseCall(); }; <>c.<>9__14_0 = val; obj2 = (object)val; } obj.CloseCallEvent += (CloseCallDelegate)obj2; VGPlayer obj3 = __instance; object obj4 = <>c.<>9__14_1; if (obj4 == null) { HitDelegate val2 = delegate { PointsManager.Inst.AddHit(); }; <>c.<>9__14_1 = val2; obj4 = (object)val2; } obj3.HitEvent += (HitDelegate)obj4; VGPlayer obj5 = __instance; object obj6 = <>c.<>9__14_2; if (obj6 == null) { DeathDelegate val3 = delegate { PointsManager.Inst.AddDeath(); }; <>c.<>9__14_2 = val3; obj6 = (object)val3; } obj5.DeathEvent += (DeathDelegate)obj6; _holdingBoost = 0f; } if (!GlobalsManager.IsMultiplayer) { return; } if (Settings.Transparent.Value && !__instance.IsLocalPlayer()) { foreach (PlayerTrailReference item in __instance.Player_Trail.Trail) { ((Renderer)item.Render_Trail).enabled = false; } } if (__instance.PlayerID >= 4) { if (__instance.PlayerID < 8) { SetPlayerMesh(__instance, CircleMesh); } else if (__instance.PlayerID < 12) { SetPlayerMesh(__instance, TriangleMesh); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(0f, 0f, -90f); Transform transform = ((Component)__instance.Player_Wrapper).transform; transform.Find("core").Rotate(val4); transform.Find("zen-marker").Rotate(val4); ((Component)transform).transform.Find("boost").Rotate(val4); } else { SetPlayerMesh(__instance, ArrowMesh); Transform transform2 = ((Component)__instance.Player_Wrapper).transform; Vector3 localScale = default(Vector3); ((Vector3)(ref localScale))..ctor(2f, 2f, 1f); transform2.Find("core").localScale = localScale; transform2.Find("zen-marker").localScale = localScale; ((Component)transform2).transform.Find("boost").localScale = localScale; } } static void SetPlayerMesh(VGPlayer player, Mesh mesh) { Transform child = ((Component)player).transform.GetChild(2); ((Component)child.Find("core")).GetComponent<MeshFilter>().mesh = mesh; ((Component)child.Find("zen-marker")).GetComponent<MeshFilter>().mesh = mesh; ((Component)child.Find("boost")).GetComponent<MeshFilter>().mesh = mesh; } } [HarmonyPatch("SetColor")] [HarmonyPrefix] private static bool PreSetColor(VGPlayer __instance, Color _col, Color _colTail) { //IL_0098: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if (GlobalsManager.IsMultiplayer && Settings.Transparent.Value && !__instance.IsLocalPlayer()) { _colTail.a = (_col.a = Settings.TransparentAlpha.Value switch { 1 => 0.5f, 2 => 0.85f, _ => 0.35f, }); } int num = (Object.op_Implicit((Object)(object)SingletonBase<GameManager>.Inst) ? SingletonBase<GameManager>.Inst.ColorID : ChallengeManager.Inst.ColorID); __instance.Player_Core_Rend.material.SetColor(num, _col); __instance.Player_Boost_Rend.material.SetColor(num, _colTail); foreach (PlayerTrailReference item in __instance.Player_Trail.Trail) { if (item != null) { ((Renderer)item.Render_Mesh).material.color = _colTail; item.Render_Trail.startColor = _colTail; item.Render_Trail.endColor = LSColors.fadeColor(_colTail, 0f); if (Object.op_Implicit((Object)(object)item.ParticleSystem)) { MainModule main = item.ParticleSystem.main; ((MainModule)(ref main)).startColor = new MinMaxGradient(_colTail); } } } return false; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void PostUpate(VGPlayer __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)SingletonBase<GameManager>.Inst) && (int)SingletonBase<GameManager>.Inst.CurGameState == 1 && !__instance.isDead && __instance.RPlayer.id == 0 && Object.op_Implicit((Object)(object)PointsManager.Inst)) { PointsManager.Inst.AddTimeAlive(Time.deltaTime); if (__instance.internalVelocity != Vector2.zero) { PointsManager.Inst.AddTimeMoving(Time.deltaTime); } PointsManager.Inst.AddPosition(((Component)SingletonBase<CameraDB>.Inst.CamerasRoot).transform.InverseTransformPoint(__instance.Player_Wrapper.position)); } } [HarmonyPatch("HandleBoost")] [HarmonyPostfix] private static void PostHandleBoost(VGPlayer __instance) { if (!GlobalsManager.IsMultiplayer || __instance.IsLocalPlayer()) { if (__instance.BoostDuration < _holdingBoost) { PointsManager.Inst?.AddBoost(_holdingBoost); } _holdingBoost = __instance.BoostDuration; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static bool RPlayerGetter(ref VGPlayer __instance, ref Player __result) { if (!GlobalsManager.IsMultiplayer) { return true; } __result = ReInput.players.GetPlayer((!__instance.IsLocalPlayer()) ? 1 : 0); return false; } private static void CallRpc_Server_PlayerDamaged(int healthPreHit) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Server_PlayerDamaged(NetworkManager.Instance.ServerSelfPeerConnection, healthPreHit); return; } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)54552); NetWriterExtensions.Write(val, healthPreHit); NetworkManager.Instance.SendToServer(val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Server_PlayerDamaged_54552(ClientNetworkConnection senderConn, NetworkReader reader) { Server_PlayerDamaged(senderConn, NetReaderExtensions.ReadInt32(reader)); } public static void CallRpc_Server_PlayerBoost() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Server_PlayerBoost(NetworkManager.Instance.ServerSelfPeerConnection); return; } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)59657); NetworkManager.Instance.SendToServer(val.GetData(), (SendType)1); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Server_PlayerBoost_59657(ClientNetworkConnection senderConn, NetworkReader reader) { Server_PlayerBoost(senderConn); } private static void CallRpc_Multi_PlayerDamaged(SteamId steamID, int healthPreHit) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Multi_PlayerDamaged(steamID, healthPreHit); } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)40080); val.WriteSteamId(steamID); NetWriterExtensions.Write(val, healthPreHit); NetworkManager.Instance.SendToAllClients(val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Multi_PlayerDamaged_40080(ClientNetworkConnection senderConn, NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Multi_PlayerDamaged(reader.ReadSteamId(), NetReaderExtensions.ReadInt32(reader)); } private static void CallRpc_Multi_DamageAll(int healthPreHit, SteamId playerHit) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Multi_DamageAll(healthPreHit, playerHit); } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)5034); NetWriterExtensions.Write(val, healthPreHit); val.WriteSteamId(playerHit); NetworkManager.Instance.SendToAllClients(val.GetData(), (SendType)0); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Multi_DamageAll_5034(ClientNetworkConnection senderConn, NetworkReader reader) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) Multi_DamageAll(NetReaderExtensions.ReadInt32(reader), reader.ReadSteamId()); } public static void CallRpc_Multi_PlayerBoost(SteamId steamID) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Instance == null) { return; } if (NetworkManager.Instance.PeerServer) { Multi_PlayerBoost(steamID); } NetworkWriter val = new NetworkWriter(); try { NetWriterExtensions.Write(val, (ushort)29337); val.WriteSteamId(steamID); NetworkManager.Instance.SendToAllClients(val.GetData(), (SendType)1); } finally { ((IDisposable)val)?.Dispose(); } } public static void Deserialize_Multi_PlayerBoost_29337(ClientNetworkConnection senderConn, NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Multi_PlayerBoost(reader.ReadSteamId()); } } [HarmonyPatch(typeof(VGPlayerManager))] public static class PlayerManagerPatch { [HarmonyPatch("OnControllerConnected")] [HarmonyPrefix] private static bool PreConnected(ControllerStatusChangedEventArgs args) { return !GlobalsManager.IsMultiplayer; } [HarmonyPatch("OnControllerDisconnected")] [HarmonyPrefix] private static bool PreDisConnected() { return !GlobalsManager.IsMultiplayer; } [HarmonyPatch("RespawnPlayers")] [HarmonyPrefix] private static void OnCheckpoint(VGPlayerManager __instance) { foreach (VGPlayerData player in __instance.players) { if (player.ControllerID == 0 && player.hasSpawnedObject() && player.PlayerObject.Health == 1) { PointsManager.Inst.AddCheckpointWithOneHealth(); } } } [HarmonyPatch("GetPlayerColorHex")] [HarmonyPostfix] private static void PostGetColorHex(ref string __result) { if (__result == "#ffffff") { __result = "ffffff";