83 lines
No EOL
2.8 KiB
C#
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";
|
|
} |