using System;
using System.Diagnostics;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PlayerCounter")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Simply just counts how much players are playing the MBLCP modpack")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+00bab9c65c5cf5f92832a514cdf153706f27f530")]
[assembly: AssemblyProduct("PlayerCounter")]
[assembly: AssemblyTitle("PlayerCounter")]
[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.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 PlayerCounter
{
[BepInPlugin("com.seeya.mblcp.playercounter", "Player Counter", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance { get; private set; }
internal static ManualLogSource Log { get; private set; }
private void Awake()
{
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"Initializing Player Counter");
HeartbeatHost.EnsureExists();
Log.LogInfo((object)"Player Counter is loaded!");
}
public static string LoadOrCreatePlayerId()
{
string text = PlayerPrefs.GetString("MBLCP_PlayerId", string.Empty);
if (string.IsNullOrEmpty(text))
{
text = SystemInfo.deviceUniqueIdentifier;
PlayerPrefs.SetString("MBLCP_PlayerId", text);
PlayerPrefs.Save();
Log.LogDebug((object)"Generated new player ID");
}
return text;
}
}
public class HeartbeatHost : MonoBehaviour
{
private static HeartbeatHost? _instance;
private static readonly HttpClient Http = new HttpClient();
private const string ApiUrl = "https://mblcp-player-tracker-still-snow-8423.fly.dev/heartbeat";
private const int IntervalMs = 30000;
private Timer? _timer;
private string _playerId = string.Empty;
private int _isSending = 0;
public static void EnsureExists()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if (!((Object)(object)_instance != (Object)null))
{
GameObject val = new GameObject("MBLCP_HeartbeatHost");
((Object)val).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)val);
_instance = val.AddComponent<HeartbeatHost>();
}
}
private void Awake()
{
if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
else
{
_instance = this;
}
}
private void Start()
{
_playerId = Plugin.LoadOrCreatePlayerId();
Plugin.Log.LogDebug((object)("Player ID: " + _playerId));
_timer = new Timer(async delegate
{
await SendHeartbeat();
}, null, 0, 30000);
Application.quitting += OnAppQuitting;
}
private async Task SendHeartbeat()
{
Plugin.Log.LogDebug((object)"Ping sent to server");
if (Interlocked.Exchange(ref _isSending, 1) == 1)
{
Plugin.Log.LogDebug((object)"Heartbeat already in progress, skipping");
return;
}
try
{
string jsonData = "{\"modpack\":\"MBLCP\"}";
using StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://mblcp-player-tracker-still-snow-8423.fly.dev/heartbeat")
{
Content = content
};
request.Headers.Add("X-Player-ID", _playerId);
using HttpResponseMessage response = await Http.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
string body = await response.Content.ReadAsStringAsync();
Plugin.Log.LogDebug((object)$"Server returned {(int)response.StatusCode}: {body}");
return;
}
string result = await response.Content.ReadAsStringAsync();
Plugin.Log.LogDebug((object)("Heartbeat successful: " + result));
}
catch (HttpRequestException ex2)
{
HttpRequestException httpEx = ex2;
Plugin.Log.LogDebug((object)("Network error: " + httpEx.Message));
}
catch (TaskCanceledException)
{
Plugin.Log.LogDebug((object)"Heartbeat timed out");
}
catch (Exception ex4)
{
Exception ex = ex4;
Plugin.Log.LogDebug((object)("Error: " + ex.GetType().Name + " - " + ex.Message));
}
finally
{
Interlocked.Exchange(ref _isSending, 0);
}
}
private void OnAppQuitting()
{
DisposeTimer();
}
private void OnDestroy()
{
Plugin.Log.LogInfo((object)"Heartbeat host destroyed, disposing timer");
DisposeTimer();
Application.quitting -= OnAppQuitting;
}
private void DisposeTimer()
{
try
{
_timer?.Dispose();
}
catch
{
}
_timer = null;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.seeya.mblcp.playercounter";
public const string PLUGIN_NAME = "Player Counter";
public const string PLUGIN_VERSION = "1.0.0";
}
}