Commit graph

2867 commits

Author SHA1 Message Date
Kamron Batman
c1d8606167
fix: Refactors Custom Hairstylist (#2188) 2025-05-17 03:30:07 -07:00
Kamron Batman
31fb68015f
chore: Updates SPONSORS.md 2025-05-15 23:38:36 -07:00
Kamron Batman
e468f79e18
feat: Adds SpecialAttack monster ability trigger. Fixes fanning fire. (#2186) 2025-05-15 22:14:52 -07:00
Kamron Batman
91b2912ee4
fix: Cleans up potential memory leak in monster abilities. (#2185) 2025-05-15 19:42:54 -07:00
Kamron Batman
f2526c82f3
fix: Fixes Freeshard Protocol (UOGateway) support. (#2183) 2025-05-12 12:24:24 -07:00
mdodkins
0f3d984efc
fix: Fixes craft gump non-cliloc label offsets. (#2182) 2025-05-11 18:13:00 -07:00
Kamron Batman
18903ee17b
fix: Fixes props gump for interfaces again (#2180) 2025-05-09 15:44:32 -07:00
Kamron Batman
05825a11e2
fix: Fixes props for interfaces and adds account manipulation (#2179) 2025-05-09 15:39:47 -07:00
Kamron Batman
f95b3a8b3b
fix: Streamlines event scheduler API. Adds months to weekly recurrence (#2178) 2025-05-07 22:42:44 -07:00
Kamron Batman
990e86b983
fix: Fixes guard infinite loop, and streamlines call methods (#2175) 2025-05-06 23:54:13 -07:00
Kamron Batman
f02403a374
feat: Adds yearly calendared events with recurrences (#2177) 2025-05-06 23:52:49 -07:00
Kamron Batman
4beda6a29d
fix: Eliminate intermediate string in typecache (#2176) 2025-05-06 21:04:54 -07:00
Kamron Batman
f0f7d44d4d
fix: Fixes polymorph spell (#2173) 2025-05-04 09:31:32 -07:00
Kamron Batman
da517f56c4
chore: Fixes variable types for possible performance issues (#2172) 2025-05-01 21:54:41 -07:00
Kamron Batman
6d43f2549c
fix: Adjusts spell ranges to match OSI (#2171)
### Summary

Adjusts spell ranges according to OSI. Specifically, the [April 14, 1999 patch](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/1999-2/1999-06-14th-april/) changed spell ranges to 10 tiles, and 15 tiles for fields.
2025-05-01 20:03:56 -07:00
Kamron Batman
5cb97cc6de
fix: Fixes BitArray serialization (#2170)
Fixes serialization/deserialization edge cases with BitArray. If you use BitArray, you will need to migrate.

1. Change the type in the migration JSON file (if there is one) from `BitArray` to `byte[]` for all the versions you need to migrate.
2. Then in the `MigrateFrom`, use the following function to convert the field from a byte[] back to the BitArray.

Example Migration JSON:
```json
    {
      "name": "RestrictedSpells",
      "type": "byte[]",
      "rule": "ArrayMigrationRule",
      "ruleArguments": [
        "byte",
        "PrimitiveTypeMigrationRule",
        ""
      ]
    },
```

Migration function to use in MigrateFrom:
```cs
public static BitArray MigrateBitArray(byte[] data, int bitLength) => new(data) { Length = bitLength };
```

Example use:
```cs
    private void MigrateFrom(V0Content content)
    {
        // ... deserialize
        _restrictedSpells = content.RestrictedSpells.MigrateBitArray(SpellRegistry.Types.Length);
        _restrictedSkills = content.RestrictedSkills.MigrateBitArray(SkillInfo.Table.Length);
        // ... rest of deserialize
    }

```
2025-04-30 19:45:55 -07:00
Kamron Batman
1eeeabb729
fix: Fixes weekly interval schedules for multiple weeks (biweekly) (#2169) 2025-04-30 17:12:29 -07:00
Kamron Batman
7dbfc9d161
fix: Fixes flaky tests, formatting, and sequential testing. (#2168) 2025-04-30 16:42:38 -07:00
Kamron Batman
415c7a6bfd
fix: Optimizes EventScheduler by using PriorityQueue (#2167) 2025-04-30 16:33:59 -07:00
Kamron Batman
21a4092dd8
fix: Changes EventScheduler API so it is more explicit (#2164)
### Summary

Refactors ScheduledEvent and EventScheduler API to use TimeOnly so recurrence offset is explicit.

API:

```cs
public ScheduledEvent(
    DateTime startAfter,
    DateTime endOn,
    TimeOnly time,
    IRecurrencePattern recurrence,
    TimeZoneInfo timeZone = null
)
```

Example:
```cs
// Schedule a daily event at 8:00 AM UTC
EventScheduler.DailyAt(
    new DateTime(2024, 6, 1, 8, 0, 0, DateTimeKind.Utc),
    () => Console.WriteLine("Daily event triggered!")
);

// Schedule a custom recurring event at 3:30 PM UTC every Monday
var recurrence = new WeeklyRecurrencePattern(1, DaysOfWeek.Monday);
EventScheduler.Shared.ScheduleEvent(
    DateTime.UtcNow,
    new TimeOnly(15, 30),
    () => Console.WriteLine("Weekly Monday event!"),
    recurrence
);
```
2025-04-28 16:16:33 -07:00
Kamron Batman
f89b2be653
fix: Fixes major bug with BoBEntries removal (#2165) 2025-04-27 22:05:07 -07:00
Kamron Batman
78feea86b4
feat: Adds scheduler with wallclock timer (#2163)
### Summary

* Adds an event scheduler.
* Adds conveniences for hourly, daily, weekly, biweekly, monthly, ordinal monthly, and yearly recurrences

Example:

```cs
var tz = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");

// Specify the time of the day, and the day of the week you want it to occur. Make sure it is translated into Utc.
// The next occurrence will be _after_ the specified date/time.
var scheduledEvent = EventScheduler.WeeklyAt(new DateTime(2025, 04, 26, 17, 00, 00), StartEvent, tz);

void StartEvent()
{
    World.Broadcast(0x30, false, "The event has started!");
}

Console.WriteLine("Event starts on {0}", scheduledEvent.NextOccurrence);
```

In this example, on _Saturday, May 3rd, 2025 @ 5pm ET_, the message "The event has started!" will be broadcasted.
2025-04-26 22:27:08 -07:00
Kamron Batman
4e25c74cdf
fix: Fixes magical barrier NPE and an edge case (#2162) 2025-04-22 17:52:09 -07:00
Kamron Batman
47b03f5d62
fix: Fixes NPCs not able to equip armor/clothing/weapons (#2161) 2025-04-21 14:01:08 -07:00
Kamron Batman
e54782441e
fix: Fixes TcpServer edge cases where packets are split on login (#2160) 2025-04-15 19:29:17 -07:00
Kamron Batman
4aa272d429
feat: Adds an Item/Mobile memory leak detector. Fixes minor leak in doors. (#2159)
### Summary

Adds the command [TrackLeaks to enable tracking item/mobiles that have been deleted but still have dangling references. Requires adding the _TRACK_LEAKS_ define constant during build.
2025-04-15 19:14:45 -07:00
Kamron Batman
1e349f4369
fix: Fixes mutate speech character limit (#2157)
### Summary

* Fixes the accidental limitation of dead character speech (OoOo) to 256 characters.
* Optimizes it by 1.5x

```cs
| Method                  | Mean      | Error    | StdDev   | Allocated |
|------------------------ |----------:|---------:|---------:|----------:|
| ManuaLoopMutation       | 147.01 ns | 1.298 ns | 1.084 ns |         - |
| SpanLoopMutation        |  92.03 ns | 0.583 ns | 0.487 ns |         - |
```
2025-04-13 22:55:44 -07:00
Kamron Batman
61d074213b
chore(deps): Updates MailKit to 4.11.0 and Microsoft deps to 9.0.4 (#2156) 2025-04-12 12:54:40 -07:00
Kamron Batman
5a23d9f6f8
fix: Fixes an edge case in GetString that can cause a crash while parsing (#2155) 2025-04-12 12:52:10 -07:00
Kamron Batman
872de8d095
fix: Optimizes GetString to eliminate allocations (#2154)
### Summary

* Optimized GetString by eliminating the intermediate string allocation.

** Note **: Encoding.GetChars() is still really inefficient, especially when strings are not aligned or have regular ascii/unicode characters. Thankfully we generally don't have to worry about these odd edge cases, but if they happen then GetChars can allocate hundreds of bytes.


This is a benchmark for just the related changes. NonSpecial are just ascii characters, while the other tests include control codes.
```cs
| Method                         | Mean     | Error   | StdDev  | Gen0   | Allocated |
|------------------------------- |---------:|--------:|--------:|-------:|----------:|
| GetString                      | 306.7 ns | 5.96 ns | 6.86 ns | 0.0124 |     200 B |
| GetStringNotSpecial            | 257.0 ns | 4.83 ns | 4.52 ns | 0.0114 |     184 B |
| GetStringSpanHelpers           | 166.4 ns | 3.26 ns | 3.48 ns |      - |         - |
| GetStringSpanHelpersNotSpecial | 137.3 ns | 1.57 ns | 1.22 ns |      - |         - |
```
2025-04-12 12:42:15 -07:00
Kamron Batman
a94814a7ef
fix: Fixes and optimizes NameVerification and ProfanityProtection (#2153)
### Summary

Significantly improves the performance of NameVerification & ProfanityProtection:

```cs
| Method         | Mean      | Error     | StdDev    |
|--------------- |----------:|----------:|----------:|
| ValidateName   | 728.34 ns | 13.244 ns | 11.059 ns |
| ValidateNameSV |  26.62 ns |  0.233 ns |  0.207 ns |
```
2025-04-12 02:26:10 -07:00
Kamron Batman
0ce2a62a76
fix: Use vectorized search for username-password validation. (#2152)
### Summary

Optimizes account validation:

```cs
| Method              | Mean       | Error     | StdDev    |
|-------------------- |-----------:|----------:|----------:|
| ForLoopUsernameSafe | 158.536 ns | 1.6247 ns | 1.5198 ns |
| SVUsernameSafe      |   2.859 ns | 0.0581 ns | 0.0796 ns |
```
2025-04-11 22:40:06 -07:00
Kamron Batman
fdf8c5cf23
fix: Fixes critical bug in TickCount calculation. (#2151)
### Summary

On some operating systems (like hosted Linux VMs), the `TimeStamp.GetTimeStamp()` CPU tick count will wrap around. This is generally not an issue, except for legacy reasons the TickCount is returned in milliseconds instead of ticks. This means when the values wrap around, they are already divided by the CPU Frequency (usually 1million) and then converted to milliseconds. That means the delta between the tick count before and after wrapping is off by a magnitude of (Frequency / 1000).

Example:

TimeStamp A = 9223372036654775807
Some time has passed:
TimeStamp B = -9223372036654775809

The raw delta is 400_000_000 (400ms) when you do `unchecked(A - B)`.
If we do the calculation AFTER converting it to milliseconds, then:

TickCount A = 9223372036654
TickCount B = -9223372036654

The raw delta is -18446744073308 instead of 400_000_000.

To fix this the calculation was changed so `long` -> `ulong`, then divided, then converted back to `long`, effectively bypassing wrap-around issue.

The new TickCount values in our example become:

TickCount A = 9223372037054
TickCount B = 9223372036654

The delta is 400 (in milliseconds). 🎉
2025-04-09 16:46:53 -07:00
Kamron Batman
0a4579f298
fix: Fixes duping bags (#2148)
### Summary

Fixes duping items in a container not working properly.
2025-04-07 22:27:41 -07:00
Kamron Batman
2c6f1854fa
fix: Fixes guards attacking mobs (#2145)
### Summary

- Fixes infinite teleport from guard refactor for spawners
- Fixes guards not attacking Always Murderer creatures
- Fixes crash when calling guards due to map modification while enumeration
2025-03-12 16:45:39 -07:00
Kamron Batman
47da961a37
fix: Fixes spawning guards. Adds back non-lethal with config (#2140) 2025-03-12 13:08:14 -07:00
mark1145
0024d53739
fix: Fixes edge cases where a leader resigns and becomes promoted in their new guild. (#2136) 2025-03-05 17:59:07 -08:00
Kamron Batman
56e3086ed1
fix: Makes hairdye gump static (#2138) 2025-03-04 15:55:05 -08:00
Kamron Batman
ad361001c5
fix: Fixes CUO connecting with new TCP Peek Filtering (#2137) 2025-03-04 11:00:20 -08:00
Kamron Batman
49fd5f210d
fix: Fixes removing virtue when player is deleted (#2135) 2025-03-02 17:50:18 -08:00
Kamron Batman
2a8c62e8be
fix: Fixes TCPServer accept async, makes Firewall/IP Limiter multithreaded (#2134) 2025-02-27 22:19:38 -08:00
Kamron Batman
bcab91255a
fix: Fixes EVs/BSs attacking players in Pre-AOS (#2132) 2025-02-26 18:43:49 -08:00
Voxpire
b8a8bfd1a9
fix: Fixes console clobbering when prompted to add an owner account (#2133)
### Summary
- Updates AccountPrompt to use `logger` to avoid console clobbering

### Screenshot
![image](https://github.com/user-attachments/assets/8bfbaccc-3c23-4d05-ab49-a656e6a8803f)
2025-02-26 18:43:20 -08:00
Kamron Batman
0265e0673a
fix: Fixes empty spellbooks with EA client on Pre-AOS (#2131) 2025-02-25 20:46:20 -08:00
Kamron Batman
9b361822f3
fix: Fixes issue with delete all of missing type on deserialize (#2129) 2025-02-19 15:36:29 -08:00
Kamron Batman
d10b32aed3
fix: Fixes dead plant serialization (#2128) 2025-02-19 15:23:49 -08:00
Kamron Batman
525112943c
fix: Changes Chyloth gump to static (#2126) 2025-02-14 00:18:38 -08:00
Kamron Batman
2e08eda8cb
feat: Standardizes South/East selection gumps (#1839) 2025-02-14 00:15:14 -08:00
Kamron Batman
279b10dd0f
feat: Replaces params array with params ReadOnlySpan (#2125) 2025-02-13 21:19:02 -08:00
Kamron Batman
90059c5e74
feat: Adds convenience methods to GumpStringsBuilder (#2124) 2025-02-13 19:58:46 -08:00