Commit graph

142 commits

Author SHA1 Message Date
Kamron Batman
1f0acddc46
fix: Fixes serialization threading, moves world save to end of loop, and eliminates Parallel.ForEach. (#1530) 2023-10-03 00:42:49 -07:00
Kamron Batman
e0225c6e59
fix: Adds generic entity persistence support and BOBEntry as entities (#1527)
### Summary
Adds a generic entity persistence. This can be used to create new entity types that have a `Serial`.

Here is an example:

```cs
public class BOBEntries : GenericEntitySerialization<IBOBEntry>
{
    public static void Configure()
    {
        Configure("BOBEntries");
    }
}
```

The annotation tells the system what folder to serialize the entries to. The class/interface (`IBOBEntry`) is the root type that implements `ISerializable`.
2023-10-01 17:38:52 -07:00
Kamron Batman
a4cabe2fa4
fix: Optimizes FindItemsByType by removing allocations. (#1515)
### Summary
Container enumeration is in dire need of optimization. Thanks to @stefanomerotta for initiating this work with PR #1443. This PR handles a small part of what Stefan started. Also included are some bug fixes.

### Method Signatures

```cs
// Use with foreach without moving/deleting items
FindItemsByTypeEnumerator<T> FindItemsByType<T>(bool recurse = true, Predicate<T> predicate = null)

// Use with foreach when moving/deleting items
QueuedItemsEnumerator<T> EnumerateItemsByType<T>(bool recurse = true, Predicate<T> predicate = null)

// Use when iterating multiple times or queuing
PooledRefQueue<T> QueueItemsByType<T>(bool recurse = true, Predicate<T> predicate = null)

// Use when iterating multiples times or manipulating elements without traversing
PooledRefList<T> ListItemsByType<T>(bool recurse = true, Predicate<T> predicate = null)
```

* `FindItemsByType<T>` has changed from returning `List<T>` to `FindItemsByTypeEnumerator<T>` - This method is not safe to use in situations where an item may get consumed, deleted, or moved.

* `EnumerateItemsByType<T>` was added as a safe way to iterate and manipulate items.
  * **Note**: EnumerateItemsByType will _completely traverse the container_ before iteration starts because it uses `QueueItemsByType` under the hood.

* `QueueItemsByType<T>`  and `ListItemsByType<T>` was added to return a queue or list of items to iterate multiple times and manipulate the items. This isn't the most efficient since it uses a predicate and can result in 2 or 3 total iterations unnecessarily.

### Bug Fixes
- [X] Fishing had an error in the random check that may have caused slight bias.
2023-09-28 19:36:45 -07:00
Kamron Batman
146abad36e
feat: Adds a movement throttle system. Removes Fastwalk system. (#1511)
### Summary

- Removes Fastwalk system
  - Removed the following settings:
    - `movement.enableFastWalkPrevention`
    - `movement.fastwalkExemptionLevel`
- Adds movement throttle system.
  - Adds the following settings:
    - `movement.throttleReset` - Default value is `1000` (1 second).
    - `movement.throttleThreshold` - Default value is `400` (400ms).

### Movement Throttling

This new system will trigger if a player requests 400ms (configurable) worth of movements quicker than wall clock time. When this happens, the player is throttled (all incoming packets to the server are halted) until wall clock time catches up with the requests. Upon each throttle, the player receives enough credit to handle up to 400ms of "lag" as a grace/catch-up.


### Developer Notes
We use two throttle queues to prevent an infinite loop.
2023-09-27 20:53:22 -07:00
Kamron Batman
2a3e048b86
fix: Fixes more packet initializations (#1507) 2023-09-19 00:02:17 -07:00
Kamron Batman
0f2870e94a
feat: Adds Stamina System to overhaul overweight. (#1465)
## Overhaul to Stamina (Overweight) System

### Added configurations

```json
{
  "settings": {
    "stamina.enableMountStamina": "True",
    "stamina.cannotMoveWhenFatigued": "True",
    "stamina.stonesPerOverweightLoss": "25",
    "stamina.stonesOverweightAllowance": "4",
    "stamina.baseOverweightLoss": "5",
    "stamina.additionalLossWhenBelow": "0.1",
    "stamina.mountLastMoveStepsReset": "01:00:00:00",
    "stamina.enableMountStamina": "True",
    "stamina.useMountStaminaOnlyWhenOverloaded": "False",
  },
}
```
- `stamina.cannotMoveWhenFatigued` - By default, Pre-AOS expansions will outright block a player if they are fatigued. A player is fatigued when they run out of stamina by any mechanism.
- `stamina.stonesPerOverweightLoss` - The amount of stamina lost for every X stones above overweight. Example, if a person is overweight 28 stones overweight, then there there is 1 additional stamina. 28 / 25 = 1 (no decimals, no rounding)
- `stamina.stonesOverweightAllowance` - The number of stones allowed before overweight penalties take affect. This _does not_ substract from the overweight stones calculation.
- `stamina.baseOverweightLoss` - The base amount of stamina loss for being overweight. While running, the final amount is multiplied by 2. If mount stamina is turned off, then the final amount is divided by 3 while mounted. 

### Mount stamina

Mounts have a new property `StepsMax` to determine the maximum steps they can take before being fatigued. To regain steps, the player _must stay on the mount and not move_ (per OSI). The gain rates are configurable. If a mount is dismounted, or the player logs off, the mount is considered inactive and mounts regain all of their steps after _24 hours_.

### Changes to player stamina

Players now have a proper inactivity time reset for their steps. If a player is idle for 16 seconds (including logging off, or the server being offline), then the steps counter is rest.

### Developer Notes

- `StepsTaken` - This field has been removed. It was not serialized and could not be used reliably. If a developer was using it, then the recommendation is to build a mechanism to track total steps another way.
- `IHasStamina` - This new interface was added and currently `IMount` and `PlayerMobile` are valid types.

Important: Entities that are sent to the StaminaSystem for tracking (mounts, players, or something else), must be an `ISerializable` to be serialized properly. If they are not, then the serialization system will record a null, and nothing will be deserialized upon world load. No errors will be given.
2023-09-16 17:52:54 -07:00
Kamron Batman
cd5fddd8d1
fix: Fixes stat mod having no owner (#1463) 2023-08-17 22:01:44 -07:00
Kamron Batman
455b11de9c
fix: Updates schema generator to 2.6.4 (#1452) 2023-08-11 00:09:56 -07:00
Kamron Batman
8389bfacfe
chore: Updates copyright (#1448) 2023-08-09 09:09:26 -07:00
mdodkins
a9a2a89908
feat: Customize expansion and set maps on first boot (#1425) 2023-07-31 20:46:49 -07:00
Kamron Batman
51ecee6caa
fix: Overhauls champion titles & codegen champion system (#1430)
## MAJOR CHANGE

Added a champion title system to facilitate the existing champion titles. This should make it easier to extend or create other related game content. Champion titles will be saved in a folder called _ChampionTitles_.

### Motivation

The motivation to refactor was two-folder, but mostly related to performance in two ways.
First, every player had a ChampionTitleInfo object with an array of ChamptionTitleInfo. We want to eliminate the need for this information unless a player actually uses it. This should save a considerable amount of memory.

Second, to facilitate the atrophy mechanic, the champion titles would run atrophy post-world save, adding to the time that the server is frozen. Eliminating this post-world save side effect unlocks our ability to further optimize the world save process since there are no direct side effects.


### Bugs fixed

- [X] Fixed titles getting cut off on the paperdoll
- [X] Fixed champion title not displaying overhead (OPL)

### Screenshots
<img width="216" alt="image" src="https://github.com/modernuo/ModernUO/assets/3953314/8916f895-8d68-4fb0-892e-108a0c43be90">
2023-07-27 21:44:06 -07:00
Kamron Batman
f77dd91811
fix: Overhauls virtue system (#1376)
## MAJOR CHANGE (API BREAKING)

Moved the virtues to it's own system _VirtueSystem_. This should make it easier to extend or remove the virtue system. Virtues will be saved to a new folder called _Virtues_.

### Motivation

The motivation was also two-fold, performance/stability, and to fix bugs.

First, virtues is the second system (first is murders), that has a pre-world-save check on _every mobile in the game_ to atrophy virtue stats. This is taxing since it freexes the world and makes world saves take longer. Every mobile had Gain/Loss dates for each virtue, whether they needed them or not. Most players don't even use the virtue system, so this will increase performance considerably.

Second, when I tried to optimize/refactor the code, I found several bugs that needed to be fixed.

### Major API Changes

- [X] The properties on players related to virtues are gone. Use `pm.GetVirtues()?.<PropertyName>` instead.
- [X] Virtues were removed from non-player Mobiles.
- [X] `pm.JusticeProtectors` was removed. Use `JusticeVirtue.GetProtector()` or `JusticeVirtue.GetProtected()` instead.

### Screenshots

<img width="221" alt="Props-1" src="https://github.com/modernuo/ModernUO/assets/3953314/5c09cb83-b8d5-44a2-b899-a7ed7cd736ac">
<img width="220" alt="props-2" src="https://github.com/modernuo/ModernUO/assets/3953314/aeade4d3-8df0-47bd-955a-a864d0946cf7">
2023-07-19 21:43:47 -07:00
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
Kamron Batman
3b97e8d39c
fix: Fixes stabled, abilities targeting self, and unsummon memory leak (#1418)
## **MAJOR CHANGE**
* `Stabled` has been moved to `PlayerMobile`.
* New methods added, `PlayerMobile.AddStabled` and `PlayerMobile.RemoveStabled`.
* Added `PlayerMobile.AddFollower` and `PlayerMobile.RemoveFollower`.
* `Stabled`, `AutoStabled`, and `AllFollowers` are now `HashSet` and **_CAN BE NULL_**.

### Summary
* Fixes monster abilities causing harm to the monster through reflect
* Adds `CanTriggerAgainstSelf` to override this for healing or some other self-affecting ability
* Fixes a major memory leak where `UnsummonTimer` from animated dead spell lasts up-to 24hrs and therefore holds onto references of dead/deleted mobs.
* Fixes another minor leak where a mob is not unregistered from the animated dead spell list until the next spell cast.
2023-07-03 09:45:22 -07:00
Kamron Batman
4242c446c8
fix: Creates an override for disabling cast paralyze (#1398) 2023-04-28 20:44:30 -07:00
mark1145
55dc4a7da5
fix: Fixes casting by sending ParalyzeFlag to client while animating (#1397) 2023-04-27 23:12:07 -07:00
Kamron Batman
fea7aef95f
fix: Fixes NPE with setting stats in-game (#1390) 2023-04-13 23:43:09 -07:00
Kamron Batman
57ff488d51
fix: Removes run flag from NPC movement (#1357) 2023-03-02 10:58:17 -08:00
Kamron Batman
bfb987c758
fix: Fixes client crash while selling items to NPC (#1296) 2022-12-05 20:16:31 -08:00
Mink80
f82f61b4c5
fix: Fixes old version not being passed properly to OnRegionChange (#1295) 2022-12-05 17:11:51 -08:00
Fabrizio
537526a328
fix: Update LabelTo, SendMessage, etc to Interpolated Strings (#1283) 2022-11-28 19:58:12 -08:00
Kamron Batman
ff79d3db40
fix: Fixes NPE from AddStatMod (#1252) 2022-11-15 15:53:41 -08:00
Kamron Batman
03fb36c869
fix: Adds ISpanParsable and fixes command conditionals (#1241)
* Adds `ISpanParsable<T>`
* Removes `[Parsable]`
* Fixes querying by serial, body, and a few others.
* Adds `Parse` to `Rectangle3D`
* Fixes AutoArchive NPE


Closes #1209
2022-11-12 00:26:02 -08:00
Kamron Batman
6426996f29
chore: Code Cleanup (#1239) 2022-11-10 22:49:25 -08:00
Kamron Batman
59dcd24bed
fix: Fixes DeltaQueue recursion, StatMod bug, and memory leak (#1233)
* Fixes recursion with DeltaQueue causing multiple sets of packets to be sent to the client.
* Fixes StatMods that are expired not being checked properly.
* Adds a timer to properly expire/remove stat mods instead of relying on a side-effect.
2022-11-08 09:08:05 -08:00
Kamron Batman
fd6f4239e2
fix: Adds FindItemOnLayer generic (#1223) 2022-11-01 00:49:20 -07:00
mark1145
053dbcbad0
fix: Fixes ignoring mobs, champions, party crash, slayer rarity, boat speedhack, etc (#1222)
* Movie ignore mobiles to Mobile class
* Allow necromancer familiars to ignore mobiles
* ChampionSpawn should not quietly fail when creating new spawn
* Fix client party crash bug: 2 people partied, the leader logs out, other client is hung
* Fix spellbooks creating with magery/meditation only and creating magery multiple times
* Fix BaseRunicTool.GetRandomSlayer() creating more undead slayers than intended
* Do not allow players to dismount each other whilst mounted
* Fix AOS onwards damage increase tooltip and wrong formula in AOS
* Fix monsters killing other monster revenants + animate dead should not attack player pets + other animates
* Fix fire steed having loot pack added twice
* Fix oaks spawn not able to create Unicorns + Kirins via Activator.CreateInstace() due to constructor having name as parametr
* Fix ignoreMobiles flag not propagated to client for non-players.
* Fix harrower tents not leeching from players
* Fix boats speedhacking around the map
* Fix bless, agility etc. not renewing duration
* Fix reveal always worked
* Fix empty constructor for steeds so they don't throw now.
2022-10-31 22:16:50 -07:00
Kamron Batman
49e6c6f2d1
fix: Adds AfterSerialize support. Removes BeforeSerialize support. (#1208)
### Changes
* Implements an AfterSerialize method that is executed synchronously.
* Removes `BeforeSerialize` support since it was dangerous in its current implementation.
* Moves PlayerMobile kill/virtual decay to AfterSerialize.
* Adds kill decay to after Deserialize.
2022-10-27 23:27:22 -07:00
Kamron Batman
c711e7ab02
fix: Fixes NPE with resistance mods in Mobile (#1199) 2022-10-22 09:11:56 -07:00
Kamron Batman
8479306279
fix: Removes SetTypeRef for generated code. (#1189) 2022-10-15 15:12:49 -07:00
Kamron Batman
ffdc08259f
fix: Adds name support for all mods (#1128) 2022-10-15 10:46:31 -07:00
Kamron Batman
e1e30998ba
fix: Adds ReadType/Write(Type) and improves type referencing (#1172)
## Changes
* Improves type hashing by introducing xxHash3 (64bit)
* Removes individual `tdb` files in favor of a single `SerializedTypes.db` file. This file is only used to identify a type that is being deserialized, which doesn't exist.
* Adds duplicate type alias detection
* Adds `AssemblyHandler.FindTypeByHash`

View changed files whitespaces: https://github.com/modernuo/ModernUO/pull/1172/files?diff=split&w=1

## SerializedTypes.db
The serialized types file is used to get back the original name of a type in case it no longer exists in code. This can easily be necessary if a class is renamed in code and no `TypeAlias` is provided.

### Format
byte[4] - version
byte[4] - count
--array--
byte[8] - xxHash
byte[1] - flag, 0 - null, 1 - not null
byte[n] - Full class name in UTF8

### Example
<img width="472" alt="SerializedTypes_Example" src="https://user-images.githubusercontent.com/3953314/195255429-31d24293-6bd1-419e-811b-07874dd0f78d.png">

## Benchmarks
Serialized 500 Type fields. The 8192bytes comes from the _ConcurrentQueue_ that would later be used for SerializedTypes.
Note that the queue is never cleared, so it's size grew considerably.
```cs
|               Method |     Mean |    Error |   StdDev | Allocated |
|--------------------- |---------:|---------:|---------:|----------:|
|      BenchmarkXXHash | 18.44 us | 0.278 us | 0.260 us |    8192 B |
| BenchmarkTypeStrings | 25.09 us | 0.292 us | 0.259 us |         - |
```

TODO:
* Add support in the Serialization Generator for `ReadType()` and `Write(Type)`
* Remove `SetTypeRef` from Serialization Generator
2022-10-11 22:17:22 -07:00
Kamron Batman
f268d5d4e2
fix: Cleans up core code (#1187)
**Only one functional change**
* Fixes a bug in LogFactory where `Warning` is being logged as `Information`

Non-functional changes:
* Updates/Fixes copyright headers
* Removes namespace scopes for core files.

View with [whitespace off](https://github.com/modernuo/ModernUO/pull/1187/files?w=1).
2022-10-10 21:47:08 -07:00
Kamron Batman
2806e5d4b7
feat: Adds reflect damage ability. Fixes magical barrier (#1184) 2022-10-08 10:39:28 -07:00
Kamron Batman
89815ad4d3
feat: Updates to Serialization Generator v2.2 (#1157)
* Adds `SerializationProperty` - This will generate the private variable for serialization. Also provides an option `useField` to specify your own. Example:
  ```cs
  [SerializationProperty(0, useField: nameof(_resource)]
  ```
2022-09-04 08:45:27 -07:00
mark1145
b8146f26f1
fix: Fixes mobile titles not displaying properly (#1149) 2022-08-27 13:31:22 -07:00
Kamron Batman
fa3515f930
fix: Cleans up some comments and spell code (#1120) 2022-07-16 19:45:41 -07:00
Kamron Batman
38686c09b2
fix: Updates more logging to Serilog (#1105)
Adds more serilog logging and cleans up some server files.
2022-07-01 11:57:08 -07:00
Kamron Batman
cb474712f8
fix: Removes side effect of setting skill mod when changing Owner (#1101)
## Breaking Change!
Setting `mod.Owner` will no longer update a skill mod.
**Please stick to the API and use `mobile.AddSkillMod(mod)` for all situations, including equipping.**


## Fixes
- [X] Fixes memory leak in factions.
- [X] Changes `List<SkillMod>` to `HashSet<SkillMod>`.
- [X] Eliminates skill mods adding/removing twice.
2022-06-30 12:07:08 -07:00
Kamron Batman
414ef8d8d6
fix: Fixes skill mods (#1099) 2022-06-30 08:46:54 -07:00
Kamron Batman
da877f59a7
fix: Fixes possibel NPE with misbehaving Weapon property (#1083) 2022-06-20 16:31:39 -07:00
Kamron Batman
7adf52ef48
fix: Moves mods and fixes migrations for lights (#1080)
- [X] Removes duplicate property for owner.
- [X] Codegens them all (even though they aren't used, just in case someone wants to).
2022-06-18 21:28:51 -07:00
Kamron Batman
41efa69b56
fix: Adds OSI candle/torch functionality, codegens lights (#1075) 2022-06-17 23:26:27 -07:00
Kamron Batman
b779d7737f
fix: Adds ISpanFormattable support to Serial (#1065) 2022-06-14 18:39:46 -07:00
Kamron Batman
4b2b7e2277
fix: Fixes old RunUO bug with skill mod owners (#1064) 2022-06-14 16:44:50 -07:00
Kamron Batman
db20722711
fix: Simplifies OPL (#1051) 2022-06-12 21:27:16 -07:00
Kamron Batman
b74b47159f
fix: Fixes localization corner cases with OPL (#1050)
## Changes
- [X] Adds OPL convenience methods
    - `opl.Add(cliloc, value)` and `opl.Add(value)` - value as an integer or string works just like `opl.Add(cliloc, $"{value}")`
    - `opl.AddLocalized(cliloc, clilocValue)` - works the same as `opl.Add(cliloc, $"#{clilocValue}");`
- [X] Simplifies basic `list.Add()` situations
- [X] Changes cliloc as an argument so it works with custom IPropertyList implementations (HTML)
- [X] Fixes plants so they support the old localization and new (changed in 7.0.12.0+)
- [X] Exposes more methods to override for Item to make creating custom OPL possible.

## Important Notes
* Using a ternary as an argument, like this `opl.Add(number, showType ? $"{type}\t{value}" : $"{value}");` _will not use the correct string interpolation_. This means if you use a custom PropertyList (for HTML or some other purpose), the property list won't be localized properly.
* All localization values must be interpolated, even if they are literal strings, or integers. Example: `opl.Add(number, $"{"Charges"}\t{m_Charges}");` is correct. Using the following: `$"Charges\t{m_Charges}"` will not work for custom PropertyList implementations!
2022-06-12 21:17:42 -07:00
Kamron Batman
6e69d25e33
fix: Fixes structured logging (#1043)
- [X] Fixes various bugs in logging.
2022-06-05 01:00:22 -07:00
Kamron Batman
ecbee17690
fix: Optimizes OPL using string interpolation (#1041)
## Breaking Changes (New API)
ObjectPropertyList supports the following API:
```cs
list.Add(500000);
list.Add(500001, stringArgument);
list.Add("Some text");
list.Add($"Some text with {argument}");
list.Add(500002, $"{arg1}\t{arg2}");
```

## Notes
1. All API uses that require a formatter like this:
    ```cs
    list.Add(500002, "{0}\t{1}", arg1, arg2);
    ```
    Should be changed to use string interpolation, for example:
    ```cs
    list.Add(500002, $"{arg1}\t{arg2}");
    ```
2. The following paradigm should no longer be used:
    ```cs
    list.Add(1061170, prop.ToString()); // strength requirement ~1_val~
    ```
    The new string interpolation API will avoid having to convert the argument to a string before writing it to the packet. Instead use the following:
    ```cs
    list.Add(1061170, $"{prop}"); // strength requirement ~1_val~
    ```

### Benchmarks
```cs
|                         Method |     Mean |   Error |  StdDev |  Gen 0 | Allocated |
|------------------------------- |---------:|--------:|--------:|-------:|----------:|
|                BenchmarkOldOPL | 241.0 ns | 0.56 ns | 0.47 ns | 0.0105 |      88 B |
| BenchmarkStringInterpolatedOPL | 199.9 ns | 2.44 ns | 2.39 ns |      - |         - |
```

### Changes
- [X] Removes crash in STArray.Return when array is null.
- [X] Fixes NPE in OPL when entity is null. Serial in packet will be 0 when entity is null.
- [X] Fixes NPE in AosAttributes when Parent is null.
- [X] Changes OPL to use string interpolation.
- [X] Introduces `IPropertyList` to allow extending PropertyList for other uses.
2022-06-02 10:09:53 -07:00
Kamron Batman
ef883b2872
fix: Fixes socket disconnect on block. Fixes debug logging (#1031) 2022-05-21 20:24:46 -07:00