ModernUO/Projects/Server/Mobiles
Kamron Batman 73d1ee3874
fix(network): don't leak duped-layer equipment via EquipUpdate/OPL (#2502)
## Problem

A creature equipped with two items that resolve to the **same layer** can crash the legacy EA 2D client (use-after-free). Equipment `Layer` comes from tiledata (`Layer = (Layer)ItemData.Quality`), so a **two-handed weapon and a shield both resolve to `Layer.TwoHanded`**. `Mobile.FindItemOnLayer` even documents the invariant: *"We only allow 1 item per layer. Its an implicit contract."*

## Root cause

- `SendMobileIncoming` (0x78) **dedupes by layer** (the `layers` span) and sends only the first item per slot — so a static creature is fine.
- But the per-item **`SendEquipUpdate` (0x2E)** and the item **OPL** sends do **not** dedupe. On any equip/property delta (`Item.ProcessDelta`) they fire per item and leak the second same-layer item on its own.
- The client then holds two items on one equipment slot; when that slot is torn down (e.g. a large group of such creatures and the player runs out of range → mass remove) the legacy 2D client frees one and dereferences it → UAF. ClassicUO bounds-checks and is unaffected, but the server is emitting an invalid, self-contradictory stream either way.

## Fix

Make per-item equip/OPL sends honor the same first-item-per-layer rule `SendMobileIncoming` already uses:

- `Item.IsDupedEquipLayer()` — `m_Parent is Mobile m && m.FindItemOnLayer(m_Layer) != this` (reuses the existing helper; true when an earlier item already holds this items layer).
- `Item.ProcessDelta`: early-return before the per-client loop for a duped equipped item (skips the EquipUpdate and OPL to everyone).
- `Mobile` lift-reject re-show: skip the EquipUpdate and OPL for the dupe.

No behavioral change for valid equipment (distinct layers → never duped). For the invalid duped-layer case the second item was already omitted by the 0x78 packet; this just stops it leaking back via the per-item paths.
2026-06-22 23:20:57 -07:00
..
Mods fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
AggressorInfo.cs fix: Cleans up core code (#1187) 2022-10-10 21:47:08 -07:00
BaseVendor.cs fix: Fixes client crash while selling items to NPC (#1296) 2022-12-05 20:16:31 -08:00
Body.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
IHasSteps.cs feat: Adds Stamina System to overhaul overweight. (#1465) 2023-09-16 17:52:54 -07:00
IMount.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
IVendor.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
Mobile.cs fix(network): don't leak duped-layer equipment via EquipUpdate/OPL (#2502) 2026-06-22 23:20:57 -07:00
Mobile.Enumerators.cs feat: Adds proper OSI tracking up to 120 tiles. (#2281) 2025-11-29 09:55:52 -08:00
Mobile.Messages.cs perf: Zero-alloc interpolation for SendMessage/Overhead APIs (#2434) 2026-05-03 18:04:02 -07:00
Mobile.Migrations.cs fix: Overhauls virtue system (#1376) 2023-07-19 21:43:47 -07:00
Movement.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
Notoriety.cs fix: Cleans up core code (#1187) 2022-10-10 21:47:08 -07:00
SimplePrompt.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
SimpleTarget.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00