ModernUO/ToAdd/LoginStats.cs

83 lines
No EOL
2.8 KiB
C#

/*********************************
* Author: Anna *
* Fixed and Refactoring: Expa *
* Optimized ModernUO .Net10/C#14 *
**********************************/
using System;
using System.Linq;
using System.Diagnostics;
using Server;
using Server.Mobiles;
using Server.Network;
namespace Server.Misc;
public static class LoginStats
{
static readonly TimeSpan ReadyDelay = TimeSpan.FromSeconds(1);
static readonly TimeSpan InvulDuration = TimeSpan.FromSeconds(10);
const int HuePersonal = 0x35, HueGlobalLoginLogout = 0x3B2, HueDisconnected = 0x22;
const int MaxReadyAttempts = 10;
public static void Initialize()
{
EventSink.Connected += OnConnected;
EventSink.BeforeDisconnected += OnBeforeDisconnected;
EventSink.Logout += OnDisconnect;
EventSink.Disconnected += OnDisconnect;
Trace.WriteLine("[LoginStats] initialized.");
}
static void OnConnected(Mobile m)
{
if (m is PlayerMobile pm && pm.AccessLevel == AccessLevel.Player)
Timer.StartTimer(ReadyDelay, () => HandleLogin(pm, 0));
}
static void OnBeforeDisconnected(Mobile m)
{
if (m is PlayerMobile pm)
try { pm.NetState?.Disconnect("Connection lost"); } catch { }
}
static void OnDisconnect(Mobile m)
{
if (m is PlayerMobile pm)
{
World.Broadcast(HueDisconnected, false, $"{pm.Name} has disconnected.");
Trace.WriteLine($"[LoginStats] Disconnected: {pm.Name}");
}
}
static void HandleLogin(PlayerMobile pm, int attempt)
{
if (pm == null || pm.Deleted) return;
if ((pm.NetState == null || pm.SessionStart == default) && attempt < MaxReadyAttempts)
{
Timer.StartTimer(ReadyDelay, () => HandleLogin(pm, attempt + 1)); return;
}
if (pm.NetState == null || pm.SessionStart == default) return;
var gt = pm.GameTime;
if (gt.TotalDays > 10000) gt = TimeSpan.Zero;
pm.SendMessage(HuePersonal, $"Welcome back {pm.Name}! Total play time: {FormatPlaytime(gt)}");
Timer.StartTimer(TimeSpan.FromMilliseconds(500), () =>
{
if (pm == null || pm.Deleted) return;
var text = $"{pm.Name} has logged in.";
foreach (var ns in NetState.Instances.ToArray())
{
var mob = ns?.Mobile;
if (mob == null || mob == pm) continue;
try { mob.SendMessage(HueGlobalLoginLogout, text); } catch { }
}
});
pm.Hidden = true; pm.Blessed = true;
Timer.StartTimer(InvulDuration, () => { if (pm != null && !pm.Deleted) { pm.Hidden = false; pm.Blessed = false; } });
Trace.WriteLine($"[LoginStats] Login: {pm.Name}");
}
static string FormatPlaytime(TimeSpan ts) => $"{ts.Days}d {ts.Hours}h {ts.Minutes}m";
}