ModernUO/Projects/Server/Events/EventSink.cs
Kamron Batman 26f784f45d
fix: Overhauls murder system (#1419)
## MAJOR CHANGE (API BREAKING)

Added a player murder system to facilitate reporting murders. This should make it easier to extend to create a bounty system or  other related game content. Player murders will be saved in a folder called _PlayerMurders_.

### Motivation

The motivation was two-fold, performance, and bug fixes.

First, murders are one of two systems that do a pre-world-save check on _every mobile in the game_ to decay kills and set their expiring murders. This is taxing since it freezes the world and makes world saves take longer. Every mobile has ShortTermMurders even though it is a player concept. And next, 90%+ of players are not murderers but had an ever increasing MurderElapse time that was being tracked against GameTime. These properties were also serialized unnecessarily for all mobs.

Second, when I tried to optimize/refactor the code, it was obvious that the system has bugs.

### Major API Changes
- [X] Created a player murder system and moved `ShortTermMurders`, `ShortTermElapse`, and `LongTermElapse` to the system.
- [X] Added convenience property `PlayerMobile.ShortTermMurders`.
- [X] Added convenience properties `PlayerMobile.ShortTermMurderExpiration` and `PlayerMobile.LongTermMurderExpiration`
- [X] Moved ReportMurdererGump.cs
- [X] Adds an `EventSink.PlayerDeleted` event.

### Notes
The system currently does not support NPCs. To support expiring murders on NPCs I highly recommend a different architecture for large servers (500k+ mobs including players). Specifically switching from looping through all MurderContext to a time-order link list.
2023-07-15 22:42:49 -07:00

163 lines
6.9 KiB
C#

/*************************************************************************
* ModernUO *
* Copyright 2019-2022 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: EventSink.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Generic;
using Server.Network;
namespace Server;
public static partial class EventSink
{
public static event Action<Mobile> OpenDoorMacroUsed;
public static void InvokeOpenDoorMacroUsed(Mobile m) => OpenDoorMacroUsed?.Invoke(m);
public static event Action<Mobile> Login;
public static void InvokeLogin(Mobile m) => Login?.Invoke(m);
public static event Action<Mobile, int> HungerChanged;
public static void InvokeHungerChanged(Mobile mobile, int oldValue) => HungerChanged?.Invoke(mobile, oldValue);
public static event Action Shutdown;
public static void InvokeShutdown() => Shutdown?.Invoke();
public static event Action<Mobile> HelpRequest;
public static void InvokeHelpRequest(Mobile m) => HelpRequest?.Invoke(m);
public static event Action<Mobile> DisarmRequest;
public static void InvokeDisarmRequest(Mobile m) => DisarmRequest?.Invoke(m);
public static event Action<Mobile> StunRequest;
public static void InvokeStunRequest(Mobile m) => StunRequest?.Invoke(m);
public static event Action<Mobile, int> OpenSpellbookRequest;
public static void InvokeOpenSpellbookRequest(Mobile m, int type) => OpenSpellbookRequest?.Invoke(m, type);
public static event Action<Mobile, int, Item> CastSpellRequest;
public static void InvokeCastSpellRequest(Mobile m, int spellID, Item book) =>
CastSpellRequest?.Invoke(m, spellID, book);
public static event Action<Mobile, Item, Mobile> BandageTargetRequest;
public static void InvokeBandageTargetRequest(Mobile m, Item bandage, Mobile target) =>
BandageTargetRequest?.Invoke(m, bandage, target);
public static event Action<Mobile, string> AnimateRequest;
public static void InvokeAnimateRequest(Mobile m, string action) => AnimateRequest?.Invoke(m, action);
public static event Action<Mobile> Logout;
public static void InvokeLogout(Mobile m) => Logout?.Invoke(m);
public static event Action<Mobile> Connected;
public static void InvokeConnected(Mobile m) => Connected?.Invoke(m);
public static event Action<Mobile> BeforeDisconnected;
public static void InvokeBeforeDisconnected(Mobile m) => BeforeDisconnected?.Invoke(m);
public static event Action<Mobile> Disconnected;
public static void InvokeDisconnected(Mobile m) => Disconnected?.Invoke(m);
public static event Action<Mobile, Mobile, string> RenameRequest;
public static void InvokeRenameRequest(Mobile from, Mobile target, string name) =>
RenameRequest?.Invoke(from, target, name);
public static event Action<Mobile> PlayerDeath;
public static void InvokePlayerDeath(Mobile m) => PlayerDeath?.Invoke(m);
public static event Action<Mobile, Mobile> VirtueGumpRequest;
public static void InvokeVirtueGumpRequest(Mobile beholder, Mobile beheld) =>
VirtueGumpRequest?.Invoke(beholder, beheld);
public static event Action<Mobile, Mobile, int> VirtueItemRequest;
public static void InvokeVirtueItemRequest(Mobile beholder, Mobile beheld, int gumpID) =>
VirtueItemRequest?.Invoke(beholder, beheld, gumpID);
public static event Action<Mobile, int> VirtueMacroRequest;
public static void InvokeVirtueMacroRequest(Mobile mobile, int virtueID) =>
VirtueMacroRequest?.Invoke(mobile, virtueID);
public static event Action<Mobile, Mobile> PaperdollRequest;
public static void InvokePaperdollRequest(Mobile beholder, Mobile beheld) =>
PaperdollRequest?.Invoke(beholder, beheld);
public static event Action<Mobile, Mobile> ProfileRequest;
public static void InvokeProfileRequest(Mobile beholder, Mobile beheld) => ProfileRequest?.Invoke(beholder, beheld);
public static event Action<Mobile, Mobile, string> ChangeProfileRequest;
public static void InvokeChangeProfileRequest(Mobile beholder, Mobile beheld, string text) =>
ChangeProfileRequest?.Invoke(beholder, beheld, text);
public static event Action<NetState, int> DeleteRequest;
public static void InvokeDeleteRequest(NetState state, int index) => DeleteRequest?.Invoke(state, index);
public static event Action<Mobile> PlayerDeleted;
public static void InvokePlayerDeleted(Mobile m) => PlayerDeleted?.Invoke(m);
public static event Action ServerStarted;
public static void InvokeServerStarted() => ServerStarted?.Invoke();
public static event Action<Mobile> GuildGumpRequest;
public static void InvokeGuildGumpRequest(Mobile m) => GuildGumpRequest?.Invoke(m);
public static event Action<Mobile> QuestGumpRequest;
public static void InvokeQuestGumpRequest(Mobile m) => QuestGumpRequest?.Invoke(m);
public static event Action<NetState, ClientVersion> ClientVersionReceived;
public static void InvokeClientVersionReceived(NetState state, ClientVersion cv) =>
ClientVersionReceived?.Invoke(state, cv);
public static event Action<Mobile, List<Serial>> EquipMacro;
public static void InvokeEquipMacro(Mobile m, List<Serial> list)
{
if (list?.Count > 0)
{
EquipMacro?.Invoke(m, list);
}
}
public static event Action<Mobile, List<Layer>> UnequipMacro;
public static void InvokeUnequipMacro(Mobile m, List<Layer> layers)
{
if (layers?.Count > 0)
{
UnequipMacro?.Invoke(m, layers);
}
}
public static event Action<Mobile, IEntity, int> TargetedSpell;
public static void InvokeTargetedSpell(Mobile m, IEntity target, int spellId) =>
TargetedSpell?.Invoke(m, target, spellId);
public static event Action<Mobile, IEntity, int> TargetedSkillUse;
public static void InvokeTargetedSkillUse(Mobile m, IEntity target, int skillId) =>
TargetedSkillUse?.Invoke(m, target, skillId);
public static event Action<Mobile, Item, short> TargetByResourceMacro;
public static void InvokeTargetByResourceMacro(Mobile m, Item item, short resourceType) =>
TargetByResourceMacro?.Invoke(m, item, resourceType);
}