- Create JSON-based packet documentation for 145 packets (66 incoming, 79 outgoing) - Add HTML template with search, filtering, and navigation - Support enum/bitfield field display with values and descriptions - Support packet variants for version-specific structures - Include 0xBF extended command subpackets documentation - Add PowerShell build script to generate final HTML 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
736 lines
160 KiB
HTML
736 lines
160 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="description" content="Network packet documentation for the Ultima Online Server Emulator ModernUO">
|
|
<meta name="author" content="ModernUO Development Team">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="icon" href="https://modernuo.com/branding/favicon.png">
|
|
<title>ModernUO Packet Documentation</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
<script src="https://cdn.tailwindcss.com/3.4.1?plugins=typography@0.5.10"></script>
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
fontFamily: {
|
|
mono: ['Roboto Mono', 'monospace'],
|
|
},
|
|
colors: {
|
|
"modern-black": "#212121",
|
|
"modern-black-hover": "#2F2F2F",
|
|
"modern-dark-black": "#1A1A1A",
|
|
"incoming": "#3b82f6",
|
|
"outgoing": "#22c55e",
|
|
"both": "#a855f7",
|
|
gold: {
|
|
50: "#fbf3ee",
|
|
100: "#f8e9dd",
|
|
200: "#f0d9bd",
|
|
300: "#e8cea1",
|
|
400: "#dfc688",
|
|
500: "#d5bf74",
|
|
600: "#cab664",
|
|
700: "#bdab58",
|
|
800: "#b09f4f",
|
|
900: "#a29147",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
<style>
|
|
.packet-list::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
.packet-list::-webkit-scrollbar-track {
|
|
background: #1A1A1A;
|
|
}
|
|
.packet-list::-webkit-scrollbar-thumb {
|
|
background: #404040;
|
|
border-radius: 4px;
|
|
}
|
|
.packet-list::-webkit-scrollbar-thumb:hover {
|
|
background: #525252;
|
|
}
|
|
.field-row:nth-child(even) {
|
|
background-color: rgba(255, 255, 255, 0.02);
|
|
}
|
|
.loop-field {
|
|
border-left: 2px solid #d5bf74;
|
|
margin-left: 1rem;
|
|
padding-left: 0.75rem;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body class="bg-modern-dark-black text-gold-300 font-sans">
|
|
<div id="app" class="min-h-screen flex flex-col">
|
|
<!-- Header -->
|
|
<header class="bg-modern-black p-4 shadow-lg border-b border-gold-500/30">
|
|
<div class="max-w-7xl mx-auto flex items-center justify-between">
|
|
<div class="flex items-center space-x-4">
|
|
<img src="https://modernuo.com/branding/logo.svg" class="h-12 w-12">
|
|
<div>
|
|
<h1 class="text-white text-xl font-medium">ModernUO Packet Documentation</h1>
|
|
<p class="text-gold-500/70 text-sm">Ultima Online Network Protocol Reference</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center space-x-2">
|
|
<span id="packetCount" class="text-gold-500/70 text-sm"></span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Main Content -->
|
|
<div class="flex-1 flex overflow-hidden">
|
|
<!-- Left Panel: Packet List -->
|
|
<aside id="sidebar" class="w-80 bg-modern-black border-r border-gold-500/30 flex flex-col">
|
|
<!-- Search & Filter -->
|
|
<div class="p-3 border-b border-gold-500/20 space-y-2">
|
|
<input
|
|
type="text"
|
|
id="searchInput"
|
|
placeholder="Search packets (ID, name, field)..."
|
|
class="w-full bg-modern-dark-black text-gold-300 placeholder-gold-500/50 px-3 py-2 rounded border border-gold-500/30 focus:outline-none focus:border-gold-500 text-sm"
|
|
>
|
|
<div class="flex space-x-1">
|
|
<button data-filter="all" class="filter-btn flex-1 px-2 py-1 text-xs rounded bg-gold-500 text-modern-black font-medium">All</button>
|
|
<button data-filter="incoming" class="filter-btn flex-1 px-2 py-1 text-xs rounded bg-modern-dark-black text-incoming border border-incoming/50 hover:bg-incoming/20">In</button>
|
|
<button data-filter="outgoing" class="filter-btn flex-1 px-2 py-1 text-xs rounded bg-modern-dark-black text-outgoing border border-outgoing/50 hover:bg-outgoing/20">Out</button>
|
|
<button data-filter="both" class="filter-btn flex-1 px-2 py-1 text-xs rounded bg-modern-dark-black text-both border border-both/50 hover:bg-both/20">Both</button>
|
|
</div>
|
|
<select id="categoryFilter" class="w-full bg-modern-dark-black text-gold-300 px-3 py-2 rounded border border-gold-500/30 focus:outline-none focus:border-gold-500 text-sm">
|
|
<option value="">All Categories</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Packet List -->
|
|
<div id="packetList" class="packet-list flex-1 overflow-y-auto">
|
|
<!-- Populated by JavaScript -->
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Right Panel: Packet Details -->
|
|
<main class="flex-1 overflow-y-auto bg-modern-dark-black">
|
|
<div id="packetDetails" class="p-6 max-w-4xl mx-auto">
|
|
<!-- Welcome message when no packet selected -->
|
|
<div id="welcomeMessage" class="text-center py-16">
|
|
<div class="text-gold-500/50 text-6xl mb-4">📦</div>
|
|
<h2 class="text-gold-500 text-xl mb-2">Select a Packet</h2>
|
|
<p class="text-gold-500/70">Choose a packet from the list to view its documentation.</p>
|
|
<p class="text-gold-500/50 text-sm mt-4">Use the search box to find packets by ID (0x02), name, or field names.</p>
|
|
</div>
|
|
|
|
<!-- Packet detail content (hidden by default) -->
|
|
<div id="packetContent" class="hidden">
|
|
<!-- Header -->
|
|
<div class="flex items-start justify-between mb-6">
|
|
<div>
|
|
<div class="flex items-center space-x-3 mb-2">
|
|
<span id="detailId" class="font-mono text-2xl text-white"></span>
|
|
<span id="detailSubId" class="font-mono text-lg text-gold-500/70 hidden"></span>
|
|
<span id="detailDirection" class="px-2 py-0.5 rounded text-xs font-medium uppercase"></span>
|
|
</div>
|
|
<h2 id="detailName" class="text-xl text-gold-500 font-medium"></h2>
|
|
</div>
|
|
<a id="sourceLink" href="#" target="_blank" class="flex items-center space-x-1 text-sm text-gold-500/70 hover:text-gold-500 transition-colors">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
|
<span>View Source</span>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Description -->
|
|
<p id="detailDescription" class="text-gold-300/90 mb-6 leading-relaxed"></p>
|
|
|
|
<!-- Size Info -->
|
|
<div class="bg-modern-black rounded-lg p-4 mb-6 border border-gold-500/20">
|
|
<div class="flex items-center space-x-6">
|
|
<div>
|
|
<span class="text-gold-500/70 text-sm">Size:</span>
|
|
<span id="detailSize" class="text-white font-mono ml-2"></span>
|
|
</div>
|
|
<div id="detailDynamic" class="hidden">
|
|
<span class="px-2 py-0.5 bg-gold-500/20 text-gold-500 rounded text-xs">Dynamic Length</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Client Version Requirements -->
|
|
<div id="clientVersionSection" class="bg-modern-black rounded-lg p-4 mb-6 border border-gold-500/20 hidden">
|
|
<h3 class="text-gold-500 font-medium mb-2">Client Version Requirements</h3>
|
|
<div id="clientVersionContent" class="text-gold-300/80 text-sm"></div>
|
|
</div>
|
|
|
|
<!-- Fields Table -->
|
|
<div class="mb-6">
|
|
<h3 class="text-gold-500 font-medium mb-3">Packet Structure</h3>
|
|
<div class="bg-modern-black rounded-lg border border-gold-500/20 overflow-hidden">
|
|
<table class="w-full text-sm">
|
|
<thead>
|
|
<tr class="bg-gold-500/10 text-gold-500">
|
|
<th class="px-4 py-2 text-left font-medium">Offset</th>
|
|
<th class="px-4 py-2 text-left font-medium">Name</th>
|
|
<th class="px-4 py-2 text-left font-medium">Type</th>
|
|
<th class="px-4 py-2 text-left font-medium">Size</th>
|
|
<th class="px-4 py-2 text-left font-medium">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="fieldsTable">
|
|
<!-- Populated by JavaScript -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Related Packets -->
|
|
<div id="relatedSection" class="mb-6 hidden">
|
|
<h3 class="text-gold-500 font-medium mb-3">Related Packets</h3>
|
|
<div id="relatedPackets" class="space-y-2">
|
|
<!-- Populated by JavaScript -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Packet Variants -->
|
|
<div id="variantsSection" class="mb-6 hidden">
|
|
<h3 class="text-gold-500 font-medium mb-3">Packet Variants</h3>
|
|
<div id="variantsList" class="space-y-4">
|
|
<!-- Populated by JavaScript -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes -->
|
|
<div id="notesSection" class="hidden">
|
|
<h3 class="text-gold-500 font-medium mb-2">Notes</h3>
|
|
<p id="detailNotes" class="text-gold-300/80 text-sm bg-modern-black rounded-lg p-4 border border-gold-500/20"></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Hidden data containers -->
|
|
<span id="packets" style="display:none; visibility: hidden">
|
|
{"incoming":[{"id":"0x80","name":"Account Login","description":"Initial login request sent to the login server. Contains account credentials for authentication.","direction":"incoming","isDynamic":false,"size":62,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x80","description":"Packet identifier"},{"name":"username","type":"ascii","size":30,"description":"Account username (null-terminated)"},{"name":"password","type":"ascii","size":30,"description":"Account password (null-terminated)"},{"name":"nextLoginKey","type":"byte","size":1,"description":"Next login key"}],"related":[{"id":"0x82","relationship":"rej","note":"Sent if login fails"},{"id":"0xA8","relationship":"ack","note":"Sent if login succeeds (server list)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":439},"category":"Account"},{"id":"0x91","name":"Game Login","description":"Login request sent to the game server after selecting a shard from the server list.","direction":"incoming","isDynamic":false,"size":65,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x91","description":"Packet identifier"},{"name":"authId","type":"int","size":4,"description":"Authentication ID from PlayServerAck (0x8C)"},{"name":"username","type":"ascii","size":30,"description":"Account username"},{"name":"password","type":"ascii","size":30,"description":"Account password"}],"related":[{"id":"0xA9","relationship":"response","note":"Character list sent on success"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":345},"category":"Account"},{"id":"0x5D","name":"Play Character","description":"Request to enter the world with a selected character from the character list.","direction":"incoming","isDynamic":false,"size":73,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x5D","description":"Packet identifier"},{"name":"pattern","type":"uint","size":4,"value":"0xEDEDEDED","description":"Fixed pattern"},{"name":"name","type":"ascii","size":30,"description":"Character name (unused)"},{"name":"unknown","type":"byte[2]","size":2,"description":"Unknown"},{"name":"flags","type":"int","size":4,"description":"Client flags"},{"name":"unknown2","type":"byte[24]","size":24,"description":"Unknown"},{"name":"charSlot","type":"int","size":4,"description":"Character slot index (0-based)"},{"name":"clientIP","type":"int","size":4,"description":"Client IP address"}],"related":[{"id":"0x1B","relationship":"response","note":"Login confirmation sent on success"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":210},"category":"Account"},{"id":"0xA0","name":"Play Server","description":"Request to connect to a specific game server from the server list.","direction":"incoming","isDynamic":false,"size":3,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA0","description":"Packet identifier"},{"name":"serverIndex","type":"short","size":2,"description":"Index of selected server in the list"}],"related":[{"id":"0x8C","relationship":"response","note":"Server connection details"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":398},"category":"Account"},{"id":"0x83","name":"Delete Character","description":"Request to delete a character from the account.","direction":"incoming","isDynamic":false,"size":39,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x83","description":"Packet identifier"},{"name":"password","type":"ascii","size":30,"description":"Account password for verification"},{"name":"charIndex","type":"int","size":4,"description":"Character slot index to delete"},{"name":"clientIP","type":"int","size":4,"description":"Client IP address"}],"related":[{"id":"0x85","relationship":"response","note":"Delete result"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":185},"category":"Account"},{"id":"0xEF","name":"Login Server Seed","description":"Initial connection packet sent before account login. Contains seed and client version information.","direction":"incoming","isDynamic":false,"size":21,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xEF","description":"Packet identifier"},{"name":"seed","type":"int","size":4,"description":"Random seed for encryption"},{"name":"clientMajor","type":"int","size":4,"description":"Client major version"},{"name":"clientMinor","type":"int","size":4,"description":"Client minor version"},{"name":"clientRevision","type":"int","size":4,"description":"Client revision"},{"name":"clientPatch","type":"int","size":4,"description":"Client patch level"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":419},"category":"Account"},{"id":"0xBD","name":"Client Version","description":"Response to server's version request (0xBD). Contains the client version string.","direction":"incoming","isDynamic":true,"size":"3 + version string length","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBD","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"version","type":"ascii","description":"Client version string (e.g., '7.0.95.0')"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":193},"category":"Account"},{"id":"0xE1","name":"Client Type","description":"Sent by the client to identify the client type and version.","direction":"incoming","isDynamic":true,"size":"variable","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xE1","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"unknown","type":"ushort","size":2,"description":"Unknown"},{"name":"clientType","type":"ushort","size":2,"description":"Client type identifier"},{"name":"version","type":"ascii","description":"Client version string"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":200},"category":"Account"},{"id":"0x00","name":"Create Character (Old)","description":"Request to create a new character. This is the older 104-byte version.","direction":"incoming","isDynamic":false,"size":104,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x00","description":"Packet identifier"},{"name":"unknown1","type":"int","size":4,"description":"Unknown"},{"name":"unknown2","type":"int","size":4,"description":"Unknown"},{"name":"unknown3","type":"byte","size":1,"description":"Unknown"},{"name":"name","type":"ascii","size":30,"description":"Character name"},{"name":"unknown4","type":"byte[2]","size":2,"description":"Unknown"},{"name":"flags","type":"int","size":4,"description":"Client flags"},{"name":"unknown5","type":"byte[8]","size":8,"description":"Unknown"},{"name":"profession","type":"byte","size":1,"description":"Starting profession"},{"name":"unknown6","type":"byte[15]","size":15,"description":"Unknown"},{"name":"genderRace","type":"byte","size":1,"description":"Gender and race combined value"},{"name":"strength","type":"byte","size":1,"description":"Starting strength"},{"name":"dexterity","type":"byte","size":1,"description":"Starting dexterity"},{"name":"intelligence","type":"byte","size":1,"description":"Starting intelligence"},{"name":"skill1Id","type":"byte","size":1,"description":"First skill ID"},{"name":"skill1Value","type":"byte","size":1,"description":"First skill value"},{"name":"skill2Id","type":"byte","size":1,"description":"Second skill ID"},{"name":"skill2Value","type":"byte","size":1,"description":"Second skill value"},{"name":"skill3Id","type":"byte","size":1,"description":"Third skill ID"},{"name":"skill3Value","type":"byte","size":1,"description":"Third skill value"},{"name":"skinHue","type":"ushort","size":2,"description":"Skin color hue"},{"name":"hairStyle","type":"short","size":2,"description":"Hair style ID"},{"name":"hairHue","type":"short","size":2,"description":"Hair color hue"},{"name":"facialHairStyle","type":"short","size":2,"description":"Facial hair style ID"},{"name":"facialHairHue","type":"short","size":2,"description":"Facial hair color hue"},{"name":"unknown7","type":"byte","size":1,"description":"Unknown"},{"name":"cityIndex","type":"byte","size":1,"description":"Starting city index"},{"name":"charSlot","type":"int","size":4,"description":"Character slot"},{"name":"clientIP","type":"int","size":4,"description":"Client IP"},{"name":"shirtHue","type":"short","size":2,"description":"Starting shirt hue"},{"name":"pantsHue","type":"short","size":2,"description":"Starting pants hue"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":58},"category":"Account"},{"id":"0xF8","name":"Create Character (New)","description":"Request to create a new character. This is the newer 106-byte version with support for 4 skills.","direction":"incoming","isDynamic":false,"size":106,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xF8","description":"Packet identifier"},{"name":"unknown1","type":"int","size":4,"description":"Unknown"},{"name":"unknown2","type":"int","size":4,"description":"Unknown"},{"name":"unknown3","type":"byte","size":1,"description":"Unknown"},{"name":"name","type":"ascii","size":30,"description":"Character name"},{"name":"unknown4","type":"byte[2]","size":2,"description":"Unknown"},{"name":"flags","type":"int","size":4,"description":"Client flags"},{"name":"unknown5","type":"byte[8]","size":8,"description":"Unknown"},{"name":"profession","type":"byte","size":1,"description":"Starting profession"},{"name":"unknown6","type":"byte[15]","size":15,"description":"Unknown"},{"name":"genderRace","type":"byte","size":1,"description":"Gender and race combined value"},{"name":"strength","type":"byte","size":1,"description":"Starting strength"},{"name":"dexterity","type":"byte","size":1,"description":"Starting dexterity"},{"name":"intelligence","type":"byte","size":1,"description":"Starting intelligence"},{"name":"skill1Id","type":"byte","size":1,"description":"First skill ID"},{"name":"skill1Value","type":"byte","size":1,"description":"First skill value"},{"name":"skill2Id","type":"byte","size":1,"description":"Second skill ID"},{"name":"skill2Value","type":"byte","size":1,"description":"Second skill value"},{"name":"skill3Id","type":"byte","size":1,"description":"Third skill ID"},{"name":"skill3Value","type":"byte","size":1,"description":"Third skill value"},{"name":"skill4Id","type":"byte","size":1,"description":"Fourth skill ID (newer clients)"},{"name":"skill4Value","type":"byte","size":1,"description":"Fourth skill value (newer clients)"},{"name":"skinHue","type":"ushort","size":2,"description":"Skin color hue"},{"name":"hairStyle","type":"short","size":2,"description":"Hair style ID"},{"name":"hairHue","type":"short","size":2,"description":"Hair color hue"},{"name":"facialHairStyle","type":"short","size":2,"description":"Facial hair style ID"},{"name":"facialHairHue","type":"short","size":2,"description":"Facial hair color hue"},{"name":"unknown7","type":"byte","size":1,"description":"Unknown"},{"name":"cityIndex","type":"byte","size":1,"description":"Starting city index"},{"name":"charSlot","type":"int","size":4,"description":"Character slot"},{"name":"clientIP","type":"int","size":4,"description":"Client IP"},{"name":"shirtHue","type":"short","size":2,"description":"Starting shirt hue"},{"name":"pantsHue","type":"short","size":2,"description":"Starting pants hue"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingAccountPackets.cs","line":58},"notes":"Uses the same handler as 0x00 but with 2 additional bytes for the 4th skill.","category":"Account"},{"id":"0x06","name":"Use Request (Double-Click)","description":"Sent when the player double-clicks an item or mobile. Can also trigger paperdoll if high bit is set.","direction":"incoming","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x06","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of the target. If high bit (0x80000000) is set, opens player's paperdoll instead."}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingEntityPackets.cs","line":61},"category":"Entity"},{"id":"0x09","name":"Look Request (Single-Click)","description":"Sent when the player single-clicks an item or mobile to see its name/properties.","direction":"incoming","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x09","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of the target entity"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingEntityPackets.cs","line":105},"category":"Entity"},{"id":"0xB6","name":"Object Help Request","description":"Sent when the player requests help/info about an object (Shift+Click or context menu).","direction":"incoming","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xB6","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of the target entity"},{"name":"unknown","type":"byte","size":1,"description":"Unknown"},{"name":"language","type":"ascii","size":3,"description":"Language code (e.g., 'ENU')"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingEntityPackets.cs","line":32},"category":"Entity"},{"id":"0xD6","name":"Batch Query Properties","description":"Sent by the client to request Object Property Lists (tooltips) for multiple entities at once.","direction":"incoming","isDynamic":true,"size":"3 + (4 * entityCount)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xD6","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serials","type":"array","description":"List of entity serials to query","loop":{"countField":"(length-3)/4","fields":[{"name":"serial","type":"uint","size":4,"description":"Entity serial"}]}}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingEntityPackets.cs","line":154},"category":"Entity"},{"id":"0xBF","name":"Extended Command","description":"Wrapper packet for extended command subpackets.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"description":"Extended command ID"},{"name":"data","type":"byte[]","description":"Subcommand-specific data"}],"notes":"See individual 0xBF/0xXX packets for subcommand details.","source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":43},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x05","subId":"0x05","name":"Screen Size","description":"Client reports screen size.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x05","description":"Screen Size subcommand"},{"name":"width","type":"int","size":4,"description":"Screen width"},{"name":"unknown","type":"int","size":4,"description":"Unknown value"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":136},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x06","subId":"0x06","name":"Party Message","description":"Client sends party-related commands.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x06","description":"Party Message subcommand"},{"name":"partyCommand","type":"enum","enumType":"sequential","size":1,"description":"Party command type","values":[{"value":1,"name":"AddMember","description":"Add member to party"},{"value":2,"name":"RemoveMember","description":"Remove member from party"},{"value":3,"name":"PrivateMessage","description":"Send private message to party member"},{"value":4,"name":"PublicMessage","description":"Send public message to party"},{"value":6,"name":"SetCanLoot","description":"Set loot permission"},{"value":8,"name":"Accept","description":"Accept party invitation"},{"value":9,"name":"Decline","description":"Decline party invitation"}]},{"name":"data","type":"byte[]","description":"Command-specific data (target serial, message text)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":142},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x09","subId":"0x09","name":"Disarm Request","description":"Client requests to disarm opponent.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x09","description":"Disarm Request subcommand"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":289},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x0A","subId":"0x0A","name":"Stun Request","description":"Client requests to stun opponent.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x0A","description":"Stun Request subcommand"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":277},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x0B","subId":"0x0B","name":"Language","description":"Client sets language preference.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x0B","description":"Language subcommand"},{"name":"language","type":"ascii","size":4,"description":"Language code (e.g., 'ENU')"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":343},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x0C","subId":"0x0C","name":"Close Status","description":"Client closes a status gump.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x0C","description":"Close Status subcommand"},{"name":"serial","type":"uint","size":4,"description":"Serial of mobile whose status to close"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":338},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x0E","subId":"0x0E","name":"Animate","description":"Client requests to play an animation.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x0E","description":"Animate subcommand"},{"name":"action","type":"int","size":4,"description":"Animation action ID (must be in valid list)"}],"notes":"Only specific animation IDs are allowed for security.","source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":233},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x10","subId":"0x10","name":"Query Properties","description":"Client queries Object Property List (tooltip) for an entity.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x10","description":"Query Properties subcommand"},{"name":"serial","type":"uint","size":4,"description":"Serial of entity to query"}],"related":[{"id":"0xDC","relationship":"response","note":"OPL Info packet"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":355},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x1A","subId":"0x1A","name":"Stat Lock Change","description":"Client changes stat lock (STR/DEX/INT).","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x1A","description":"Stat Lock Change subcommand"},{"name":"stat","type":"enum","enumType":"sequential","size":1,"description":"Which stat to change","values":[{"value":0,"name":"Strength","description":"Strength lock"},{"value":1,"name":"Dexterity","description":"Dexterity lock"},{"value":2,"name":"Intelligence","description":"Intelligence lock"}]},{"name":"lockValue","type":"enum","enumType":"sequential","size":1,"description":"New lock state","values":[{"value":0,"name":"Up","description":"Stat gains enabled"},{"value":1,"name":"Down","description":"Stat decreases enabled"},{"value":2,"name":"Locked","description":"Stat locked"}]}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":301},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x1C","subId":"0x1C","name":"Cast Spell","description":"Client casts a spell (optionally from spellbook).","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x1C","description":"Cast Spell subcommand"},{"name":"hasBook","type":"short","size":2,"description":"1 if casting from book, 0 otherwise"},{"name":"bookSerial","type":"uint","size":4,"description":"Serial of spellbook (if hasBook)","condition":"hasBook == 1"},{"name":"spellId","type":"short","size":2,"description":"Spell ID + 1 (1-based)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":257},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x2C","subId":"0x2C","name":"Bandage Target","description":"Client uses bandage on a target.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x2C","description":"Bandage Target subcommand"},{"name":"bandageSerial","type":"uint","size":4,"description":"Serial of the bandage item"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of target mobile"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":387},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x2D","subId":"0x2D","name":"Targeted Spell","description":"Client casts spell with pre-selected target.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x2D","description":"Targeted Spell subcommand"},{"name":"spellId","type":"short","size":2,"description":"Spell ID + 1 (1-based)"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of target entity"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":422},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x2E","subId":"0x2E","name":"Targeted Skill Use","description":"Client uses skill with pre-selected target.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x2E","description":"Targeted Skill Use subcommand"},{"name":"skillId","type":"short","size":2,"description":"Skill ID"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of target entity"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":429},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x30","subId":"0x30","name":"Target By Resource Macro","description":"Client uses resource-based targeting macro.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x30","description":"Target By Resource Macro subcommand"},{"name":"itemSerial","type":"uint","size":4,"description":"Serial of item"},{"name":"resourceType","type":"short","size":2,"description":"Resource type ID"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":439},"category":"Extended Commands (0xBF)"},{"id":"0xBF/0x32","subId":"0x32","name":"Toggle Flying","description":"Client toggles gargoyle flying mode.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x32","description":"Toggle Flying subcommand"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs","line":272},"category":"Extended Commands (0xBF)"},{"id":"0x07","name":"Lift Request","description":"Client requests to pick up an item from the world or a container.","direction":"incoming","isDynamic":false,"size":7,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x07","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of the item to lift"},{"name":"amount","type":"ushort","size":2,"description":"Amount to pick up"}],"related":[{"id":"0x27","relationship":"rej","note":"Sent if lift is rejected"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingItemPackets.cs","line":35},"category":"Items"},{"id":"0x08","name":"Drop Request","description":"Client requests to drop an item at a location or into a container. Size varies by client version.","direction":"incoming","isDynamic":false,"size":"14 (pre-6017) or 15 (6017+)","variants":[{"version":"pre-6017","name":"Classic","size":14,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x08","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of item being dropped (ignored)"},{"name":"x","type":"short","size":2,"description":"Target X coordinate"},{"name":"y","type":"short","size":2,"description":"Target Y coordinate"},{"name":"z","type":"sbyte","size":1,"description":"Target Z coordinate"},{"name":"dest","type":"uint","size":4,"description":"Target container/mobile serial, or 0xFFFFFFFF for world"}]},{"version":"6017+","name":"Container Grid Lines","condition":"Client version >= 6.0.1.7 (ContainerGridLines)","size":15,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x08","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of item being dropped (ignored)"},{"name":"x","type":"short","size":2,"description":"Target X coordinate"},{"name":"y","type":"short","size":2,"description":"Target Y coordinate"},{"name":"z","type":"sbyte","size":1,"description":"Target Z coordinate"},{"name":"gridLocation","type":"byte","size":1,"description":"Grid slot position in container"},{"name":"dest","type":"uint","size":4,"description":"Target container/mobile serial, or 0xFFFFFFFF for world"}]}],"clientVersion":{"feature":"ContainerGridLines adds gridLocation byte"},"source":{"file":"Projects/UOContent/Network/Packets/IncomingItemPackets.cs","line":69},"category":"Items"},{"id":"0x13","name":"Equip Request","description":"Client requests to equip a held item on a mobile.","direction":"incoming","isDynamic":false,"size":10,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x13","description":"Packet identifier"},{"name":"itemSerial","type":"uint","size":4,"description":"Serial of item to equip"},{"name":"layer","type":"byte","size":1,"description":"Equipment layer"},{"name":"mobileSerial","type":"uint","size":4,"description":"Serial of target mobile"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingItemPackets.cs","line":44},"category":"Items"},{"id":"0xEC","name":"Equip Macro","description":"Client requests to equip multiple items from a saved macro.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xEC","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"count","type":"byte","size":1,"description":"Number of items to equip"},{"name":"items","type":"loop","loop":{"countField":"count","fields":[{"name":"serial","type":"uint","size":4,"description":"Serial of item to equip"}]}}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingItemPackets.cs","line":112},"category":"Items"},{"id":"0xED","name":"Unequip Macro","description":"Client requests to unequip items from specific layers via macro.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xED","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"count","type":"byte","size":1,"description":"Number of layers to unequip"},{"name":"layers","type":"loop","loop":{"countField":"count","fields":[{"name":"layer","type":"ushort","size":2,"description":"Layer to unequip from"}]}}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingItemPackets.cs","line":125},"category":"Items"},{"id":"0x03","name":"ASCII Speech","description":"Client sends ASCII-encoded speech message.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x03","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"type","type":"enum","enumType":"sequential","size":1,"description":"Message type","values":[{"value":0,"name":"Regular","description":"Normal speech"},{"value":1,"name":"System","description":"System message"},{"value":2,"name":"Emote","description":"Emote (*action*)"},{"value":6,"name":"Label","description":"Object label"},{"value":7,"name":"Focus","description":"Focused message"},{"value":8,"name":"Whisper","description":"Whisper"},{"value":9,"name":"Yell","description":"Yell"},{"value":10,"name":"Spell","description":"Spell words"},{"value":13,"name":"Guild","description":"Guild chat"},{"value":14,"name":"Alliance","description":"Alliance chat"},{"value":15,"name":"Command","description":"Command"}]},{"name":"hue","type":"short","size":2,"description":"Text color hue"},{"name":"font","type":"short","size":2,"description":"Font ID"},{"name":"text","type":"ascii-null","description":"Speech text (max 128 chars)"}],"related":[{"id":"0x1C","relationship":"response","note":"ASCII Message sent to other clients"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingMessagePackets.cs","line":31},"category":"Message"},{"id":"0xAD","name":"Unicode Speech","description":"Client sends Unicode-encoded speech message with optional keywords.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xAD","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"type","type":"bitfield","size":1,"description":"Message type with possible Encoded flag","flags":[{"bit":"0x0F","name":"MessageType","description":"Base message type (see 0x03)"},{"bit":"0xC0","name":"Encoded","description":"If set, packet contains encoded keywords"}]},{"name":"hue","type":"short","size":2,"description":"Text color hue"},{"name":"font","type":"short","size":2,"description":"Font ID"},{"name":"language","type":"ascii","size":4,"description":"Language code (e.g., 'ENU')"},{"name":"encodedKeywords","type":"conditional","condition":"type & 0xC0 != 0","fields":[{"name":"keywordValue","type":"short","size":2,"description":"Keyword count (upper 12 bits) and first hold value (lower 4 bits)"},{"name":"keywords","type":"byte[]","description":"Packed keyword IDs"},{"name":"text","type":"utf8-null","description":"Speech text (UTF-8 when encoded)"}]},{"name":"unicodeText","type":"conditional","condition":"type & 0xC0 == 0","fields":[{"name":"text","type":"unicode-be-null","description":"Speech text (Big Endian Unicode)"}]}],"related":[{"id":"0xAE","relationship":"response","note":"Unicode Message sent to other clients"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingMessagePackets.cs","line":58},"category":"Message"},{"id":"0x6F","name":"Secure Trade","description":"Client interacts with a secure trade window.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x6F","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"action","type":"enum","enumType":"sequential","size":1,"description":"Trade action type","values":[{"value":1,"name":"Cancel","description":"Cancel the trade"},{"value":2,"name":"Check","description":"Toggle accept checkbox"},{"value":3,"name":"UpdateGold","description":"Update virtual gold/platinum amounts"}]},{"name":"containerSerial","type":"uint","size":4,"description":"Serial of the trade container"},{"name":"checkData","type":"conditional","condition":"action == 2","fields":[{"name":"accepted","type":"int","size":4,"description":"Non-zero if accepting trade"}]},{"name":"goldData","type":"conditional","condition":"action == 3","fields":[{"name":"gold","type":"int","size":4,"description":"Gold amount to trade"},{"name":"platinum","type":"int","size":4,"description":"Platinum amount to trade"}]}],"related":[{"id":"0x6F","relationship":"response","note":"Server sends Secure Trade packet updates"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingMobilePackets.cs","line":93},"category":"Mobile"},{"id":"0x75","name":"Rename Request","description":"Client requests to rename a mobile (pet).","direction":"incoming","isDynamic":false,"size":35,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x75","description":"Packet identifier"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of mobile to rename"},{"name":"newName","type":"ascii","size":30,"description":"New name for the mobile"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingMobilePackets.cs","line":32},"category":"Mobile"},{"id":"0x98","name":"Mobile Name Request","description":"Client requests the name of a mobile.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x98","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"mobileSerial","type":"uint","size":4,"description":"Serial of mobile to query"}],"related":[{"id":"0x98","relationship":"response","note":"Server sends Mobile Name response"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingMobilePackets.cs","line":43},"category":"Mobile"},{"id":"0xB8","name":"Profile Request","description":"Client requests to view or edit a mobile's profile.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xB8","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"mode","type":"enum","enumType":"sequential","size":1,"description":"Request mode","values":[{"value":0,"name":"Display","description":"Request to view profile"},{"value":1,"name":"Edit","description":"Request to edit profile"}]},{"name":"mobileSerial","type":"uint","size":4,"description":"Serial of target mobile"},{"name":"editData","type":"conditional","condition":"mode == 1","fields":[{"name":"padding","type":"short","size":2,"description":"Unused padding"},{"name":"textLength","type":"ushort","size":2,"description":"Length of text in characters"},{"name":"text","type":"unicode-be","description":"New profile text"}]}],"related":[{"id":"0xB8","relationship":"response","note":"Display Profile packet"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingMobilePackets.cs","line":53},"category":"Mobile"},{"id":"0x02","name":"Movement Request","description":"Sent by the client when the player attempts to move in a direction. The server responds with either MovementAck (0x22) if successful or MovementRej (0x21) if blocked.","direction":"incoming","isDynamic":false,"size":7,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x02","description":"Packet identifier"},{"name":"direction","type":"byte","size":1,"description":"Movement direction (0-7). Bit 0x80 indicates running."},{"name":"sequence","type":"byte","size":1,"description":"Movement sequence number (1-255, wraps). Used for ack/rej matching."},{"name":"fastwalkKey","type":"uint","size":4,"description":"Anti-speedhack prevention key. Set to 0 if fastwalk prevention is disabled."}],"related":[{"id":"0x21","relationship":"rej","note":"Sent if movement is blocked"},{"id":"0x22","relationship":"ack","note":"Sent if movement is successful"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingMovementPackets.cs","line":83},"category":"Movement"},{"id":"0x01","name":"Disconnect","description":"Client sends disconnect notification.","direction":"incoming","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x01","description":"Packet identifier"},{"name":"minusOne","type":"int","size":4,"value":"0xFFFFFFFF","description":"Always -1"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":317},"category":"Player"},{"id":"0x05","name":"Attack Request","description":"Client requests to attack a mobile.","direction":"incoming","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x05","description":"Packet identifier"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of mobile to attack"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":69},"category":"Player"},{"id":"0x12","name":"Text Command","description":"Client sends text-based commands for skills, spells, virtues, etc.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x12","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"commandType","type":"enum","enumType":"sequential","size":1,"description":"Type of text command","values":[{"value":"0x24","name":"UseSkill","description":"Use a skill by ID"},{"value":"0x27","name":"CastSpellFromBook","description":"Cast spell from spellbook"},{"value":"0x2F","name":"OldScrollClick","description":"Old scroll double-click"},{"value":"0x43","name":"OpenSpellbook","description":"Open spellbook of type"},{"value":"0x56","name":"CastSpellMacro","description":"Cast spell from macro"},{"value":"0x58","name":"OpenDoor","description":"Open door macro"},{"value":"0xC7","name":"Animate","description":"Play animation"},{"value":"0xF4","name":"InvokeVirtue","description":"Invoke virtue from macro"}]},{"name":"command","type":"ascii-null","description":"Command-specific text (skill ID, spell ID, etc.)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":119},"category":"Player"},{"id":"0x22","name":"Resynchronize","description":"Client requests full world state resync.","direction":"incoming","isDynamic":false,"size":3,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x22","description":"Packet identifier"},{"name":"padding","type":"ushort","size":2,"description":"Unused padding"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":349},"category":"Player"},{"id":"0x2C","name":"Death Status Response","description":"Client acknowledges death status packet. Currently ignored by server.","direction":"incoming","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x2C","description":"Packet identifier"},{"name":"unknown","type":"byte","size":1,"description":"Unknown"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":58},"category":"Player"},{"id":"0x34","name":"Mobile Query","description":"Client queries information about a mobile (stats or skills).","direction":"incoming","isDynamic":false,"size":10,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x34","description":"Packet identifier"},{"name":"pattern","type":"uint","size":4,"value":"0xEDEDEDED","description":"Fixed pattern"},{"name":"queryType","type":"enum","enumType":"sequential","size":1,"description":"Type of query","values":[{"value":"0x04","name":"Stats","description":"Request mobile stats"},{"value":"0x05","name":"Skills","description":"Request mobile skills"}]},{"name":"mobileSerial","type":"uint","size":4,"description":"Serial of mobile to query"}],"related":[{"id":"0x11","relationship":"response","note":"Mobile Status packet sent in response to stats query"},{"id":"0x3A","relationship":"response","note":"Skills Update sent in response to skills query"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":376},"category":"Player"},{"id":"0x3A","name":"Change Skill Lock","description":"Client changes the lock state of a skill.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x3A","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"skillIndex","type":"short","size":2,"description":"Skill index to change"},{"name":"lockState","type":"enum","enumType":"sequential","size":1,"description":"New lock state","values":[{"value":0,"name":"Up","description":"Skill gains enabled"},{"value":1,"name":"Down","description":"Skill decreases enabled"},{"value":2,"name":"Locked","description":"Skill locked at current value"}]}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":331},"category":"Player"},{"id":"0x72","name":"Set War Mode","description":"Client toggles war/peace mode.","direction":"incoming","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x72","description":"Packet identifier"},{"name":"warmode","type":"bool","size":1,"description":"True = war mode, False = peace mode"},{"name":"padding","type":"byte","size":3,"description":"Unused padding (0x00, 0x32, 0x00)"}],"related":[{"id":"0x72","relationship":"response","note":"Server echoes back war mode state"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":343},"category":"Player"},{"id":"0x73","name":"Ping Request","description":"Client sends ping for latency measurement.","direction":"incoming","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x73","description":"Packet identifier"},{"name":"sequence","type":"byte","size":1,"description":"Ping sequence number"}],"related":[{"id":"0x73","relationship":"response","note":"Server echoes back same sequence"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":366},"category":"Player"},{"id":"0x7D","name":"Menu Response","description":"Client responds to a displayed item menu.","direction":"incoming","isDynamic":false,"size":13,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x7D","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Menu dialog serial"},{"name":"menuId","type":"short","size":2,"description":"Menu ID (unused in implementation)"},{"name":"index","type":"short","size":2,"description":"Selected item index (1-based, 0 = cancel)"},{"name":"itemId","type":"short","size":2,"description":"Item graphic ID of selection"},{"name":"hue","type":"short","size":2,"description":"Hue of selection"}],"related":[{"id":"0x7C","relationship":"request","note":"Display Item List Menu packet"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":287},"category":"Player"},{"id":"0x95","name":"Hue Picker Response","description":"Client responds to a hue picker dialog.","direction":"incoming","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x95","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Hue picker serial"},{"name":"itemId","type":"short","size":2,"description":"Item ID (unused)"},{"name":"hue","type":"short","size":2,"description":"Selected hue (masked with 0x3FFF)"}],"related":[{"id":"0x95","relationship":"request","note":"Display Hue Picker packet"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":86},"category":"Player"},{"id":"0x9A","name":"ASCII Prompt Response","description":"Client responds to an ASCII text prompt.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x9A","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Prompt serial"},{"name":"promptId","type":"int","size":4,"description":"Prompt ID"},{"name":"type","type":"int","size":4,"description":"Response type: 0 = cancel, other = submit"},{"name":"text","type":"ascii-null","description":"Response text (max 128 chars)"}],"related":[{"id":"0xC2","relationship":"request","note":"Prompt packet that triggered this response"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":214},"category":"Player"},{"id":"0x9B","name":"Help Request","description":"Client requests help/GM assistance.","direction":"incoming","isDynamic":false,"size":258,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x9B","description":"Packet identifier"},{"name":"data","type":"byte[]","size":257,"description":"Help request data (format TBD)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":338},"category":"Player"},{"id":"0xA4","name":"System Info","description":"Client sends system/hardware information.","direction":"incoming","isDynamic":false,"size":149,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA4","description":"Packet identifier"},{"name":"unknown1","type":"byte","size":1,"description":"Unknown"},{"name":"unknown2","type":"ushort","size":2,"description":"Unknown"},{"name":"unknown3","type":"byte","size":1,"description":"Unknown"},{"name":"string1","type":"ascii","size":32,"description":"System string 1"},{"name":"string2","type":"ascii","size":32,"description":"System string 2"},{"name":"string3","type":"ascii","size":32,"description":"System string 3"},{"name":"string4","type":"ascii","size":32,"description":"System string 4"},{"name":"unknown4","type":"ushort","size":2,"description":"Unknown"},{"name":"unknown5","type":"ushort","size":2,"description":"Unknown"},{"name":"unknown6","type":"int","size":4,"description":"Unknown"},{"name":"unknown7","type":"int","size":4,"description":"Unknown"},{"name":"unknown8","type":"int","size":4,"description":"Unknown"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":103},"category":"Player"},{"id":"0xA7","name":"Request Scroll Window","description":"Client requests a tips/scroll window.","direction":"incoming","isDynamic":false,"size":4,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA7","description":"Packet identifier"},{"name":"lastTip","type":"short","size":2,"description":"Last tip ID viewed"},{"name":"type","type":"byte","size":1,"description":"Scroll type"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":63},"category":"Player"},{"id":"0xC2","name":"Unicode Prompt Response","description":"Client responds to a Unicode text prompt.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xC2","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Prompt serial"},{"name":"promptId","type":"int","size":4,"description":"Prompt ID"},{"name":"type","type":"int","size":4,"description":"Response type: 0 = cancel, other = submit"},{"name":"language","type":"ascii","size":4,"description":"Language code (e.g., 'ENU')"},{"name":"text","type":"unicode-le-null","description":"Response text (max 128 chars)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":250},"category":"Player"},{"id":"0xC8","name":"Set Update Range","description":"Client requests to change update range. Server ignores and sends back fixed range.","direction":"incoming","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xC8","description":"Packet identifier"},{"name":"range","type":"byte","size":1,"description":"Requested update range (ignored)"}],"related":[{"id":"0xC8","relationship":"response","note":"Server sends back fixed range (18)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":371},"category":"Player"},{"id":"0xD0","name":"Configuration File","description":"Client sends configuration data. Currently ignored by server.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xD0","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"data","type":"byte[]","description":"Configuration data (ignored)"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":322},"category":"Player"},{"id":"0xD1","name":"Logout Request","description":"Client requests to logout.","direction":"incoming","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xD1","description":"Packet identifier"},{"name":"unknown","type":"byte","size":1,"description":"Unknown (typically 0x01)"}],"related":[{"id":"0xD1","relationship":"response","note":"Server sends Logout Ack"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":326},"category":"Player"},{"id":"0xD7","name":"Encoded Command","description":"Wrapper packet for encoded commands (0xD7 subpackets). Used for house design, abilities, guild/quest requests.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xD7","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"entitySerial","type":"uint","size":4,"description":"Serial of target entity"},{"name":"subCommand","type":"ushort","size":2,"description":"Encoded command ID"},{"name":"data","type":"byte[]","description":"Subcommand-specific data"}],"notes":"See encoded.json for subpacket definitions","source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":457},"category":"Player"},{"id":"0xF4","name":"Crash Report","description":"Client sends crash/error report.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xF4","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"clientMajor","type":"byte","size":1,"description":"Client major version"},{"name":"clientMinor","type":"byte","size":1,"description":"Client minor version"},{"name":"clientRev","type":"byte","size":1,"description":"Client revision"},{"name":"clientPat","type":"byte","size":1,"description":"Client patch"},{"name":"x","type":"ushort","size":2,"description":"Player X coordinate at crash"},{"name":"y","type":"ushort","size":2,"description":"Player Y coordinate at crash"},{"name":"z","type":"sbyte","size":1,"description":"Player Z coordinate at crash"},{"name":"map","type":"byte","size":1,"description":"Map ID at crash"},{"name":"accountName","type":"ascii","size":32,"description":"Account name"},{"name":"characterName","type":"ascii","size":32,"description":"Character name"},{"name":"ipAddress","type":"ascii","size":15,"description":"Client IP address"},{"name":"unknown1","type":"int","size":4,"description":"Unknown"},{"name":"exceptionCode","type":"int","size":4,"description":"Exception code"},{"name":"processName","type":"ascii","size":100,"description":"Process name"},{"name":"reportText","type":"ascii","size":100,"description":"Report text"},{"name":"terminator","type":"byte","size":1,"value":"0x00","description":"Null terminator"},{"name":"offset","type":"int","size":4,"description":"Crash offset"},{"name":"stackCount","type":"byte","size":1,"description":"Number of stack trace entries"},{"name":"stackAddresses","type":"loop","loop":{"countField":"stackCount","fields":[{"name":"address","type":"int","size":4,"description":"Stack frame address"}]}}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs","line":413},"category":"Player"},{"id":"0x6C","name":"Target Response","description":"Client responds to a target cursor request.","direction":"incoming","isDynamic":false,"size":19,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x6C","description":"Packet identifier"},{"name":"type","type":"enum","enumType":"sequential","size":1,"description":"Target type","values":[{"value":0,"name":"Object","description":"Targeting a specific object (mobile/item)"},{"value":1,"name":"Location","description":"Targeting a location/tile"}]},{"name":"targetId","type":"int","size":4,"description":"Target cursor ID to match request"},{"name":"flags","type":"enum","enumType":"sequential","size":1,"description":"Target flags","values":[{"value":0,"name":"Neutral","description":"Neutral targeting"},{"value":1,"name":"Harmful","description":"Harmful action"},{"value":2,"name":"Beneficial","description":"Beneficial action"},{"value":3,"name":"Cancel","description":"Targeting canceled"}]},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of targeted object (0 for ground)"},{"name":"x","type":"short","size":2,"description":"Target X coordinate (-1 if canceled)"},{"name":"y","type":"short","size":2,"description":"Target Y coordinate (-1 if canceled)"},{"name":"unknown","type":"byte","size":1,"description":"Unknown (typically 0)"},{"name":"z","type":"sbyte","size":1,"description":"Target Z coordinate"},{"name":"graphic","type":"ushort","size":2,"description":"Graphic ID of targeted tile (0 for land)"}],"related":[{"id":"0x6C","relationship":"request","note":"Target Request packet that initiated this"}],"notes":"If x == -1 && y == -1 && serial is invalid, user pressed Escape to cancel targeting.","source":{"file":"Projects/UOContent/Network/Packets/IncomingTargetingPackets.cs","line":28},"category":"Targeting"},{"id":"0x3B","name":"Vendor Buy Reply","description":"Client confirms items to purchase from a vendor.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x3B","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"vendorSerial","type":"uint","size":4,"description":"Serial of the vendor"},{"name":"flag","type":"byte","size":1,"description":"0x00 = buy, 0x02 = cancel"},{"name":"items","type":"loop","loop":{"untilEnd":true,"fields":[{"name":"layer","type":"byte","size":1,"description":"Layer/container index"},{"name":"itemSerial","type":"uint","size":4,"description":"Serial of item to buy"},{"name":"amount","type":"short","size":2,"description":"Amount to purchase"}]}}],"related":[{"id":"0x74","relationship":"request","note":"Vendor Buy List packet that initiated this"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingVendorPackets.cs","line":25},"category":"Vendor"},{"id":"0x9F","name":"Vendor Sell Reply","description":"Client confirms items to sell to a vendor.","direction":"incoming","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x9F","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"vendorSerial","type":"uint","size":4,"description":"Serial of the vendor"},{"name":"itemCount","type":"ushort","size":2,"description":"Number of items to sell"},{"name":"items","type":"loop","loop":{"countField":"itemCount","fields":[{"name":"itemSerial","type":"uint","size":4,"description":"Serial of item to sell"},{"name":"amount","type":"short","size":2,"description":"Amount to sell"}]}}],"related":[{"id":"0x9E","relationship":"request","note":"Vendor Sell List packet that initiated this"}],"source":{"file":"Projects/UOContent/Network/Packets/IncomingVendorPackets.cs","line":26},"category":"Vendor"}],"outgoing":[{"id":"0x82","name":"Account Login Rejected","description":"Sent when account login fails. Contains the reason for rejection.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x82","description":"Packet identifier"},{"name":"reason","type":"byte","size":1,"description":"Rejection reason: 0=Invalid, 1=InUse, 2=Blocked, 3=BadPass, 254=Idle, 255=BadComm"}],"related":[{"id":"0x80","relationship":"request","note":"The login attempt that failed"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":402},"category":"Account"},{"id":"0xA8","name":"Account Login Ack (Server List)","description":"Sent after successful account login. Contains the list of available game servers.","direction":"outgoing","isDynamic":true,"size":"6 + (40 * serverCount)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA8","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"systemInfoFlag","type":"byte","size":1,"value":"0x5D","description":"System info flag"},{"name":"serverCount","type":"ushort","size":2,"description":"Number of servers in list"},{"name":"servers","type":"array","description":"Server list entries","loop":{"countField":"serverCount","fields":[{"name":"index","type":"ushort","size":2,"description":"Server index"},{"name":"name","type":"ascii","size":32,"description":"Server name"},{"name":"fullPercent","type":"byte","size":1,"description":"Server load percentage"},{"name":"timezone","type":"sbyte","size":1,"description":"Server timezone offset"},{"name":"ipAddress","type":"uint","size":4,"description":"Server IP address (IPv4)"}]}}],"related":[{"id":"0x80","relationship":"request","note":"The successful login request"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":411},"category":"Account"},{"id":"0x8C","name":"Play Server Ack","description":"Sent after selecting a server. Contains connection details for the game server.","direction":"outgoing","isDynamic":false,"size":11,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x8C","description":"Packet identifier"},{"name":"ipAddress","type":"uint","size":4,"description":"Game server IP address (little-endian)"},{"name":"port","type":"short","size":2,"description":"Game server port"},{"name":"authId","type":"int","size":4,"description":"Authentication ID for game login"}],"related":[{"id":"0xA0","relationship":"request","note":"The server selection request"},{"id":"0x91","relationship":"response","note":"Client sends game login with this authId"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":447},"category":"Account"},{"id":"0xA9","name":"Character List","description":"Sent after game login. Contains the list of characters on the account and starting city information.","direction":"outgoing","isDynamic":true,"size":"variable (client version dependent)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA9","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"charCount","type":"byte","size":1,"description":"Number of character slots"},{"name":"characters","type":"array","description":"Character list entries","loop":{"countField":"charCount","fields":[{"name":"name","type":"ascii","size":30,"description":"Character name (empty if slot unused)"},{"name":"password","type":"ascii","size":30,"description":"Always empty"}]}},{"name":"cityCount","type":"byte","size":1,"description":"Number of starting cities"},{"name":"cities","type":"array","description":"Starting city entries","loop":{"countField":"cityCount","fields":[{"name":"index","type":"byte","size":1,"description":"City index"},{"name":"cityName","type":"ascii","size":31,"description":"City name (32 for 7.0.13.0+)"},{"name":"buildingName","type":"ascii","size":31,"description":"Building name (32 for 7.0.13.0+)"},{"name":"x","type":"int","size":4,"description":"X coordinate (7.0.13.0+ only)","condition":"client >= 7.0.13.0"},{"name":"y","type":"int","size":4,"description":"Y coordinate (7.0.13.0+ only)","condition":"client >= 7.0.13.0"},{"name":"z","type":"int","size":4,"description":"Z coordinate (7.0.13.0+ only)","condition":"client >= 7.0.13.0"},{"name":"mapId","type":"int","size":4,"description":"Map ID (7.0.13.0+ only)","condition":"client >= 7.0.13.0"},{"name":"cliloc","type":"int","size":4,"description":"Description cliloc (7.0.13.0+ only)","condition":"client >= 7.0.13.0"},{"name":"unknown","type":"int","size":4,"description":"Unknown (7.0.13.0+ only)","condition":"client >= 7.0.13.0"}]}},{"name":"flags","type":"int","size":4,"description":"Character list flags (slot limits, features)"},{"name":"lastCharSlot","type":"short","size":2,"description":"Last played character slot (7.0.13.0+ only)","condition":"client >= 7.0.13.0"}],"clientVersion":{"feature":"NewCharacterList","notes":"Clients 7.0.13.0+ use extended city format with coordinates"},"related":[{"id":"0x91","relationship":"request","note":"Game login request"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":293},"category":"Account"},{"id":"0x1B","name":"Login Confirmation","description":"Sent when entering the world. Confirms the player's mobile serial and initial position.","direction":"outgoing","isDynamic":false,"size":37,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x1B","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Player mobile serial"},{"name":"unknown","type":"int","size":4,"value":"0","description":"Unknown (always 0)"},{"name":"body","type":"short","size":2,"description":"Player body ID"},{"name":"x","type":"short","size":2,"description":"X coordinate"},{"name":"y","type":"short","size":2,"description":"Y coordinate"},{"name":"z","type":"short","size":2,"description":"Z coordinate"},{"name":"direction","type":"byte","size":1,"description":"Facing direction"},{"name":"unknown2","type":"byte","size":1,"value":"0","description":"Unknown"},{"name":"unknown3","type":"int","size":4,"value":"-1","description":"Unknown (always -1)"},{"name":"unknown4","type":"int","size":4,"value":"0","description":"Unknown"},{"name":"mapWidth","type":"short","size":2,"description":"Map width in tiles"},{"name":"mapHeight","type":"short","size":2,"description":"Map height in tiles"},{"name":"unknown5","type":"byte[6]","size":6,"description":"Unknown (zeros)"}],"related":[{"id":"0x5D","relationship":"request","note":"Play character request"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":190},"category":"Account"},{"id":"0x55","name":"Login Complete","description":"Final packet in the login sequence. Signals that the client can begin normal gameplay.","direction":"outgoing","isDynamic":false,"size":1,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x55","description":"Packet identifier"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":231},"category":"Account"},{"id":"0xBD","name":"Client Version Request","description":"Request for the client to send its version string.","direction":"outgoing","isDynamic":false,"size":3,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBD","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"0x0003","description":"Packet length"}],"related":[{"id":"0xBD","relationship":"response","note":"Client responds with version string"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":112},"notes":"Same packet ID (0xBD) is used for both request (server) and response (client).","category":"Account"},{"id":"0xB9","name":"Supported Features","description":"Informs the client which features are enabled on the server.","direction":"outgoing","isDynamic":false,"size":"3 or 5 (client version dependent)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xB9","description":"Packet identifier"},{"name":"features","type":"ushort/uint","size":"2 or 4","description":"Feature flags bitmask. Extended (4 bytes) for newer clients."}],"clientVersion":{"feature":"ExtendedSupportedFeatures","notes":"Clients with ExtendedSupportedFeatures use 4-byte flags instead of 2-byte"},"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":140},"category":"Account"},{"id":"0x85","name":"Character Delete Result","description":"Result of a character deletion request.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x85","description":"Packet identifier"},{"name":"result","type":"byte","size":1,"description":"Result: 0=PasswordInvalid, 1=CharNotExist, 2=CharBeingPlayed, 3=CharTooYoung, 4=CharQueued, 5=BadRequest"}],"related":[{"id":"0x83","relationship":"request","note":"The delete request"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":121},"category":"Account"},{"id":"0x53","name":"Popup Message","description":"Displays a predefined popup message to the client.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x53","description":"Packet identifier"},{"name":"messageId","type":"byte","size":1,"description":"Message ID: 1=CharNoExist, 2=CharExists, 5=CharInWorld, 6=LoginSyncError, 7=IdleWarning"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":131},"category":"Account"},{"id":"0x81","name":"Change Character","description":"Updates the character list during reconnection. Currently unused.","direction":"outgoing","isDynamic":true,"size":"5 + (60 * charCount)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x81","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"charCount","type":"ushort","size":2,"description":"Number of characters"},{"name":"characters","type":"array","description":"Character list entries","loop":{"countField":"charCount","fields":[{"name":"name","type":"ascii","size":30,"description":"Character name"},{"name":"password","type":"ascii","size":30,"description":"Always empty"}]}}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":63},"notes":"Currently unused in ModernUO.","category":"Account"},{"id":"0x86","name":"Character List Update","description":"Updates the character list after character creation or deletion.","direction":"outgoing","isDynamic":true,"size":"4 + (60 * charCount)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x86","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"charCount","type":"byte","size":1,"description":"Number of character slots"},{"name":"characters","type":"array","description":"Character list entries","loop":{"countField":"charCount","fields":[{"name":"name","type":"ascii","size":30,"description":"Character name (empty if slot unused)"},{"name":"password","type":"ascii","size":30,"description":"Always empty"}]}}],"source":{"file":"Projects/Server/Network/Packets/OutgoingAccountPackets.cs","line":242},"category":"Account"},{"id":"0x2F","name":"Swing","description":"Notifies client of a melee swing between two mobiles.","direction":"outgoing","isDynamic":false,"size":10,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x2F","description":"Packet identifier"},{"name":"unknown","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"attackerSerial","type":"uint","size":4,"description":"Serial of attacker"},{"name":"defenderSerial","type":"uint","size":4,"description":"Serial of defender"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingCombatPackets.cs","line":23},"category":"Combat"},{"id":"0x72","name":"Set War Mode","description":"Sets the client's war/peace mode state.","direction":"outgoing","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x72","description":"Packet identifier"},{"name":"warmode","type":"bool","size":1,"description":"True = war mode, False = peace mode"},{"name":"unknown1","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"unknown2","type":"byte","size":1,"value":"0x32","description":"Unknown (50)"},{"name":"unknown3","type":"byte","size":1,"value":"0x00","description":"Unknown"}],"related":[{"id":"0x72","relationship":"request","note":"Set War Mode from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingCombatPackets.cs","line":40},"category":"Combat"},{"id":"0xAA","name":"Change Combatant","description":"Notifies client of current combat target.","direction":"outgoing","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xAA","description":"Packet identifier"},{"name":"combatantSerial","type":"uint","size":4,"description":"Serial of current combatant (0 = none)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingCombatPackets.cs","line":43},"category":"Combat"},{"id":"0x24","name":"Display Container","description":"Opens a container gump on the client.","direction":"outgoing","isDynamic":false,"size":"7 (pre-HS) or 9 (HS+)","variants":[{"version":"pre-HighSeas","name":"Classic","size":7,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x24","description":"Packet identifier"},{"name":"containerSerial","type":"uint","size":4,"description":"Serial of the container"},{"name":"gumpId","type":"ushort","size":2,"description":"Gump graphic ID"}]},{"version":"HighSeas+","name":"High Seas Extended","condition":"Client version >= 7.0.9.0 (HighSeas)","size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x24","description":"Packet identifier"},{"name":"containerSerial","type":"uint","size":4,"description":"Serial of the container"},{"name":"gumpId","type":"ushort","size":2,"description":"Gump graphic ID"},{"name":"containerType","type":"short","size":2,"value":"0x007D","description":"Container type (125)"}]}],"clientVersion":{"feature":"HighSeas adds containerType field"},"source":{"file":"Projects/Server/Network/Packets/OutgoingContainerPackets.cs","line":108},"category":"Container"},{"id":"0x25","name":"Container Content Update","description":"Updates a single item in a container.","direction":"outgoing","isDynamic":false,"size":"20 (pre-6017) or 21 (6017+)","variants":[{"version":"pre-6017","name":"Classic","size":20,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x25","description":"Packet identifier"},{"name":"itemSerial","type":"uint","size":4,"description":"Serial of the item"},{"name":"itemId","type":"ushort","size":2,"description":"Item graphic ID"},{"name":"itemIdOffset","type":"byte","size":1,"value":"0x00","description":"Item ID offset (signed)"},{"name":"amount","type":"ushort","size":2,"description":"Stack amount"},{"name":"x","type":"short","size":2,"description":"X position in container"},{"name":"y","type":"short","size":2,"description":"Y position in container"},{"name":"containerSerial","type":"uint","size":4,"description":"Serial of parent container"},{"name":"hue","type":"ushort","size":2,"description":"Item hue"}]},{"version":"6017+","name":"Container Grid Lines","condition":"Client version >= 6.0.1.7 (ContainerGridLines)","size":21,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x25","description":"Packet identifier"},{"name":"itemSerial","type":"uint","size":4,"description":"Serial of the item"},{"name":"itemId","type":"ushort","size":2,"description":"Item graphic ID"},{"name":"itemIdOffset","type":"byte","size":1,"value":"0x00","description":"Item ID offset (signed)"},{"name":"amount","type":"ushort","size":2,"description":"Stack amount"},{"name":"x","type":"short","size":2,"description":"X position in container"},{"name":"y","type":"short","size":2,"description":"Y position in container"},{"name":"gridLocation","type":"byte","size":1,"description":"Grid slot position"},{"name":"containerSerial","type":"uint","size":4,"description":"Serial of parent container"},{"name":"hue","type":"ushort","size":2,"description":"Item hue"}]}],"clientVersion":{"feature":"ContainerGridLines adds gridLocation byte"},"source":{"file":"Projects/Server/Network/Packets/OutgoingContainerPackets.cs","line":127},"category":"Container"},{"id":"0x3C","name":"Container Content","description":"Sends full contents of a container.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x3C","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"itemCount","type":"ushort","size":2,"description":"Number of items"},{"name":"items","type":"loop","loop":{"countField":"itemCount","itemSize":"19 (pre-6017) or 20 (6017+)","fields":[{"name":"itemSerial","type":"uint","size":4,"description":"Serial of the item"},{"name":"itemId","type":"ushort","size":2,"description":"Item graphic ID"},{"name":"itemIdOffset","type":"byte","size":1,"description":"Item ID offset (signed)"},{"name":"amount","type":"ushort","size":2,"description":"Stack amount"},{"name":"x","type":"short","size":2,"description":"X position in container"},{"name":"y","type":"short","size":2,"description":"Y position in container"},{"name":"gridLocation","type":"byte","size":1,"description":"Grid slot (6017+ only)","condition":"ContainerGridLines"},{"name":"containerSerial","type":"uint","size":4,"description":"Serial of parent container"},{"name":"hue","type":"ushort","size":2,"description":"Item hue"}]}}],"clientVersion":{"feature":"ContainerGridLines adds gridLocation byte per item"},"source":{"file":"Projects/Server/Network/Packets/OutgoingContainerPackets.cs","line":169},"category":"Container"},{"id":"0xBF/0x1B","name":"New Spellbook Content","description":"Sends spellbook contents using AOS format.","direction":"outgoing","isDynamic":false,"size":23,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"23","description":"Packet length"},{"name":"subCommand","type":"short","size":2,"value":"0x1B","description":"Subcommand (New Spellbook Content)"},{"name":"command","type":"short","size":2,"value":"0x01","description":"Command (always 1)"},{"name":"bookSerial","type":"uint","size":4,"description":"Serial of the spellbook"},{"name":"graphic","type":"short","size":2,"description":"Spellbook graphic ID"},{"name":"offset","type":"short","size":2,"description":"Spell offset (circle/school start)"},{"name":"spellBits","type":"ulong","size":8,"description":"64-bit mask of known spells (Little Endian)"}],"clientVersion":{"min":"5.0.0a","feature":"NewSpellbook"},"notes":"Used when Core.AOS && ns.NewSpellbook. Otherwise, old 0x3C format is used.","source":{"file":"Projects/Server/Network/Packets/OutgoingContainerPackets.cs","line":46},"category":"Container"},{"id":"0x0B","name":"Damage","description":"Shows damage dealt to a mobile (client 5.0.0a+).","direction":"outgoing","isDynamic":false,"size":7,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x0B","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of damaged mobile"},{"name":"damage","type":"ushort","size":2,"description":"Damage amount (clamped 0-65535)"}],"clientVersion":{"min":"5.0.0a","feature":"DamagePacket"},"notes":"For pre-5.0.0a clients, use 0xBF/0x22 instead.","source":{"file":"Projects/Server/Network/Packets/OutgoingDamagePackets.cs","line":34},"category":"Damage"},{"id":"0xBF/0x22","name":"Damage (Old)","description":"Shows damage dealt to a mobile (pre-5.0.0a clients).","direction":"outgoing","isDynamic":false,"size":11,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"11","description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x22","description":"Subcommand (Damage)"},{"name":"unknown","type":"byte","size":1,"value":"0x01","description":"Unknown (always 1)"},{"name":"serial","type":"uint","size":4,"description":"Serial of damaged mobile"},{"name":"damage","type":"byte","size":1,"description":"Damage amount (clamped 0-255)"}],"clientVersion":{"max":"5.0.0a","notes":"For clients before DamagePacket feature"},"notes":"Damage is capped at 255 for old clients.","source":{"file":"Projects/Server/Network/Packets/OutgoingDamagePackets.cs","line":40},"category":"Damage"},{"id":"0x54","name":"Sound Effect","description":"Plays a sound effect at a location.","direction":"outgoing","isDynamic":false,"size":12,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x54","description":"Packet identifier"},{"name":"flags","type":"byte","size":1,"value":"0x01","description":"Sound flags"},{"name":"soundId","type":"short","size":2,"description":"Sound effect ID"},{"name":"volume","type":"short","size":2,"value":"0x0000","description":"Volume (unused)"},{"name":"x","type":"short","size":2,"description":"X coordinate"},{"name":"y","type":"short","size":2,"description":"Y coordinate"},{"name":"z","type":"short","size":2,"description":"Z coordinate"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingEffectPackets.cs","line":41},"category":"Effects"},{"id":"0x70","name":"Screen Effect","description":"Triggers a screen-wide visual effect (fade in/out).","direction":"outgoing","isDynamic":false,"size":28,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x70","description":"Packet identifier"},{"name":"effectType","type":"byte","size":1,"value":"0x04","description":"Effect type (4)"},{"name":"padding1","type":"byte[]","size":8,"description":"Padding (zeros)"},{"name":"type","type":"enum","enumType":"sequential","size":2,"description":"Screen effect type","values":[{"value":0,"name":"FadeOut","description":"Fade screen to black"},{"value":1,"name":"FadeIn","description":"Fade screen from black"},{"value":2,"name":"LightFlash","description":"Light flash effect"},{"value":3,"name":"FadeInOut","description":"Fade out then in"},{"value":4,"name":"DarkenScreen","description":"Darken screen"}]},{"name":"padding2","type":"byte[]","size":16,"description":"Padding (zeros)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingEffectPackets.cs","line":322},"category":"Effects"},{"id":"0xC0","name":"Hued Effect","description":"Displays a graphical effect with hue and render mode.","direction":"outgoing","isDynamic":false,"size":36,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xC0","description":"Packet identifier"},{"name":"effectType","type":"enum","enumType":"sequential","size":1,"description":"Effect type","values":[{"value":0,"name":"Moving","description":"Effect moves between two points"},{"value":1,"name":"Lightning","description":"Lightning bolt effect"},{"value":2,"name":"FixedXYZ","description":"Effect at fixed location"},{"value":3,"name":"FixedFrom","description":"Effect attached to source"}]},{"name":"sourceSerial","type":"uint","size":4,"description":"Serial of source entity"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of target entity"},{"name":"itemId","type":"short","size":2,"description":"Effect graphic ID"},{"name":"srcX","type":"short","size":2,"description":"Source X coordinate"},{"name":"srcY","type":"short","size":2,"description":"Source Y coordinate"},{"name":"srcZ","type":"sbyte","size":1,"description":"Source Z coordinate"},{"name":"dstX","type":"short","size":2,"description":"Destination X coordinate"},{"name":"dstY","type":"short","size":2,"description":"Destination Y coordinate"},{"name":"dstZ","type":"sbyte","size":1,"description":"Destination Z coordinate"},{"name":"speed","type":"byte","size":1,"description":"Effect speed"},{"name":"duration","type":"byte","size":1,"description":"Effect duration"},{"name":"unknown1","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"unknown2","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"fixedDirection","type":"bool","size":1,"description":"Fixed direction"},{"name":"explode","type":"bool","size":1,"description":"Explode on impact"},{"name":"hue","type":"int","size":4,"description":"Effect hue"},{"name":"renderMode","type":"int","size":4,"description":"Render mode"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingEffectPackets.cs","line":175},"category":"Effects"},{"id":"0xC7","name":"Particle Effect","description":"Displays an advanced particle effect with extended parameters.","direction":"outgoing","isDynamic":false,"size":49,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xC7","description":"Packet identifier"},{"name":"effectType","type":"byte","size":1,"description":"Effect type (see 0xC0)"},{"name":"sourceSerial","type":"uint","size":4,"description":"Serial of source entity"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of target entity"},{"name":"itemId","type":"short","size":2,"description":"Effect graphic ID"},{"name":"srcX","type":"short","size":2,"description":"Source X coordinate"},{"name":"srcY","type":"short","size":2,"description":"Source Y coordinate"},{"name":"srcZ","type":"sbyte","size":1,"description":"Source Z coordinate"},{"name":"dstX","type":"short","size":2,"description":"Destination X coordinate"},{"name":"dstY","type":"short","size":2,"description":"Destination Y coordinate"},{"name":"dstZ","type":"sbyte","size":1,"description":"Destination Z coordinate"},{"name":"speed","type":"byte","size":1,"description":"Effect speed"},{"name":"duration","type":"byte","size":1,"description":"Effect duration"},{"name":"unknown1","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"unknown2","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"fixedDirection","type":"bool","size":1,"description":"Fixed direction"},{"name":"explode","type":"bool","size":1,"description":"Explode on impact"},{"name":"hue","type":"int","size":4,"description":"Effect hue"},{"name":"renderMode","type":"int","size":4,"description":"Render mode"},{"name":"effect","type":"short","size":2,"description":"Particle effect ID"},{"name":"explodeEffect","type":"short","size":2,"description":"Explosion effect ID"},{"name":"explodeSound","type":"short","size":2,"description":"Explosion sound ID"},{"name":"serial","type":"uint","size":4,"description":"Associated entity serial"},{"name":"layer","type":"byte","size":1,"description":"Effect layer"},{"name":"unknown3","type":"short","size":2,"description":"Unknown"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingEffectPackets.cs","line":58},"category":"Effects"},{"id":"0x1D","name":"Remove Entity","description":"Removes an entity (item, mobile, or multi) from the client's view.","direction":"outgoing","isDynamic":false,"size":5,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x1D","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of entity to remove"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingEntityPackets.cs","line":75},"category":"Entity"},{"id":"0xDC","name":"OPL Info (Object Property List)","description":"Notifies the client of an entity's Object Property List hash. Client compares hash to cached version and requests full OPL if different.","direction":"outgoing","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xDC","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Entity serial"},{"name":"hash","type":"int","size":4,"description":"Hash of the Object Property List"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingEntityPackets.cs","line":33},"category":"Entity"},{"id":"0xF3","name":"World Entity (SA+)","description":"Unified entity packet for items, mobiles, and multis. Replaces older item/mobile-specific packets for Stygian Abyss+ clients.","direction":"outgoing","isDynamic":false,"size":"24 (pre-HS) or 26 (HS+)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xF3","description":"Packet identifier"},{"name":"command","type":"short","size":2,"value":"0x0001","description":"Command (always 1)"},{"name":"entityType","type":"byte","size":1,"description":"Entity type: 0=Item, 1=Mobile, 2=Multi"},{"name":"serial","type":"uint","size":4,"description":"Entity serial"},{"name":"graphicId","type":"ushort","size":2,"description":"Graphic/Body ID"},{"name":"direction","type":"byte","size":1,"description":"Direction (mobiles) or 0"},{"name":"amountMin","type":"short","size":2,"description":"Minimum amount (items) or 1"},{"name":"amountMax","type":"short","size":2,"description":"Maximum amount (items) or 1"},{"name":"x","type":"short","size":2,"description":"X coordinate (masked with 0x7FFF)"},{"name":"y","type":"short","size":2,"description":"Y coordinate (masked with 0x3FFF)"},{"name":"z","type":"sbyte","size":1,"description":"Z coordinate"},{"name":"light","type":"byte","size":1,"description":"Light level (items)"},{"name":"hue","type":"short","size":2,"description":"Hue/color"},{"name":"flags","type":"byte","size":1,"description":"Packet flags (hidden, blessed, etc.)"},{"name":"unknown","type":"short","size":2,"description":"Unknown (HS+ only)","condition":"HighSeas"}],"clientVersion":{"min":"7.0.9.0","feature":"StygianAbyss"},"source":{"file":"Projects/Server/Network/Packets/OutgoingEntityPackets.cs","line":88},"category":"Entity"},{"id":"0x1A","name":"World Item","description":"Displays an item in the world (pre-Stygian Abyss clients).","direction":"outgoing","isDynamic":true,"size":"Dynamic (14-20 bytes)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x1A","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length (14-20)"},{"name":"serial","type":"uint","size":4,"description":"Item serial (bit 31 set if amount present)"},{"name":"itemId","type":"ushort","size":2,"description":"Item graphic ID (bit 14 set for multi)"},{"name":"amount","type":"ushort","size":2,"description":"Stack amount (if serial bit 31 set)","condition":"serial & 0x80000000"},{"name":"x","type":"ushort","size":2,"description":"X coordinate (bit 15 set if direction present)"},{"name":"y","type":"ushort","size":2,"description":"Y coordinate (bit 15=hue, bit 14=flags)"},{"name":"direction","type":"byte","size":1,"description":"Direction (if x bit 15 set)","condition":"x & 0x8000"},{"name":"z","type":"sbyte","size":1,"description":"Z coordinate"},{"name":"hue","type":"ushort","size":2,"description":"Item hue (if y bit 15 set)","condition":"y & 0x8000"},{"name":"flags","type":"byte","size":1,"description":"Packet flags (if y bit 14 set)","condition":"y & 0x4000"}],"notes":"For Stygian Abyss+ clients, use 0xF3 World Entity instead.","clientVersion":{"max":"6.0.14.2","notes":"Replaced by 0xF3 for SA+ clients"},"source":{"file":"Projects/Server/Network/Packets/OutgoingItemPackets.cs","line":24},"category":"Items"},{"id":"0x4E","name":"Personal Light Level","description":"Sets the light level for a specific entity.","direction":"outgoing","isDynamic":false,"size":6,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x4E","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of entity"},{"name":"level","type":"byte","size":1,"description":"Light level (0=brightest, 25-30=typical night)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingLightPackets.cs","line":23},"category":"Light"},{"id":"0x4F","name":"Global Light Level","description":"Sets the global ambient light level for the client.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x4F","description":"Packet identifier"},{"name":"level","type":"byte","size":1,"description":"Light level (0=brightest, 25-30=typical night)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingLightPackets.cs","line":39},"category":"Light"},{"id":"0x15","name":"Follow Message","description":"Instructs client to follow one entity with another.","direction":"outgoing","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x15","description":"Packet identifier"},{"name":"followerSerial","type":"uint","size":4,"description":"Serial of the follower"},{"name":"targetSerial","type":"uint","size":4,"description":"Serial of the target to follow"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMessagePackets.cs","line":231},"category":"Message"},{"id":"0x1C","name":"ASCII Message","description":"Server sends ASCII-encoded message to client.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x1C","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Serial of speaker (0xFFFFFFFF for system)"},{"name":"graphic","type":"short","size":2,"description":"Body graphic of speaker"},{"name":"type","type":"enum","enumType":"sequential","size":1,"description":"Message type","values":[{"value":0,"name":"Regular","description":"Normal speech"},{"value":1,"name":"System","description":"System message"},{"value":2,"name":"Emote","description":"Emote (*action*)"},{"value":6,"name":"Label","description":"Object label"},{"value":7,"name":"Focus","description":"Focused message"},{"value":8,"name":"Whisper","description":"Whisper"},{"value":9,"name":"Yell","description":"Yell"},{"value":10,"name":"Spell","description":"Spell words"},{"value":13,"name":"Guild","description":"Guild chat"},{"value":14,"name":"Alliance","description":"Alliance chat"},{"value":15,"name":"Command","description":"Command"}]},{"name":"hue","type":"short","size":2,"description":"Text color hue"},{"name":"font","type":"short","size":2,"description":"Font ID"},{"name":"name","type":"ascii","size":30,"description":"Speaker name"},{"name":"text","type":"ascii-null","description":"Message text"}],"related":[{"id":"0x03","relationship":"request","note":"ASCII Speech from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMessagePackets.cs","line":180},"category":"Message"},{"id":"0xAE","name":"Unicode Message","description":"Server sends Unicode-encoded message to client.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xAE","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Serial of speaker (0xFFFFFFFF for system)"},{"name":"graphic","type":"short","size":2,"description":"Body graphic of speaker"},{"name":"type","type":"byte","size":1,"description":"Message type (see 0x1C)"},{"name":"hue","type":"short","size":2,"description":"Text color hue"},{"name":"font","type":"short","size":2,"description":"Font ID"},{"name":"language","type":"ascii","size":4,"description":"Language code (e.g., 'ENU')"},{"name":"name","type":"ascii","size":30,"description":"Speaker name"},{"name":"text","type":"unicode-be-null","description":"Message text (Big Endian Unicode)"}],"related":[{"id":"0xAD","relationship":"request","note":"Unicode Speech from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMessagePackets.cs","line":180},"category":"Message"},{"id":"0xB7","name":"Help Response","description":"Server sends help text response to client.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xB7","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Serial of entity"},{"name":"text","type":"unicode-be-null","description":"Help text"}],"related":[{"id":"0xB6","relationship":"request","note":"Object Help Request from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMessagePackets.cs","line":263},"category":"Message"},{"id":"0xC1","name":"Localized Message","description":"Server sends a localized (cliloc) message to client.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xC1","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Serial of speaker"},{"name":"graphic","type":"short","size":2,"description":"Body graphic of speaker"},{"name":"type","type":"byte","size":1,"description":"Message type (see 0x1C)"},{"name":"hue","type":"short","size":2,"description":"Text color hue"},{"name":"font","type":"short","size":2,"description":"Font ID"},{"name":"clilocNumber","type":"int","size":4,"description":"Cliloc entry number"},{"name":"name","type":"ascii","size":30,"description":"Speaker name"},{"name":"arguments","type":"unicode-le-null","description":"Tab-separated arguments for cliloc"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMessagePackets.cs","line":55},"category":"Message"},{"id":"0xC2","name":"Prompt","description":"Server requests text input from client.","direction":"outgoing","isDynamic":false,"size":21,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xC2","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"21","description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Prompt serial"},{"name":"promptId","type":"uint","size":4,"description":"Prompt ID (same as serial)"},{"name":"padding","type":"byte[]","size":10,"description":"Unused padding (zeros)"}],"related":[{"id":"0x9A","relationship":"response","note":"ASCII Prompt Response"},{"id":"0xC2","relationship":"response","note":"Unicode Prompt Response"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMessagePackets.cs","line":246},"category":"Message"},{"id":"0xCC","name":"Localized Message Affix","description":"Server sends a localized message with text prefix/suffix.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xCC","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Serial of speaker"},{"name":"graphic","type":"short","size":2,"description":"Body graphic of speaker"},{"name":"type","type":"byte","size":1,"description":"Message type (see 0x1C)"},{"name":"hue","type":"short","size":2,"description":"Text color hue"},{"name":"font","type":"short","size":2,"description":"Font ID"},{"name":"clilocNumber","type":"int","size":4,"description":"Cliloc entry number"},{"name":"affixType","type":"bitfield","size":1,"description":"How to apply the affix","flags":[{"bit":"0x00","name":"Append","description":"Append affix to end"},{"bit":"0x01","name":"Prepend","description":"Prepend affix to start"},{"bit":"0x02","name":"System","description":"System message style"}]},{"name":"name","type":"ascii","size":30,"description":"Speaker name"},{"name":"affix","type":"ascii-null","description":"Text to prepend/append"},{"name":"arguments","type":"unicode-be-null","description":"Tab-separated arguments for cliloc"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMessagePackets.cs","line":112},"category":"Message"},{"id":"0x11","name":"Mobile Status","description":"Detailed status information for a mobile. Length and content varies based on client version and whether viewing self or others.","direction":"outgoing","isDynamic":true,"size":"43-121 bytes (version dependent)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x11","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"name","type":"ascii","size":30,"description":"Mobile name"},{"name":"hitsMax","type":"short","size":2,"description":"Maximum hits (normalized to 100 for non-self)"},{"name":"hits","type":"short","size":2,"description":"Current hits"},{"name":"canBeRenamed","type":"bool","size":1,"description":"Whether the mobile can be renamed by viewer"},{"name":"version","type":"byte","size":1,"description":"Status version: 0=compact, 3=basic, 4=AOS, 5=ML, 6=HS"},{"name":"female","type":"bool","size":1,"description":"Gender flag (version 1+)","condition":"version >= 1"},{"name":"str","type":"short","size":2,"description":"Strength","condition":"version >= 1"},{"name":"dex","type":"short","size":2,"description":"Dexterity","condition":"version >= 1"},{"name":"int","type":"short","size":2,"description":"Intelligence","condition":"version >= 1"},{"name":"stam","type":"short","size":2,"description":"Current stamina","condition":"version >= 1"},{"name":"stamMax","type":"short","size":2,"description":"Maximum stamina","condition":"version >= 1"},{"name":"mana","type":"short","size":2,"description":"Current mana","condition":"version >= 1"},{"name":"manaMax","type":"short","size":2,"description":"Maximum mana","condition":"version >= 1"},{"name":"gold","type":"int","size":4,"description":"Total gold","condition":"version >= 1"},{"name":"armorRating","type":"short","size":2,"description":"Armor rating (physical resist in AOS+)","condition":"version >= 1"},{"name":"weight","type":"short","size":2,"description":"Current weight","condition":"version >= 1"},{"name":"maxWeight","type":"short","size":2,"description":"Maximum weight","condition":"version >= 5"},{"name":"race","type":"byte","size":1,"description":"Race ID + 1 (0 = no race)","condition":"version >= 5"},{"name":"statCap","type":"short","size":2,"description":"Stat cap","condition":"version >= 1"},{"name":"followers","type":"byte","size":1,"description":"Current followers","condition":"version >= 1"},{"name":"followersMax","type":"byte","size":1,"description":"Maximum followers","condition":"version >= 1"},{"name":"fireResist","type":"short","size":2,"description":"Fire resistance","condition":"version >= 4"},{"name":"coldResist","type":"short","size":2,"description":"Cold resistance","condition":"version >= 4"},{"name":"poisonResist","type":"short","size":2,"description":"Poison resistance","condition":"version >= 4"},{"name":"energyResist","type":"short","size":2,"description":"Energy resistance","condition":"version >= 4"},{"name":"luck","type":"short","size":2,"description":"Luck","condition":"version >= 4"},{"name":"damageMin","type":"short","size":2,"description":"Minimum weapon damage","condition":"version >= 4"},{"name":"damageMax","type":"short","size":2,"description":"Maximum weapon damage","condition":"version >= 4"},{"name":"tithingPoints","type":"int","size":4,"description":"Tithing points","condition":"version >= 4"},{"name":"aosStatus","type":"short[15]","size":30,"description":"Extended AOS status values","condition":"version >= 6"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":497},"category":"Mobile"},{"id":"0x20","name":"Mobile Update","description":"Updates a mobile's basic display information (body, hue, position, flags).","direction":"outgoing","isDynamic":false,"size":19,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x20","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"body","type":"short","size":2,"description":"Body/graphic ID"},{"name":"unknown","type":"byte","size":1,"description":"Unknown (always 0)"},{"name":"hue","type":"short","size":2,"description":"Hue/color (or solid hue override)"},{"name":"flags","type":"byte","size":1,"description":"Packet flags (hidden, poisoned, etc.)"},{"name":"x","type":"short","size":2,"description":"X coordinate"},{"name":"y","type":"short","size":2,"description":"Y coordinate"},{"name":"unknown2","type":"short","size":2,"description":"Unknown (always 0)"},{"name":"direction","type":"byte","size":1,"description":"Facing direction"},{"name":"z","type":"sbyte","size":1,"description":"Z coordinate"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":578},"category":"Mobile"},{"id":"0x77","name":"Mobile Moving","description":"Sent when a mobile moves. Contains position, direction, hue, and notoriety.","direction":"outgoing","isDynamic":false,"size":17,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x77","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"body","type":"short","size":2,"description":"Body/graphic ID"},{"name":"x","type":"short","size":2,"description":"X coordinate"},{"name":"y","type":"short","size":2,"description":"Y coordinate"},{"name":"z","type":"sbyte","size":1,"description":"Z coordinate"},{"name":"direction","type":"byte","size":1,"description":"Direction (0-7) with running flag (0x80)"},{"name":"hue","type":"short","size":2,"description":"Hue/color"},{"name":"flags","type":"byte","size":1,"description":"Packet flags"},{"name":"notoriety","type":"byte","size":1,"description":"Notoriety (0=Innocent, 1=Friend, 2=Gray, 3=Criminal, 4=Enemy, 5=Murderer, 6=Invulnerable)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":104},"category":"Mobile"},{"id":"0x78","name":"Mobile Incoming","description":"Full mobile information including equipped items. Sent when a mobile enters view range.","direction":"outgoing","isDynamic":true,"size":"23 + (equipment count * 7-9 bytes)","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x78","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"body","type":"short","size":2,"description":"Body/graphic ID"},{"name":"x","type":"short","size":2,"description":"X coordinate"},{"name":"y","type":"short","size":2,"description":"Y coordinate"},{"name":"z","type":"sbyte","size":1,"description":"Z coordinate"},{"name":"direction","type":"byte","size":1,"description":"Facing direction"},{"name":"hue","type":"short","size":2,"description":"Hue/color"},{"name":"flags","type":"byte","size":1,"description":"Packet flags"},{"name":"notoriety","type":"byte","size":1,"description":"Notoriety flag"},{"name":"equipment","type":"array","description":"Equipped items (terminated by 0x00000000)","loop":{"countField":"variable (until terminator)","fields":[{"name":"itemSerial","type":"uint","size":4,"description":"Item serial (0 = end of list)"},{"name":"itemId","type":"ushort","size":2,"description":"Item graphic ID (bit 0x8000 = hue follows for old clients)"},{"name":"layer","type":"byte","size":1,"description":"Equipment layer"},{"name":"hue","type":"short","size":2,"description":"Item hue (only if bit 0x8000 set or NewMobileIncoming)","condition":"hue flag or NewMobileIncoming"}]}},{"name":"terminator","type":"int","size":4,"value":"0x00000000","description":"Equipment list terminator"}],"clientVersion":{"feature":"NewMobileIncoming","notes":"NewMobileIncoming clients always include hue field for equipment"},"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":601},"category":"Mobile"},{"id":"0xA1","name":"Mobile Hits","description":"Updates a mobile's hit points. Can be normalized to 0-100 scale for non-self mobiles.","direction":"outgoing","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA1","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"hitsMax","type":"short","size":2,"description":"Maximum hits"},{"name":"hits","type":"short","size":2,"description":"Current hits"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":210},"category":"Mobile"},{"id":"0xA2","name":"Mobile Mana","description":"Updates a mobile's mana points.","direction":"outgoing","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA2","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"manaMax","type":"short","size":2,"description":"Maximum mana"},{"name":"mana","type":"short","size":2,"description":"Current mana"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":235},"category":"Mobile"},{"id":"0xA3","name":"Mobile Stamina","description":"Updates a mobile's stamina points.","direction":"outgoing","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA3","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"stamMax","type":"short","size":2,"description":"Maximum stamina"},{"name":"stam","type":"short","size":2,"description":"Current stamina"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":260},"category":"Mobile"},{"id":"0x2D","name":"Mobile Attributes","description":"Updates all three attribute bars (hits, mana, stamina) in a single packet.","direction":"outgoing","isDynamic":false,"size":17,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x2D","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"hitsMax","type":"short","size":2,"description":"Maximum hits"},{"name":"hits","type":"short","size":2,"description":"Current hits"},{"name":"manaMax","type":"short","size":2,"description":"Maximum mana"},{"name":"mana","type":"short","size":2,"description":"Current mana"},{"name":"stamMax","type":"short","size":2,"description":"Maximum stamina"},{"name":"stam","type":"short","size":2,"description":"Current stamina"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":285},"category":"Mobile"},{"id":"0x98","name":"Mobile Name","description":"Returns a mobile's name in response to a name request.","direction":"outgoing","isDynamic":false,"size":37,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x98","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"0x0025","description":"Packet length (37)"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"name","type":"ascii","size":30,"description":"Mobile name (null-terminated)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":301},"category":"Mobile"},{"id":"0x6E","name":"Mobile Animation","description":"Triggers an animation on a mobile.","direction":"outgoing","isDynamic":false,"size":14,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x6E","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"action","type":"short","size":2,"description":"Animation action ID"},{"name":"frameCount","type":"short","size":2,"description":"Number of frames"},{"name":"repeatCount","type":"short","size":2,"description":"Number of times to repeat"},{"name":"reverse","type":"bool","size":1,"description":"Play animation in reverse"},{"name":"repeat","type":"bool","size":1,"description":"Loop the animation"},{"name":"delay","type":"byte","size":1,"description":"Frame delay"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":318},"category":"Mobile"},{"id":"0xE2","name":"New Mobile Animation","description":"Simplified animation packet for newer clients.","direction":"outgoing","isDynamic":false,"size":10,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xE2","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"action","type":"short","size":2,"description":"Animation action ID"},{"name":"frameCount","type":"short","size":2,"description":"Number of frames"},{"name":"delay","type":"byte","size":1,"description":"Frame delay"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":354},"category":"Mobile"},{"id":"0x17","name":"Mobile Healthbar","description":"Updates a mobile's healthbar status (poison level, yellow bar for invulnerability).","direction":"outgoing","isDynamic":false,"size":12,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x17","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"0x000C","description":"Packet length (12)"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"showBar","type":"short","size":2,"value":"0x0001","description":"Show bar (always 1)"},{"name":"healthbarType","type":"short","size":2,"description":"Healthbar type: 1=Poison, 2=Yellow"},{"name":"level","type":"byte","size":1,"description":"Level (0=off, 1-4 for poison levels, 1=on for yellow)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":419},"category":"Mobile"},{"id":"0xAF","name":"Death Animation","description":"Triggers the death animation and corpse creation for a mobile.","direction":"outgoing","isDynamic":false,"size":13,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xAF","description":"Packet identifier"},{"name":"killedSerial","type":"uint","size":4,"description":"Serial of the killed mobile"},{"name":"corpseSerial","type":"uint","size":4,"description":"Serial of the corpse created"},{"name":"unknown","type":"int","size":4,"description":"Unknown (always 0)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":78},"category":"Mobile"},{"id":"0xBF","subId":"0x0019","name":"Bonded Status","description":"Indicates whether a mobile (pet) is bonded to its owner.","direction":"outgoing","isDynamic":false,"size":11,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"0x000B","description":"Packet length (11)"},{"name":"subCommand","type":"ushort","size":2,"value":"0x0019","description":"Sub-command for bonded status"},{"name":"command","type":"byte","size":1,"value":"0x00","description":"Command type (0 for bonded)"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"bonded","type":"bool","size":1,"description":"Bonded status"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMobilePackets.cs","line":44},"category":"Mobile"},{"id":"0x21","name":"Movement Rejection","description":"Sent by the server when player movement is blocked (collision, teleport area, etc). Contains the corrected position the client should snap back to.","direction":"outgoing","isDynamic":false,"size":8,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x21","description":"Packet identifier"},{"name":"sequence","type":"byte","size":1,"description":"Sequence number of the rejected movement request"},{"name":"x","type":"short","size":2,"description":"Correct X coordinate"},{"name":"y","type":"short","size":2,"description":"Correct Y coordinate"},{"name":"direction","type":"byte","size":1,"description":"Correct facing direction (0-7)"},{"name":"z","type":"sbyte","size":1,"description":"Correct Z coordinate"}],"related":[{"id":"0x02","relationship":"request","note":"The movement request that was rejected"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMovementPackets.cs","line":45},"category":"Movement"},{"id":"0x22","name":"Movement Acknowledgment","description":"Sent by the server to confirm successful player movement. Includes the player's current notoriety for display purposes.","direction":"outgoing","isDynamic":false,"size":3,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x22","description":"Packet identifier"},{"name":"sequence","type":"byte","size":1,"description":"Sequence number of the accepted movement request"},{"name":"notoriety","type":"byte","size":1,"description":"Player's current notoriety flag (0=Innocent, 1=Friend, 2=Gray/Attackable, 3=Criminal, 4=Enemy, 5=Murderer, 6=Invulnerable)"}],"related":[{"id":"0x02","relationship":"request","note":"The movement request that was accepted"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMovementPackets.cs","line":42},"category":"Movement"},{"id":"0x97","name":"Move Player","description":"Server-initiated player movement. Forces the client to move in a direction (used for pushback effects, conveyors, etc).","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x97","description":"Packet identifier"},{"name":"direction","type":"byte","size":1,"description":"Direction to move (0-7). Bit 0x80 indicates running."}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMovementPackets.cs","line":35},"category":"Movement"},{"id":"0xBF","subId":"0x0026","name":"Speed Control","description":"Controls the player's movement speed. Used for mount speed changes, walk/run restrictions, etc.","direction":"outgoing","isDynamic":false,"size":6,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"0x0006","description":"Packet length"},{"name":"subCommand","type":"ushort","size":2,"value":"0x0026","description":"Sub-command for speed control"},{"name":"speedSetting","type":"byte","size":1,"description":"Speed setting: 0=Disable (normal), 1=Mount speed, 2=Walk only"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMovementPackets.cs","line":31},"category":"Movement"},{"id":"0xF2","name":"Time Sync Response","description":"Server response to client time synchronization request. Contains tick counts for latency calculation.","direction":"outgoing","isDynamic":false,"size":25,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xF2","description":"Packet identifier"},{"name":"tickCount1","type":"long","size":8,"description":"Server tick count"},{"name":"tickCount2","type":"long","size":8,"description":"Server tick count"},{"name":"tickCount3","type":"long","size":8,"description":"Server tick count"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingMovementPackets.cs","line":63},"category":"Movement"},{"id":"0x23","name":"Drag Effect","description":"Displays a drag/drop visual effect between two points.","direction":"outgoing","isDynamic":false,"size":26,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x23","description":"Packet identifier"},{"name":"itemId","type":"short","size":2,"description":"Item graphic ID"},{"name":"unknown","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"hue","type":"short","size":2,"description":"Item hue"},{"name":"amount","type":"short","size":2,"description":"Item amount"},{"name":"srcSerial","type":"uint","size":4,"description":"Source entity serial"},{"name":"srcX","type":"short","size":2,"description":"Source X coordinate"},{"name":"srcY","type":"short","size":2,"description":"Source Y coordinate"},{"name":"srcZ","type":"sbyte","size":1,"description":"Source Z coordinate"},{"name":"dstSerial","type":"uint","size":4,"description":"Destination entity serial"},{"name":"dstX","type":"short","size":2,"description":"Destination X coordinate"},{"name":"dstY","type":"short","size":2,"description":"Destination Y coordinate"},{"name":"dstZ","type":"sbyte","size":1,"description":"Destination Z coordinate"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":198},"category":"Player"},{"id":"0x27","name":"Lift Reject","description":"Server rejects a lift/pick up request.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x27","description":"Packet identifier"},{"name":"reason","type":"enum","enumType":"sequential","size":1,"description":"Rejection reason","values":[{"value":0,"name":"CannotLift","description":"You cannot pick that up"},{"value":1,"name":"OutOfRange","description":"That is out of range"},{"value":2,"name":"OutOfSight","description":"That is out of sight"},{"value":3,"name":"TryToSteal","description":"That does not belong to you"},{"value":4,"name":"AreHolding","description":"You are already holding an item"},{"value":5,"name":"Inspecific","description":"You cannot pick that up"}]}],"related":[{"id":"0x07","relationship":"request","note":"Lift Request that was rejected"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":90},"category":"Player"},{"id":"0x2C","name":"Death Status","description":"Notifies client of death/resurrection state.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x2C","description":"Packet identifier"},{"name":"dead","type":"byte","size":1,"value":"0x02","description":"Always 2 (dead)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":63},"category":"Player"},{"id":"0x38","name":"Pathfind Message","description":"Instructs client to pathfind to a location.","direction":"outgoing","isDynamic":false,"size":7,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x38","description":"Packet identifier"},{"name":"x","type":"short","size":2,"description":"Target X coordinate"},{"name":"y","type":"short","size":2,"description":"Target Y coordinate"},{"name":"z","type":"short","size":2,"description":"Target Z coordinate"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":319},"category":"Player"},{"id":"0x3A","name":"Skills Update","description":"Sends full skills list or single skill update to client.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0x3A","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"type","type":"enum","enumType":"sequential","size":1,"description":"Update type","values":[{"value":"0x00","name":"FullNoCaps","description":"Full list without caps"},{"value":"0x02","name":"FullWithCaps","description":"Full list with skill caps"},{"value":"0xDF","name":"SingleWithCaps","description":"Single skill update with cap"},{"value":"0xFF","name":"SingleNoCaps","description":"Single skill update"}]},{"name":"skills","type":"loop","loop":{"until":"skillId == 0","fields":[{"name":"skillId","type":"ushort","size":2,"description":"Skill ID + 1 (0 terminates)"},{"name":"value","type":"ushort","size":2,"description":"Current skill value * 10"},{"name":"base","type":"ushort","size":2,"description":"Base skill value * 10"},{"name":"lock","type":"enum","enumType":"sequential","size":1,"description":"Skill lock state","values":[{"value":0,"name":"Up","description":"Skill gains enabled"},{"value":1,"name":"Down","description":"Skill decreases enabled"},{"value":2,"name":"Locked","description":"Skill locked"}]},{"name":"cap","type":"ushort","size":2,"description":"Skill cap * 10 (if type includes caps)"}]}}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":121},"category":"Player"},{"id":"0x5B","name":"Current Time","description":"Sends current server time to client.","direction":"outgoing","isDynamic":false,"size":4,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x5B","description":"Packet identifier"},{"name":"hour","type":"byte","size":1,"description":"Hour (0-23)"},{"name":"minute","type":"byte","size":1,"description":"Minute (0-59)"},{"name":"second","type":"byte","size":1,"description":"Second (0-59)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":316},"category":"Player"},{"id":"0x65","name":"Weather","description":"Sets weather conditions for client.","direction":"outgoing","isDynamic":false,"size":4,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x65","description":"Packet identifier"},{"name":"type","type":"enum","enumType":"sequential","size":1,"description":"Weather type","values":[{"value":0,"name":"Rain","description":"Raining"},{"value":1,"name":"StormBrewing","description":"Storm brewing"},{"value":2,"name":"Snow","description":"Snowing"},{"value":3,"name":"Storm","description":"Storm in progress"},{"value":254,"name":"None","description":"No weather"},{"value":255,"name":"Clear","description":"Clear weather (stops current)"}]},{"name":"intensity","type":"byte","size":1,"description":"Weather intensity (0-255)"},{"name":"temperature","type":"byte","size":1,"description":"Temperature value"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":97},"category":"Player"},{"id":"0x6D","name":"Play Music","description":"Plays background music on client.","direction":"outgoing","isDynamic":false,"size":3,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x6D","description":"Packet identifier"},{"name":"musicId","type":"short","size":2,"description":"Music track ID (0x1FFF = stop)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":275},"category":"Player"},{"id":"0x73","name":"Ping Ack","description":"Server acknowledges ping request.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x73","description":"Packet identifier"},{"name":"sequence","type":"byte","size":1,"description":"Ping sequence (echoed from request)"}],"related":[{"id":"0x73","relationship":"request","note":"Ping Request from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":336},"category":"Player"},{"id":"0x76","name":"Server Change","description":"Notifies client of server/map transition.","direction":"outgoing","isDynamic":false,"size":16,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x76","description":"Packet identifier"},{"name":"x","type":"short","size":2,"description":"New X coordinate"},{"name":"y","type":"short","size":2,"description":"New Y coordinate"},{"name":"z","type":"short","size":2,"description":"New Z coordinate"},{"name":"unknown","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"unknown2","type":"short","size":2,"value":"0x0000","description":"Unknown"},{"name":"unknown3","type":"short","size":2,"value":"0x0000","description":"Unknown"},{"name":"mapWidth","type":"short","size":2,"description":"Map width"},{"name":"mapHeight","type":"short","size":2,"description":"Map height"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":100},"category":"Player"},{"id":"0x7B","name":"Sequence","description":"Sends sequence number to client for synchronization.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x7B","description":"Packet identifier"},{"name":"sequence","type":"byte","size":1,"description":"Sequence number"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":154},"category":"Player"},{"id":"0x88","name":"Display Paperdoll","description":"Opens paperdoll window for a mobile.","direction":"outgoing","isDynamic":false,"size":66,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x88","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Serial of mobile"},{"name":"title","type":"ascii","size":60,"description":"Title/name displayed"},{"name":"flags","type":"bitfield","size":1,"description":"Paperdoll flags","flags":[{"bit":"0x01","name":"Warmode","description":"Mobile is in war mode"},{"bit":"0x02","name":"CanLift","description":"Viewer can lift equipment"}]}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":247},"category":"Player"},{"id":"0x95","name":"Display Hue Picker","description":"Opens hue picker dialog on client.","direction":"outgoing","isDynamic":false,"size":9,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x95","description":"Packet identifier"},{"name":"serial","type":"uint","size":4,"description":"Hue picker serial"},{"name":"unknown","type":"short","size":2,"value":"0x0000","description":"Unknown"},{"name":"itemId","type":"short","size":2,"description":"Item graphic to preview hue on"}],"related":[{"id":"0x95","relationship":"response","note":"Hue Picker Response from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":338},"category":"Player"},{"id":"0xA5","name":"Launch Browser","description":"Opens a URL in client's web browser.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA5","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"url","type":"ascii-null","description":"URL to open"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":180},"category":"Player"},{"id":"0xA6","name":"Scroll Message","description":"Displays a scrollable tips/message window.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xA6","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"type","type":"byte","size":1,"description":"Scroll type"},{"name":"tipNumber","type":"int","size":4,"description":"Tip/message number"},{"name":"textLength","type":"ushort","size":2,"description":"Length of text"},{"name":"text","type":"ascii","description":"Message text"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":291},"category":"Player"},{"id":"0xB8","name":"Display Profile","description":"Displays a mobile's profile.","direction":"outgoing","isDynamic":true,"size":"Dynamic","fields":[{"name":"packetId","type":"byte","size":1,"value":"0xB8","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"description":"Packet length"},{"name":"serial","type":"uint","size":4,"description":"Serial of mobile"},{"name":"header","type":"ascii-null","description":"Profile header"},{"name":"footer","type":"unicode-be-null","description":"Profile footer"},{"name":"body","type":"unicode-be-null","description":"Profile body text"}],"related":[{"id":"0xB8","relationship":"request","note":"Profile Request from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":66},"category":"Player"},{"id":"0xBC","name":"Season Change","description":"Changes the visual season on client.","direction":"outgoing","isDynamic":false,"size":3,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBC","description":"Packet identifier"},{"name":"season","type":"enum","enumType":"sequential","size":1,"description":"Season value","values":[{"value":0,"name":"Spring","description":"Spring season"},{"value":1,"name":"Summer","description":"Summer season"},{"value":2,"name":"Fall","description":"Fall/Autumn season"},{"value":3,"name":"Winter","description":"Winter season"},{"value":4,"name":"Desolation","description":"Desolation (dead trees)"}]},{"name":"playSound","type":"bool","size":1,"description":"Play season change sound"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":244},"category":"Player"},{"id":"0xBF/0x19","name":"Stat Lock Info","description":"Sends stat lock states (STR/DEX/INT) to client.","direction":"outgoing","isDynamic":false,"size":12,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xBF","description":"Packet identifier"},{"name":"length","type":"ushort","size":2,"value":"12","description":"Packet length"},{"name":"subCommand","type":"short","size":2,"value":"0x19","description":"Subcommand (Stat Lock Info)"},{"name":"type","type":"byte","size":1,"value":"0x02","description":"Type (2 = stat locks)"},{"name":"serial","type":"uint","size":4,"description":"Mobile serial"},{"name":"unknown","type":"byte","size":1,"value":"0x00","description":"Unknown"},{"name":"lockBits","type":"bitfield","size":1,"description":"Packed lock states","flags":[{"bit":"0x30","name":"StrLock","description":"Strength lock (bits 4-5)"},{"bit":"0x0C","name":"DexLock","description":"Dexterity lock (bits 2-3)"},{"bit":"0x03","name":"IntLock","description":"Intelligence lock (bits 0-1)"}],"notes":"Each lock is 2 bits: 0=Up, 1=Down, 2=Locked"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":36},"category":"Player"},{"id":"0xC8","name":"Change Update Range","description":"Sets the client's update range.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xC8","description":"Packet identifier"},{"name":"range","type":"byte","size":1,"description":"Update range (typically 18)"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":59},"category":"Player"},{"id":"0xD1","name":"Logout Ack","description":"Server acknowledges logout request.","direction":"outgoing","isDynamic":false,"size":2,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0xD1","description":"Packet identifier"},{"name":"ack","type":"byte","size":1,"value":"0x01","description":"Acknowledgment (1 = OK)"}],"related":[{"id":"0xD1","relationship":"request","note":"Logout Request from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingPlayerPackets.cs","line":94},"category":"Player"},{"id":"0x6C","name":"Target Request","description":"Requests the client to select a target.","direction":"outgoing","isDynamic":false,"size":19,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x6C","description":"Packet identifier"},{"name":"allowGround","type":"bool","size":1,"description":"True = allow ground targeting"},{"name":"targetId","type":"int","size":4,"description":"Target cursor ID for matching response"},{"name":"flags","type":"enum","enumType":"sequential","size":1,"description":"Target cursor flags","values":[{"value":0,"name":"Neutral","description":"Neutral targeting (gray cursor)"},{"value":1,"name":"Harmful","description":"Harmful action (red cursor)"},{"value":2,"name":"Beneficial","description":"Beneficial action (green cursor)"},{"value":3,"name":"Cancel","description":"Cancel targeting"}]},{"name":"padding","type":"byte[]","size":12,"description":"Padding (zeros)"}],"related":[{"id":"0x6C","relationship":"response","note":"Target Response from client"}],"source":{"file":"Projects/Server/Network/Packets/OutgoingTargetPackets.cs","line":57},"category":"Targeting"},{"id":"0x99","name":"Multi Target Request","description":"Requests the client to place a multi (house/boat) structure.","direction":"outgoing","isDynamic":false,"size":"26 (pre-HS) or 30 (HS+)","variants":[{"version":"pre-HighSeas","name":"Classic","size":26,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x99","description":"Packet identifier"},{"name":"allowGround","type":"bool","size":1,"description":"Allow ground targeting"},{"name":"targetId","type":"int","size":4,"description":"Target cursor ID"},{"name":"flags","type":"byte","size":1,"description":"Target cursor flags"},{"name":"padding","type":"byte[]","size":11,"description":"Padding (zeros)"},{"name":"multiId","type":"short","size":2,"description":"Multi graphic ID"},{"name":"offsetX","type":"short","size":2,"description":"X offset for placement"},{"name":"offsetY","type":"short","size":2,"description":"Y offset for placement"},{"name":"offsetZ","type":"short","size":2,"description":"Z offset for placement"}]},{"version":"HighSeas+","name":"High Seas Extended","condition":"Client version >= 7.0.9.0 (HighSeas)","size":30,"fields":[{"name":"packetId","type":"byte","size":1,"value":"0x99","description":"Packet identifier"},{"name":"allowGround","type":"bool","size":1,"description":"Allow ground targeting"},{"name":"targetId","type":"int","size":4,"description":"Target cursor ID"},{"name":"flags","type":"byte","size":1,"description":"Target cursor flags"},{"name":"padding","type":"byte[]","size":11,"description":"Padding (zeros)"},{"name":"multiId","type":"short","size":2,"description":"Multi graphic ID"},{"name":"offsetX","type":"short","size":2,"description":"X offset for placement"},{"name":"offsetY","type":"short","size":2,"description":"Y offset for placement"},{"name":"offsetZ","type":"short","size":2,"description":"Z offset for placement"},{"name":"unknown","type":"int","size":4,"description":"Unknown (HighSeas extension)"}]}],"clientVersion":{"feature":"HighSeas adds 4 bytes"},"source":{"file":"Projects/Server/Network/Packets/OutgoingTargetPackets.cs","line":23},"category":"Targeting"}]}
|
|
</span>
|
|
|
|
<script>
|
|
// Parse packet data
|
|
let allPackets = { incoming: [], outgoing: [] };
|
|
try {
|
|
allPackets = JSON.parse(document.getElementById('packets').innerText.trim() || '{"incoming":[],"outgoing":[]}');
|
|
} catch (e) {
|
|
console.error('Failed to parse packet data:', e);
|
|
}
|
|
|
|
// Flatten all packets into a single array with direction info preserved
|
|
const packets = [
|
|
...allPackets.incoming.map(p => ({ ...p, direction: p.direction || 'incoming' })),
|
|
...allPackets.outgoing.map(p => ({ ...p, direction: p.direction || 'outgoing' }))
|
|
];
|
|
|
|
// Build packet index by ID for quick lookups
|
|
const packetIndex = new Map();
|
|
packets.forEach(p => {
|
|
const key = p.subId ? `${p.id}/${p.subId}` : p.id;
|
|
packetIndex.set(key, p);
|
|
packetIndex.set(p.id, p); // Also index by just ID for basic lookups
|
|
});
|
|
|
|
// State
|
|
let currentFilter = 'all';
|
|
let currentCategory = '';
|
|
let currentSearch = '';
|
|
let selectedPacket = null;
|
|
|
|
// DOM elements
|
|
const searchInput = document.getElementById('searchInput');
|
|
const categoryFilter = document.getElementById('categoryFilter');
|
|
const packetList = document.getElementById('packetList');
|
|
const packetCount = document.getElementById('packetCount');
|
|
const welcomeMessage = document.getElementById('welcomeMessage');
|
|
const packetContent = document.getElementById('packetContent');
|
|
|
|
// Extract unique categories
|
|
const categories = [...new Set(packets.map(p => p.category).filter(Boolean))].sort();
|
|
categories.forEach(cat => {
|
|
const option = document.createElement('option');
|
|
option.value = cat;
|
|
option.textContent = cat;
|
|
categoryFilter.appendChild(option);
|
|
});
|
|
|
|
// Update packet count
|
|
function updatePacketCount() {
|
|
const filtered = getFilteredPackets();
|
|
packetCount.textContent = `${filtered.length} of ${packets.length} packets`;
|
|
}
|
|
|
|
// Get direction color class
|
|
function getDirectionClass(direction) {
|
|
switch(direction) {
|
|
case 'incoming': return 'text-incoming';
|
|
case 'outgoing': return 'text-outgoing';
|
|
case 'both': return 'text-both';
|
|
default: return 'text-gold-500';
|
|
}
|
|
}
|
|
|
|
function getDirectionBgClass(direction) {
|
|
switch(direction) {
|
|
case 'incoming': return 'bg-incoming';
|
|
case 'outgoing': return 'bg-outgoing';
|
|
case 'both': return 'bg-both';
|
|
default: return 'bg-gold-500';
|
|
}
|
|
}
|
|
|
|
// Filter packets
|
|
function getFilteredPackets() {
|
|
return packets.filter(p => {
|
|
// Direction filter
|
|
if (currentFilter !== 'all' && p.direction !== currentFilter) return false;
|
|
|
|
// Category filter
|
|
if (currentCategory && p.category !== currentCategory) return false;
|
|
|
|
// Search filter
|
|
if (currentSearch) {
|
|
const search = currentSearch.toLowerCase();
|
|
const matchId = p.id.toLowerCase().includes(search) ||
|
|
(p.subId && p.subId.toLowerCase().includes(search));
|
|
const matchName = p.name.toLowerCase().includes(search);
|
|
const matchDesc = p.description && p.description.toLowerCase().includes(search);
|
|
const matchFields = p.fields && p.fields.some(f =>
|
|
f.name.toLowerCase().includes(search) ||
|
|
(f.description && f.description.toLowerCase().includes(search))
|
|
);
|
|
|
|
// Also search decimal ID
|
|
const decimalId = parseInt(p.id, 16);
|
|
const matchDecimal = !isNaN(decimalId) && decimalId.toString() === search;
|
|
|
|
if (!matchId && !matchName && !matchDesc && !matchFields && !matchDecimal) return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
// Render packet list
|
|
function renderPacketList() {
|
|
const filtered = getFilteredPackets();
|
|
|
|
// Sort by ID
|
|
filtered.sort((a, b) => {
|
|
const aId = parseInt(a.id, 16);
|
|
const bId = parseInt(b.id, 16);
|
|
if (aId !== bId) return aId - bId;
|
|
|
|
// If same ID, sort by subId
|
|
if (a.subId && b.subId) {
|
|
return parseInt(a.subId, 16) - parseInt(b.subId, 16);
|
|
}
|
|
return a.subId ? 1 : -1;
|
|
});
|
|
|
|
packetList.innerHTML = filtered.map(p => {
|
|
const displayId = p.subId ? `${p.id}/${p.subId}` : p.id;
|
|
const isSelected = selectedPacket &&
|
|
selectedPacket.id === p.id &&
|
|
selectedPacket.subId === p.subId;
|
|
|
|
return `
|
|
<div
|
|
class="packet-item px-3 py-2 cursor-pointer border-b border-gold-500/10 hover:bg-modern-black-hover transition-colors ${isSelected ? 'bg-gold-500/20' : ''}"
|
|
data-id="${p.id}"
|
|
data-subid="${p.subId || ''}"
|
|
>
|
|
<div class="flex items-center space-x-2">
|
|
<span class="font-mono text-sm ${getDirectionClass(p.direction)}">${displayId}</span>
|
|
<span class="text-gold-300/90 text-sm truncate">${p.name}</span>
|
|
</div>
|
|
<div class="text-gold-500/50 text-xs mt-0.5">${p.category || 'Uncategorized'}</div>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
|
|
// Add click handlers
|
|
document.querySelectorAll('.packet-item').forEach(el => {
|
|
el.addEventListener('click', () => {
|
|
const id = el.dataset.id;
|
|
const subId = el.dataset.subid;
|
|
const packet = packets.find(p => p.id === id && (p.subId || '') === subId);
|
|
if (packet) selectPacket(packet);
|
|
});
|
|
});
|
|
|
|
updatePacketCount();
|
|
}
|
|
|
|
// Calculate field offsets
|
|
function calculateOffsets(fields) {
|
|
let offset = 0;
|
|
return fields.map(f => {
|
|
const fieldOffset = offset;
|
|
if (f.size && typeof f.size === 'number') {
|
|
offset += f.size;
|
|
}
|
|
return { ...f, offset: fieldOffset };
|
|
});
|
|
}
|
|
|
|
// Render enum values
|
|
function renderEnumValues(f) {
|
|
if (!f.values || f.values.length === 0) return '';
|
|
|
|
const enumType = f.enumType === 'bitfield' || f.type === 'bitfield' ? 'bitfield' : 'enum';
|
|
const typeLabel = enumType === 'bitfield' ? 'Flags' : 'Values';
|
|
|
|
return `
|
|
<div class="mt-2 text-xs">
|
|
<div class="text-gold-500/70 mb-1">${typeLabel}:</div>
|
|
<div class="grid grid-cols-1 gap-1 pl-2 border-l-2 border-gold-500/30">
|
|
${f.values.map(v => `
|
|
<div class="flex items-start">
|
|
<span class="font-mono text-gold-400 w-16 flex-shrink-0">${typeof v.value === 'number' ? (enumType === 'bitfield' ? '0x' + v.value.toString(16).toUpperCase().padStart(2, '0') : v.value) : v.value}</span>
|
|
<span class="text-gold-300 font-medium">${v.name}</span>
|
|
${v.description ? `<span class="text-gold-500/60 ml-2">- ${v.description}</span>` : ''}
|
|
</div>
|
|
`).join('')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Render bitfield flags
|
|
function renderBitfieldFlags(f) {
|
|
if (!f.flags || f.flags.length === 0) return '';
|
|
|
|
return `
|
|
<div class="mt-2 text-xs">
|
|
<div class="text-gold-500/70 mb-1">Flags:</div>
|
|
<div class="grid grid-cols-1 gap-1 pl-2 border-l-2 border-purple-500/30">
|
|
${f.flags.map(flag => `
|
|
<div class="flex items-start">
|
|
<span class="font-mono text-purple-400 w-16 flex-shrink-0">${flag.bit}</span>
|
|
<span class="text-gold-300 font-medium">${flag.name}</span>
|
|
${flag.description ? `<span class="text-gold-500/60 ml-2">- ${flag.description}</span>` : ''}
|
|
</div>
|
|
`).join('')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Render fields table
|
|
function renderFields(fields, parentOffset = 0) {
|
|
const fieldsWithOffsets = calculateOffsets(fields);
|
|
|
|
return fieldsWithOffsets.map(f => {
|
|
const offset = parentOffset + f.offset;
|
|
const isEnum = f.type === 'enum' || f.values;
|
|
const isBitfield = f.type === 'bitfield' || f.flags;
|
|
const typeDisplay = isEnum ? `enum (${f.size || 1} byte${(f.size || 1) > 1 ? 's' : ''})` :
|
|
isBitfield ? `bitfield (${f.size || 1} byte${(f.size || 1) > 1 ? 's' : ''})` :
|
|
f.type;
|
|
|
|
let row = `
|
|
<tr class="field-row border-b border-gold-500/10">
|
|
<td class="px-4 py-2 font-mono text-gold-500/70">${f.size ? offset : '-'}</td>
|
|
<td class="px-4 py-2 font-mono text-white">${f.name}</td>
|
|
<td class="px-4 py-2 font-mono ${isEnum ? 'text-green-400' : isBitfield ? 'text-purple-400' : 'text-gold-400'}">${typeDisplay}</td>
|
|
<td class="px-4 py-2 font-mono text-gold-500/70">${f.size || 'var'}</td>
|
|
<td class="px-4 py-2 text-gold-300/80">
|
|
${f.description || ''}
|
|
${f.value ? `<span class="text-gold-500/70 ml-1">(${f.value})</span>` : ''}
|
|
${f.condition ? `<span class="text-gold-400/70 ml-1 text-xs italic">[${f.condition}]</span>` : ''}
|
|
${isEnum ? renderEnumValues(f) : ''}
|
|
${isBitfield ? renderBitfieldFlags(f) : ''}
|
|
</td>
|
|
</tr>
|
|
`;
|
|
|
|
// Handle loop fields
|
|
if (f.loop && f.loop.fields) {
|
|
row += `
|
|
<tr class="field-row border-b border-gold-500/10 bg-gold-500/5">
|
|
<td colspan="5" class="px-4 py-2">
|
|
<div class="loop-field">
|
|
<div class="text-gold-500/70 text-xs mb-2">Repeats for each ${f.loop.countField || 'item'}:</div>
|
|
<table class="w-full text-sm">
|
|
<tbody>
|
|
${renderFields(f.loop.fields, 0)}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
return row;
|
|
}).join('');
|
|
}
|
|
|
|
// Select and display a packet
|
|
function selectPacket(packet) {
|
|
selectedPacket = packet;
|
|
|
|
// Update list selection
|
|
document.querySelectorAll('.packet-item').forEach(el => {
|
|
const isMatch = el.dataset.id === packet.id && (el.dataset.subid || '') === (packet.subId || '');
|
|
el.classList.toggle('bg-gold-500/20', isMatch);
|
|
});
|
|
|
|
// Show content, hide welcome
|
|
welcomeMessage.classList.add('hidden');
|
|
packetContent.classList.remove('hidden');
|
|
|
|
// Populate header
|
|
document.getElementById('detailId').textContent = packet.id;
|
|
|
|
const subIdEl = document.getElementById('detailSubId');
|
|
if (packet.subId) {
|
|
subIdEl.textContent = `/ ${packet.subId}`;
|
|
subIdEl.classList.remove('hidden');
|
|
} else {
|
|
subIdEl.classList.add('hidden');
|
|
}
|
|
|
|
document.getElementById('detailName').textContent = packet.name;
|
|
|
|
const directionEl = document.getElementById('detailDirection');
|
|
directionEl.textContent = packet.direction;
|
|
directionEl.className = `px-2 py-0.5 rounded text-xs font-medium uppercase ${getDirectionBgClass(packet.direction)} text-white`;
|
|
|
|
// Description
|
|
document.getElementById('detailDescription').textContent = packet.description || 'No description available.';
|
|
|
|
// Size
|
|
const sizeText = typeof packet.size === 'number'
|
|
? `${packet.size} bytes`
|
|
: packet.size || 'Variable';
|
|
document.getElementById('detailSize').textContent = sizeText;
|
|
document.getElementById('detailDynamic').classList.toggle('hidden', !packet.isDynamic);
|
|
|
|
// Client version
|
|
const versionSection = document.getElementById('clientVersionSection');
|
|
const versionContent = document.getElementById('clientVersionContent');
|
|
if (packet.clientVersion) {
|
|
versionSection.classList.remove('hidden');
|
|
let versionText = '';
|
|
if (packet.clientVersion.min) versionText += `Min: ${packet.clientVersion.min} `;
|
|
if (packet.clientVersion.max) versionText += `Max: ${packet.clientVersion.max} `;
|
|
if (packet.clientVersion.feature) versionText += `Feature: ${packet.clientVersion.feature} `;
|
|
if (packet.clientVersion.notes) versionText += `<br>${packet.clientVersion.notes}`;
|
|
versionContent.innerHTML = versionText || 'Version-specific behavior';
|
|
} else {
|
|
versionSection.classList.add('hidden');
|
|
}
|
|
|
|
// Fields
|
|
const fieldsTable = document.getElementById('fieldsTable');
|
|
if (packet.fields && packet.fields.length > 0) {
|
|
fieldsTable.innerHTML = renderFields(packet.fields);
|
|
} else {
|
|
fieldsTable.innerHTML = '<tr><td colspan="5" class="px-4 py-4 text-center text-gold-500/50">No field documentation available</td></tr>';
|
|
}
|
|
|
|
// Related packets
|
|
const relatedSection = document.getElementById('relatedSection');
|
|
const relatedPackets = document.getElementById('relatedPackets');
|
|
if (packet.related && packet.related.length > 0) {
|
|
relatedSection.classList.remove('hidden');
|
|
relatedPackets.innerHTML = packet.related.map(r => {
|
|
const relatedPacket = packetIndex.get(r.id);
|
|
const relationshipColors = {
|
|
'request': 'bg-blue-500/20 text-blue-400',
|
|
'response': 'bg-green-500/20 text-green-400',
|
|
'ack': 'bg-green-500/20 text-green-400',
|
|
'rej': 'bg-red-500/20 text-red-400',
|
|
'variant': 'bg-purple-500/20 text-purple-400'
|
|
};
|
|
const colorClass = relationshipColors[r.relationship] || 'bg-gold-500/20 text-gold-400';
|
|
|
|
return `
|
|
<div class="flex items-center justify-between bg-modern-black rounded-lg p-3 border border-gold-500/20 cursor-pointer hover:border-gold-500/40 transition-colors related-packet" data-id="${r.id}">
|
|
<div class="flex items-center space-x-3">
|
|
<span class="font-mono text-white">${r.id}</span>
|
|
<span class="text-gold-300/90">${relatedPacket?.name || 'Unknown'}</span>
|
|
</div>
|
|
<div class="flex items-center space-x-2">
|
|
<span class="px-2 py-0.5 rounded text-xs ${colorClass}">${r.relationship}</span>
|
|
${r.note ? `<span class="text-gold-500/50 text-sm">${r.note}</span>` : ''}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
|
|
// Add click handlers to related packets
|
|
document.querySelectorAll('.related-packet').forEach(el => {
|
|
el.addEventListener('click', () => {
|
|
const id = el.dataset.id;
|
|
const relatedPacket = packetIndex.get(id);
|
|
if (relatedPacket) selectPacket(relatedPacket);
|
|
});
|
|
});
|
|
} else {
|
|
relatedSection.classList.add('hidden');
|
|
}
|
|
|
|
// Variants
|
|
const variantsSection = document.getElementById('variantsSection');
|
|
const variantsList = document.getElementById('variantsList');
|
|
if (packet.variants && packet.variants.length > 0) {
|
|
variantsSection.classList.remove('hidden');
|
|
variantsList.innerHTML = packet.variants.map((v, index) => `
|
|
<div class="bg-modern-black rounded-lg border border-gold-500/20 overflow-hidden">
|
|
<div class="bg-gold-500/10 px-4 py-2 flex items-center justify-between">
|
|
<div>
|
|
<span class="text-gold-500 font-medium">${v.name || 'Variant ' + (index + 1)}</span>
|
|
${v.version ? `<span class="text-gold-500/70 ml-2 text-sm">(${v.version})</span>` : ''}
|
|
</div>
|
|
<div class="flex items-center space-x-3 text-sm">
|
|
${v.size ? `<span class="text-gold-500/70">Size: <span class="text-white font-mono">${v.size} bytes</span></span>` : ''}
|
|
${v.condition ? `<span class="text-gold-400/70 italic">${v.condition}</span>` : ''}
|
|
</div>
|
|
</div>
|
|
${v.fields && v.fields.length > 0 ? `
|
|
<table class="w-full text-sm">
|
|
<thead>
|
|
<tr class="bg-gold-500/5 text-gold-500 text-xs">
|
|
<th class="px-4 py-1 text-left font-medium">Offset</th>
|
|
<th class="px-4 py-1 text-left font-medium">Name</th>
|
|
<th class="px-4 py-1 text-left font-medium">Type</th>
|
|
<th class="px-4 py-1 text-left font-medium">Size</th>
|
|
<th class="px-4 py-1 text-left font-medium">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
${renderFields(v.fields)}
|
|
</tbody>
|
|
</table>
|
|
` : ''}
|
|
</div>
|
|
`).join('');
|
|
} else {
|
|
variantsSection.classList.add('hidden');
|
|
}
|
|
|
|
// Notes
|
|
const notesSection = document.getElementById('notesSection');
|
|
const notesEl = document.getElementById('detailNotes');
|
|
if (packet.notes) {
|
|
notesSection.classList.remove('hidden');
|
|
notesEl.textContent = packet.notes;
|
|
} else {
|
|
notesSection.classList.add('hidden');
|
|
}
|
|
|
|
// Source link
|
|
const sourceLink = document.getElementById('sourceLink');
|
|
if (packet.source && packet.source.file) {
|
|
sourceLink.href = `https://github.com/modernuo/ModernUO/blob/main/${packet.source.file}#L${packet.source.line || 1}`;
|
|
sourceLink.classList.remove('hidden');
|
|
} else {
|
|
sourceLink.classList.add('hidden');
|
|
}
|
|
|
|
// Update URL hash
|
|
const hash = packet.subId ? `${packet.id}-${packet.subId}` : packet.id;
|
|
history.replaceState(null, '', `#${hash}`);
|
|
}
|
|
|
|
// Filter button handlers
|
|
document.querySelectorAll('.filter-btn').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
currentFilter = btn.dataset.filter;
|
|
|
|
// Update button styles
|
|
document.querySelectorAll('.filter-btn').forEach(b => {
|
|
const isActive = b.dataset.filter === currentFilter;
|
|
if (b.dataset.filter === 'all') {
|
|
b.classList.toggle('bg-gold-500', isActive);
|
|
b.classList.toggle('text-modern-black', isActive);
|
|
b.classList.toggle('bg-modern-dark-black', !isActive);
|
|
b.classList.toggle('text-gold-500', !isActive);
|
|
} else {
|
|
const color = b.dataset.filter;
|
|
b.classList.toggle(`bg-${color}/20`, isActive);
|
|
b.classList.toggle('bg-modern-dark-black', !isActive);
|
|
}
|
|
});
|
|
|
|
renderPacketList();
|
|
});
|
|
});
|
|
|
|
// Search handler
|
|
let searchTimeout;
|
|
searchInput.addEventListener('input', (e) => {
|
|
clearTimeout(searchTimeout);
|
|
searchTimeout = setTimeout(() => {
|
|
currentSearch = e.target.value;
|
|
renderPacketList();
|
|
}, 150);
|
|
});
|
|
|
|
// Category filter handler
|
|
categoryFilter.addEventListener('change', (e) => {
|
|
currentCategory = e.target.value;
|
|
renderPacketList();
|
|
});
|
|
|
|
// Keyboard navigation
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.target.tagName === 'INPUT' || e.target.tagName === 'SELECT') return;
|
|
|
|
const filtered = getFilteredPackets();
|
|
if (filtered.length === 0) return;
|
|
|
|
let currentIndex = selectedPacket
|
|
? filtered.findIndex(p => p.id === selectedPacket.id && p.subId === selectedPacket.subId)
|
|
: -1;
|
|
|
|
if (e.key === 'ArrowDown') {
|
|
e.preventDefault();
|
|
currentIndex = Math.min(currentIndex + 1, filtered.length - 1);
|
|
selectPacket(filtered[currentIndex]);
|
|
} else if (e.key === 'ArrowUp') {
|
|
e.preventDefault();
|
|
currentIndex = Math.max(currentIndex - 1, 0);
|
|
selectPacket(filtered[currentIndex]);
|
|
}
|
|
});
|
|
|
|
// Handle URL hash on load
|
|
function loadFromHash() {
|
|
const hash = window.location.hash.slice(1);
|
|
if (hash) {
|
|
// Try to find packet by hash (format: 0x02 or 0xBF-0x0026)
|
|
const parts = hash.split('-');
|
|
const id = parts[0];
|
|
const subId = parts[1];
|
|
|
|
const packet = packets.find(p =>
|
|
p.id.toLowerCase() === id.toLowerCase() &&
|
|
(p.subId || '').toLowerCase() === (subId || '').toLowerCase()
|
|
);
|
|
|
|
if (packet) selectPacket(packet);
|
|
}
|
|
}
|
|
|
|
// Initialize
|
|
renderPacketList();
|
|
loadFromHash();
|
|
|
|
// Handle hash changes
|
|
window.addEventListener('hashchange', loadFromHash);
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|