From 7c8d02e63a5b2f377c0a23f7d7a243a7229c5c4f Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:45:51 -0700 Subject: [PATCH] chore: Removes docs (#2397) --- .github/workflows/update-docs.yml | 40 - docs/CNAME | 1 - docs/assets/stylesheets/extra.css | 112 - docs/assets/stylesheets/home_overrides.css | 101 - docs/branding/android-chrome-192x192.png | Bin 21617 -> 0 bytes docs/branding/android-chrome-512x512.png | Bin 67106 -> 0 bytes docs/branding/apple-touch-icon.png | Bin 10895 -> 0 bytes docs/branding/favicon-16x16.png | Bin 1418 -> 0 bytes docs/branding/favicon-32x32.png | Bin 2660 -> 0 bytes docs/branding/favicon.ico | Bin 15086 -> 0 bytes docs/branding/favicon.png | Bin 2660 -> 0 bytes docs/branding/logo.svg | 1 - docs/branding/mstile-144x144.png | Bin 4453 -> 0 bytes docs/branding/mstile-150x150.png | Bin 4580 -> 0 bytes docs/branding/mstile-310x150.png | Bin 4896 -> 0 bytes docs/branding/mstile-310x310.png | Bin 9861 -> 0 bytes docs/branding/mstile-70x70.png | Bin 3165 -> 0 bytes docs/branding/safari-pinned-tab.svg | 1 - docs/building-server.md | 33 - docs/commands/commands.html | 2619 -------------------- docs/index.md | 4 - docs/installation.md | 54 - docs/overrides/.icons/modernuo/logo.svg | 1 - docs/overrides/home.html | 55 - docs/overrides/main.html | 43 - docs/overrides/partials/footer.html | 52 - docs/overrides/partials/nav.html | 69 - docs/packets/incoming/account.json | 1081 -------- docs/packets/incoming/assistant.json | 39 - docs/packets/incoming/book.json | 216 -- docs/packets/incoming/bulletinboard.json | 250 -- docs/packets/incoming/chat.json | 93 - docs/packets/incoming/encoded.json | 965 -------- docs/packets/incoming/entity.json | 142 -- docs/packets/incoming/extended.json | 1292 ---------- docs/packets/incoming/freeshard.json | 134 - docs/packets/incoming/gump.json | 116 - docs/packets/incoming/hardware.json | 188 -- docs/packets/incoming/house.json | 37 - docs/packets/incoming/items.json | 298 --- docs/packets/incoming/mahjong.json | 907 ------- docs/packets/incoming/map.json | 84 - docs/packets/incoming/message.json | 300 --- docs/packets/incoming/mobile.json | 168 -- docs/packets/incoming/movement.json | 56 - docs/packets/incoming/player.json | 989 -------- docs/packets/incoming/securetrade.json | 144 -- docs/packets/incoming/store.json | 32 - docs/packets/incoming/targeting.json | 117 - docs/packets/incoming/vendor.json | 145 -- docs/packets/outgoing/account.json | 1183 --------- docs/packets/outgoing/arrow.json | 137 - docs/packets/outgoing/assistant.json | 75 - docs/packets/outgoing/boat.json | 122 - docs/packets/outgoing/book.json | 217 -- docs/packets/outgoing/bufficon.json | 307 --- docs/packets/outgoing/bulletinboard.json | 276 --- docs/packets/outgoing/chat.json | 69 - docs/packets/outgoing/combat.json | 120 - docs/packets/outgoing/container.json | 594 ----- docs/packets/outgoing/contextmenu.json | 212 -- docs/packets/outgoing/corpse.json | 76 - docs/packets/outgoing/damage.json | 107 - docs/packets/outgoing/effects.json | 459 ---- docs/packets/outgoing/entity.json | 403 --- docs/packets/outgoing/equipment.json | 173 -- docs/packets/outgoing/freeshard.json | 70 - docs/packets/outgoing/gump.json | 1060 -------- docs/packets/outgoing/house.json | 309 --- docs/packets/outgoing/items.json | 104 - docs/packets/outgoing/light.json | 65 - docs/packets/outgoing/mahjong.json | 501 ---- docs/packets/outgoing/map.json | 427 ---- docs/packets/outgoing/menu.json | 185 -- docs/packets/outgoing/message.json | 534 ---- docs/packets/outgoing/mobile.json | 2102 ---------------- docs/packets/outgoing/movement.json | 256 -- docs/packets/outgoing/party.json | 276 --- docs/packets/outgoing/player.json | 1211 --------- docs/packets/outgoing/securetrade.json | 275 -- docs/packets/outgoing/targeting.json | 223 -- docs/packets/outgoing/vendor.json | 216 -- docs/packets/outgoing/weaponability.json | 89 - docs/packets/template.html | 1910 -------------- docs/readme.md | 10 - docs/scripting-guide/serialization.md | 198 -- docs/scripting-guide/timers.md | 8 - docs/starting-server.md | 30 - docs/tools/build-packets.ps1 | 194 -- mkdocs.yml | 83 - 90 files changed, 25845 deletions(-) delete mode 100644 .github/workflows/update-docs.yml delete mode 100644 docs/CNAME delete mode 100644 docs/assets/stylesheets/extra.css delete mode 100644 docs/assets/stylesheets/home_overrides.css delete mode 100644 docs/branding/android-chrome-192x192.png delete mode 100644 docs/branding/android-chrome-512x512.png delete mode 100644 docs/branding/apple-touch-icon.png delete mode 100644 docs/branding/favicon-16x16.png delete mode 100644 docs/branding/favicon-32x32.png delete mode 100644 docs/branding/favicon.ico delete mode 100644 docs/branding/favicon.png delete mode 100644 docs/branding/logo.svg delete mode 100644 docs/branding/mstile-144x144.png delete mode 100644 docs/branding/mstile-150x150.png delete mode 100644 docs/branding/mstile-310x150.png delete mode 100644 docs/branding/mstile-310x310.png delete mode 100644 docs/branding/mstile-70x70.png delete mode 100644 docs/branding/safari-pinned-tab.svg delete mode 100644 docs/building-server.md delete mode 100644 docs/commands/commands.html delete mode 100644 docs/index.md delete mode 100644 docs/installation.md delete mode 100644 docs/overrides/.icons/modernuo/logo.svg delete mode 100644 docs/overrides/home.html delete mode 100644 docs/overrides/main.html delete mode 100644 docs/overrides/partials/footer.html delete mode 100644 docs/overrides/partials/nav.html delete mode 100644 docs/packets/incoming/account.json delete mode 100644 docs/packets/incoming/assistant.json delete mode 100644 docs/packets/incoming/book.json delete mode 100644 docs/packets/incoming/bulletinboard.json delete mode 100644 docs/packets/incoming/chat.json delete mode 100644 docs/packets/incoming/encoded.json delete mode 100644 docs/packets/incoming/entity.json delete mode 100644 docs/packets/incoming/extended.json delete mode 100644 docs/packets/incoming/freeshard.json delete mode 100644 docs/packets/incoming/gump.json delete mode 100644 docs/packets/incoming/hardware.json delete mode 100644 docs/packets/incoming/house.json delete mode 100644 docs/packets/incoming/items.json delete mode 100644 docs/packets/incoming/mahjong.json delete mode 100644 docs/packets/incoming/map.json delete mode 100644 docs/packets/incoming/message.json delete mode 100644 docs/packets/incoming/mobile.json delete mode 100644 docs/packets/incoming/movement.json delete mode 100644 docs/packets/incoming/player.json delete mode 100644 docs/packets/incoming/securetrade.json delete mode 100644 docs/packets/incoming/store.json delete mode 100644 docs/packets/incoming/targeting.json delete mode 100644 docs/packets/incoming/vendor.json delete mode 100644 docs/packets/outgoing/account.json delete mode 100644 docs/packets/outgoing/arrow.json delete mode 100644 docs/packets/outgoing/assistant.json delete mode 100644 docs/packets/outgoing/boat.json delete mode 100644 docs/packets/outgoing/book.json delete mode 100644 docs/packets/outgoing/bufficon.json delete mode 100644 docs/packets/outgoing/bulletinboard.json delete mode 100644 docs/packets/outgoing/chat.json delete mode 100644 docs/packets/outgoing/combat.json delete mode 100644 docs/packets/outgoing/container.json delete mode 100644 docs/packets/outgoing/contextmenu.json delete mode 100644 docs/packets/outgoing/corpse.json delete mode 100644 docs/packets/outgoing/damage.json delete mode 100644 docs/packets/outgoing/effects.json delete mode 100644 docs/packets/outgoing/entity.json delete mode 100644 docs/packets/outgoing/equipment.json delete mode 100644 docs/packets/outgoing/freeshard.json delete mode 100644 docs/packets/outgoing/gump.json delete mode 100644 docs/packets/outgoing/house.json delete mode 100644 docs/packets/outgoing/items.json delete mode 100644 docs/packets/outgoing/light.json delete mode 100644 docs/packets/outgoing/mahjong.json delete mode 100644 docs/packets/outgoing/map.json delete mode 100644 docs/packets/outgoing/menu.json delete mode 100644 docs/packets/outgoing/message.json delete mode 100644 docs/packets/outgoing/mobile.json delete mode 100644 docs/packets/outgoing/movement.json delete mode 100644 docs/packets/outgoing/party.json delete mode 100644 docs/packets/outgoing/player.json delete mode 100644 docs/packets/outgoing/securetrade.json delete mode 100644 docs/packets/outgoing/targeting.json delete mode 100644 docs/packets/outgoing/vendor.json delete mode 100644 docs/packets/outgoing/weaponability.json delete mode 100644 docs/packets/template.html delete mode 100644 docs/readme.md delete mode 100644 docs/scripting-guide/serialization.md delete mode 100644 docs/scripting-guide/timers.md delete mode 100644 docs/starting-server.md delete mode 100644 docs/tools/build-packets.ps1 delete mode 100644 mkdocs.yml diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml deleted file mode 100644 index 9ea51d261..000000000 --- a/.github/workflows/update-docs.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Updates Docs - -on: - repository_dispatch: - types: [docs] - workflow_dispatch: - -jobs: - update-docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - uses: actions/setup-python@v6 - with: - python-version: 3.x - - - name: Install mkdocs-material - run: pip install mkdocs-material - - - name: Build mkdocs site - run: mkdocs build --strict - - - name: Build packets documentation - shell: pwsh - run: ./docs/tools/build-packets.ps1 - - - name: Copy commands and packets to site - run: | - cp ./docs/commands/commands.html ./site/ - cp ./docs/packets/packets.html ./site/ - - - name: Deploy to GitHub Pages - uses: JamesIves/github-pages-deploy-action@v4 - with: - folder: ./site - branch: gh-pages - clean: true - clean-exclude: | - .nojekyll diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 9716c910a..000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -modernuo.com diff --git a/docs/assets/stylesheets/extra.css b/docs/assets/stylesheets/extra.css deleted file mode 100644 index dfe2e4d38..000000000 --- a/docs/assets/stylesheets/extra.css +++ /dev/null @@ -1,112 +0,0 @@ -:root { - --muo-gold: #d5bf74; - --muo-gold-compl: #748ad5; - --muo-gold-analog: #bf74d5; - --muo-green: #77d574; - --muo-gold-a-link: #947a40; - - /* default */ - --md-default-fg-color: #212121; - --md-default-bg-color: #ffffff; - - /* primary */ - --md-primary-fg-color: #212121; - --md-primary-bg-color: #ffffff; - --md-primary-fg-color--dark: #212121; - - /* accent */ - --md-accent-fg-color: var(--muo-gold); -} - -:root > * { - --md-code-bg-color: #212121; - --md-code-fg-color: rgba(255, 255, 255, 0.7); - - --md-typeset-a-color: var(--muo-gold-a-link); - - --md-footer-fg-color: #ffffff; - --md-footer-bg-color: #212121; - --md-footer-bg-color--dark: #212121; - - --md-code-hl-color: var(--muo-gold); - - - --md-code-hl-number-color: var(--muo-gold-analog); - --md-code-hl-special-color: var(--md-default-bg-color--lighter); - --md-code-hl-function-color: var(--muo-gold-compl); - --md-code-hl-constant-color: rgba(255, 255, 255, 0.7); - --md-code-hl-keyword-color: var(--muo-gold); - --md-code-hl-string-color: var(--muo-green); - --md-code-hl-name-color: rgba(255, 255, 255, 0.7); - - --md-code-hl-operator-color: var(--muo-gold-a-link); - --md-code-hl-punctuation-color: var(--muo-gold-a-link); - --md-code-hl-comment-color: var(--md-default-bg-color--lighter); - --md-code-hl-generic-color: var(--muo-gold-compl); - --md-code-hl-variable-color: var(--muo-gold-compl); -} - -.md-tabs__link--active, -.md-tabs__link:focus, -.md-tabs__link:hover, -.md-footer-nav__link:focus, -.md-footer-nav__link:hover, -.md-header-nav__button:focus, -.md-header-nav__button:hover, -.md-source:hover, -html .md-footer-meta.md-typeset a:focus, -html .md-footer-meta.md-typeset a:hover { - color: var(--muo-gold); - opacity: 1; -} - -@media screen and (max-width: 76.1875em) { - .md-nav--primary .md-nav__title[for=__drawer] .md-nav__button { - left: 3.75rem; - } - - .md-nav--primary .md-nav__title { - padding: 3rem 3.75rem 0.2rem - } -} - -.windows { - color: #00adef; -} - -.apple { - color: #000000; -} - -.ubuntu { - color: #e95420; -} - -.linuxmint { - color: #87cF3e; -} - -.debian { - color: #d70a53; -} - -.fedora { - color: #3c6eb4; -} - -.centos { - color: #212078; -} - -.redhat { - color: #be0000; -} - -.codehilitetable .linenodiv pre, .highlighttable .linenodiv pre { - color: var(--md-default-bg-color); -} - -.codehilitetable .linenodiv, .highlighttable .linenodiv { - box-shadow: -0.05rem 0 var(--md-default-bg-color) inset; - opacity: 0.7; -} diff --git a/docs/assets/stylesheets/home_overrides.css b/docs/assets/stylesheets/home_overrides.css deleted file mode 100644 index 713c49eef..000000000 --- a/docs/assets/stylesheets/home_overrides.css +++ /dev/null @@ -1,101 +0,0 @@ -/* Remove spacing, as we cannot hide it completely */ -.md-main__inner { - margin: 0; -} - -/* Hide main content for now */ -.md-content { - display: none; -} - -/* Hide table of contents */ -@media screen and (min-width: 60em) { - .md-sidebar--secondary { - display: none; - } -} - -/* Hide navigation */ -@media screen and (min-width: 76.25em) { - .md-sidebar--primary { - display: none; - } -} - -.md-main { - background: var(--md-default-fg-color); -} - -.md-typeset h1 { - color: var(--md-default-bg-color--light); -} - -.tx-container { - background: var(--md-default-fg-color); - padding-top: 1rem; -} - -.tx-hero { - display: flex; - align-content: center; - justify-content: center; - flex-direction: column; - min-height: 400px; - margin: 0 0.8rem; -} - -.tx-hero div { - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.tx-hero__image { - text-align: center; -} - -.tx-hero__content { - text-align: center; -} - -.tx-hero__content .md-button { - background-color: transparent; - color: var(--md-primary-bg-color--light); - border-color: var(--md-primary-bg-color--light); -} - -.tx-hero__content .md-button--primary { - background-color: var(--muo-gold); - color: var(--md-primary-fg-color); - border-color: transparent; -} - -.tx-hero__content .md-button:hover { - border-color: transparent; - color: var(--md-primary-fg-color); - background-color: var(--md-primary-bg-color); -} - -.tx-hero__content .md-button--primary:hover { - border-color: var(--md-primary-bg-color--light); -} - -/*@media screen and (max-width: 60em)*/ -/*{*/ -/* .tx-hero__image img {*/ -/* max-width: 64px;*/ -/* }*/ -/*}*/ - -@media screen and (max-width: 60em) -{ - .tx-hero__image img { - max-width: 128px; - } -} - -@media screen and (min-width: 60em) -{ - .tx-hero__image img { - max-width: 200px; - } -} diff --git a/docs/branding/android-chrome-192x192.png b/docs/branding/android-chrome-192x192.png deleted file mode 100644 index 177604a9ee48b3e34385f57c943e59182f6330f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21617 zcmW(+1ymI87oDY>m2&AtkrHL;6qfF81OW-@MroGr4(TpYx*J8MyQI6j8~*$I&(7?e zojGUEnfcy(-@W(UFHA*A8Xt!O2LJ$kSs4j6|0}BKBtu}9ii9Dfw5>*rhfT|eW zdt-FuZ>Wiknj!#rFaQ7|5CCqGmk`?k;0gnPT_XSxNCAN74jIj=LdY8!ALXSbfT#aH zIc>!W$SasGvWk+J>)6;BWHjTbEWH4rP9!TKs^KyhlmuGsft;-bRG(HZI1OPj*8DKEv-J&}x&E%~#2x75?YJ2%T{6h!FaRM?XHw?Fuvo|! zY=NQWl*sv%g~u!bufIEW654>OtTup1!&BDx`9$!SBed%~B{;+9bHe5XPbBj_K?yz> z(C!4h0zu22=XQ}+PmxI{x`6&kQr*3s0K8KD&EEz>y|pj3e=9#=c1l0TqvZ!CDp!j8 zO0@oN4bsWRS6Yr2{ZUj@G^o-kcn|(fpqe<#A8l!>TkmJq#E@+EF)-Gs>_%0Nvq(uvr(c!?Ppg9a4! zoGYo#(I@B*besX#(lj@_&rv{*oWl|CsJhFbfoMObx$#hgje$h6rM(f?1j5WPFa};f z!b}H-hbo2zNiMs_E7Z`^ywDfU7EDs=FJ3*l?nT8UplWy78AHPvsK~{`+jBtqBTa!v zYX$JZ+HY!-X391rZ>%0z7h0pS+kFR8D(`7Qi1T9K+ox7ptQ{>)^wPW+73*Nm^qK!PJy9St8h5a;Y zS1KYGPJ}OSdZ75I;s0%rzh$BHam1u-bB?IYFAHnqWLhB;0~e4$b7EboFu`Je{1AW$ z0WM4ggJF1_#aFfv47FZ*N9l+Ll+V{GJ zBQ-Ko4yIEV@Deg`@c;v@h=UN!uy%vKGXO1m{14_AG<)6IUhlUg(1vFyAI6!8WKmz5 zu*4G!@RZ|<@pk3|K-snT3k0;#2o8vCetl6m0TI&TSI_sX-id0-*bsOmb8bJ2eJV|0>`FZG=Z0Vk!BUT59)r`fiaF9>m{ zbjvB>9EJJ5GNMXv1xt#Ird|6$Sb3dLI0zt8839bAxjRi0wMo{yR{=m2433tdFsbSh zpEm5+$;GEE-=U^e7P`5dJG#IA9Y!1goR&=CP4$e0;9#A}yC?>*4j4w9C>A{jLTTq% z%G)kkE+eX7XV_v;vuX^CU=4)=*Xg|f)0KOjcbRF{;2A(CN zrB2`5IF|5ddO?L9u!Rox*XKy}xb5^4U-I3`{4zvxG&zC8()Z|}kX>mcTDi=He8_BZ zza4a7^`QYPeX4@!kqNqjA;(N4ON}bdqEU7{04WNlf+9qJ=60TMcCmdZ29tAV4h2b- z=6&?Cp~CBe5=EeWtoqm0u;jBR{=VL3*86b&kG;s*0H=LEfYzc_!VyK|zWxlrCB(wT z0SE?;7)~UCG4BSf=?cSF_o^zt@Y9soxk^n;HG)*VB-B^lqaeoA_LmX^&3kHL&&+?a zAWJs7BulCoN1Oybk#PZhIr(DG)2?Z^lvH{+Q}F7GvhdBod%#rV4o3?LNY+@;`5B1< zIl&WOOz)|AkKd(F;TT2)_hhCi^=^Qu*JR7iNypc;QRJ9KQ+J}m-N6Xm9E#2rt++u` zi4UjWhUu=%o;HU; zcBAfXjYVivx?1dtDt`WnzxVJ2UEw!p148!Vx)E*!@wZZcH=$@a6k!B&>sREpo%1=U z+w-mRyvpiWY_MPAPgHz~jt&O@`&Eo9N{M`sMj3BUJVP`nhC9XM{X;I>=Q>yn7$eS9 zu6sF@K#ti9XM}GOC+X?fcoZO@?|1KUqVaxG`Y483;mrd)}Jib>JI!QP(HlGwzS&iOmyt7ZXbP#r_y z#Je;K9n-V((?yeAK_(&7acnZXR>wI;@?bPg&5I4aGxzQ0U@u|9=(Ru{)_U9VqP-() zTibS*-H9C#-?XykNReWCPrLWsW?EgT#iAvEd-i_M^+%Q0Gk8u*l�M$uC;&KmUeR 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 diff --git a/docs/branding/android-chrome-512x512.png b/docs/branding/android-chrome-512x512.png deleted file mode 100644 index 0fda32a430a7c972e88935e44dbc562148be8f1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67106 zcma%ii9b~T_y3(S82i`@F?NYavXwQmW#1}$$-YG*%gopk$`aWbOV(r!NsLkMS-$uEdHnu>-!&fBGIL+cdA-i_oacGI;!TZpndo`w0RUjq*V8r!04Vq)6oAu! zw}X(;Q}70J(=^fqfcj(xqBAx4JMw{^xe)+_iU9y71_1th3uYAnf@A?;-3b6xvH*bF zKkuX24e%c{_YHNm0m^@0h3(~O;9qDT>l^9NF4ED_a0$GD@i>AX2K2QxEkmX@NWocr z;}K%?xbpkmz0rA8ngEOrDk8C*r=9w$Lc=`6TfbStFr(|RW*pnzb~Jl9J4im7nsxG9 z2(@W=PjAhfo~0k34HMRj5()UuC>Ff6UZsK;P#ue?`dHO<``9vQ;OTCjTN$m@ScDc9 zABJL``~SOE4G=hWfL1rlpF%oTJj)mIA%wLbuYV2BZ6=@x$nUZ#RKSg$PAaC_`MEiF z<~+dPzn?uQ26a`dZT6ol%I_#*D)JVzJsWR(f(u1AMzT{eC;k3R2heu&%?lB1S!WN) zzc);3ajosXw4Y*v-m2TSmraf<_?vfrHWT>oY4722bAGq(D4yE3q1@07S%b%)X5;fn zYs82eN*ovJV}zPX(I6d!Htxdz-VNL$T#v1r{ulc0wO4Kg%~@+6Zjjrd{5bSow%5G~ z8dI#45;{1H3BwL$W;OuG z>Am_TuCJ9WqOV#kahOm%bQ2CUh?j(Gi)tg_f^+}^#zuu?({j<$8=cfO@W?Rt?C+4w z5;MTul{Ko$7L#VvN-WbieCAxn*rmt&tl(GBRiAUE=Z!|pC%sW}xkg3>s$sqh`N6Z< z7<>O*{@MYtTCdm0I`w}f2Z%U~FOdlxm=wMIzx-`6*g72jxitPVS~$od?VWAQQLTNO zrsKN&HXI(U5(a&6L4B>~8^`CGp$5)bWmg{NEWdZoS}`d7b=PR* z=W@Ww)wRc`2d#lC#<;`Zw!+!BZ$;-bhLC3IJ=|UH14@G6>VRQ{^W2d;`IPaETiap; z9o@7n{G}MD!2;E{ziaH?mjt5# zgNtxMq|1B@oq>n`_~C;bYn7bA6=qkt)-GXTVOj^&$&&D-cZMhp&9Vt25F9W^ya0$( z@y$cT0Y3YeG+MaxEKeB@jpK}))GrZU%b<1{uts8O!G^CM^9#Od$tN|!l&%?_6QjOn zlr78$<(umnwf*8n-qW*KZU?pW0as}Ys3H7MkEW`H*4qwP9;5%` zYv6ROs>q*5GN=ba-G9Lp#4iO4HXa7u9R-OQfkHFQg^D*)&yNZ z8@+wpK~&rg*-Hw=;^moEMX7Siir#qitn5p?mdC|iLx5xU6p4Dy6ItDp;_}owSN3?b zSGJ$d=+dYBUYDZ+<-p}7N7DLauxk@c>byVM+u9Hqtzj{yQTq6w1A%c#R~-L~U2G-! z&KN?5m<$E=+M&#RvilXBG+YxSI8ovQ;J)L@4?l{P++bF`}v7@Fk*sRLc)xtA!lK#T7W+|)YAW! zx@lJVkXx)OZ_*0mKv#sKZg91onBDnAxXll?_Jh^)`(2bX@m3pPwT^+xYrnam1TckY zL%u>pI*3bW6nj5EiqY>l)xcBv1M}YPB1UPLriKX5O(}2+sse?m(|<*kapG^6%E^F( zUvCx1633=vwLT{zVEyvGMi^sHcbHI8PA(!>k_YtAF?$b-JHwFJ>GHTDS zirRb?`m$8~+-j*iu)arKXO0W!Z4+DrbcN$@hJnt^0!B{FXw7r&aEWA zL`1nuC57Ce(XkR#*pWuYXj@(jnB4JSY?z-f!sF(m7{2eFEF?a7@D~?8AIn{!j3N@` ze?(zLV+OJqCvMFlseY@hXk&!o;OulM$~%wy>8xIVuv=iyr`I6$XcOmLIu->cUO2JiI9BDri}o zqjX+d>*Lkb=lE6>>7K>N`{R+d{#xUFmEFaXWVL#e@t_Mwjoe6#OG;cn81XCYj;H3bYU&t*q3i z0wZst@DF~NCEl;c+^;u%dLjN6;^jBim$#4!K`m;UX6f&uqp56ZX=zbm)6JW4=9Qy= zbZqpB}=PVWJsXW z-3&!0W@cX=K0e~+Oq+~aszIrMI*Pd3#iCA}P_yjCj93o6aP4#zn$yNSC<1X)S9f^P z1HbuZyK;&a88HWay7bLm zVnD&mg4^kss^a8DdVt%MuXa(&&7u@4Q)7P)6A{Eq9l^eY71dWF@6MlFr4TzcC@V4_ zSBnGJ9v{U=)3QWR>bv>FXpe#{k{RpnK{8;#pBtU^nEzaau)EeySnS4AdeX~FF&(*= zlmE23V8ZQEdw$=-ejd7Lex9o2FVC;+Q@WtXB?~Z#F8*sybm*f-TihV($r=AZ1n`li z%tI*OKrr86l8^qO4vpZ}A9KW4(e`%LWBY*Kny}!F3G(-eiLZkNX!1!Mvw+%-$mMHP z4joXi3&W4VH8E^0U%4F2ep<6mDtL}){U^3``ugUA{jNmov-H^a;*9zC#eD8RzI{`{ zO-|tJ<&^w|NqJ;R&ItbWhH=Bflk1Ph0e|SwyF!khhmAcC`)!fFT69xCo9vqOZhl_n+Bx9XdFd5K78fYgIn4TBZ@5NT ziHF{2HR2J#9&PP&Z+wFpA;j9RO1-p(hen7@7jndd~OqR;>dLwK;~{zwUVY*HZFuf7~JL zudNJ@xJNfJV90g8g4^0%7&3=~^7+t!u(q$27KL9^-R2<50hQ`W6S}@H{(QWzM|9B^ zZ8Pnz@ypUs@o{poys6;#I~-%}Y;H^ExUz=R>EBgI>byB(kd+6l- zTie@|jhBiJlz%q%K_{2oe!f6$|2GLBtSTgbCqpw%ddF^b#sj+7JL!P#yrHPM+Tf{7 zNRQ1{`uJ9>2HD%uj*x;xt{oO|Xk7NY|F}A)(xd%o#y0XVzrjCx)GuP%2O6h(jq!x6 z94RlF;`(z7@k%24PlTzWs%{-sJK~-UR$I?~Zo$tU&$wYDc4arTJEhlBa%(Zv#xSL2 zYA}$yr^OzHm%bq5HJ%CdymFB|p56~xt(mX_)h8Q0o8PGAAF9 zg@c>z64dfONAJ~rMmxO5Fg4cv_PRVx@H@;B@0=@t-GA1!_|NroO4Fkh%hk?f!vFH05bbT3&eF{0 zUA2&H?cAjrk`Lzk-RZvFpDd~!5nna_zWIm=pk>g~D-B7NG6a`zQAN{mH8`b=OiZ(s z;pACTwx#6$5U<~-ld+Y8uq`CO^l*Og7GiXt{eKPGgB!@Xi;o(&|Ft%paPRPy5APe9 z??Q|8Arr?z7tSe{J4ZEb#w{%NUjz8IBwjP#HZryjr@mjGl~@bJA03EncP!_;RSQ@v zZ7Wa@*_oqKr<`4rx3U{W!)qH}$`!gn25?c&kn!5&}5EfNvRx3)_R%3vVH%9PAb}x4Iu^W&Cjz z34P?iob^Dhuq=MGU;a4~nSEQ!jKfB#?m_nvrRnMZ_e}iLl^M#xYDsd(vwH%N+K*Jt zEq}G0cB9xaIx%7}+*NzOfp|)^jU@NhpJHNTMS`mDw&uleZ!C7sW*%|FcCSA2uajVp zJde=&QJPRPoZ}^w+EV~RCVBa2)7BBSlHWo(8rH>zus;;)Jf*AC?yQn=@}QRV>yGbS zpb`fXVN9c>jY_=rOP0nc%Ey`Y<-W@)WF)Kbc-O#NER=oZqtT9x^~JtENZ@ z$Wyj5tuDud{9zlr6#u!-NVAD}a1(as(0Ep{1o(6=0OEikjW98{Y2U`1*!vuDHX0{{ zy?aF>eE6+~iKNfm!QBhi#j`ak2TyhyGuR^KIwBL66U*f z$){jjy=iq`RC#omY#}=>s^1LL^OZ%XipmECTLSisw=QAyuEMQV_LpieQmIh`< z%4un3**HoN#8&$xnsV~9b+QRsHgx*C)fWLnp}Py=3Z!v@=rQF~K=yG_WO!ML*-Y{@4Xr2%M$a;G#J7^jJW zkJJ4C>zzR7-$EZ~FkR@yeQFMR zov-YVdKy&Q>qPYX6nyO{+mu?$zvHd2wNe}M!2X~*8hFx(DP^q-r@BJ{FkVzz5M$sY zg1;Q~`{!W6sn0sOfd9%aZ_8Upo-J-vKBD5MTjnN_hB57#?Xw_jNT)u#u7*bHfD2Ne z4Mb+`VF!N+ws?o|fonDq$Dmoxu=tao!4zkOdxg)}`M+@S-q!~kn@fe-gYNbtqfx=> z(0^@$g>m5vKmg2Tm62jfK;hQIf(ox#`lI z$YgvW@sXqX2Zkgm6bFdE@$nZ8X9lUq!#|e*N>TJiBZVG3_v_EOd@E4bFiRiEv}-sM zQ1qE1kg((fH+0x?f3`>ZF-IaCG3rU>8BV1{x5^I&htyerD;=o|XCodgRxv2(QSN2b z{W$rfmAbG|!93%BK&Nz%)(znMtaCXt?v9iYSMp6nl^awGd31a{v+sp_g14e&<|72F zpY#qE+#1VUEn}+KWtyA9Y=Hy>L^t08XXB2AYS=fuVEhwocrX~c@MZI-o4IG@ncLqJ z?xJc>i%fe(r5cbDpvfwWzpe68Pab-=*@iD&#AB)1XPW#k=h|C-)WNVWWe>!p?ngNZj*-9+X2x}EP6pZ*)E~2x*Q(=%#SMFwJakN@ zzyH3Am<{=tW8K3ITHBfDT9w8ty@NlfaeIN2@@YTZ5LO;H%P@aGM%Ei<` z&_D>zDhP)~Au$L@3=rjHCHNS<-%1EJz4!7|Zoo6R@~+xWwphLo4P*55tB;)NIX$k8 z&$TUk5>%D+UcFhm9_&EGjn~*yX8ch5wiLB|<8o*2BX9@(5b6n}c}%ASfuFnQfAF^A z3{uhJShV%YCHG*PBiq|w?P`AMxm=0dwGW=5To*3T`U(DlMKocPu z6;hNh|8`r~DG|xeJ9AfzCf)qpGrAE8cG!qK?@Z6UFg-O>PMI)QVidgjDr{|gyKRNR zk?<~Gri1VcdxJvU-!Ae*jhfmY{L!pS?4;Ac%oXpor`xKVne?sWb;e0`6K%GDYjFZr=`dn|%-&XhP1ap1JiYRNbgcjl(HRocfd8PZgGG~zM@%ScmcAR5!8>wfmY@a8h{|cEt zc-A0w@s-HMHvyaaCMD@}4%h2J|PYm7RroRk^f~bbwzp`G` z80EZ_L7BJd*ju`wPFjnm9DR*ve^AE`vF7bGfCzswz(rHZ%74 z5GnrT?uFeuLOd_O-LH2SVlyjgsMcQoWugVwuD_jCz0vg0T*G-)<#9W#M&gc!X+rpA zmTPR067*OrYnmx|qx28o_X29)HFu1ti2mwav6d zsxbEauSBHVK+NU8)95-jPTm#3?H+@39KA=j%4;7Q5a}F&(}Ji)fU(SPFRhjX&+R_x z+zp(5z32GNGN69{sl~+v%TR@vGU^8{yww9f!Fr~!iI&AH%o9Ja++qWdTAQV0Dyv*ZEPfyQc zPtWs_NGkw&aCG!NL+b7?-2HER^F`oACX+vRbj*HseI8kA&kBPyc>6eWJo7Dl^G{Zp zY72gQL_;C%rU=iY-y8@UT3U6=k_>uxAx;3bkvto5JTp?kMCW1z1&$fuFeS(xr;v%W z{P+m(aukqiGRxQQJWaEUPk^3ItYnMHs`wUL7T@?#+vrbkd5JE;82;$B(n+}5HC0tr zwJTSyD5!+`5*K?dNMbe~RktWf`eX>>#NXp8E_4ok!qe z3nq6ZaQ0EoY;dPd6iD!jh9a%z7WW+0htWGo`MTrAFF3YooNuLU__j|yE}`3B^h}E0 zDd3q<=3jhT>;2wB;0V}nbW5NtFSQuf0$DIwDkK#$xj}kFr3o%EnEE>C3Itj2F;W)P zopfO&$i9VKQV+>sS|{3U0wN!KZ85YxYN?ot^)KD z=uCq~Bi*2g@i(l?B2Lbobe+&boiH>^WARzvC_~LhQ?l*dF9t_<%jjMhXUz?p?cYp; zA>#sGu~RL*><#FDZ!XhqYMji2C8;KOCRnnLZF76cWhKwmx^4T35LcF9tAuubR)1l@ z*QKyv&h4sw1FlWMjAQ8~@3_qLhev;>USG1QInT#uCkEI0YpK)tGbU7jB`Ibeq5B%R6IfO(weyZE+s7L9*bvzud1gIIe(6m-93>5e zP#V$4Q?%>ZP@X1Nc_`RZR=N~kQo(I8_URTs`xX@GJJThb%eK=JBE#|*v*hXc0%MQ} z3D0*AzsnC~2jgcbfS@R=$x7$c`zx25@Z#@GjaAV?ajb!t%L}9THxi! zsk4#u36|ft9b##_s9*+OuuknUmo62Ld$DHKX}A~bd{kSo!eI~G`68AO26W-ICLH&A zHq``vT8Cx=KQl`4PIIO(x3*_MB>w$=cQ^DiHFsW1=;3-$L_|dNPvaah9sQAIC2c-q zy#_|JYP#4`c6N5kikIWrDc(IN<7PJ8y#j@+-p&e~31l161OrHj{QSlW2RW6guT&KK z$%@n$lCHEt;$R;E)C=EpcafOrGnQjdn|LrsV6Ym-n!;U$+nJ%Jd z{*F^D-&mde&M#ucQH2PVN&^g2@?A37BbhO}koV^=f5A(C9n2Wp-b-8@P_!>5((2T6 z?_Du+@@}x}O}>88az2pPBoS8ka9ipOMK`7_mPElO9;2?7pM`$un8_904N-NJj?8o| zOttPb67GBj*q+<;PUKfd?Y)<}1T_TUA>aF-bjdTW7N+q1jO=yUD;q=|joYXacS>+A zXbRb)t~U17{*^}cr!g9FV64PD|LXU+A;DJi?`m9)_2o8~w|nEo&rwHrshP5J#G2zC z5opR~6`a&ddFvQ1*M{Xjnx&c&-xiwOYt3so3757oUxPa{Cidk z{${A`(R>Bfh-}e$9v7V_9319@xW7r$I5nk-kgXbos+2CIV)A@$haik38je3QP5V+v11qaS3TjW)Ig@bYFWjiWE(#g%c*ff$ zo3{*b<-y*c&jb3YjNs^8$p-Of1!wA9XNj}0*4Gh99&ES!)APw6!~%+jMmvUI%*Aj{^b%c#fXB_NYjVq=I zmc5$U2sBWU%@-<6=iaB2<)PcUB~my~!`W<9ZHDH970rgI=tu5{bw6{XuP}NKv$Rm+ zhPZ6GSB=ozfk+2%Tep0;X!y5wxqQ&$zRkfTV zSd5lKS(n(~aC$ii#f*ymTE^q3sY^#+!@k}h?o&Ig3?t8rgNbJ*%LSECuBHy;??03D zbdT6%6+y2gbPqvh1%?w_^t`q|-6Q!m-2UA#*vm~Pcei7k5POnz9q&Dr%%u-8gilm3 z{?@k$mZ!qZOX2OvLi>ITQPCMUsi`&VA_O^gX7*B(!wlPG-h*7}Ct)NxPX3pB}zznI+;lbWVOG{S?-DU8;G%#$&4IGbpRY2CpZ*l$q=q znKW?;E`3AMv59G;#~KJ0$yJ??Y}n65hP z{GCz}-u^G=(d0ZDMBlr$;mhIa!g; zo1N3-K~9v6?yM^=qp|U8#tm+m;L~2wHu6^Uv~LIB*sp2tL!-Au1#yUUR4%Yy7`YQX zMSLL8CKy1{S<$ByASM#-mp2G8M)&1AMS8(+GAlA+6hE+N6e1A|B9Ptu>oVl)`sS3? z&$I%>(rzE`7@%_i!u0tX!0)a}(1m>6YP%MC20jVB$w3}DUvEB;+~RaCNhf|84vDKR z_bo`h`(my7xmC%5Hf8QpQAP5E=S5E zcUjZrOy;GPUPebl1Y=q-*EEqxZU3KXpPueNML+7k5NyZNW`cRhJSS2}?GK&PU?@VF z0mCML&b4~1aGm(+PhKpI%C3fIk^7WqKM+^uR;};2bnYrX?M~W62d;qn8F(-jFox#9 zjv-D%F)cVF0zSxRas5JWDNZCQprbO+(s-*olb2R^&P;)BSH{agx7g<(HIOWwxB959kJhaL$JT3po_yp0wu(vOS%5!y$wMQN z&yR43;;pHseZQKvtsMKhGnfSUJ&}&KV>hK92MQ~zP_GkE!2Om84UpnJ`QgX_V?9## zK<$Cu*Fw}lR@o3jQNKK;k(!8wu%nF=lW+Ie5@kN^e7U}pM4Y3Jv8!9X1_V`|wk{vx zmI9uRFL7U_+(jU2)nbLxxce^s^!uye_lFe|E&K)%bI%APk~<=M13accru)9Tx@ zC!h^!-!M`(l4L-4p#Pg4DL9-J3CDO?>tm$)F8Sg}8MsRva>oK{;l$g~y8b58{_Mcq z=8lconV;Q7nX?|IR0>$X|2~^FE|Qf_sQt10@-0PqnHu+C_NiBUeDR$J%qb5alI(*c z4%9E(e|(HM`Uv@{t(l?kWR?r%5{39zkSD1>tB`a6?a)v?yttnk**dlN-anK<_C>C%K3QQfxq1+&SRFmq<;4j{x&Q0LnyN%;qfq2sQSCDy!qw^mHwG?&m=lygi-#ZCaxg%qw zzp(!N{ux5RF<)3wO=@TKne_M=xu)SzrtymvDsO`EF9dsMQUYG+c#Uuj`3D;A&l$eAmo z^3A}rpC_bAmGK`Uoxjly&Rx&cJC-td)iIt);0ATAKi36F&x6ZxY?7<}Q10O|SW&{k z_N9x{HAXm75H_r@buJV;g%D*Rg8`kat}#Z!i(>-zGLhy~4b{y@otGhku!Q2`J5qIM zizi!u4k@{Lc_&{$Y}mWJp$wg{gNSk6ty~@Q0&d(OOXsTRE-Qu(pZq%QlL>f3D20jM zgb0oXbJ~dKAc3mtF;+4eeXEANvU-E4-hMfT3ji3qwCnFkWJ(^Bt~TRXg*42B6u^x| zuR3lYyovtv-ebhzgD#Cy1e7b53polajOC*Y&#N(pum0%4KNmWkbaQ{kch5iq!Jc5r z*yI`=U2>jaq{p4JXl_vCL7i1Lf3~ur&8`DUxc_#D`EEuAxU*;}_>PVawU8Bf-Ia>E zG|Uhiz*4TR(2dq1P(4R2Crx0rIlQaYA`4x90D>Jd%f|BhvVw`FJh9_zR|1Kv=O3h# zcq1v;Ot9Lk!hkk@o9|Hxka~GHDDIN?oNso(bN@X+@wh zI_&2W2GAj7H`=HSCxenYwI!*3@!7b_*!YQ`m}Il9ofgBUUF5=h)j-oRDuvqgazy)X&)UourBAuz$~eK{;?)DibENvN zi4@k>9{(N;Umn55Pkqr$G-d}Ip2LU|XYP|q1lleJj8us(kT#gaUONfBs3$+1mqCPu zqxE&y#7(%dC*K;swMdBa2;MMJ=)NCK5&vzRPljL+S?RwP{wAyM{=Uhgx_7(MvLPQd zoko!e4nC>|d{m4htz9;70btFF-2(9=OGxSy@steKH59>&;GW zoWydpFm%1a%TwfAf(+D%iF{H3bq?wG&67BX8AlbyLZDECkNbo&IgS598C!PeLe+kY z9fBgX82eE;urx8yrB0k@5%{sPfA@%IMBY?l5r~m-)R5;15~F8p_QRjnf-HSASEC2M z9-a@qsRQsRktSm(AD6zovb}6WzQvK^f^{|(1@f9^24b}3m6*s6ES7uFB!{iAIOFr> zz@n?I^OMGkPRbyj{Qa|8EdFi%{@XmnXCXitXcg8?%0FGV!5y{l?#8nosf@^{4z4)o z$OBkhyOC8%^A%Q|dI}gaoJ>bXMxvz5Ei~NW8fhLVPJq=+{sH!b@~Iz3c6Gy6IdHrG zSyD^|YZk&ThEmD;w}(PB+oHXCUWFNCP7)^vH2tgS=FsXYp*I%p9PETCUrwRv6gs&J zWM^lO64c3m$8qSr#dxZXrgU=-dgUzF59{#f#TdP>#!ySEnUL*vtW!R;y^8kPD_G1k zpg-!Nm%~!T1Ki;}!SC>E@9QJmv4&2@PAwlB_UFuz>7K@){P>3)L+83%1r`&twC)nh z%|szj8_wMZ`1ll35Y3XX$aBD67AHB2^wTRxfi&QUS`qidk$xI(9HyHu?muLqVMMGcWS+NS- zlD0^+P8@BZiA6Uad_BfW+%UeVU-XIYj{2p0fO!dIZVs+U6nn$)2I9|#;lRk3${#jj zRS5*p|D3w`#ArZrtPk2{Hoa5z-jv1cfH;gk&he_5ioYj~d28Wx=RIIAbI6l^-1L;> z=O|M%8yHEXAk2*-Z_`0oUGUrwZFvolb#W)>#SY>eB*?2pD~W?er%Np{I2|AWp#LH? z1jH;%_YL17pjCX(4?=B30p)buKLs`bNt$?&tbX>D-GnqD%b4HZ!Y5WiU8uh4HSFH6 ztoGw!X2cw223&|dQpF;g_Vx^guU*txXxZ%6-$45u%l_j1Z&=wdCxXL z*{NJOo>i_ExHa}0OIrweohS;>09tlmfG%!jfo8IQKW!3J&Yr~$4Hp#qVT?JM#BLlr zeBN-V3*MepG!T6kvOl0WBdu?)W8)yj<&@+4a&E&Kp_QU{fK1c3B8%xSbQ&qn?5yY} z@tw?Q6*(2!@pgLt%z*$J+c*kpuak=9v5(|f4H!cmEpAtxQV!b|aOV?W<^MKHha!Yg z?8D6p241mf&63G&HEZJ0^|(W-3b52Tg8p`ty!YKSmlg>`{F|G99^FMboS46+W(dez zf`v)CI(f|Ni20X_v*9cMB}R&g-|iSlIGYVqKgq3d zltIe3>5a2t#5T#2m{r{xn_ByJOTwpje~THlU=*uiA5Ymt z@4DhTnXy5uEj3NLz_R+A<|b9ejGxTwE8UcFlYPhQS6vI99rxnpsPBBi#WZ*hmHpal zLti+5m6@3fCDW566QE^A_H7jD9JpBb>nEr~U#AeUev}6)`ORYpP|Uj+Fh2~_esIO@ z6*2(Sh!WQt9`-$R3Z_qIl|y4{M1V#oYFzG)jSiTUqe@R}byy>sc}t&DbcYnKd2(o8 z5T|4_UN~Eij`e$C^o#WamMA@s?W&#AP~JRw`}?t4^FK$qNiSZRyBV1?5y$rE7b$TxPcA_G z%}DH{-_PCx#kfbh#18Ej8?M{j-}DChgS<*YA)x30YmhBW`PY4d=EKU(#Hi=)h$r8D ztzPvL^RSz{JK(4doA1fT2M`^fGqiLvjfz8j#Uc;-`}-$aa3m9oTWIL_ThPbtF}KAw z(dyGf&ovN<;@;6?)6?h?UA2I5p9)b(M#r*)7guk`B#)1#1I{XWcpR8Q6xdK5CwusYR)sSyO2@4z~*EpCr* zJttXfi}Fq;ii$2@@AB?eZ?yEUS zBm}2%6O?x%*qx?r8YVXugFE(T{L0PO0ym><|Q>FeKj;|%lQ(k6QD>DZ- zp^c&hgPq*e%Zz9GB}D+UH3Ws_0P;$t#xLpt)0}&yhBPtBb;pJV z90(}VV|f^)=4v>-9arrl%Wx;A^SNnPmz9<1Lkkr?Cyz`HRv!7~b*lh>J4@Ad#pjRX zM`)#iIbUXXF&oTFSon4r{w!1ti***r>wQy{Y0#1UIh-6H6?3PbpXY;1@2h0{h{LhA zxf<$K6$_0*x=yJ-F*xaE^=y&$OkWFf)@CyDIYPA8k4?FjW<|$v$e!MHwycZ4U-cVUinETbgPpx$~>9} zBwy!5`mU0byKdZ*;*S=Y^jxL`6(;|%7ZYA-NYmBDpvSYIATNG{jr`#)*)MUnw#RBr zT?486phKqMMBdYg z%~}afC!Jy-#%A4Vdj9VO$n6S*@2ueEj7ktbcdbNRyG z1t(014hm>P!Z^de?fZKGGczyIA%!d*poj&^1Dz~H=0M2_U+7+MIm$ifz4`4I<_VRR zbf%`1?gvRm2)-$7tZan1_u|k>lGp z5dVup0&iTQ<=Wp!j^E?{`qT-TgrAJg0WcdgXY0ADs_nh1VV6lxOU`BS*=rXMj#*As zr2=mW6=>I+Vw}_2>sYlG`#=%3i9^`t0ABL7!OuERMI$e-d*jqvbMgRF0BQOQd5h$9 zz|Q(QuiJrdEno~?pAzRW^>()-Y&2vomHYjQ>BAY{FL>2jT-%Dw(2pp_&JX_AK$-r0 zi$xVKsm9^#W_xvHwFyRgZGzq8#>t=0(X@`P_(DrbXR&L4DOvp`heu2kG}1gT^Fe(q z>cCh2Cli3ox`)wV#fbeNN;Vp`hrIpdOfpzY+#n_JKm@-Ax5|xMOL93Y-6xs6IJX^s zmii~UB8bpetk7QjdK_=GsV+maemvoSGB~VHXy>A8?#R7Hdk0qd{mKrlI$=0k+@xT3 zQ0@Jl9^qX5GquZsJ`Ey*JTE6{JV~cbj#D3l{@ok3W_-L%jnvrD(

vsH%6|=rmv& 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

k0_6hLHE=Eh*apTrs%j- zxbjJOh`11`04|srB2|M1WOQk6sBf$f+=n_EAe%483OFXjcDs_`PJ#af04l8{RU=^( G^uGXLn98vL diff --git a/docs/branding/favicon-16x16.png b/docs/branding/favicon-16x16.png deleted file mode 100644 index 45b6741aabf09562784a18656a5f8a34d3dc5772..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1418 zcmZ`(Yfw{H5I%|$6s=mUg3=N}ATN@8gAncw5JMgiLINZqq=aZ9AdeymaFNJEsUn0{ zF$hMqJX=6bRFFtjP@$E!Drg^~K()0Rp&e(Gjz4|W9;QD!{n0b$?9P7Qx4S=f=hP+1 zW0x;ow-f-dToNZ#K)-VSdALDK30a|pZc#R0#s}csAGWQATXF27#I{98cJs%bUK~ILRs)2Yz7l$ zFc=gXLZMJLY-B(d$HK%SfmW+c*J=|Jizu#C{z}Xh3DvF^YU_W9EbW~Doen} zVq#)^{b*b~oXf@i{K!-qi^xwXE-t20sgd&_H!+?om&?_1u3D{5kzvrv;xLH(!_q_8 zIeK1Up@~MLkpq~pJ1p++?@yzn{AdoJ&xbgTfkIrTiZU1s7={G~vzRP4>?jdo$x<$# zhhrEX5)u*=6m)o>+Om%r8XCNEdGON33vF$!hpRQWE||s!jKeDBNi*F1RJiKAnX#`9r!elaax^$PzH9kHzH8t7V+A?$7TuCH#HtL?=t1xJV z2+BqfM6cJ+&CPXoc2-ta&dko*o6~z+w?;&S*=kd!NAh*4F(`uSbh`Tw9@viBA|fLC z`ugk+M{jeAF;iGu8b8#Ts!5JUQ8tRA8jWUnWY|(?F&d5iPUo>Ip)vtS*`em_&24)H ziUeG#RCaZDm6eyNRI2v&_9GS13Mp2S6?v>ODp`tk_w`4>yW$U2io}8lu^>D@&oDVT zRZ>#I;c)u;dhHJTlX;I^+ZG3C>n&LtWmfQ+7D<($doD>FMg7qSH2M z&Q@NW2rJ6w*Y6S6?-py-BC$BuWHOG9UTbKuRul-@>m>ULp+OU^l0_LLaTyGW;`I?&A+P81t+RmPN3RhN6DCG0&|L<{+?Qy+&_2i_4&B@#wZ6u%m^Xq(?=Ki#i;_b60@CXxLcYrT&VrQ-=Kh+OFMnsn z%2n@rt$uIKLKwO&TI=m2PfSWyDA%p`UF-(j-~T|BqE6LlK1|c5`}vXpd4q1tR=r_c zMrPLb>>U39urV+<@1y)31x8b0Q85t|3@9Z#OU=8=3d$=gckikCmpM)L8 z%-rp}{y(Ac>P|aMNG(%o2!)}PY$`Ht&&|&w6T3`Vto0_;jIzH+xgH9r)yUcFJi)u Pz!pFvk_*qq==c5&P@xSE diff --git a/docs/branding/favicon-32x32.png b/docs/branding/favicon-32x32.png deleted file mode 100644 index 023b48d9a817db6051a37aa1e33d660bdff39c0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2660 zcmZ`*XHb&~6Mi8lgsPEHM34xP4u&Rzh!PS5ArvEGq=ybcY7|sdsv^>)qa1Kz=yvIjsSoKPXI72 z007yrqUMWc{DP2|4F(1L`cF&S%Cq?yVY0O?T6j)GL`X)8`j-b`qo2y`SV~RsN?x*OwB=palD|4UfwK2VS2J#Z``)M$0s&Bo2yqRWlqq?IxfzPh`lkB}2lc7T z*tW`?9i6bFJaRbSy$dWql;{1xocO2=*ZJ}3&@$+BYeB7Bi~Ee) z?v}x>qehZodt+E!g7B}-m6b4llLwvUb#`A&b|u!5oeN!)S4OOO_V2R$3SQkpKOvaq`x+uFm;BxwOI%Dh39t@zIj`;`i^QZA@ zLhSNnL*16}?T4sVs`3vR9yuy%?8ujT<=uL6!%82^m+l2&sABiNwYgWjvLO;vrl9oV zX#t8+yV9ZGF2+oMUKp)x{kb_QE^!c&);->K+xY3JYYgXI(^ru5W6$!HD2Lq_D^KdG zES$mR_O-6P>G=9n^AT4Rl0Zlx^jq3?rg&1(Ri(79`Tl&9^>Rz-BlI(lTuu9?W`$!! zT=Eh~L4xeuAH}_HRQsG37kne@(l3R%k*4FX@yXz%n1@qzc+(V|81Sjvn32i;+&dou zO+llyok^@BlXpy|J2>-_&m2sC?TuyAD%zPiwbz}J>|vX+C`!STB0rz!ovQ{78o3hK zI2zL2xSP&zwggvwy|&;V@U|J$jT9gqpg<`@hRh5l@95})h^B#^P%3k+72O$GO_<;m zq%`WJNlvUP7p`iKg~%*$9)Y)GL@*-nIfk8a!zdS`0@0C?24!Vsm2RbHkDZ2!U4kJ$g(TAuPnW!sVyY8GDx-@N zL?qUJk1I40H0a72fM}9*3UT-6n-r2Wt>C~=HL}|k)8ngl@q9QwE+&D9R-Y^X(@_&; zmOmKqscukCblYqcK@V3z?Y9JpCJAoG*tWZ|(Hhc?2G!g?TpaJi7Ew#4Rz^!`?zm|z zGBAxRPyOam?x>^WHzwE^k8_gfg)Jy6(*^G+b+v!znMxL4$)4FB2v^AJ^;rh{NTwOc z*u$+;H<2qmc$;_y^Qb*Ly{>1@G9nWJ9Y96GHX6rPMxL+$ zh(E_`#7vjtD@L;Qj%5sUI2M|P^c3IVU~!6LhLiK}ebSX53CH69v?0~`ZO@dlI(>Q% zrKrkB2Cf(>+Ni*1b-CEK%PuZ1i_MY`ec~N8lW2Lpz1BH+0_p40l23PvWL5>#vha9B zQxV6xWJuKfrQfdu z6q<^I6W+hLN}D3iK7p5?V|%5}58Gr{xlQ1dgI)>RQ#T1TFM)}8v{rY#>O0wd8*zKB zm}&p8uuN}e`sjw|WIZ)_s_~%}92pvVGGEsXMY?nN%V_N7l&H1tm2a5ODL8vls>scd z$Rd`n9#B2~WTvOrY$85E&q4R7tKwg;I73DH>LMbRkCG7xL}wgGxG{WI2yk(~i+>P17#JEV+z8TEI8qZ5h&%NPF<+WXoOl-7BK4L~-?#ix9~6ZY zJQuGNe!f#KNl%m{ouHD}KV}p2qgTzfH5vjT&iCamO*Uk3xlWq7qH1|WQYm&rsS(FvZe~qr6S?KrW zn;}E)8Atu-sbJ5sYBxh;V^G+9pR}Z+DV;AS)Qzp!8g|LKd(#fhz0NmlC`}(%^Basg zS%*_=1D3;X;~L3S`nxkHL@ym@fTwXKv=5LpA@U7#*06o(^SU}IX1D{EGd9ND{ocXu z>9OkI?p)_-kK7*;PMc?6eGIbgwPG6lt&vAFEeN8X(Oh;Yy3Z-{eRc@1IhLp@b9yf2 z_~SXO``zu9KaU)#=MGIycCF4TWxey;rE$-J(pmA5HBKyFWa4ym@rOP7j{@g9WtdED z!OIGf94Ff2+kOpBDK6gktH`TMb!QL^gtbR6{mn-c~@4Bvlf-=BFzB<9K#6PUyU!Kpb-)Gmq8iV5Y81J?6+ z0Hh+O>n$dwB4v{e1xdkBv4&kfAeA~tSpWD)4}E~HKo{Pb@(-j@E`J1I MjkZHoBR%8)1tERiX8-^I diff --git a/docs/branding/favicon.ico b/docs/branding/favicon.ico deleted file mode 100644 index 10c47ee1c701754ee5987325f19e9eb5e31b2ff5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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 An*aa+ diff --git a/docs/branding/favicon.png b/docs/branding/favicon.png deleted file mode 100644 index 023b48d9a817db6051a37aa1e33d660bdff39c0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2660 zcmZ`*XHb&~6Mi8lgsPEHM34xP4u&Rzh!PS5ArvEGq=ybcY7|sdsv^>)qa1Kz=yvIjsSoKPXI72 z007yrqUMWc{DP2|4F(1L`cF&S%Cq?yVY0O?T6j)GL`X)8`j-b`qo2y`SV~RsN?x*OwB=palD|4UfwK2VS2J#Z``)M$0s&Bo2yqRWlqq?IxfzPh`lkB}2lc7T z*tW`?9i6bFJaRbSy$dWql;{1xocO2=*ZJ}3&@$+BYeB7Bi~Ee) z?v}x>qehZodt+E!g7B}-m6b4llLwvUb#`A&b|u!5oeN!)S4OOO_V2R$3SQkpKOvaq`x+uFm;BxwOI%Dh39t@zIj`;`i^QZA@ zLhSNnL*16}?T4sVs`3vR9yuy%?8ujT<=uL6!%82^m+l2&sABiNwYgWjvLO;vrl9oV zX#t8+yV9ZGF2+oMUKp)x{kb_QE^!c&);->K+xY3JYYgXI(^ru5W6$!HD2Lq_D^KdG zES$mR_O-6P>G=9n^AT4Rl0Zlx^jq3?rg&1(Ri(79`Tl&9^>Rz-BlI(lTuu9?W`$!! zT=Eh~L4xeuAH}_HRQsG37kne@(l3R%k*4FX@yXz%n1@qzc+(V|81Sjvn32i;+&dou zO+llyok^@BlXpy|J2>-_&m2sC?TuyAD%zPiwbz}J>|vX+C`!STB0rz!ovQ{78o3hK zI2zL2xSP&zwggvwy|&;V@U|J$jT9gqpg<`@hRh5l@95})h^B#^P%3k+72O$GO_<;m zq%`WJNlvUP7p`iKg~%*$9)Y)GL@*-nIfk8a!zdS`0@0C?24!Vsm2RbHkDZ2!U4kJ$g(TAuPnW!sVyY8GDx-@N zL?qUJk1I40H0a72fM}9*3UT-6n-r2Wt>C~=HL}|k)8ngl@q9QwE+&D9R-Y^X(@_&; zmOmKqscukCblYqcK@V3z?Y9JpCJAoG*tWZ|(Hhc?2G!g?TpaJi7Ew#4Rz^!`?zm|z zGBAxRPyOam?x>^WHzwE^k8_gfg)Jy6(*^G+b+v!znMxL4$)4FB2v^AJ^;rh{NTwOc z*u$+;H<2qmc$;_y^Qb*Ly{>1@G9nWJ9Y96GHX6rPMxL+$ zh(E_`#7vjtD@L;Qj%5sUI2M|P^c3IVU~!6LhLiK}ebSX53CH69v?0~`ZO@dlI(>Q% zrKrkB2Cf(>+Ni*1b-CEK%PuZ1i_MY`ec~N8lW2Lpz1BH+0_p40l23PvWL5>#vha9B zQxV6xWJuKfrQfdu z6q<^I6W+hLN}D3iK7p5?V|%5}58Gr{xlQ1dgI)>RQ#T1TFM)}8v{rY#>O0wd8*zKB zm}&p8uuN}e`sjw|WIZ)_s_~%}92pvVGGEsXMY?nN%V_N7l&H1tm2a5ODL8vls>scd z$Rd`n9#B2~WTvOrY$85E&q4R7tKwg;I73DH>LMbRkCG7xL}wgGxG{WI2yk(~i+>P17#JEV+z8TEI8qZ5h&%NPF<+WXoOl-7BK4L~-?#ix9~6ZY zJQuGNe!f#KNl%m{ouHD}KV}p2qgTzfH5vjT&iCamO*Uk3xlWq7qH1|WQYm&rsS(FvZe~qr6S?KrW zn;}E)8Atu-sbJ5sYBxh;V^G+9pR}Z+DV;AS)Qzp!8g|LKd(#fhz0NmlC`}(%^Basg zS%*_=1D3;X;~L3S`nxkHL@ym@fTwXKv=5LpA@U7#*06o(^SU}IX1D{EGd9ND{ocXu z>9OkI?p)_-kK7*;PMc?6eGIbgwPG6lt&vAFEeN8X(Oh;Yy3Z-{eRc@1IhLp@b9yf2 z_~SXO``zu9KaU)#=MGIycCF4TWxey;rE$-J(pmA5HBKyFWa4ym@rOP7j{@g9WtdED z!OIGf94Ff2+kOpBDK6gktH`TMb!QL^gtbR6{mn-c~@4Bvlf-=BFzB<9K#6PUyU!Kpb-)Gmq8iV5Y81J?6+ z0Hh+O>n$dwB4v{e1xdkBv4&kfAeA~tSpWD)4}E~HKo{Pb@(-j@E`J1I MjkZHoBR%8)1tERiX8-^I diff --git a/docs/branding/logo.svg b/docs/branding/logo.svg deleted file mode 100644 index 5583999ad..000000000 --- a/docs/branding/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/branding/mstile-144x144.png b/docs/branding/mstile-144x144.png deleted file mode 100644 index a03597d2eb1a696c1dee9dfd4ad5bdbb825f02ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4453 zcmV-r5t{CaP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 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 *k%o}l| z$U_A)R5BA^a@KDnJV$=2efQOQv(Tzm{mhsl;h787eF!kAU@&r)7`D6`U;)~Ez}hPS zi^W;p_|)9r)1W|6zF1MS>`wbV-eVqslRe5twtGdOt6G__>yYH&_E6(J0}7q%X92kF z?DC4K6i2Nbt5>hMx4_OH{Wu_Kf_Z29!BKYQ@XnFmFx+hXWa|hE>eTo!Fde(RN(kXB z&~tQ78GK7+@!bbGrfL7taA&PVSy_CtOMI;q7V$+b~)r7?OS@fb{~B^;Rj~Kc3M~8c%OCW zeuT-*wG|0Mw4zyE==#e5W3&BPsecFz=c|zq3p6}K-tzuhaJCxr&h=KP(cRI4Tc4PF zC2B){m6?Z2nh8y#3Ob$ak}5VfL=!^4Khb+19sZWa0=D9pMtXty+V1>svNPJvtOc{z zFahDsCfiOfz+KMU`9aOZ!k`*?9CZBKTw0X38mjJi+gjn*Kb09&MsN!W{C>UAGxx#A z*8KcGmGF=PXG_cNWZjMWhHV}Au!n(Mkxz zb7x<+z35Dzv!yWAm$&TJ;-b={O4jE3D12YW-s-_~5)#e{H}m#Vk~@>no8(l+=^>b3 zXnGBH28)|IcPHzu@5_(BJA;)5-k-{0Pez;}spH{qyIibXO@>-BY2)TZ=nIxFWAuwJ z{w>?pZRWDqSPG`z4>J3SirW89{+f_jga0>P^MwWXzx8nH;Jc z3B3@~FnxDuo6t>36b~r~tuGsAo=g^rO%j0c1__qFaf0RWwiJQ&SMljoIoCD%*97Zf z_ft<6uSc`!{i?351;Y%RnX*^k|(4%)byo8h>Yw-5nd z&ePdQ7xP=L9OBKBU4zbdWp<-CL>gSX_d5UF_Mb!i^45wf(qI9FE6|E+@@vG+V&&!h{1fv%vCS5IR8 zfK#>|z#GvNca9a^Bm3{>~;X+%^!^vZdZv8`ydF=Cbeg*zphN-k_!Uvv|ve ze>^i1BbJ}JsJJMBT#qY;>Q%LPiLv`~7z9;GPrVVr&YGMbu0zcbhl@5Ofju|k=Kv)( zVfkLOY7GDgbjW_coauFt)!pjYJvd%)X}Rq~_}8D~O|{B?ylRUB#}9<87k(>jP0ooN z(4oRQ``yw1!1ZDUB=L&t=?7@JA%8vYUe| z;X%Gi@4olE5%SsE6;@@b!p+2UK@?FRv|AO)gcWQy87}H=F1_y( zOy>}Md8+R0e#LDzqorhUOqeI*?BEwAZri-{ZQ3(Etz`KlA9np@M4vKZ92N>i)PF~;P3#o+4dR7X&J`tVO*CT#nCjyJVSus=9^l=}CG ze$Q1U8xR0hr>7=+>Xg{>_rXi$`10J~Fg=5hbc-&6$_q1izEQtx2M3 z#=W`+%ZP@7WXE)S@H+qd-)G#So`Ay4G%44>%Wz{#R8!QOs>Ub5H-l$Wd@3X24Q@Dk?EDL(Y= zKmUApjW%qtWDju33uqt(MC3)RazwdAWKCmrNcXtpTW-qI=o4?r!(=d-mlkVYZm9u$ Y6&J?t7+=gg-U6_=Vr%-s*ggKg098GE1^@s6 diff --git a/docs/branding/mstile-310x150.png b/docs/branding/mstile-310x150.png deleted file mode 100644 index 6196557f945940c13abb38b8c8876d7ba700ddce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4896 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 diff --git a/docs/branding/mstile-310x310.png b/docs/branding/mstile-310x310.png deleted file mode 100644 index fcab2046c6dabeef1c9e71e693a67635f0354b86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9861 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 AWB>pF diff --git a/docs/branding/mstile-70x70.png b/docs/branding/mstile-70x70.png deleted file mode 100644 index 2416cf18da6fe6554c5b010caf85a44a6d618a27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3165 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 \ No newline at end of file diff --git a/docs/building-server.md b/docs/building-server.md deleted file mode 100644 index bd793c978..000000000 --- a/docs/building-server.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Creating a build ---- - -# Creating a build - -The server software must be built before it can be run. - -=== "Windows" - Using _windows terminal_, _git bash_, or _powershell_, run: - ```bash - ./publish.cmd - ``` - -=== "OSX/Linux" - Using _terminal_, run: - ```bash - ./publish.sh - ``` -

-`os` (_Optional_)
-The operating system to build the server against. If not specified then the server will be built for the same operating system. - -:fontawesome-brands-windows:{: .windows } `win`
-:fontawesome-brands-apple:{: .apple } `osx`
-:fontawesome-brands-linux:{: .linux } `linux`
- -

-`arch` (_Optional_)
-The architecture to build the server against. If not specified then the server will be built for x64. - -`x64`
-`arm64`
diff --git a/docs/commands/commands.html b/docs/commands/commands.html deleted file mode 100644 index cce8ae7ce..000000000 --- a/docs/commands/commands.html +++ /dev/null @@ -1,2619 +0,0 @@ - - - - - - - - - ModernUO Commands - - - - - - -

-
-
- -
- -
- -

ModernUO Commands

- -
    - -
- -
- -
-
-
-
- - - - - - - diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 487ccfec7..000000000 --- a/docs/index.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Home -template: home.html ---- diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100644 index 2fefc1d58..000000000 --- a/docs/installation.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Installation ---- - -# Installation - -=== "Windows" - ### Prerequisites - 1. Download and install the latest [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) - 1. Download and install from [here](https://git-scm.com/download/win) - - !!! Tip - Use [Windows Terminal](https://learn.microsoft.com/en-us/windows/terminal/install) as your command prompt. - - ### Install ModernUO - 1. Navigate to the folder where you want to install ModernUO. - 1. Using _Windows Terminal_ run: - ```bash - git clone https://github.com/modernuo/modernuo - cd modernuo - ``` - -=== "OSX" - ### Prerequisites - 1. Download and install the latest [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0). - 1. Using _terminal_, install [homebrew](https://brew.sh) and git: - ```bash - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" - brew install git - ``` - ### Install ModernUO - 1. Using _terminal_, navigate to the folder where you want to install ModernUO and run: - ```bash - git clone https://github.com/modernuo/modernuo - cd modernuo - ``` - -=== "Linux" - ### Prerequisites - 1. Download and install the latest [.NET 10 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux). - 1. Using _bash_, install git: - ```bash - sudo apt update && sudo apt install git - ``` - - !!! Note - The command to install git might be different for your flavor of linux. Consult your local Google search for answers. - - ### Install ModernUO - 1. Using _bash_, navigate to the folder where you want to install ModernUO and run: - ```bash - git clone https://github.com/modernuo/modernuo - cd modernuo - ``` diff --git a/docs/overrides/.icons/modernuo/logo.svg b/docs/overrides/.icons/modernuo/logo.svg deleted file mode 100644 index 5583999ad..000000000 --- a/docs/overrides/.icons/modernuo/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/overrides/home.html b/docs/overrides/home.html deleted file mode 100644 index 64153b7bf..000000000 --- a/docs/overrides/home.html +++ /dev/null @@ -1,55 +0,0 @@ -{% extends "main.html" %} -{% block extrahead %} - - -{% endblock %} - - -{% block tabs %} -{{ super() }} - - -
-
-
-
- -
- - -
-

Ultima Online Server Emulator for the modern era!

- - Get started - - - Go to GitHub - -
-
-
-
-{% endblock %} - - -{% block content %}{% endblock %} - - -{% block footer %} -{% include "partials/footer.html" %} -{% endblock %} diff --git a/docs/overrides/main.html b/docs/overrides/main.html deleted file mode 100644 index e49ce3a10..000000000 --- a/docs/overrides/main.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "base.html" %} - - -{% block extrahead %} - - -{% set title = config.site_name %} -{% if page and page.title and not page.is_homepage %} -{% set title = config.site_name ~ " - " ~ page.title | striptags %} -{% endif %} - - -{% set image = config.site_url ~ '/branding/android-chrome-512x512.png' %} - - - - - - - - - - - - - - - - - - - -{% endblock %} - - -{% block content %} -{{ super() }} - - -
- -
-{% endblock %} diff --git a/docs/overrides/partials/footer.html b/docs/overrides/partials/footer.html deleted file mode 100644 index d160b2f2c..000000000 --- a/docs/overrides/partials/footer.html +++ /dev/null @@ -1,52 +0,0 @@ -{#- -This file was automatically generated - do not edit --#} -{% import "partials/language.html" as lang with context %} - diff --git a/docs/overrides/partials/nav.html b/docs/overrides/partials/nav.html deleted file mode 100644 index 8924593d6..000000000 --- a/docs/overrides/partials/nav.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - diff --git a/docs/packets/incoming/account.json b/docs/packets/incoming/account.json deleted file mode 100644 index 410864d6d..000000000 --- a/docs/packets/incoming/account.json +++ /dev/null @@ -1,1081 +0,0 @@ -{ - "category": "Account", - "packets": [ - { - "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": "Packet ID", - "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": "Next Login Key", - "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 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x91", - "description": "Packet identifier" - }, - { - "name": "Auth ID", - "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 - } - }, - { - "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": "Packet ID", - "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": "Char Slot", - "type": "int", - "size": 4, - "description": "Character slot index (0-based)" - }, - { - "name": "Client IP", - "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 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA0", - "description": "Packet identifier" - }, - { - "name": "Server Index", - "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 - } - }, - { - "id": "0x83", - "name": "Delete Character", - "description": "Request to delete a character from the account.", - "direction": "incoming", - "isDynamic": false, - "size": 39, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x83", - "description": "Packet identifier" - }, - { - "name": "Password", - "type": "ascii", - "size": 30, - "description": "Account password for verification" - }, - { - "name": "Char Index", - "type": "int", - "size": 4, - "description": "Character slot index to delete" - }, - { - "name": "Client IP", - "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 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xEF", - "description": "Packet identifier" - }, - { - "name": "Seed", - "type": "int", - "size": 4, - "description": "Random seed for encryption" - }, - { - "name": "Client Major", - "type": "int", - "size": 4, - "description": "Client major version" - }, - { - "name": "Client Minor", - "type": "int", - "size": 4, - "description": "Client minor version" - }, - { - "name": "Client Revision", - "type": "int", - "size": 4, - "description": "Client revision" - }, - { - "name": "Client Patch", - "type": "int", - "size": 4, - "description": "Client patch level" - } - ], - "clientVersion": { - "classic": { - "min": "6.0.5.0" - }, - "enhanced": {}, - "notes": "Replaces the legacy 4-byte seed for clients 6.0.5.0+. Pre-6.0.5.0 clients send only a 4-byte seed without version info." - }, - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingAccountPackets.cs", - "line": 419 - } - }, - { - "id": "0xBD", - "name": "Client Version", - "description": "Response to server\u0027s version request (0xBD). Contains the client version string.", - "direction": "incoming", - "isDynamic": true, - "size": "3 + version string length", - "fields": [ - { - "name": "Packet ID", - "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., \u00277.0.95.0\u0027)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingAccountPackets.cs", - "line": 193 - } - }, - { - "id": "0xE1", - "name": "Client Type", - "description": "Sent by the client to identify the client type and version. Added during Kingdom Reborn/Stygian Abyss expansion.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xE1", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Unknown", - "type": "ushort", - "size": 2, - "value": "0x0001", - "description": "Unknown (always 0x0001)" - }, - { - "name": "Client Type", - "type": "enum", - "enumType": "sequential", - "size": 2, - "description": "Client type identifier", - "values": [ - { "value": "0x00", "name": "Classic", "description": "Classic 2D Client" }, - { "value": "0x02", "name": "KR", "description": "Kingdom Reborn Client" }, - { "value": "0x03", "name": "EC", "description": "Enhanced Client (Stygian Abyss)" } - ] - }, - { - "name": "Version", - "type": "ascii", - "description": "Client version string" - } - ], - "related": [ - { - "id": "0xBF/0x0F", - "relationship": "related", - "note": "Client Info - similar client type information sent at login" - } - ], - "clientVersion": { - "classic": { - "min": "6.0.14.3" - }, - "enhanced": {}, - "notes": "Added during Kingdom Reborn/Stygian Abyss expansion" - }, - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingAccountPackets.cs", - "line": 200 - } - }, - { - "id": "0x00", - "name": "Create Character (Old)", - "description": "Request to create a new character. This is the older 104-byte version with 3 starting skills. Replaced by 0xF8 in client 7.0.16.0+.", - "direction": "incoming", - "isDynamic": false, - "size": 104, - "fields": [ - { - "name": "Packet ID", - "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": "Gender Race", - "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": "Skin Hue", - "type": "ushort", - "size": 2, - "description": "Skin color hue" - }, - { - "name": "Hair Style", - "type": "short", - "size": 2, - "description": "Hair style ID" - }, - { - "name": "Hair Hue", - "type": "short", - "size": 2, - "description": "Hair color hue" - }, - { - "name": "Facial Hair Style", - "type": "short", - "size": 2, - "description": "Facial hair style ID" - }, - { - "name": "Facial Hair Hue", - "type": "short", - "size": 2, - "description": "Facial hair color hue" - }, - { - "name": "Unknown7", - "type": "byte", - "size": 1, - "description": "Unknown" - }, - { - "name": "City Index", - "type": "byte", - "size": 1, - "description": "Starting city index" - }, - { - "name": "Char Slot", - "type": "int", - "size": 4, - "description": "Character slot" - }, - { - "name": "Client IP", - "type": "int", - "size": 4, - "description": "Client IP" - }, - { - "name": "Shirt Hue", - "type": "short", - "size": 2, - "description": "Starting shirt hue" - }, - { - "name": "Pants Hue", - "type": "short", - "size": 2, - "description": "Starting pants hue" - } - ], - "related": [ - { - "id": "0xF8", - "relationship": "variant", - "note": "Create Character (New) for Classic 7.0.16.0+ with 4th skill" - }, - { - "id": "0x8D", - "relationship": "variant", - "note": "Create Character (EC) for Enhanced Client" - } - ], - "clientVersion": { - "classic": { - "max": "7.0.15.x" - }, - "notes": "Replaced by 0xF8 in Classic Client 7.0.16.0+. EC uses 0x8D instead." - }, - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingAccountPackets.cs", - "line": 58 - } - }, - { - "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": "Packet ID", - "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": "Gender Race", - "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": "Skin Hue", - "type": "ushort", - "size": 2, - "description": "Skin color hue" - }, - { - "name": "Hair Style", - "type": "short", - "size": 2, - "description": "Hair style ID" - }, - { - "name": "Hair Hue", - "type": "short", - "size": 2, - "description": "Hair color hue" - }, - { - "name": "Facial Hair Style", - "type": "short", - "size": 2, - "description": "Facial hair style ID" - }, - { - "name": "Facial Hair Hue", - "type": "short", - "size": 2, - "description": "Facial hair color hue" - }, - { - "name": "Unknown7", - "type": "byte", - "size": 1, - "description": "Unknown" - }, - { - "name": "City Index", - "type": "byte", - "size": 1, - "description": "Starting city index" - }, - { - "name": "Char Slot", - "type": "int", - "size": 4, - "description": "Character slot" - }, - { - "name": "Client IP", - "type": "int", - "size": 4, - "description": "Client IP" - }, - { - "name": "Shirt Hue", - "type": "short", - "size": 2, - "description": "Starting shirt hue" - }, - { - "name": "Pants Hue", - "type": "short", - "size": 2, - "description": "Starting pants hue" - } - ], - "related": [ - { - "id": "0x00", - "relationship": "variant", - "note": "Create Character (Old) for Classic pre-7.0.16.0 with 3 skills" - }, - { - "id": "0x8D", - "relationship": "variant", - "note": "Create Character (EC) for Enhanced Client" - } - ], - "clientVersion": { - "classic": { - "min": "7.0.16.0" - }, - "notes": "Classic Client only. Replaces 0x00, adds 4th starting skill. EC uses 0x8D instead." - }, - "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." - }, - { - "id": "0x8D", - "name": "Create Character", - "description": "Request to create a new character from Enhanced Client (KR/SA 3D clients). Variable length packet with different field layout than Classic client versions.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "implemented": false, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x8D", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Pattern1", - "type": "uint", - "size": 4, - "value": "0xEDEDEDED", - "description": "Fixed pattern" - }, - { - "name": "Character Index", - "type": "uint", - "size": 4, - "description": "Character slot index" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Character name" - }, - { - "name": "Unknown", - "type": "byte[30]", - "size": 30, - "description": "Unknown (possibly password field)" - }, - { - "name": "Profession", - "type": "byte", - "size": 1, - "description": "Starting profession" - }, - { - "name": "Client Flags", - "type": "byte", - "size": 1, - "description": "Client flags (0x41 or 0x3F)" - }, - { - "name": "Gender", - "type": "byte", - "size": 1, - "description": "0=male, 1=female" - }, - { - "name": "Race", - "type": "byte", - "size": 1, - "description": "0=human, 1=elf, 2=gargoyle" - }, - { - "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": "Skin Color", - "type": "ushort", - "size": 2, - "description": "Character skin hue" - }, - { - "name": "Unknown2", - "type": "byte[8]", - "size": 8, - "description": "Unknown padding" - }, - { - "name": "Skill 1 ID", - "type": "byte", - "size": 1, - "description": "First skill ID" - }, - { - "name": "Skill 1 Value", - "type": "byte", - "size": 1, - "description": "First skill starting value" - }, - { - "name": "Skill 2 ID", - "type": "byte", - "size": 1, - "description": "Second skill ID" - }, - { - "name": "Skill 2 Value", - "type": "byte", - "size": 1, - "description": "Second skill starting value" - }, - { - "name": "Skill 3 ID", - "type": "byte", - "size": 1, - "description": "Third skill ID" - }, - { - "name": "Skill 3 Value", - "type": "byte", - "size": 1, - "description": "Third skill starting value" - }, - { - "name": "Skill 4 ID", - "type": "byte", - "size": 1, - "description": "Fourth skill ID" - }, - { - "name": "Skill 4 Value", - "type": "byte", - "size": 1, - "description": "Fourth skill starting value" - }, - { - "name": "Unknown3", - "type": "byte[26]", - "size": 26, - "description": "Unknown padding and appearance fields" - }, - { - "name": "Hair Color", - "type": "ushort", - "size": 2, - "description": "Hair hue" - }, - { - "name": "Hair Style", - "type": "ushort", - "size": 2, - "description": "Hair graphic ID" - }, - { - "name": "Shirt Color", - "type": "ushort", - "size": 2, - "description": "Shirt hue" - }, - { - "name": "Shirt Style", - "type": "ushort", - "size": 2, - "description": "Shirt graphic ID" - }, - { - "name": "Face Color", - "type": "ushort", - "size": 2, - "description": "Face hue" - }, - { - "name": "Face Style", - "type": "ushort", - "size": 2, - "description": "Face graphic ID" - }, - { - "name": "Beard Color", - "type": "ushort", - "size": 2, - "description": "Facial hair hue" - }, - { - "name": "Beard Style", - "type": "ushort", - "size": 2, - "description": "Facial hair graphic ID" - } - ], - "related": [ - { - "id": "0x00", - "relationship": "variant", - "note": "Create Character (Old) for Classic Client pre-7.0.16.0" - }, - { - "id": "0xF8", - "relationship": "variant", - "note": "Create Character (New) for Classic Client 7.0.16.0+" - } - ], - "clientVersion": { - "enhanced": {}, - "notes": "Enhanced Client only. Uses different field layout with separate gender/race bytes." - }, - "notes": "EC clients use this packet instead of 0x00/0xF8. The field layout differs significantly from Classic client versions, with separate gender and race bytes instead of combined genderRace field." - } - ] -} diff --git a/docs/packets/incoming/assistant.json b/docs/packets/incoming/assistant.json deleted file mode 100644 index f7d83d658..000000000 --- a/docs/packets/incoming/assistant.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "category": "Assistant", - "packets": [ - { - "id": "0xBE", - "name": "Assistant Version", - "description": "Client sends assistant version information. Razor CE sends version as ASCII string.", - "direction": "incoming", - "isDynamic": true, - "size": "3+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBE", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Version String", - "type": "ascii", - "size": "var", - "description": "Assistant version string (Razor CE sends \u0027version\u0027 or \u0027ProductName version\u0027)" - } - ], - "notes": "Razor Community Edition sends version as ASCII. Legacy UOAssist would send int32 + ASCII client version.", - "source": { - "file": "Projects/UOContent/Assistants/AssistantHandler.cs", - "line": 69 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/book.json b/docs/packets/incoming/book.json deleted file mode 100644 index 7a8078c18..000000000 --- a/docs/packets/incoming/book.json +++ /dev/null @@ -1,216 +0,0 @@ -{ - "category": "Book", - "packets": [ - { - "id": "0x66", - "name": "Book Content Change", - "description": "Client sends updated book page content when player edits a writable book.", - "direction": "incoming", - "isDynamic": true, - "size": "9+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x66", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Book Serial", - "type": "uint", - "size": 4, - "description": "Serial of the book being edited" - }, - { - "name": "Page Count", - "type": "ushort", - "size": 2, - "description": "Number of pages being updated" - }, - { - "name": "Pages", - "type": "loop", - "description": "Page contents being updated", - "loop": { - "countField": "pageCount", - "fields": [ - { - "name": "Page Index", - "type": "ushort", - "size": 2, - "description": "Page number (1-indexed)" - }, - { - "name": "Line Count", - "type": "ushort", - "size": 2, - "description": "Number of lines on page (max 8)" - }, - { - "name": "Lines", - "type": "loop", - "description": "Lines on the page", - "loop": { - "countField": "lineCount", - "fields": [ - { - "name": "Text", - "type": "utf8-t", - "description": "Line text (max 80 characters)" - } - ] - } - } - ] - } - } - ], - "source": { - "file": "Projects/UOContent/Items/Books/BookPackets.cs", - "line": 87 - } - }, - { - "id": "0xD4", - "name": "Book Header Change", - "description": "Client sends updated book title and author when player edits a writable book\u0027s cover.", - "direction": "incoming", - "isDynamic": true, - "size": "13+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD4", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Book Serial", - "type": "uint", - "size": 4, - "description": "Serial of the book being edited" - }, - { - "name": "Flags", - "type": "ushort", - "size": 2, - "description": "Book flags (ignored by server)" - }, - { - "name": "Page Count", - "type": "ushort", - "size": 2, - "description": "Number of pages (ignored by server)" - }, - { - "name": "Title Length", - "type": "ushort", - "size": 2, - "description": "Length of title string including null terminator (max 61)" - }, - { - "name": "Title", - "type": "utf8-t", - "description": "Book title (max 60 characters)" - }, - { - "name": "Author Length", - "type": "ushort", - "size": 2, - "description": "Length of author string including null terminator (max 31)" - }, - { - "name": "Author", - "type": "utf8-t", - "description": "Book author (max 30 characters)" - } - ], - "related": [ - { - "id": "0x93", - "direction": "incoming", - "relationship": "variant", - "note": "Old Header Change format for older clients" - } - ], - "source": { - "file": "Projects/UOContent/Items/Books/BookPackets.cs", - "line": 51 - } - }, - { - "id": "0x93", - "name": "Old Book Header Change", - "description": "Legacy format for book header changes. Uses fixed-size ASCII strings.", - "direction": "incoming", - "isDynamic": false, - "size": 99, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x93", - "description": "Packet identifier" - }, - { - "name": "Book Serial", - "type": "uint", - "size": 4, - "description": "Serial of the book being edited" - }, - { - "name": "Flags", - "type": "ushort", - "size": 2, - "description": "Book flags (ignored by server)" - }, - { - "name": "Page Count", - "type": "ushort", - "size": 2, - "description": "Number of pages (ignored by server)" - }, - { - "name": "Title", - "type": "ascii", - "size": 60, - "description": "Book title (fixed 60 bytes, null-padded)" - }, - { - "name": "Author", - "type": "ascii", - "size": 30, - "description": "Book author (fixed 30 bytes, null-padded)" - } - ], - "related": [ - { - "id": "0xD4", - "direction": "incoming", - "relationship": "variant", - "note": "New Header Change format for newer clients" - } - ], - "notes": "Old format used by older clients. Title and author are fixed-size ASCII.", - "source": { - "file": "Projects/UOContent/Items/Books/BookPackets.cs", - "line": 32 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/bulletinboard.json b/docs/packets/incoming/bulletinboard.json deleted file mode 100644 index 9238e5e9c..000000000 --- a/docs/packets/incoming/bulletinboard.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "category": "Bulletin Board", - "packets": [ - { - "id": "0x71", - "subId": "0x03", - "name": "Bulletin Board Request Content", - "description": "Client requests the full content of a bulletin board message.", - "direction": "incoming", - "isDynamic": true, - "size": "12", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x71", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x03", - "description": "Request Content command" - }, - { - "name": "Board Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bulletin board" - }, - { - "name": "Message Serial", - "type": "uint", - "size": 4, - "description": "Serial of the message to read" - } - ], - "related": [ - { - "id": "0x71", - "subId": "0x02", - "direction": "outgoing", - "relationship": "response", - "note": "Message Content response" - } - ], - "source": { - "file": "Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs", - "line": 78 - } - }, - { - "id": "0x71", - "subId": "0x04", - "name": "Bulletin Board Request Header", - "description": "Client requests the header (poster, subject, time) of a bulletin board message.", - "direction": "incoming", - "isDynamic": true, - "size": "12", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x71", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x04", - "description": "Request Header command" - }, - { - "name": "Board Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bulletin board" - }, - { - "name": "Message Serial", - "type": "uint", - "size": 4, - "description": "Serial of the message" - } - ], - "related": [ - { - "id": "0x71", - "subId": "0x01", - "direction": "outgoing", - "relationship": "response", - "note": "Message Header response" - } - ], - "source": { - "file": "Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs", - "line": 88 - } - }, - { - "id": "0x71", - "subId": "0x05", - "name": "Bulletin Board Post Message", - "description": "Client posts a new message or reply to the bulletin board.", - "direction": "incoming", - "isDynamic": true, - "size": "12+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x71", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x05", - "description": "Post Message command" - }, - { - "name": "Board Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bulletin board" - }, - { - "name": "Thread Serial", - "type": "uint", - "size": 4, - "description": "Serial of parent message (0 for new thread)" - }, - { - "name": "Subject Length", - "type": "byte", - "size": 1, - "description": "Length of subject string" - }, - { - "name": "Subject", - "type": "utf8", - "description": "Message subject" - }, - { - "name": "Line Count", - "type": "byte", - "size": 1, - "description": "Number of message lines" - }, - { - "name": "Lines", - "type": "loop", - "description": "Message body lines", - "loop": { - "countField": "Line Count", - "fields": [ - { - "name": "Line Length", - "type": "byte", - "size": 1, - "description": "Length of this line" - }, - { - "name": "Line", - "type": "utf8", - "description": "Line text" - } - ] - } - } - ], - "source": { - "file": "Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs", - "line": 98 - } - }, - { - "id": "0x71", - "subId": "0x06", - "name": "Bulletin Board Remove Message", - "description": "Client requests to delete a bulletin board message.", - "direction": "incoming", - "isDynamic": true, - "size": "12", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x71", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x06", - "description": "Remove Message command" - }, - { - "name": "Board Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bulletin board" - }, - { - "name": "Message Serial", - "type": "uint", - "size": 4, - "description": "Serial of the message to delete" - } - ], - "notes": "Only the message poster or GameMaster+ can delete messages.", - "source": { - "file": "Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs", - "line": 153 - } - } - ] -} diff --git a/docs/packets/incoming/chat.json b/docs/packets/incoming/chat.json deleted file mode 100644 index a62d2e9ed..000000000 --- a/docs/packets/incoming/chat.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "category": "Chat", - "packets": [ - { - "id": "0xB5", - "name": "Open Chat Window Request", - "description": "Client requests to open the chat window. Newer clients don\u0027t send chat username.", - "direction": "incoming", - "isDynamic": false, - "size": 64, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB5", - "description": "Packet identifier" - }, - { - "name": "Reserved", - "type": "byte[]", - "size": 63, - "description": "Reserved/unused (newer clients don\u0027t send chat username)" - } - ], - "related": [ - { - "id": "0xB2", - "direction": "outgoing", - "relationship": "response", - "note": "Server responds with Chat Message (OpenChatWindow command)" - } - ], - "source": { - "file": "Projects/UOContent/Engines/Chat/ChatPackets.cs", - "line": 30 - } - }, - { - "id": "0xB3", - "name": "Chat Action", - "description": "Client sends chat action commands like sending messages, joining channels, etc.", - "direction": "incoming", - "isDynamic": true, - "size": "8+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB3", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Language", - "type": "ascii", - "size": 4, - "description": "Language code (e.g., \u0027enu\u0027 for English)" - }, - { - "name": "Action ID", - "type": "short", - "size": 2, - "description": "Chat action ID" - }, - { - "name": "Parameter", - "type": "utf16be", - "size": "var", - "description": "Action parameter (Big Endian Unicode)" - } - ], - "related": [ - { - "id": "0xB2", - "direction": "outgoing", - "relationship": "response", - "note": "Server responds with Chat Message" - } - ], - "source": { - "file": "Projects/UOContent/Engines/Chat/ChatPackets.cs", - "line": 51 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/encoded.json b/docs/packets/incoming/encoded.json deleted file mode 100644 index 3b5cad9db..000000000 --- a/docs/packets/incoming/encoded.json +++ /dev/null @@ -1,965 +0,0 @@ -{ - "category": "Encoded Commands (0xD7)", - "packets": [ - { - "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": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Entity Serial", - "type": "uint", - "size": 4, - "description": "Serial of target entity" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "description": "Encoded command ID" - }, - { - "name": "Data", - "type": "byte[]", - "description": "Subcommand-specific data" - } - ], - "subpackets": [ - { - "subId": "0x02", - "name": "Backup", - "description": "Backup current house design state", - "direction": "incoming" - }, - { - "subId": "0x03", - "name": "Restore", - "description": "Restore house design from backup", - "direction": "incoming" - }, - { - "subId": "0x04", - "name": "Commit", - "description": "Commit house design changes", - "direction": "incoming" - }, - { - "subId": "0x05", - "name": "Delete Component", - "description": "Delete component from house", - "direction": "incoming" - }, - { - "subId": "0x06", - "name": "Build Component", - "description": "Place component in house", - "direction": "incoming" - }, - { - "subId": "0x0C", - "name": "Close Tool", - "description": "Close house design tool", - "direction": "incoming" - }, - { - "subId": "0x0D", - "name": "Add Stairs", - "description": "Add stairs to house design", - "direction": "incoming" - }, - { - "subId": "0x0E", - "name": "Sync Request", - "description": "Synchronize house design state", - "direction": "incoming" - }, - { - "subId": "0x10", - "name": "Clear Floor", - "description": "Clear a floor in house design", - "direction": "incoming" - }, - { - "subId": "0x12", - "name": "Change Floor Level", - "description": "Change visible floor level", - "direction": "incoming" - }, - { - "subId": "0x13", - "name": "Add Roof", - "description": "Add roof tile (SE+)", - "direction": "incoming" - }, - { - "subId": "0x14", - "name": "Delete Roof", - "description": "Delete roof tile (SE+)", - "direction": "incoming" - }, - { - "subId": "0x19", - "name": "Set Weapon Ability", - "description": "Select weapon special ability", - "direction": "incoming" - }, - { - "subId": "0x1A", - "name": "Revert", - "description": "Revert house to original state", - "direction": "incoming" - }, - { - "subId": "0x28", - "name": "Guild Gump Request", - "description": "Open guild gump", - "direction": "incoming" - }, - { - "subId": "0x32", - "name": "Quest Gump Request", - "description": "Open quest/MLB gump", - "direction": "incoming" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 457 - } - }, - { - "id": "0xD7/0x02", - "subId": "0x02", - "name": "House Design: Backup", - "description": "Client requests to backup current house design state.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x02", - "description": "Backup subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1024 - } - }, - { - "id": "0xD7/0x03", - "subId": "0x03", - "name": "House Design: Restore", - "description": "Client requests to restore house design from backup.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x03", - "description": "Restore subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1025 - } - }, - { - "id": "0xD7/0x04", - "subId": "0x04", - "name": "House Design: Commit", - "description": "Client commits the current house design changes.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x04", - "description": "Commit subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1026 - } - }, - { - "id": "0xD7/0x05", - "subId": "0x05", - "name": "House Design: Delete Component", - "description": "Client requests to delete a component from house design.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x05", - "description": "Delete subcommand" - }, - { - "name": "Tile ID", - "type": "int", - "size": 4, - "description": "Tile graphic ID to delete" - }, - { - "name": "X", - "type": "int", - "size": 4, - "description": "X offset from foundation" - }, - { - "name": "Y", - "type": "int", - "size": 4, - "description": "Y offset from foundation" - }, - { - "name": "Z", - "type": "int", - "size": 4, - "description": "Z offset from foundation" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1027 - } - }, - { - "id": "0xD7/0x06", - "subId": "0x06", - "name": "House Design: Build Component", - "description": "Client requests to place a component in house design.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x06", - "description": "Build subcommand" - }, - { - "name": "Tile ID", - "type": "int", - "size": 4, - "description": "Tile graphic ID to place" - }, - { - "name": "X", - "type": "int", - "size": 4, - "description": "X offset from foundation" - }, - { - "name": "Y", - "type": "int", - "size": 4, - "description": "Y offset from foundation" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1028 - } - }, - { - "id": "0xD7/0x0C", - "subId": "0x0C", - "name": "House Design: Close Tool", - "description": "Client closes the house design tool.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0C", - "description": "Close subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1029 - } - }, - { - "id": "0xD7/0x0D", - "subId": "0x0D", - "name": "House Design: Add Stairs", - "description": "Client requests to add stairs to house design.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0D", - "description": "Stairs subcommand" - }, - { - "name": "Tile ID", - "type": "int", - "size": 4, - "description": "Stair tile graphic ID" - }, - { - "name": "X", - "type": "int", - "size": 4, - "description": "X offset from foundation" - }, - { - "name": "Y", - "type": "int", - "size": 4, - "description": "Y offset from foundation" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1030 - } - }, - { - "id": "0xD7/0x0E", - "subId": "0x0E", - "name": "House Design: Sync Request", - "description": "Client requests to synchronize house design state.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0E", - "description": "Sync subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1031 - } - }, - { - "id": "0xD7/0x10", - "subId": "0x10", - "name": "House Design: Clear Floor", - "description": "Client requests to clear a floor in house design.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x10", - "description": "Clear subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1032 - } - }, - { - "id": "0xD7/0x12", - "subId": "0x12", - "name": "House Design: Change Floor Level", - "description": "Client changes the visible floor level in house design.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x12", - "description": "Level subcommand" - }, - { - "name": "Floor", - "type": "int", - "size": 4, - "description": "Floor level (1-4)" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1033 - } - }, - { - "id": "0xD7/0x13", - "subId": "0x13", - "name": "House Design: Add Roof", - "description": "Client requests to add a roof tile (Samurai Empire+).", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x13", - "description": "Roof subcommand" - }, - { - "name": "Tile ID", - "type": "int", - "size": 4, - "description": "Roof tile graphic ID" - }, - { - "name": "X", - "type": "int", - "size": 4, - "description": "X offset from foundation" - }, - { - "name": "Y", - "type": "int", - "size": 4, - "description": "Y offset from foundation" - }, - { - "name": "Z", - "type": "int", - "size": 4, - "description": "Z offset for roof placement" - } - ], - "clientVersion": { - "classic": { - "min": "4.0.3a" - }, - "enhanced": {}, - "notes": "Added with Samurai Empire expansion" - }, - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1035 - } - }, - { - "id": "0xD7/0x14", - "subId": "0x14", - "name": "House Design: Delete Roof", - "description": "Client requests to delete a roof tile (Samurai Empire+).", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x14", - "description": "Roof Delete subcommand" - }, - { - "name": "Tile ID", - "type": "int", - "size": 4, - "description": "Roof tile graphic ID" - }, - { - "name": "X", - "type": "int", - "size": 4, - "description": "X offset from foundation" - }, - { - "name": "Y", - "type": "int", - "size": 4, - "description": "Y offset from foundation" - }, - { - "name": "Z", - "type": "int", - "size": 4, - "description": "Z offset of roof to delete" - } - ], - "clientVersion": { - "classic": { - "min": "4.0.3a" - }, - "enhanced": {}, - "notes": "Added with Samurai Empire expansion" - }, - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1036 - } - }, - { - "id": "0xD7/0x19", - "subId": "0x19", - "name": "Set Weapon Ability", - "description": "Client selects a weapon special ability.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["Combat"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Player serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x19", - "description": "Set Ability subcommand" - }, - { - "name": "Ability Index", - "type": "int", - "size": 4, - "description": "Ability index (0 = clear, 1+ = ability index)" - } - ], - "related": [ - { - "id": "0xBF/0x21", - "relationship": "response", - "note": "Clear Weapon Ability" - }, - { - "id": "0xBF/0x25", - "relationship": "response", - "note": "Toggle Special Ability" - } - ], - "source": { - "file": "Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs", - "line": 11 - } - }, - { - "id": "0xD7/0x1A", - "subId": "0x1A", - "name": "House Design: Revert", - "description": "Client requests to revert house design to original state.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "House foundation serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x1A", - "description": "Revert subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1038 - } - }, - { - "id": "0xD7/0x28", - "subId": "0x28", - "name": "Guild Gump Request", - "description": "Client requests to open the guild gump.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["Guild"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Player serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x28", - "description": "Guild Gump subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 54 - } - }, - { - "id": "0xD7/0x32", - "subId": "0x32", - "name": "Quest Gump Request", - "description": "Client requests to open the quest/MLB gump.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["Quest"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Player serial" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x32", - "description": "Quest Gump subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 55 - } - } - ] -} diff --git a/docs/packets/incoming/entity.json b/docs/packets/incoming/entity.json deleted file mode 100644 index 52f2d32b4..000000000 --- a/docs/packets/incoming/entity.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "category": "Item", - "tags": ["Mobile"], - "packets": [ - { - "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": "Packet ID", - "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\u0027s paperdoll instead." - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingEntityPackets.cs", - "line": 61 - } - }, - { - "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": "Packet ID", - "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 - } - }, - { - "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": "Packet ID", - "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., \u0027ENU\u0027)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingEntityPackets.cs", - "line": 32 - } - }, - { - "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 x entityCount)", - "fields": [ - { - "name": "Packet ID", - "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 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/extended.json b/docs/packets/incoming/extended.json deleted file mode 100644 index a4b531bc5..000000000 --- a/docs/packets/incoming/extended.json +++ /dev/null @@ -1,1292 +0,0 @@ -{ - "category": "Extended Commands (0xBF)", - "packets": [ - { - "id": "0xBF", - "name": "Extended Command", - "description": "Wrapper packet for extended command subpackets. Used for both client-to-server and server-to-client communication.", - "direction": "both", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "description": "Extended command ID" - }, - { - "name": "Data", - "type": "byte[]", - "description": "Subcommand-specific data" - } - ], - "subpackets": [ - { - "subId": "0x04", - "name": "Close Gump", - "description": "Close a generic gump", - "direction": "outgoing" - }, - { - "subId": "0x05", - "name": "Screen Size", - "description": "Client reports screen dimensions", - "direction": "incoming" - }, - { - "subId": "0x06", - "name": "Party Message", - "description": "Party system commands and messages", - "direction": "both" - }, - { - "subId": "0x07", - "name": "Quest Arrow Click", - "description": "Client clicked the quest tracking arrow", - "direction": "incoming" - }, - { - "subId": "0x08", - "name": "Map Change", - "description": "Notify client of map/facet change", - "direction": "outgoing" - }, - { - "subId": "0x09", - "name": "Disarm Request", - "description": "Request to disarm opponent", - "direction": "incoming" - }, - { - "subId": "0x0A", - "name": "Stun Request", - "description": "Request to stun opponent", - "direction": "incoming" - }, - { - "subId": "0x0B", - "name": "Language", - "description": "Client language setting", - "direction": "incoming" - }, - { - "subId": "0x0C", - "name": "Status Bar Close", - "description": "Client closed a status bar", - "direction": "incoming" - }, - { - "subId": "0x0E", - "name": "Animate", - "description": "Request to play animation", - "direction": "incoming" - }, - { - "subId": "0x0F", - "name": "Client Info", - "description": "Client type and flags (Spy on Client)", - "direction": "incoming" - }, - { - "subId": "0x10", - "name": "Query Object Properties", - "description": "Request object property list", - "direction": "incoming" - }, - { - "subId": "0x13", - "name": "Context Menu Request", - "description": "Request context menu for entity", - "direction": "incoming" - }, - { - "subId": "0x14", - "name": "Context Menu Display", - "description": "Display context menu to client", - "direction": "outgoing" - }, - { - "subId": "0x15", - "name": "Context Menu Response", - "description": "Selected context menu option", - "direction": "incoming" - }, - { - "subId": "0x18", - "name": "Map Patches", - "description": "Send map diff/patch information", - "direction": "outgoing" - }, - { - "subId": "0x19", - "name": "Stat Lock Info", - "description": "Stat lock states and bonded status", - "direction": "outgoing" - }, - { - "subId": "0x1A", - "name": "Stat Lock Change", - "description": "Change STR/DEX/INT lock state", - "direction": "incoming" - }, - { - "subId": "0x1B", - "name": "New Spellbook Content", - "description": "Spellbook spell list (AOS+)", - "direction": "outgoing" - }, - { - "subId": "0x1C", - "name": "Cast Spell", - "description": "Cast spell by ID", - "direction": "incoming" - }, - { - "subId": "0x1E", - "name": "Query Design Details", - "description": "Request house design details", - "direction": "incoming" - }, - { - "subId": "0x21", - "name": "Set Weapon Ability", - "description": "Clear weapon ability selection", - "direction": "outgoing" - }, - { - "subId": "0x22", - "name": "Damage", - "description": "Display damage number (old clients)", - "direction": "outgoing" - }, - { - "subId": "0x25", - "name": "Toggle Special Ability", - "description": "Toggle weapon special move icon", - "direction": "outgoing" - }, - { - "subId": "0x26", - "name": "Speed Mode", - "description": "Set movement speed mode", - "direction": "outgoing" - }, - { - "subId": "0x2A", - "name": "Race Change Reply", - "description": "Response to race change confirmation", - "direction": "incoming" - }, - { - "subId": "0x2C", - "name": "Bandage Target", - "description": "Apply bandage to target", - "direction": "incoming" - }, - { - "subId": "0x2D", - "name": "Targeted Spell", - "description": "Cast spell with pre-selected target", - "direction": "incoming" - }, - { - "subId": "0x2E", - "name": "Targeted Skill Use", - "description": "Use skill with pre-selected target", - "direction": "incoming" - }, - { - "subId": "0x30", - "name": "Target By Resource Macro", - "description": "Resource-based targeting macro", - "direction": "incoming" - }, - { - "subId": "0x32", - "name": "Toggle Flying", - "description": "Toggle gargoyle flying mode", - "direction": "incoming" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 43 - } - }, - { - "id": "0xBF/0x05", - "subId": "0x05", - "name": "Screen Size", - "description": "Client reports screen size.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "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 - } - }, - { - "id": "0xBF/0x06", - "subId": "0x06", - "name": "Party Message", - "description": "Client sends party-related commands.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x06", - "description": "Party Message subcommand" - }, - { - "name": "Party Command", - "type": "enum", - "enumType": "sequential", - "size": 1, - "description": "Party command type", - "values": [ - { - "value": 1, - "name": "Add Member", - "description": "Add member to party" - }, - { - "value": 2, - "name": "Remove Member", - "description": "Remove member from party" - }, - { - "value": 3, - "name": "Private Message", - "description": "Send private message to party member" - }, - { - "value": 4, - "name": "Public Message", - "description": "Send public message to party" - }, - { - "value": 6, - "name": "Set Can Loot", - "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 - } - }, - { - "id": "0xBF/0x07", - "subId": "0x07", - "name": "Quest Arrow Click", - "description": "Client clicked the quest tracking arrow.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x07", - "description": "Quest Arrow Click subcommand" - }, - { - "name": "Right Click", - "type": "bool", - "size": 1, - "description": "True if right-clicked, false if left-clicked" - } - ], - "related": [ - { - "id": "0xBA", - "relationship": "response", - "note": "Quest Arrow packet" - } - ], - "source": { - "file": "Projects/UOContent/Skills/Tracking/Tracking.cs", - "line": 26 - } - }, - { - "id": "0xBF/0x09", - "subId": "0x09", - "name": "Disarm Request", - "description": "Client requests to disarm opponent.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x09", - "description": "Disarm Request subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 289 - } - }, - { - "id": "0xBF/0x0A", - "subId": "0x0A", - "name": "Stun Request", - "description": "Client requests to stun opponent.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0A", - "description": "Stun Request subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 277 - } - }, - { - "id": "0xBF/0x0B", - "subId": "0x0B", - "name": "Language", - "description": "Client sets language preference.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0B", - "description": "Language subcommand" - }, - { - "name": "Language", - "type": "ascii", - "size": 4, - "description": "Language code (e.g., \u0027ENU\u0027)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 343 - } - }, - { - "id": "0xBF/0x0C", - "subId": "0x0C", - "name": "Close Status", - "description": "Client closes a status gump.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "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 - } - }, - { - "id": "0xBF/0x0E", - "subId": "0x0E", - "name": "Animate", - "description": "Client requests to play an animation.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "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 - } - }, - { - "id": "0xBF/0x0F", - "subId": "0x0F", - "name": "Client Info", - "description": "Client type information sent once at login. ModernUO currently ignores this packet data.", - "direction": "incoming", - "isDynamic": true, - "implemented": false, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x000F", - "description": "Client Info subcommand" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "value": "0x0A", - "description": "Unknown (always 0x0A)" - }, - { - "name": "Client Type", - "type": "enum", - "enumType": "sequential", - "size": 4, - "description": "Client type flag (same as character create/login)", - "values": [ - { "value": "0x00", "name": "Classic", "description": "Classic 2D Client" }, - { "value": "0x02", "name": "KR", "description": "Kingdom Reborn Client" }, - { "value": "0x03", "name": "EC", "description": "Enhanced Client (Stygian Abyss)" } - ] - } - ], - "related": [ - { - "id": "0xE1", - "relationship": "related", - "note": "Client Type packet - similar client type information" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 52 - }, - "notes": "ModernUO registers this packet but ignores its data (calls Empty handler). The client type should match the value in 0xE1 Client Type packet." - }, - { - "id": "0xBF/0x10", - "subId": "0x10", - "name": "Query Properties", - "description": "Client queries Object Property List (tooltip) for an entity.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "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", - "direction": "outgoing", - "relationship": "response", - "note": "OPL Info packet" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 355 - } - }, - { - "id": "0xBF/0x13", - "subId": "0x13", - "name": "Context Menu Request", - "description": "Client requests context menu for an entity.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x13", - "description": "Context Menu Request subcommand" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of entity to show context menu for" - } - ], - "related": [ - { - "id": "0xBF/0x14", - "relationship": "response", - "note": "Context Menu Display packet" - } - ], - "source": { - "file": "Projects/UOContent/Context Menus/ContextMenuSystem.cs", - "line": 101 - } - }, - { - "id": "0xBF/0x15", - "subId": "0x15", - "name": "Context Menu Response", - "description": "Client selects an option from context menu.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x15", - "description": "Context Menu Response subcommand" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of entity context menu was shown for" - }, - { - "name": "Index", - "type": "ushort", - "size": 2, - "description": "Index of selected menu option" - } - ], - "related": [ - { - "id": "0xBF/0x13", - "relationship": "request", - "note": "Context Menu Request packet" - } - ], - "source": { - "file": "Projects/UOContent/Context Menus/ContextMenuSystem.cs", - "line": 48 - } - }, - { - "id": "0xBF/0x1A", - "subId": "0x1A", - "name": "Stat Lock Change", - "description": "Client changes stat lock (STR/DEX/INT).", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "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": "Lock Value", - "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 - } - }, - { - "id": "0xBF/0x1C", - "subId": "0x1C", - "name": "Cast Spell", - "description": "Client casts a spell (optionally from spellbook).", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["Spell"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x1C", - "description": "Cast Spell subcommand" - }, - { - "name": "Has Book", - "type": "short", - "size": 2, - "description": "1 if casting from book, 0 otherwise" - }, - { - "name": "Book Serial", - "type": "uint", - "size": 4, - "description": "Serial of spellbook (if hasBook)", - "condition": "hasBook == 1" - }, - { - "name": "Spell ID", - "type": "short", - "size": 2, - "description": "Spell ID + 1 (1-based)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 257 - } - }, - { - "id": "0xBF/0x1E", - "subId": "0x1E", - "name": "Query Design Details", - "description": "Client requests house design details.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x1E", - "description": "Query Design Details subcommand" - }, - { - "name": "House Serial", - "type": "uint", - "size": 4, - "description": "Serial of house foundation" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HouseFoundation.cs", - "line": 1826 - } - }, - { - "id": "0xBF/0x2A", - "subId": "0x2A", - "name": "Race Change Reply", - "description": "Client response to race change confirmation gump.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x2A", - "description": "Race Change Reply subcommand" - }, - { - "name": "Skin Hue", - "type": "ushort", - "size": 2, - "description": "Selected skin hue", - "condition": "length \u003e 5" - }, - { - "name": "Hair Item ID", - "type": "ushort", - "size": 2, - "description": "Selected hair style", - "condition": "length \u003e 5" - }, - { - "name": "Hair Hue", - "type": "ushort", - "size": 2, - "description": "Selected hair hue", - "condition": "length \u003e 5" - }, - { - "name": "Facial Hair Item ID", - "type": "ushort", - "size": 2, - "description": "Selected facial hair style", - "condition": "length \u003e 5" - }, - { - "name": "Facial Hair Hue", - "type": "ushort", - "size": 2, - "description": "Selected facial hair hue", - "condition": "length \u003e 5" - } - ], - "source": { - "file": "Projects/UOContent/Engines/ML Quests/Gumps/RaceChangeGump.cs", - "line": 199 - } - }, - { - "id": "0xBF/0x2C", - "subId": "0x2C", - "name": "Bandage Target", - "description": "Client uses bandage on a target.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x2C", - "description": "Bandage Target subcommand" - }, - { - "name": "Bandage Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bandage item" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of target mobile" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 387 - } - }, - { - "id": "0xBF/0x2D", - "subId": "0x2D", - "name": "Targeted Spell", - "description": "Client casts spell with pre-selected target.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["Spell"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x2D", - "description": "Targeted Spell subcommand" - }, - { - "name": "Spell ID", - "type": "short", - "size": 2, - "description": "Spell ID + 1 (1-based)" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of target entity" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 422 - } - }, - { - "id": "0xBF/0x2E", - "subId": "0x2E", - "name": "Targeted Skill Use", - "description": "Client uses skill with pre-selected target.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x2E", - "description": "Targeted Skill Use subcommand" - }, - { - "name": "Skill ID", - "type": "short", - "size": 2, - "description": "Skill ID" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of target entity" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 429 - } - }, - { - "id": "0xBF/0x30", - "subId": "0x30", - "name": "Target By Resource Macro", - "description": "Client uses resource-based targeting macro.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x30", - "description": "Target By Resource Macro subcommand" - }, - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of item" - }, - { - "name": "Resource Type", - "type": "short", - "size": 2, - "description": "Resource type ID" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 439 - } - }, - { - "id": "0xBF/0x32", - "subId": "0x32", - "name": "Toggle Flying", - "description": "Client toggles gargoyle flying mode.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x32", - "description": "Toggle Flying subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingExtendedCommandPackets.cs", - "line": 272 - } - } - ] -} diff --git a/docs/packets/incoming/freeshard.json b/docs/packets/incoming/freeshard.json deleted file mode 100644 index 83e50ccd4..000000000 --- a/docs/packets/incoming/freeshard.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "category": "FreeShard Protocol (0xF1)", - "packets": [ - { - "id": "0xF1", - "name": "FreeShard Protocol", - "description": "Bundle packet for freeshard-specific commands (UOGateway). Sub-command is a single byte.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF1", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "byte", - "size": 1, - "description": "Subcommand ID" - }, - { - "name": "Data", - "type": "byte[]", - "description": "Subcommand-specific data" - } - ], - "subpackets": [ - { - "subId": "0xFE", - "name": "Query Compact Shard Stats", - "direction": "incoming" - }, - { - "subId": "0xFF", - "name": "Query Extended Shard Stats", - "direction": "incoming" - } - ], - "source": { - "file": "Projects/UOContent/Network/FreeshardProtocol.cs", - "line": 21 - } - }, - { - "id": "0xF1/0xFE", - "subId": "0xFE", - "name": "Query Compact Shard Stats", - "description": "Query server for compact statistics. Server responds with 0x51.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF1", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "byte", - "size": 1, - "value": "0xFE", - "description": "Query Compact Shard Stats subcommand" - } - ], - "notes": "Outgame only. Requires uogateway.enabled configuration.", - "related": [ - { - "id": "0x51", - "relationship": "response", - "note": "Compact Shard Stats response" - } - ], - "source": { - "file": "Projects/UOContent/Network/UOGateway.cs", - "line": 31 - } - }, - { - "id": "0xF1/0xFF", - "subId": "0xFF", - "name": "Query Extended Shard Stats", - "description": "Query server for extended statistics. Server responds with raw UTF-8 string.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF1", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "byte", - "size": 1, - "value": "0xFF", - "description": "Query Extended Shard Stats subcommand" - } - ], - "notes": "Outgame only. Requires uogateway.enabled configuration. Response is a raw UTF-8 string (no packet wrapper): 'ModernUO, Name={name}, Age={hours}, Clients={count}, Items={count}, Chars={count}, Mem={kb}K, Ver=2\\0'", - "source": { - "file": "Projects/UOContent/Network/UOGateway.cs", - "line": 32 - } - } - ] -} diff --git a/docs/packets/incoming/gump.json b/docs/packets/incoming/gump.json deleted file mode 100644 index 932baa998..000000000 --- a/docs/packets/incoming/gump.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "category": "Gump", - "packets": [ - { - "id": "0xB1", - "name": "Gump Response", - "description": "Client response to a generic gump dialog (button press, checkbox/radio selections, text entries).", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB1", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Serial from the 0xB0/0xDD gump packet" - }, - { - "name": "Gump ID", - "type": "uint", - "size": 4, - "description": "Gump type ID from the 0xB0/0xDD gump packet" - }, - { - "name": "Button ID", - "type": "uint", - "size": 4, - "description": "ID of button pressed (0 if gump closed without pressing a button)" - }, - { - "name": "Switch Count", - "type": "uint", - "size": 4, - "description": "Number of active switches (checkboxes/radio buttons)" - }, - { - "name": "Switches", - "type": "array", - "description": "Array of switch IDs that are active/checked", - "entries": [ - { - "name": "Switch ID", - "type": "uint", - "size": 4, - "description": "ID of an active switch" - } - ] - }, - { - "name": "Text Entry Count", - "type": "uint", - "size": 4, - "description": "Number of text entries" - }, - { - "name": "Text Entries", - "type": "array", - "description": "Array of text entry responses", - "entries": [ - { - "name": "Entry ID", - "type": "ushort", - "size": 2, - "description": "Text entry field ID" - }, - { - "name": "Text Length", - "type": "ushort", - "size": 2, - "description": "Length of text in characters" - }, - { - "name": "Text", - "type": "unicode-be", - "size": "var", - "description": "UTF-16 BE encoded text (length * 2 bytes, not null-terminated)" - } - ] - } - ], - "related": [ - { - "id": "0xB0", - "relationship": "response", - "note": "Generic Gump (uncompressed) - server sends this to display the gump" - }, - { - "id": "0xDD", - "relationship": "response", - "note": "Compressed Gump - server sends this to display a compressed gump" - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {} - }, - "source": { - "file": "Projects/UOContent/Gumps/Base/GumpSystem.cs", - "line": 31 - } - } - ] -} diff --git a/docs/packets/incoming/hardware.json b/docs/packets/incoming/hardware.json deleted file mode 100644 index 81bb40be7..000000000 --- a/docs/packets/incoming/hardware.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "category": "Hardware", - "packets": [ - { - "id": "0xD9", - "name": "Hardware Info", - "description": "Client sends hardware and system information. Also known as 'Spy on Client' packet.", - "direction": "incoming", - "isDynamic": false, - "size": 268, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD9", - "description": "Packet identifier" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown (1 for pre-4.0.1a, 2 for 4.0.1a+)" - }, - { - "name": "Instance ID", - "type": "int", - "size": 4, - "description": "UO client instance identifier" - }, - { - "name": "OS Major", - "type": "int", - "size": 4, - "description": "Operating system major version" - }, - { - "name": "OS Minor", - "type": "int", - "size": 4, - "description": "Operating system minor version" - }, - { - "name": "OS Revision", - "type": "int", - "size": 4, - "description": "Operating system revision" - }, - { - "name": "CPU Manufacturer", - "type": "byte", - "size": 1, - "description": "CPU manufacturer code" - }, - { - "name": "CPU Family", - "type": "int", - "size": 4, - "description": "CPU family identifier" - }, - { - "name": "CPU Model", - "type": "int", - "size": 4, - "description": "CPU model number" - }, - { - "name": "CPU Clock Speed", - "type": "int", - "size": 4, - "description": "CPU clock speed in MHz" - }, - { - "name": "CPU Quantity", - "type": "byte", - "size": 1, - "description": "Number of CPUs/cores" - }, - { - "name": "Physical Memory", - "type": "int", - "size": 4, - "description": "Physical memory in MB" - }, - { - "name": "Screen Width", - "type": "int", - "size": 4, - "description": "Screen width in pixels" - }, - { - "name": "Screen Height", - "type": "int", - "size": 4, - "description": "Screen height in pixels" - }, - { - "name": "Screen Depth", - "type": "int", - "size": 4, - "description": "Screen color depth in bits" - }, - { - "name": "DirectX Major", - "type": "short", - "size": 2, - "description": "DirectX major version" - }, - { - "name": "DirectX Minor", - "type": "short", - "size": 2, - "description": "DirectX minor version" - }, - { - "name": "Video Card Description", - "type": "unicode-le", - "size": 128, - "description": "Video card description string (64 chars, little-endian UTF-16)" - }, - { - "name": "Video Card Vendor ID", - "type": "int", - "size": 4, - "description": "Video card vendor identifier" - }, - { - "name": "Video Card Device ID", - "type": "int", - "size": 4, - "description": "Video card device identifier" - }, - { - "name": "Video Card Memory", - "type": "int", - "size": 4, - "description": "Video card memory in MB" - }, - { - "name": "Distribution", - "type": "byte", - "size": 1, - "description": "Distribution type" - }, - { - "name": "Clients Running", - "type": "byte", - "size": 1, - "description": "Number of UO clients currently running" - }, - { - "name": "Clients Installed", - "type": "byte", - "size": 1, - "description": "Number of UO clients installed" - }, - { - "name": "Partial Installed", - "type": "byte", - "size": 1, - "description": "Partial installation flag" - }, - { - "name": "Language", - "type": "unicode-le", - "size": 8, - "description": "Language code (4 chars, little-endian UTF-16)" - }, - { - "name": "Unknown2", - "type": "ascii", - "size": 64, - "description": "Unknown data" - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "Packet size is 268 bytes (0x10C) for clients 4.0.1a+" - }, - "source": { - "file": "Projects/UOContent/Misc/HardwareInfo.cs", - "line": 93 - }, - "notes": "This packet is sent automatically by the client after login. The server uses this to track hardware information for debugging and statistics purposes." - } - ] -} diff --git a/docs/packets/incoming/house.json b/docs/packets/incoming/house.json deleted file mode 100644 index bd7aa8e5a..000000000 --- a/docs/packets/incoming/house.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "category": "House", - "packets": [ - { - "id": "0xFB", - "name": "Public House Content", - "description": "Client toggles whether to receive content updates for public houses. When enabled, the server sends container contents for publicly accessible houses.", - "direction": "incoming", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xFB", - "description": "Packet identifier" - }, - { - "name": "Show Contents", - "type": "bool", - "size": 1, - "description": "0 = hide public house contents, 1 = show public house contents" - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {} - }, - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingHousePackets.cs", - "line": 24 - }, - "notes": "This packet allows clients to opt-in or opt-out of receiving container content data for publicly accessible houses, which can reduce bandwidth for players who don't need to see inside public houses." - } - ] -} diff --git a/docs/packets/incoming/items.json b/docs/packets/incoming/items.json deleted file mode 100644 index 09bef1230..000000000 --- a/docs/packets/incoming/items.json +++ /dev/null @@ -1,298 +0,0 @@ -{ - "category": "Items", - "packets": [ - { - "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": "Packet ID", - "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 - } - }, - { - "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": "Varies", - "variants": [ - { - "name": "Classic", - "size": 14, - "fields": [ - { - "name": "Packet ID", - "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" - } - ] - }, - { - "name": "Container Grid Lines", - "condition": "Client version \u003e= 6.0.1.7 (ContainerGridLines)", - "size": 15, - "fields": [ - { - "name": "Packet ID", - "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": "Grid Location", - "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": { - "classic": {}, - "enhanced": {}, - "notes": "ContainerGridLines (6.0.1.7+) adds gridLocation byte" - }, - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingItemPackets.cs", - "line": 69 - } - }, - { - "id": "0x13", - "name": "Equip Request", - "description": "Client requests to equip a held item on a mobile.", - "direction": "incoming", - "isDynamic": false, - "size": 10, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x13", - "description": "Packet identifier" - }, - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of item to equip" - }, - { - "name": "Layer", - "type": "byte", - "size": 1, - "description": "Equipment layer" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of target mobile" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingItemPackets.cs", - "line": 44 - } - }, - { - "id": "0xEC", - "name": "Equip Macro", - "description": "Client requests to equip multiple items from a saved macro.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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" - } - ] - } - } - ], - "clientVersion": { - "enhanced": {} - }, - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingItemPackets.cs", - "line": 112 - } - }, - { - "id": "0xED", - "name": "Unequip Macro", - "description": "Client requests to unequip items from specific layers via macro.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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" - } - ] - } - } - ], - "clientVersion": { - "enhanced": {} - }, - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingItemPackets.cs", - "line": 125 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/mahjong.json b/docs/packets/incoming/mahjong.json deleted file mode 100644 index 7703ed530..000000000 --- a/docs/packets/incoming/mahjong.json +++ /dev/null @@ -1,907 +0,0 @@ -{ - "category": "Mahjong", - "packets": [ - { - "id": "0xDA", - "name": "Mahjong Game", - "description": "Mahjong game packets for controlling the in-game Mahjong table. Used for both client commands and server updates.", - "direction": "both", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "description": "Command ID (incoming uses byte prefix + byte command)" - }, - { - "name": "Data", - "type": "byte[]", - "description": "Command-specific data" - } - ], - "subpackets": [ - { - "subId": "0x02", - "name": "Players Info", - "description": "Sends player information for all seats", - "direction": "outgoing" - }, - { - "subId": "0x03", - "name": "Tile Info", - "description": "Sends information about a single tile", - "direction": "outgoing" - }, - { - "subId": "0x04", - "name": "Tiles Info", - "description": "Sends information about all tiles", - "direction": "outgoing" - }, - { - "subId": "0x05", - "name": "General Info", - "description": "Sends game state (dice, dealer, wall break)", - "direction": "outgoing" - }, - { - "subId": "0x06", - "name": "Exit Game", - "description": "Client exits the game", - "direction": "incoming" - }, - { - "subId": "0x0A", - "name": "Give Points", - "description": "Transfer points to another player", - "direction": "incoming" - }, - { - "subId": "0x0B", - "name": "Roll Dice", - "description": "Client requests to roll dice", - "direction": "incoming" - }, - { - "subId": "0x0C", - "name": "Build Walls", - "description": "Dealer builds/resets tile walls", - "direction": "incoming" - }, - { - "subId": "0x0D", - "name": "Reset Scores", - "description": "Dealer resets all scores", - "direction": "incoming" - }, - { - "subId": "0x0F", - "name": "Assign Dealer", - "description": "Assign a new dealer", - "direction": "incoming" - }, - { - "subId": "0x10", - "name": "Open Seat", - "description": "Open a seat for new players", - "direction": "incoming" - }, - { - "subId": "0x11", - "name": "Change Option", - "description": "Change game options", - "direction": "incoming" - }, - { - "subId": "0x15", - "name": "Move Wall Break", - "description": "Move wall break indicator", - "direction": "incoming" - }, - { - "subId": "0x16", - "name": "Toggle Public Hand", - "description": "Toggle hand visibility", - "direction": "incoming" - }, - { - "subId": "0x17", - "name": "Move Tile", - "description": "Move a tile on the board", - "direction": "incoming" - }, - { - "subId": "0x18", - "name": "Move Dealer Indicator", - "description": "Move dealer indicator", - "direction": "incoming" - }, - { - "subId": "0x19", - "name": "Join Game", - "description": "Server opens game interface", - "direction": "outgoing" - }, - { - "subId": "0x1A", - "name": "Relieve", - "description": "Server closes game interface", - "direction": "outgoing" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 46 - } - }, - { - "id": "0xDA", - "subId": "0x06", - "name": "Mahjong Exit Game", - "description": "Client requests to exit the Mahjong game.", - "direction": "incoming", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x06", - "description": "Exit Game command" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 108 - } - }, - { - "id": "0xDA", - "subId": "0x0A", - "name": "Mahjong Give Points", - "description": "Client transfers points to another player.", - "direction": "incoming", - "isDynamic": false, - "size": 14, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x0A", - "description": "Give Points command" - }, - { - "name": "To Position", - "type": "byte", - "size": 1, - "description": "Target player seat position" - }, - { - "name": "Amount", - "type": "int", - "size": 4, - "description": "Points to transfer" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 120 - } - }, - { - "id": "0xDA", - "subId": "0x0B", - "name": "Mahjong Roll Dice", - "description": "Client requests to roll the dice.", - "direction": "incoming", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x0B", - "description": "Roll Dice command" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 133 - } - }, - { - "id": "0xDA", - "subId": "0x0C", - "name": "Mahjong Build Walls", - "description": "Dealer requests to reset and build the tile walls.", - "direction": "incoming", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x0C", - "description": "Build Walls command" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 143 - } - }, - { - "id": "0xDA", - "subId": "0x0D", - "name": "Mahjong Reset Scores", - "description": "Dealer requests to reset all player scores to base value.", - "direction": "incoming", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x0D", - "description": "Reset Scores command" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 153 - } - }, - { - "id": "0xDA", - "subId": "0x0F", - "name": "Mahjong Assign Dealer", - "description": "Dealer assigns another player as the new dealer.", - "direction": "incoming", - "isDynamic": false, - "size": 10, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x0F", - "description": "Assign Dealer command" - }, - { - "name": "Position", - "type": "byte", - "size": 1, - "description": "Seat position of new dealer" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 163 - } - }, - { - "id": "0xDA", - "subId": "0x10", - "name": "Mahjong Open Seat", - "description": "Dealer opens a seat, removing the current player.", - "direction": "incoming", - "isDynamic": false, - "size": 10, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x10", - "description": "Open Seat command" - }, - { - "name": "Position", - "type": "byte", - "size": 1, - "description": "Seat position to open" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 175 - } - }, - { - "id": "0xDA", - "subId": "0x11", - "name": "Mahjong Change Option", - "description": "Dealer changes game options (show scores, spectator vision).", - "direction": "incoming", - "isDynamic": false, - "size": 13, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x11", - "description": "Change Option command" - }, - { - "name": "Reserved", - "type": "short", - "size": 2, - "description": "Reserved (not used)" - }, - { - "name": "Reserved 2", - "type": "byte", - "size": 1, - "description": "Reserved (not used)" - }, - { - "name": "Options", - "type": "bitflags", - "size": 1, - "description": "Game options", - "values": [ - { "value": "0x01", "name": "Show Scores", "description": "Display player scores" }, - { "value": "0x02", "name": "Spectator Vision", "description": "Spectators can see all tiles" } - ] - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 192 - } - }, - { - "id": "0xDA", - "subId": "0x15", - "name": "Mahjong Move Wall Break Indicator", - "description": "Dealer moves the wall break indicator position.", - "direction": "incoming", - "isDynamic": false, - "size": 13, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x15", - "description": "Move Wall Break Indicator command" - }, - { - "name": "Y Position", - "type": "short", - "size": 2, - "description": "New Y coordinate" - }, - { - "name": "X Position", - "type": "short", - "size": 2, - "description": "New X coordinate" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 208 - } - }, - { - "id": "0xDA", - "subId": "0x16", - "name": "Mahjong Toggle Public Hand", - "description": "Player toggles whether their hand is visible to others.", - "direction": "incoming", - "isDynamic": false, - "size": 13, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x16", - "description": "Toggle Public Hand command" - }, - { - "name": "Reserved", - "type": "short", - "size": 2, - "description": "Reserved (not used)" - }, - { - "name": "Reserved 2", - "type": "byte", - "size": 1, - "description": "Reserved (not used)" - }, - { - "name": "Public Hand", - "type": "bool", - "size": 1, - "description": "True to show hand publicly" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 221 - } - }, - { - "id": "0xDA", - "subId": "0x17", - "name": "Mahjong Move Tile", - "description": "Player moves a tile to a new position with direction and flip state.", - "direction": "incoming", - "isDynamic": false, - "size": 22, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x17", - "description": "Move Tile command" - }, - { - "name": "Tile Number", - "type": "byte", - "size": 1, - "description": "Tile index number" - }, - { - "name": "Current Direction", - "type": "byte", - "size": 1, - "description": "Current tile direction (unused)" - }, - { - "name": "New Direction", - "type": "enum", - "size": 1, - "description": "New tile direction", - "values": [ - { "value": "0", "name": "Up", "description": "Facing up" }, - { "value": "1", "name": "Left", "description": "Facing left" }, - { "value": "2", "name": "Down", "description": "Facing down" }, - { "value": "3", "name": "Right", "description": "Facing right" } - ] - }, - { - "name": "Reserved", - "type": "byte", - "size": 1, - "description": "Reserved byte" - }, - { - "name": "Flip", - "type": "bool", - "size": 1, - "description": "True to flip tile face-up" - }, - { - "name": "Current Y", - "type": "short", - "size": 2, - "description": "Current Y position (unused)" - }, - { - "name": "Current X", - "type": "short", - "size": 2, - "description": "Current X position (unused)" - }, - { - "name": "Reserved 2", - "type": "byte", - "size": 1, - "description": "Reserved byte" - }, - { - "name": "New Y", - "type": "short", - "size": 2, - "description": "New Y position" - }, - { - "name": "New X", - "type": "short", - "size": 2, - "description": "New X position" - }, - { - "name": "Reserved 3", - "type": "byte", - "size": 1, - "description": "Reserved byte" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 236 - } - }, - { - "id": "0xDA", - "subId": "0x18", - "name": "Mahjong Move Dealer Indicator", - "description": "Dealer moves the dealer indicator with direction and wind.", - "direction": "incoming", - "isDynamic": false, - "size": 15, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown byte" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x18", - "description": "Move Dealer Indicator command" - }, - { - "name": "Direction", - "type": "enum", - "size": 1, - "description": "Indicator direction", - "values": [ - { "value": "0", "name": "Up", "description": "Facing up" }, - { "value": "1", "name": "Left", "description": "Facing left" }, - { "value": "2", "name": "Down", "description": "Facing down" }, - { "value": "3", "name": "Right", "description": "Facing right" } - ] - }, - { - "name": "Wind", - "type": "enum", - "size": 1, - "description": "Wind direction displayed", - "values": [ - { "value": "0", "name": "North", "description": "North wind" }, - { "value": "1", "name": "East", "description": "East wind" }, - { "value": "2", "name": "South", "description": "South wind" }, - { "value": "3", "name": "West", "description": "West wind" } - ] - }, - { - "name": "Y Position", - "type": "short", - "size": 2, - "description": "New Y position" - }, - { - "name": "X Position", - "type": "short", - "size": 2, - "description": "New X position" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 271 - } - } - ] -} diff --git a/docs/packets/incoming/map.json b/docs/packets/incoming/map.json deleted file mode 100644 index 2e8565423..000000000 --- a/docs/packets/incoming/map.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "category": "Map", - "packets": [ - { - "id": "0x56", - "name": "Map Command", - "description": "Client sends map pin commands for editable map items. Commands include adding, inserting, changing, and removing pins.", - "direction": "incoming", - "isDynamic": false, - "size": 11, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x56", - "description": "Packet identifier" - }, - { - "name": "Map Serial", - "type": "uint", - "size": 4, - "description": "Serial of the map item" - }, - { - "name": "Command", - "type": "enum", - "size": 1, - "description": "Map pin command type", - "values": [ - { "value": "1", "name": "AddPin", "description": "Add a new pin" }, - { "value": "2", "name": "InsertPin", "description": "Insert pin at position" }, - { "value": "3", "name": "ChangePin", "description": "Change existing pin" }, - { "value": "4", "name": "RemovePin", "description": "Remove a pin" }, - { "value": "5", "name": "ClearPins", "description": "Clear all pins" }, - { "value": "6", "name": "ToggleEditable", "description": "Toggle edit mode" } - ] - }, - { - "name": "Number", - "type": "byte", - "size": 1, - "description": "Pin number (for insert, change, remove commands)" - }, - { - "name": "X", - "type": "short", - "size": 2, - "description": "X coordinate of pin" - }, - { - "name": "Y", - "type": "short", - "size": 2, - "description": "Y coordinate of pin" - } - ], - "related": [ - { - "id": "0x56", - "direction": "outgoing", - "relationship": "related", - "note": "Server map pin commands" - }, - { - "id": "0x90", - "direction": "outgoing", - "relationship": "related", - "note": "Map Details packet (old)" - }, - { - "id": "0xF5", - "direction": "outgoing", - "relationship": "related", - "note": "Map Details packet (new)" - } - ], - "source": { - "file": "Projects/UOContent/Items/Maps/MapItemPackets.cs", - "line": 28 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/message.json b/docs/packets/incoming/message.json deleted file mode 100644 index 4dc5fc429..000000000 --- a/docs/packets/incoming/message.json +++ /dev/null @@ -1,300 +0,0 @@ -{ - "category": "Message", - "packets": [ - { - "id": "0x03", - "name": "ASCII Speech", - "description": "Client sends ASCII-encoded speech message.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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-t", - "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 - } - }, - { - "id": "0xAD", - "name": "Unicode Speech", - "description": "Client sends Unicode-encoded speech message. Type byte upper bits (0xC0) indicate if keywords are encoded.", - "direction": "incoming", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Standard Unicode", - "condition": "type & 0xC0 == 0", - "size": "12+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xAD", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Type", - "type": "enum", - "size": 1, - "description": "Message type (0xC0 bits clear)", - "values": [ - { - "value": 0, - "name": "Regular", - "description": "Normal speech" - }, - { - "value": 1, - "name": "System", - "description": "System message" - }, - { - "value": 2, - "name": "Emote", - "description": "Emote (*action*)" - }, - { - "value": 8, - "name": "Whisper", - "description": "Whisper" - }, - { - "value": 9, - "name": "Yell", - "description": "Yell" - }, - { - "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": "Language", - "type": "ascii", - "size": 4, - "description": "Language code (e.g., 'ENU')" - }, - { - "name": "Text", - "type": "utf16be-t", - "description": "Speech text (Big Endian Unicode, null-terminated)" - } - ] - }, - { - "name": "Encoded Keywords", - "condition": "type & 0xC0 != 0", - "size": "14+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xAD", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Type", - "type": "byte", - "size": 1, - "description": "Message type with 0xC0 flag set. Lower 4 bits = message type (see Standard variant)" - }, - { - "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": "Keyword Header", - "type": "ushort", - "size": 2, - "description": "Bits 15-4: keyword count (0-50), Bits 3-0: first hold value for packed IDs" - }, - { - "name": "Packed Keywords", - "type": "byte[]", - "description": "12-bit keyword IDs packed alternating: even indices use hold<<8|byte, odd indices use (short&0xFFF0)>>4 with new hold" - }, - { - "name": "Text", - "type": "utf8-t", - "description": "Speech text (UTF-8, null-terminated)" - } - ] - } - ], - "notes": "Encoded keywords use 12-bit speech IDs packed efficiently. Keyword count must be 0-50. The packing alternates: even-indexed keywords combine the previous 4-bit hold with a new byte (12 bits total), odd-indexed keywords read a short and extract bits 15-4 as the ID, bits 3-0 as the next hold.", - "related": [ - { - "id": "0x03", - "direction": "incoming", - "relationship": "variant", - "note": "ASCII Speech (simpler format)" - }, - { - "id": "0xAE", - "direction": "outgoing", - "relationship": "response", - "note": "Unicode Message sent to other clients" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingMessagePackets.cs", - "line": 58 - } - } - ] -} diff --git a/docs/packets/incoming/mobile.json b/docs/packets/incoming/mobile.json deleted file mode 100644 index 9cea2c944..000000000 --- a/docs/packets/incoming/mobile.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "category": "Mobile", - "packets": [ - { - "id": "0x75", - "name": "Rename Request", - "description": "Client requests to rename a mobile (pet).", - "direction": "incoming", - "isDynamic": false, - "size": 35, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x75", - "description": "Packet identifier" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of mobile to rename" - }, - { - "name": "New Name", - "type": "ascii", - "size": 30, - "description": "New name for the mobile" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingMobilePackets.cs", - "line": 32 - } - }, - { - "id": "0x98", - "name": "Mobile Name Request", - "description": "Client requests the name of a mobile.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x98", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of mobile to query" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingMobilePackets.cs", - "line": 43 - } - }, - { - "id": "0xB8", - "name": "Profile Request", - "description": "Client requests to view or edit a mobile's profile.", - "direction": "incoming", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Display Profile", - "condition": "mode == Display (0)", - "size": 8, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB8", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Mode", - "type": "byte", - "size": 1, - "value": "0", - "description": "Display mode" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of target mobile" - } - ] - }, - { - "name": "Edit Profile", - "condition": "mode == Edit (1)", - "size": "12+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB8", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Mode", - "type": "byte", - "size": 1, - "value": "1", - "description": "Edit mode" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of target mobile" - }, - { - "name": "Padding", - "type": "short", - "size": 2, - "description": "Unused padding" - }, - { - "name": "Text Length", - "type": "ushort", - "size": 2, - "description": "Length of text in characters" - }, - { - "name": "Text", - "type": "utf16be", - "description": "New profile text (Big Endian Unicode)" - } - ] - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingMobilePackets.cs", - "line": 53 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/movement.json b/docs/packets/incoming/movement.json deleted file mode 100644 index d776d3382..000000000 --- a/docs/packets/incoming/movement.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "category": "Movement", - "packets": [ - { - "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": "Packet ID", - "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": "Fastwalk Key", - "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 - } - } - ] -} diff --git a/docs/packets/incoming/player.json b/docs/packets/incoming/player.json deleted file mode 100644 index 4596bb776..000000000 --- a/docs/packets/incoming/player.json +++ /dev/null @@ -1,989 +0,0 @@ -{ - "category": "Player", - "packets": [ - { - "id": "0x01", - "name": "Disconnect", - "description": "Client sends disconnect notification.", - "direction": "incoming", - "isDynamic": false, - "size": 5, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x01", - "description": "Packet identifier" - }, - { - "name": "Minus One", - "type": "int", - "size": 4, - "value": "0xFFFFFFFF", - "description": "Always -1" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 317 - } - }, - { - "id": "0x05", - "name": "Attack Request", - "description": "Client requests to attack a mobile.", - "direction": "incoming", - "isDynamic": false, - "size": 5, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x05", - "description": "Packet identifier" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of mobile to attack" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 69 - } - }, - { - "id": "0x12", - "name": "Text Command", - "description": "Client sends text-based commands for skills, spells, virtues, etc.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x12", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command Type", - "type": "enum", - "enumType": "sequential", - "size": 1, - "description": "Type of text command", - "values": [ - { - "value": "0x24", - "name": "Use Skill", - "description": "Use a skill by ID" - }, - { - "value": "0x27", - "name": "Cast Spell From Book", - "description": "Cast spell from spellbook" - }, - { - "value": "0x2F", - "name": "Old Scroll Click", - "description": "Old scroll double-click" - }, - { - "value": "0x43", - "name": "Open Spellbook", - "description": "Open spellbook of type" - }, - { - "value": "0x56", - "name": "Cast Spell Macro", - "description": "Cast spell from macro" - }, - { - "value": "0x58", - "name": "Open Door", - "description": "Open door macro" - }, - { - "value": "0xC7", - "name": "Animate", - "description": "Play animation" - }, - { - "value": "0xF4", - "name": "Invoke Virtue", - "description": "Invoke virtue from macro" - } - ] - }, - { - "name": "Command", - "type": "ascii-t", - "description": "Command-specific text (skill ID, spell ID, etc.)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 119 - } - }, - { - "id": "0x22", - "name": "Resynchronize", - "description": "Client requests full world state resync.", - "direction": "incoming", - "noMerge": true, - "isDynamic": false, - "size": 3, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x22", - "description": "Packet identifier" - }, - { - "name": "Padding", - "type": "ushort", - "size": 2, - "description": "Unused padding" - } - ], - "notes": "Not related to outgoing 0x22 (Movement Acknowledgment) despite sharing the same packet ID.", - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 349 - } - }, - { - "id": "0x2C", - "name": "Death Status Response", - "description": "Client acknowledges death status packet. Currently ignored by server.", - "direction": "incoming", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0x34", - "name": "Mobile Query", - "description": "Client queries information about a mobile (stats or skills).", - "direction": "incoming", - "isDynamic": false, - "size": 10, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x34", - "description": "Packet identifier" - }, - { - "name": "Pattern", - "type": "uint", - "size": 4, - "value": "0xEDEDEDED", - "description": "Fixed pattern" - }, - { - "name": "Query Type", - "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": "Mobile Serial", - "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 - } - }, - { - "id": "0x3A", - "name": "Change Skill Lock", - "description": "Client changes the lock state of a skill.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x3A", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Skill Index", - "type": "short", - "size": 2, - "description": "Skill index to change" - }, - { - "name": "Lock State", - "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 - } - }, - { - "id": "0x72", - "name": "Set War Mode", - "description": "Client toggles war/peace mode.", - "direction": "incoming", - "isDynamic": false, - "size": 5, - "fields": [ - { - "name": "Packet ID", - "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)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 343 - } - }, - { - "id": "0x73", - "name": "Ping Request", - "description": "Client sends ping for latency measurement.", - "direction": "incoming", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x73", - "description": "Packet identifier" - }, - { - "name": "Sequence", - "type": "byte", - "size": 1, - "description": "Ping sequence number" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 366 - } - }, - { - "id": "0x7D", - "name": "Menu Response", - "description": "Client responds to a displayed item menu.", - "direction": "incoming", - "isDynamic": false, - "size": 13, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x7D", - "description": "Packet identifier" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Menu dialog serial" - }, - { - "name": "Menu ID", - "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": "Item ID", - "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 - } - }, - { - "id": "0x95", - "name": "Hue Picker Response", - "description": "Client responds to a hue picker dialog.", - "direction": "incoming", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x95", - "description": "Packet identifier" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Hue picker serial" - }, - { - "name": "Item ID", - "type": "short", - "size": 2, - "description": "Item ID (unused)" - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Selected hue (masked with 0x3FFF)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 86 - } - }, - { - "id": "0x9A", - "name": "ASCII Prompt Response", - "description": "Client responds to an ASCII text prompt.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["Menu"], - "fields": [ - { - "name": "Packet ID", - "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": "Prompt ID", - "type": "int", - "size": 4, - "description": "Prompt ID" - }, - { - "name": "Type", - "type": "int", - "size": 4, - "description": "Response type: 0 = cancel, other = submit" - }, - { - "name": "Text", - "type": "ascii-t", - "description": "Response text (max 128 chars)" - } - ], - "related": [ - { - "id": "0xC2", - "relationship": "request", - "note": "Unicode Prompt packet that triggered this response" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 214 - } - }, - { - "id": "0x9B", - "name": "Help Request", - "description": "Client requests help/GM assistance.", - "direction": "incoming", - "isDynamic": false, - "size": 258, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0xA4", - "name": "System Info", - "description": "Client sends system/hardware information.", - "direction": "incoming", - "isDynamic": false, - "size": 149, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0xA7", - "name": "Request Scroll Window", - "description": "Client requests a tips/scroll window.", - "direction": "incoming", - "isDynamic": false, - "size": 4, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA7", - "description": "Packet identifier" - }, - { - "name": "Last Tip", - "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 - } - }, - { - "id": "0xC2", - "name": "Unicode Prompt Response", - "description": "Client responds to a Unicode text prompt.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "tags": ["Menu"], - "fields": [ - { - "name": "Packet ID", - "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": "Prompt ID", - "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., \u0027ENU\u0027)" - }, - { - "name": "Text", - "type": "utf16le-t", - "description": "Response text (max 128 chars)" - } - ], - "related": [ - { - "id": "0xC2", - "direction": "outgoing", - "relationship": "request", - "note": "Unicode Prompt packet that triggered this response" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 250 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xC8", - "description": "Packet identifier" - }, - { - "name": "Range", - "type": "byte", - "size": 1, - "description": "Requested update range (ignored)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 371 - } - }, - { - "id": "0xD0", - "name": "Configuration File", - "description": "Client sends configuration data. Currently ignored by server.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0xD1", - "name": "Logout Request", - "description": "Client requests to logout.", - "direction": "incoming", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD1", - "description": "Packet identifier" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "description": "Unknown (typically 0x01)" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingPlayerPackets.cs", - "line": 326 - } - }, - { - "id": "0xF4", - "name": "Crash Report", - "description": "Client sends crash/error report.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF4", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Client Major", - "type": "byte", - "size": 1, - "description": "Client major version" - }, - { - "name": "Client Minor", - "type": "byte", - "size": 1, - "description": "Client minor version" - }, - { - "name": "Client Rev", - "type": "byte", - "size": 1, - "description": "Client revision" - }, - { - "name": "Client Pat", - "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": "Account Name", - "type": "ascii", - "size": 32, - "description": "Account name" - }, - { - "name": "Character Name", - "type": "ascii", - "size": 32, - "description": "Character name" - }, - { - "name": "IP Address", - "type": "ascii", - "size": 15, - "description": "Client IP address" - }, - { - "name": "Unknown1", - "type": "int", - "size": 4, - "description": "Unknown" - }, - { - "name": "Exception Code", - "type": "int", - "size": 4, - "description": "Exception code" - }, - { - "name": "Process Name", - "type": "ascii", - "size": 100, - "description": "Process name" - }, - { - "name": "Report Text", - "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": "Stack Count", - "type": "byte", - "size": 1, - "description": "Number of stack trace entries" - }, - { - "name": "Stack Addresses", - "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 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/securetrade.json b/docs/packets/incoming/securetrade.json deleted file mode 100644 index e0b26a90b..000000000 --- a/docs/packets/incoming/securetrade.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "category": "Secure Trade", - "packets": [ - { - "id": "0x6F", - "name": "Secure Trade", - "description": "Client interacts with a secure trade window.", - "direction": "incoming", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Cancel Trade", - "condition": "action == Cancel (1)", - "size": 8, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Action", - "type": "byte", - "size": 1, - "value": "1", - "description": "Cancel action" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of the trade container" - } - ] - }, - { - "name": "Toggle Accept", - "condition": "action == Check (2)", - "size": 12, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Action", - "type": "byte", - "size": 1, - "value": "2", - "description": "Check/toggle action" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of the trade container" - }, - { - "name": "Accepted", - "type": "bool", - "size": 4, - "description": "True if accepting the trade" - } - ] - }, - { - "name": "Update Gold/Platinum", - "condition": "action == UpdateGold (3)", - "size": 16, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Action", - "type": "byte", - "size": 1, - "value": "3", - "description": "Update gold action" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of the trade container" - }, - { - "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", - "direction": "outgoing", - "relationship": "response", - "note": "Server sends trade window updates" - } - ], - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingMobilePackets.cs", - "line": 93 - } - } - ] -} diff --git a/docs/packets/incoming/store.json b/docs/packets/incoming/store.json deleted file mode 100644 index 04ec54c22..000000000 --- a/docs/packets/incoming/store.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "category": "Store", - "packets": [ - { - "id": "0xFA", - "name": "Open UO Store", - "description": "Client requests to open the Ultima Store interface. Sent when player clicks the UO Store button in the client toolbar (Classic) or selects Ultima Store from the menu (Enhanced).", - "direction": "incoming", - "isDynamic": false, - "size": 1, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xFA", - "description": "Packet identifier" - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "Ultima Store feature" - }, - "source": { - "file": "Projects/UOContent/Engines/UltimaStore/UltimaStorePackets.cs", - "line": 10 - }, - "notes": "The Ultima Store is an in-game microtransaction store on official servers. ModernUO includes a placeholder that displays a 'not available' message. Free shards may implement their own store functionality using this packet trigger." - } - ] -} diff --git a/docs/packets/incoming/targeting.json b/docs/packets/incoming/targeting.json deleted file mode 100644 index ca9470029..000000000 --- a/docs/packets/incoming/targeting.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "category": "Targeting", - "packets": [ - { - "id": "0x6C", - "name": "Target Response", - "description": "Client responds to a target cursor request.", - "direction": "incoming", - "isDynamic": false, - "size": 19, - "fields": [ - { - "name": "Packet ID", - "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": "Target ID", - "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": "Target Serial", - "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)" - } - ], - "notes": "If x == -1 \u0026\u0026 y == -1 \u0026\u0026 serial is invalid, user pressed Escape to cancel targeting.", - "source": { - "file": "Projects/UOContent/Network/Packets/IncomingTargetingPackets.cs", - "line": 28 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/incoming/vendor.json b/docs/packets/incoming/vendor.json deleted file mode 100644 index ee54fa693..000000000 --- a/docs/packets/incoming/vendor.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "category": "Vendor", - "packets": [ - { - "id": "0x3B", - "name": "Vendor Buy Reply", - "description": "Client confirms items to purchase from a vendor.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x3B", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Vendor Serial", - "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": "Item Serial", - "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 - } - }, - { - "id": "0x9F", - "name": "Vendor Sell Reply", - "description": "Client confirms items to sell to a vendor.", - "direction": "incoming", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x9F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Vendor Serial", - "type": "uint", - "size": 4, - "description": "Serial of the vendor" - }, - { - "name": "Item Count", - "type": "ushort", - "size": 2, - "description": "Number of items to sell" - }, - { - "name": "Items", - "type": "loop", - "loop": { - "countField": "itemCount", - "fields": [ - { - "name": "Item Serial", - "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 - } - } - ] -} diff --git a/docs/packets/outgoing/account.json b/docs/packets/outgoing/account.json deleted file mode 100644 index 7b0fda674..000000000 --- a/docs/packets/outgoing/account.json +++ /dev/null @@ -1,1183 +0,0 @@ -{ - "category": "Account", - "packets": [ - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x82", - "description": "Packet identifier" - }, - { - "name": "Reason", - "type": "enum", - "size": 1, - "description": "Rejection reason code", - "values": [ - { "value": "0", "name": "Invalid", "description": "Invalid credentials" }, - { "value": "1", "name": "InUse", "description": "Account already in use" }, - { "value": "2", "name": "Blocked", "description": "Account blocked" }, - { "value": "3", "name": "BadPass", "description": "Incorrect password" }, - { "value": "254", "name": "Idle", "description": "Idle timeout" }, - { "value": "255", "name": "BadComm", "description": "Communication error" } - ] - } - ], - "related": [ - { - "id": "0x80", - "relationship": "request", - "note": "The login attempt that failed" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingAccountPackets.cs", - "line": 402 - } - }, - { - "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 x serverCount)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA8", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "System Info Flag", - "type": "byte", - "size": 1, - "value": "0x5D", - "description": "System info flag" - }, - { - "name": "Server Count", - "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": "Full Percent", - "type": "byte", - "size": 1, - "description": "Server load percentage" - }, - { - "name": "Timezone", - "type": "sbyte", - "size": 1, - "description": "Server timezone offset" - }, - { - "name": "IP Address", - "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 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x8C", - "description": "Packet identifier" - }, - { - "name": "IP Address", - "type": "uint", - "size": 4, - "description": "Game server IP address (little-endian)" - }, - { - "name": "Port", - "type": "short", - "size": 2, - "description": "Game server port" - }, - { - "name": "Auth ID", - "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 - } - }, - { - "id": "0xA9", - "name": "Character List", - "description": "Sent after game login. Contains the list of characters on the account and starting city information. Extended format in 7.0.13.0+ includes city coordinates.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "version": "Classic", - "name": "Pre-7.0.13.0 Format", - "condition": "Client version \u003c 7.0.13.0", - "size": "9+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA9", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Char Count", - "type": "byte", - "size": 1, - "description": "Number of character slots (1, 5, 6, or 7)" - }, - { - "name": "Characters", - "type": "loop", - "description": "Character list entries (60 bytes each)", - "loop": { - "countField": "charCount", - "itemSize": 60, - "fields": [ - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Character name (empty if slot unused)" - }, - { - "name": "Password", - "type": "ascii", - "size": 30, - "description": "Always empty (legacy field)" - } - ] - } - }, - { - "name": "City Count", - "type": "byte", - "size": 1, - "description": "Number of starting cities" - }, - { - "name": "Cities", - "type": "loop", - "description": "Starting city entries (63 bytes each)", - "loop": { - "countField": "cityCount", - "itemSize": 63, - "fields": [ - { - "name": "Index", - "type": "byte", - "size": 1, - "description": "City index" - }, - { - "name": "City Name", - "type": "ascii", - "size": 31, - "description": "City name" - }, - { - "name": "Building Name", - "type": "ascii", - "size": 31, - "description": "Building/tavern name" - } - ] - } - }, - { - "name": "Flags", - "type": "bitfield", - "size": 4, - "description": "Character list flags", - "flags": [ - { - "bit": "0", - "name": "Unknown1", - "description": "Unknown" - }, - { - "bit": "1", - "name": "Overwrite Config", - "description": "Overwrite configuration file" - }, - { - "bit": "2", - "name": "One Character Slot", - "description": "Limit to 1 character slot" - }, - { - "bit": "3", - "name": "Context Menus", - "description": "Enable context menus" - }, - { - "bit": "4", - "name": "Slot Limit", - "description": "Limit character slots" - }, - { - "bit": "5", - "name": "AOS", - "description": "Age of Shadows features" - }, - { - "bit": "6", - "name": "Sixth Character Slot", - "description": "Enable 6th character slot" - }, - { - "bit": "7", - "name": "SE", - "description": "Samurai Empire features" - }, - { - "bit": "8", - "name": "ML", - "description": "Mondain\u0027s Legacy features" - }, - { - "bit": "9", - "name": "Unknown2", - "description": "Unknown" - }, - { - "bit": "10", - "name": "KR", - "description": "Kingdom Reborn features" - }, - { - "bit": "11", - "name": "SA", - "description": "Stygian Abyss features" - }, - { - "bit": "12", - "name": "HS", - "description": "High Seas features" - }, - { - "bit": "13", - "name": "Seventh Character Slot", - "description": "Enable 7th character slot" - }, - { - "bit": "14", - "name": "Unknown3", - "description": "Unknown" - }, - { - "bit": "15", - "name": "New Movement", - "description": "New movement system" - }, - { - "bit": "16", - "name": "New Felucca Areas", - "description": "New Felucca areas" - } - ] - } - ] - }, - { - "version": "NewCharacterList (7.0.13.0+)", - "name": "Extended City Format", - "condition": "Client version \u003e= 7.0.13.0 (NewCharacterList)", - "size": "11+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA9", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Char Count", - "type": "byte", - "size": 1, - "description": "Number of character slots (1, 5, 6, or 7)" - }, - { - "name": "Characters", - "type": "loop", - "description": "Character list entries (60 bytes each)", - "loop": { - "countField": "charCount", - "itemSize": 60, - "fields": [ - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Character name (empty if slot unused)" - }, - { - "name": "Password", - "type": "ascii", - "size": 30, - "description": "Always empty (legacy field)" - } - ] - } - }, - { - "name": "City Count", - "type": "byte", - "size": 1, - "description": "Number of starting cities" - }, - { - "name": "Cities", - "type": "loop", - "description": "Starting city entries (89 bytes each, extended format)", - "loop": { - "countField": "cityCount", - "itemSize": 89, - "fields": [ - { - "name": "Index", - "type": "byte", - "size": 1, - "description": "City index" - }, - { - "name": "City Name", - "type": "ascii", - "size": 32, - "description": "City name (1 byte longer than classic)" - }, - { - "name": "Building Name", - "type": "ascii", - "size": 32, - "description": "Building/tavern name (1 byte longer than classic)" - }, - { - "name": "X", - "type": "int", - "size": 4, - "description": "X coordinate of starting location" - }, - { - "name": "Y", - "type": "int", - "size": 4, - "description": "Y coordinate of starting location" - }, - { - "name": "Z", - "type": "int", - "size": 4, - "description": "Z coordinate of starting location" - }, - { - "name": "Map ID", - "type": "int", - "size": 4, - "description": "Map ID for starting location" - }, - { - "name": "Cliloc", - "type": "int", - "size": 4, - "description": "Cliloc ID for city description" - }, - { - "name": "Unknown", - "type": "int", - "size": 4, - "value": "0", - "description": "Unknown (always 0)" - } - ] - } - }, - { - "name": "Flags", - "type": "bitfield", - "size": 4, - "description": "Character list flags (same as classic format)", - "flags": [ - { - "bit": "2", - "name": "One Character Slot", - "description": "Limit to 1 character slot" - }, - { - "bit": "3", - "name": "Context Menus", - "description": "Enable context menus" - }, - { - "bit": "4", - "name": "Slot Limit", - "description": "Limit character slots" - }, - { - "bit": "5", - "name": "AOS", - "description": "Age of Shadows features" - }, - { - "bit": "6", - "name": "Sixth Character Slot", - "description": "Enable 6th character slot" - }, - { - "bit": "7", - "name": "SE", - "description": "Samurai Empire features" - }, - { - "bit": "8", - "name": "ML", - "description": "Mondain\u0027s Legacy features" - }, - { - "bit": "11", - "name": "SA", - "description": "Stygian Abyss features" - }, - { - "bit": "12", - "name": "HS", - "description": "High Seas features" - }, - { - "bit": "13", - "name": "Seventh Character Slot", - "description": "Enable 7th character slot" - } - ] - }, - { - "name": "Last Char Slot", - "type": "short", - "size": 2, - "value": "-1", - "description": "Last played character slot index (-1 if none)" - } - ] - } - ], - "related": [ - { - "id": "0x91", - "relationship": "request", - "note": "Game login request" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingAccountPackets.cs", - "line": 293 - } - }, - { - "id": "0x1B", - "name": "Login Confirmation", - "description": "Sent when entering the world. Confirms the player\u0027s mobile serial and initial position.", - "direction": "outgoing", - "isDynamic": false, - "size": 37, - "fields": [ - { - "name": "Packet ID", - "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": "Map Width", - "type": "short", - "size": 2, - "description": "Map width in tiles" - }, - { - "name": "Map Height", - "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 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x55", - "description": "Packet identifier" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingAccountPackets.cs", - "line": 231 - } - }, - { - "id": "0xBD", - "name": "Client Version Request", - "description": "Request for the client to send its version string.", - "direction": "outgoing", - "isDynamic": false, - "size": 3, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBD", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0003", - "description": "Packet length" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingAccountPackets.cs", - "line": 112 - }, - "notes": "Same packet ID (0xBD) is used for both request (server) and response (client)." - }, - { - "id": "0xB9", - "name": "Supported Features", - "description": "Informs the client which features are enabled on the server. Feature flags control T2A, LBR, AOS, SE, ML, SA, HS features and character slot limits.", - "direction": "outgoing", - "isDynamic": false, - "size": "Varies", - "variants": [ - { - "version": "Classic", - "name": "16-bit Feature Flags", - "condition": "Client without ExtendedSupportedFeatures", - "size": 3, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB9", - "description": "Packet identifier" - }, - { - "name": "Features", - "type": "bitfield", - "size": 2, - "description": "16-bit feature flags bitmask", - "flags": [ - { - "bit": "0", - "name": "T2A", - "description": "The Second Age features" - }, - { - "bit": "1", - "name": "Renaissance", - "description": "Renaissance features" - }, - { - "bit": "2", - "name": "Third Dawn", - "description": "Third Dawn (3D client) features" - }, - { - "bit": "3", - "name": "LBR", - "description": "Lord Blackthorn\u0027s Revenge features" - }, - { - "bit": "4", - "name": "AOS", - "description": "Age of Shadows features" - }, - { - "bit": "5", - "name": "Sixth Character Slot", - "description": "Enable 6th character slot" - }, - { - "bit": "6", - "name": "SE", - "description": "Samurai Empire features" - }, - { - "bit": "7", - "name": "ML", - "description": "Mondain\u0027s Legacy features" - }, - { - "bit": "8", - "name": "Eighth Age", - "description": "Eighth Age splash screen" - }, - { - "bit": "9", - "name": "Ninth Age", - "description": "Ninth Age splash screen" - }, - { - "bit": "10", - "name": "Tenth Age", - "description": "Tenth Age splash screen" - }, - { - "bit": "11", - "name": "Increased Storage", - "description": "Increased storage" - }, - { - "bit": "12", - "name": "Seventh Character Slot", - "description": "Enable 7th character slot" - }, - { - "bit": "13", - "name": "Roleplay Faces", - "description": "Roleplay face selection" - }, - { - "bit": "14", - "name": "Trial Account", - "description": "Trial account flag" - }, - { - "bit": "15", - "name": "Live Account", - "description": "Live (paid) account flag" - } - ] - } - ] - }, - { - "version": "Extended", - "name": "32-bit Feature Flags", - "condition": "Client with ExtendedSupportedFeatures", - "size": 5, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB9", - "description": "Packet identifier" - }, - { - "name": "Features", - "type": "bitfield", - "size": 4, - "description": "32-bit feature flags bitmask (includes all 16-bit flags plus expansion flags)", - "flags": [ - { - "bit": "0", - "name": "T2A", - "description": "The Second Age features" - }, - { - "bit": "1", - "name": "Renaissance", - "description": "Renaissance features" - }, - { - "bit": "2", - "name": "Third Dawn", - "description": "Third Dawn (3D client) features" - }, - { - "bit": "3", - "name": "LBR", - "description": "Lord Blackthorn\u0027s Revenge features" - }, - { - "bit": "4", - "name": "AOS", - "description": "Age of Shadows features" - }, - { - "bit": "5", - "name": "Sixth Character Slot", - "description": "Enable 6th character slot" - }, - { - "bit": "6", - "name": "SE", - "description": "Samurai Empire features" - }, - { - "bit": "7", - "name": "ML", - "description": "Mondain\u0027s Legacy features" - }, - { - "bit": "8", - "name": "Eighth Age", - "description": "Eighth Age splash screen" - }, - { - "bit": "9", - "name": "Ninth Age", - "description": "Ninth Age splash screen" - }, - { - "bit": "10", - "name": "Tenth Age", - "description": "Tenth Age splash screen" - }, - { - "bit": "11", - "name": "Increased Storage", - "description": "Increased storage" - }, - { - "bit": "12", - "name": "Seventh Character Slot", - "description": "Enable 7th character slot" - }, - { - "bit": "13", - "name": "Roleplay Faces", - "description": "Roleplay face selection" - }, - { - "bit": "14", - "name": "Trial Account", - "description": "Trial account flag" - }, - { - "bit": "15", - "name": "Live Account", - "description": "Live (paid) account flag" - }, - { - "bit": "16", - "name": "SA", - "description": "Stygian Abyss features" - }, - { - "bit": "17", - "name": "HS", - "description": "High Seas features" - }, - { - "bit": "18", - "name": "Gothic", - "description": "Gothic housing tiles" - }, - { - "bit": "19", - "name": "Rustic", - "description": "Rustic housing tiles" - }, - { - "bit": "20", - "name": "Jungle", - "description": "Jungle housing tiles" - }, - { - "bit": "21", - "name": "Shadowguard", - "description": "Shadowguard content" - }, - { - "bit": "22", - "name": "TOL", - "description": "Time of Legends features" - }, - { - "bit": "23", - "name": "EJ", - "description": "Endless Journey (F2P) features" - } - ] - } - ] - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "ExtendedSupportedFeatures determines which variant is sent" - }, - "source": { - "file": "Projects/Server/Network/Packets/OutgoingAccountPackets.cs", - "line": 140 - } - }, - { - "id": "0x85", - "name": "Character Delete Result", - "description": "Result of a character deletion request.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x85", - "description": "Packet identifier" - }, - { - "name": "Result", - "type": "enum", - "size": 1, - "description": "Deletion result code", - "values": [ - { "value": "0", "name": "PasswordInvalid", "description": "Password is invalid" }, - { "value": "1", "name": "CharNotExist", "description": "Character does not exist" }, - { "value": "2", "name": "CharBeingPlayed", "description": "Character is being played" }, - { "value": "3", "name": "CharTooYoung", "description": "Character too young to delete" }, - { "value": "4", "name": "CharQueued", "description": "Character queued for deletion" }, - { "value": "5", "name": "BadRequest", "description": "Invalid request" } - ] - } - ], - "related": [ - { - "id": "0x83", - "relationship": "request", - "note": "The delete request" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingAccountPackets.cs", - "line": 121 - } - }, - { - "id": "0x53", - "name": "Popup Message", - "description": "Displays a predefined popup message to the client.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x53", - "description": "Packet identifier" - }, - { - "name": "Message ID", - "type": "enum", - "size": 1, - "description": "Predefined message identifier", - "values": [ - { "value": "1", "name": "CharNoExist", "description": "Character does not exist" }, - { "value": "2", "name": "CharExists", "description": "Character already exists" }, - { "value": "5", "name": "CharInWorld", "description": "Character is in world" }, - { "value": "6", "name": "LoginSyncError", "description": "Login synchronization error" }, - { "value": "7", "name": "IdleWarning", "description": "Idle timeout warning" } - ] - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingAccountPackets.cs", - "line": 131 - } - }, - { - "id": "0x81", - "name": "Change Character", - "description": "Updates the character list during reconnection. Currently unused.", - "direction": "outgoing", - "isDynamic": true, - "size": "5 + (60 x charCount)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x81", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Char Count", - "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." - }, - { - "id": "0x86", - "name": "Character List Update", - "description": "Updates the character list after character creation or deletion.", - "direction": "outgoing", - "isDynamic": true, - "size": "4 + (60 x charCount)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x86", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Char Count", - "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 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/arrow.json b/docs/packets/outgoing/arrow.json deleted file mode 100644 index ba16c5b76..000000000 --- a/docs/packets/outgoing/arrow.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "category": "Quest", - "packets": [ - { - "id": "0xBA", - "name": "Quest Arrow", - "description": "Sets or cancels the quest tracking arrow on the client.", - "direction": "outgoing", - "isDynamic": false, - "size": "Varies", - "variants": [ - { - "name": "Pre-High Seas Set Arrow", - "condition": "command == 1 (Set), pre-HighSeas client", - "size": 6, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBA", - "description": "Packet identifier" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x01", - "description": "Set arrow command" - }, - { - "name": "X", - "type": "short", - "size": 2, - "description": "Target X coordinate" - }, - { - "name": "Y", - "type": "short", - "size": 2, - "description": "Target Y coordinate" - } - ] - }, - { - "name": "Pre-High Seas Cancel Arrow", - "condition": "command == 0 (Cancel), pre-HighSeas client", - "size": 6, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBA", - "description": "Packet identifier" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Cancel arrow command" - }, - { - "name": "X", - "type": "short", - "size": 2, - "value": "-1", - "description": "X coordinate (-1)" - }, - { - "name": "Y", - "type": "short", - "size": 2, - "value": "-1", - "description": "Y coordinate (-1)" - } - ] - }, - { - "name": "High Seas", - "condition": "HighSeas client (7.0.9.0+)", - "size": 10, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBA", - "description": "Packet identifier" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "description": "Command (0 = cancel, 1 = set)" - }, - { - "name": "X", - "type": "short", - "size": 2, - "description": "Target X coordinate" - }, - { - "name": "Y", - "type": "short", - "size": 2, - "description": "Target Y coordinate" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of tracked target" - } - ] - } - ], - "related": [ - { - "id": "0xBF/0x07", - "relationship": "request", - "note": "Quest Arrow Click from client" - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "HighSeas (7.0.9.0+) adds target serial. Pre-HS clients use 6-byte variant, HS+ clients use 10-byte variant." - }, - "source": { - "file": "Projects/UOContent/Skills/Tracking/OutgoingArrowPackets.cs", - "line": 29 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/assistant.json b/docs/packets/outgoing/assistant.json deleted file mode 100644 index 1fb05e6ea..000000000 --- a/docs/packets/outgoing/assistant.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "category": "Assistant", - "packets": [ - { - "id": "0xF0", - "name": "Assistant Handshake", - "description": "Server sends handshake to negotiate assistant features with Razor-style clients. Contains disallowed feature flags.", - "direction": "outgoing", - "isDynamic": false, - "size": 12, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF0", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x000C", - "description": "Packet length (12)" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0xFE", - "description": "Handshake command" - }, - { - "name": "Disallowed Features", - "type": "ulong", - "size": 8, - "description": "Bitmask of disallowed assistant features" - } - ], - "notes": "Used for assistant negotiation with Razor Community Edition and similar clients. If negotiation fails within 30 seconds, the server may kick the player.", - "source": { - "file": "Projects/UOContent/Assistants/AssistantHandler.cs", - "line": 132 - } - }, - { - "id": "0xBE", - "name": "Assistant Version Request", - "description": "Server requests assistant version information from the client.", - "direction": "outgoing", - "isDynamic": false, - "size": 3, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBE", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0003", - "description": "Packet length (3)" - } - ], - "source": { - "file": "Projects/UOContent/Assistants/AssistantHandler.cs", - "line": 122 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/boat.json b/docs/packets/outgoing/boat.json deleted file mode 100644 index d295510d1..000000000 --- a/docs/packets/outgoing/boat.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "category": "Boat", - "packets": [ - { - "id": "0xF6", - "name": "Boat Move (High Seas)", - "description": "Sent when a boat moves, containing the boat\u0027s new position and all entities on board with their updated positions.", - "direction": "outgoing", - "isDynamic": true, - "size": "18 + (entityCount x 10)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF6", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Boat Serial", - "type": "uint", - "size": 4, - "description": "Serial of the boat" - }, - { - "name": "Speed", - "type": "byte", - "size": 1, - "description": "Boat movement speed" - }, - { - "name": "Direction", - "type": "byte", - "size": 1, - "description": "Movement direction (0-7)" - }, - { - "name": "Facing", - "type": "byte", - "size": 1, - "description": "Boat facing direction" - }, - { - "name": "X", - "type": "short", - "size": 2, - "description": "Boat X coordinate" - }, - { - "name": "Y", - "type": "short", - "size": 2, - "description": "Boat Y coordinate" - }, - { - "name": "Z", - "type": "short", - "size": 2, - "description": "Boat Z coordinate" - }, - { - "name": "Entity Count", - "type": "short", - "size": 2, - "description": "Number of entities on boat (max 65535)" - }, - { - "name": "Entities", - "type": "array", - "description": "Entities on the boat with their positions", - "loop": { - "countField": "entityCount", - "fields": [ - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Entity serial" - }, - { - "name": "X", - "type": "short", - "size": 2, - "description": "Entity X coordinate (boat offset applied)" - }, - { - "name": "Y", - "type": "short", - "size": 2, - "description": "Entity Y coordinate (boat offset applied)" - }, - { - "name": "Z", - "type": "short", - "size": 2, - "description": "Entity Z coordinate" - } - ] - } - } - ], - "clientVersion": { - "classic": { - "min": "7.0.9.0" - }, - "enhanced": {}, - "notes": "High Seas expansion feature" - }, - "source": { - "file": "Projects/UOContent/Multis/Boats/BoatPackets.cs", - "line": 27 - }, - "notes": "High Seas expansion only. Entities include mobiles and items on the boat. Coordinates include the boat\u0027s movement offset." - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/book.json b/docs/packets/outgoing/book.json deleted file mode 100644 index 6f89e299b..000000000 --- a/docs/packets/outgoing/book.json +++ /dev/null @@ -1,217 +0,0 @@ -{ - "category": "Book", - "packets": [ - { - "id": "0x66", - "name": "Book Content", - "description": "Sends full book content including all pages and lines.", - "direction": "outgoing", - "isDynamic": true, - "size": "9+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x66", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Book Serial", - "type": "uint", - "size": 4, - "description": "Serial of the book" - }, - { - "name": "Page Count", - "type": "ushort", - "size": 2, - "description": "Number of pages" - }, - { - "name": "Pages", - "type": "loop", - "description": "Page contents", - "loop": { - "countField": "pageCount", - "fields": [ - { - "name": "Page Number", - "type": "ushort", - "size": 2, - "description": "Page number (1-indexed)" - }, - { - "name": "Line Count", - "type": "ushort", - "size": 2, - "description": "Number of lines on page" - }, - { - "name": "Lines", - "type": "loop", - "description": "Lines on the page", - "loop": { - "countField": "lineCount", - "fields": [ - { - "name": "Text", - "type": "utf8-t", - "description": "Line text" - } - ] - } - } - ] - } - } - ], - "source": { - "file": "Projects/UOContent/Items/Books/BookPackets.cs", - "line": 136 - } - }, - { - "id": "0xD4", - "name": "Book Header", - "description": "Sends book cover information (title, author, writable status).", - "direction": "outgoing", - "isDynamic": true, - "size": "17+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD4", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Book Serial", - "type": "uint", - "size": 4, - "description": "Serial of the book" - }, - { - "name": "Flag On", - "type": "byte", - "size": 1, - "value": "0x01", - "description": "Flag on (always 1)" - }, - { - "name": "Writable", - "type": "bool", - "size": 1, - "description": "True if book is writable and in range" - }, - { - "name": "Page Count", - "type": "ushort", - "size": 2, - "description": "Number of pages" - }, - { - "name": "Title Length", - "type": "ushort", - "size": 2, - "description": "Length of title + 1 (for null)" - }, - { - "name": "Title", - "type": "utf8-t", - "description": "Book title" - }, - { - "name": "Author Length", - "type": "ushort", - "size": 2, - "description": "Length of author + 1 (for null)" - }, - { - "name": "Author", - "type": "utf8-t", - "description": "Book author" - } - ], - "related": [ - { - "id": "0x93", - "relationship": "variant", - "note": "Old Book Header format (outgoing)" - } - ], - "source": { - "file": "Projects/UOContent/Items/Books/BookPackets.cs", - "line": 184 - } - }, - { - "id": "0x93", - "name": "Old Book Header", - "description": "Old format for book cover (fixed-size ASCII strings).", - "direction": "outgoing", - "isDynamic": false, - "size": 99, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x93", - "description": "Packet identifier" - }, - { - "name": "Book Serial", - "type": "uint", - "size": 4, - "description": "Serial of the book" - }, - { - "name": "Flags", - "type": "byte", - "size": 1, - "description": "Book flags" - }, - { - "name": "Page Count", - "type": "ushort", - "size": 2, - "description": "Number of pages" - }, - { - "name": "Title", - "type": "ascii", - "size": 60, - "description": "Book title (fixed 60 bytes)" - }, - { - "name": "Author", - "type": "ascii", - "size": 30, - "description": "Book author (fixed 30 bytes)" - } - ], - "related": [ - { - "id": "0xD4", - "relationship": "variant", - "note": "New Book Header format (outgoing)" - } - ], - "notes": "Old format used by older clients. Title and author are fixed-size ASCII." - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/bufficon.json b/docs/packets/outgoing/bufficon.json deleted file mode 100644 index a4f2dbf7d..000000000 --- a/docs/packets/outgoing/bufficon.json +++ /dev/null @@ -1,307 +0,0 @@ -{ - "category": "Buff Icon", - "packets": [ - { - "id": "0xDF", - "name": "Buff/Debuff System", - "description": "Manages buff and debuff icons displayed on the client.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Remove Buff", - "condition": "command == 0 (Remove)", - "size": 15, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "15", - "description": "Packet length" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of the mobile" - }, - { - "name": "Icon ID", - "type": "short", - "size": 2, - "description": "Buff icon ID" - }, - { - "name": "Command", - "type": "short", - "size": 2, - "value": "0x0000", - "description": "Remove command" - }, - { - "name": "Unused", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - } - ] - }, - { - "name": "Add Buff (No Args)", - "condition": "command == 1 (Add), no arguments", - "size": 46, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "46", - "description": "Packet length" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of the mobile" - }, - { - "name": "Icon ID", - "type": "short", - "size": 2, - "description": "Buff icon ID" - }, - { - "name": "Command1", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Add command" - }, - { - "name": "Unused1", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - }, - { - "name": "Icon Id2", - "type": "short", - "size": 2, - "description": "Buff icon ID (repeated)" - }, - { - "name": "Command2", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Add command (repeated)" - }, - { - "name": "Unused2", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - }, - { - "name": "Duration", - "type": "short", - "size": 2, - "description": "Duration in seconds" - }, - { - "name": "Padding", - "type": "byte[]", - "size": 3, - "description": "Padding (zeros)" - }, - { - "name": "Title Cliloc", - "type": "int", - "size": 4, - "description": "Title cliloc number" - }, - { - "name": "Secondary Cliloc", - "type": "int", - "size": 4, - "description": "Secondary cliloc number" - }, - { - "name": "Empty Args", - "type": "byte[]", - "size": 10, - "description": "Empty arguments (zeros)" - } - ] - }, - { - "name": "Add Buff (With Args)", - "condition": "command == 1 (Add), with arguments", - "size": "52 + (args.Length x 2)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of the mobile" - }, - { - "name": "Icon ID", - "type": "short", - "size": 2, - "description": "Buff icon ID" - }, - { - "name": "Command1", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Add command" - }, - { - "name": "Unused1", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - }, - { - "name": "Icon Id2", - "type": "short", - "size": 2, - "description": "Buff icon ID (repeated)" - }, - { - "name": "Command2", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Add command (repeated)" - }, - { - "name": "Unused2", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - }, - { - "name": "Duration", - "type": "short", - "size": 2, - "description": "Duration in seconds" - }, - { - "name": "Padding", - "type": "byte[]", - "size": 3, - "description": "Padding (zeros)" - }, - { - "name": "Title Cliloc", - "type": "int", - "size": 4, - "description": "Title cliloc number" - }, - { - "name": "Secondary Cliloc", - "type": "int", - "size": 4, - "description": "Secondary cliloc number" - }, - { - "name": "Unused3", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - }, - { - "name": "Has Args", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Has arguments flag" - }, - { - "name": "Unused4", - "type": "ushort", - "size": 2, - "value": "0", - "description": "Unused" - }, - { - "name": "Tab Prefix", - "type": "utf16le", - "size": 2, - "value": "\\t", - "description": "Tab character prefix" - }, - { - "name": "Arguments", - "type": "utf16le-t", - "description": "Cliloc arguments" - }, - { - "name": "Has Args2", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Has arguments flag (repeated)" - }, - { - "name": "Unused5", - "type": "ushort", - "size": 2, - "value": "0", - "description": "Unused" - } - ] - } - ], - "clientVersion": { - "classic": { - "min": "5.0.2b" - }, - "enhanced": {}, - "notes": "BuffIcon feature supported in Classic Client 5.0.2b+" - }, - "source": { - "file": "Projects/UOContent/Engines/BuffIcons/BuffIconPackets.cs", - "line": 8 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/bulletinboard.json b/docs/packets/outgoing/bulletinboard.json deleted file mode 100644 index 0059fec55..000000000 --- a/docs/packets/outgoing/bulletinboard.json +++ /dev/null @@ -1,276 +0,0 @@ -{ - "category": "Bulletin Board", - "packets": [ - { - "id": "0x71", - "name": "Bulletin Board", - "description": "Bulletin board display and message packets.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Display Board", - "condition": "command == 0x00", - "size": 38, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x71", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "38", - "description": "Packet length" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Display board command" - }, - { - "name": "Board Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bulletin board" - }, - { - "name": "Board Name", - "type": "utf8", - "size": 30, - "description": "Board name (null-padded to 30 bytes)" - } - ] - }, - { - "name": "Message Header", - "condition": "command == 0x01", - "size": "22+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x71", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x01", - "description": "Message header command" - }, - { - "name": "Board Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bulletin board" - }, - { - "name": "Message Serial", - "type": "uint", - "size": 4, - "description": "Serial of the message" - }, - { - "name": "Thread Serial", - "type": "uint", - "size": 4, - "description": "Serial of parent thread (0 if root)" - }, - { - "name": "Poster Length", - "type": "byte", - "size": 1, - "description": "Length of poster name" - }, - { - "name": "Poster", - "type": "utf8-t", - "description": "Poster name" - }, - { - "name": "Subject Length", - "type": "byte", - "size": 1, - "description": "Length of subject" - }, - { - "name": "Subject", - "type": "utf8-t", - "description": "Message subject" - }, - { - "name": "Time Length", - "type": "byte", - "size": 1, - "description": "Length of time string" - }, - { - "name": "Time", - "type": "utf8-t", - "description": "Posted time string" - } - ] - }, - { - "name": "Message Content", - "condition": "command == 0x02", - "size": "22+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x71", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x02", - "description": "Message content command" - }, - { - "name": "Board Serial", - "type": "uint", - "size": 4, - "description": "Serial of the bulletin board" - }, - { - "name": "Message Serial", - "type": "uint", - "size": 4, - "description": "Serial of the message" - }, - { - "name": "Poster Length", - "type": "byte", - "size": 1, - "description": "Length of poster name" - }, - { - "name": "Poster", - "type": "utf8-t", - "description": "Poster name" - }, - { - "name": "Subject Length", - "type": "byte", - "size": 1, - "description": "Length of subject" - }, - { - "name": "Subject", - "type": "utf8-t", - "description": "Message subject" - }, - { - "name": "Time Length", - "type": "byte", - "size": 1, - "description": "Length of time string" - }, - { - "name": "Time", - "type": "utf8-t", - "description": "Posted time string" - }, - { - "name": "Poster Body", - "type": "short", - "size": 2, - "description": "Poster body graphic" - }, - { - "name": "Poster Hue", - "type": "short", - "size": 2, - "description": "Poster body hue" - }, - { - "name": "Equip Count", - "type": "byte", - "size": 1, - "description": "Number of equipment items" - }, - { - "name": "Equipment", - "type": "loop", - "description": "Poster\u0027s equipment", - "loop": { - "countField": "equipCount", - "fields": [ - { - "name": "Item ID", - "type": "short", - "size": 2, - "description": "Equipment item graphic" - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Equipment hue" - } - ] - } - }, - { - "name": "Line Count", - "type": "byte", - "size": 1, - "description": "Number of text lines" - }, - { - "name": "Lines", - "type": "loop", - "description": "Message lines", - "loop": { - "countField": "lineCount", - "fields": [ - { - "name": "Line Length", - "type": "byte", - "size": 1, - "description": "Line length" - }, - { - "name": "Line", - "type": "utf8", - "description": "Line text with 2-byte terminator (old client bug)" - } - ] - } - } - ] - } - ], - "source": { - "file": "Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs", - "line": 168 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/chat.json b/docs/packets/outgoing/chat.json deleted file mode 100644 index 87819fb1b..000000000 --- a/docs/packets/outgoing/chat.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "category": "Chat", - "packets": [ - { - "id": "0xB2", - "name": "Chat Message", - "description": "Server sends chat system messages and commands to the client.", - "direction": "outgoing", - "isDynamic": true, - "size": "13+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xB2", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "description": "Chat command number (original number minus 20)" - }, - { - "name": "Language", - "type": "ascii", - "size": 4, - "description": "Language code (e.g., \u0027enu\u0027 for English)" - }, - { - "name": "Param 1", - "type": "utf16be-t", - "description": "First parameter (Big Endian Unicode, null-terminated)" - }, - { - "name": "Param 2", - "type": "utf16be-t", - "description": "Second parameter (Big Endian Unicode, null-terminated)" - } - ], - "related": [ - { - "id": "0xB3", - "direction": "incoming", - "relationship": "request", - "note": "Client sends Chat Action" - }, - { - "id": "0xB5", - "direction": "incoming", - "relationship": "request", - "note": "Client sends Open Chat Window Request" - } - ], - "notes": "Part of the in-game chat system. Command numbers are offset by -20 from original values.", - "source": { - "file": "Projects/UOContent/Engines/Chat/ChatPackets.cs", - "line": 104 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/combat.json b/docs/packets/outgoing/combat.json deleted file mode 100644 index c5d09cef6..000000000 --- a/docs/packets/outgoing/combat.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "category": "Combat", - "packets": [ - { - "id": "0x2F", - "name": "Swing", - "description": "Notifies client of a melee swing between two mobiles.", - "direction": "outgoing", - "isDynamic": false, - "size": 10, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x2F", - "description": "Packet identifier" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Unknown" - }, - { - "name": "Attacker Serial", - "type": "uint", - "size": 4, - "description": "Serial of attacker" - }, - { - "name": "Defender Serial", - "type": "uint", - "size": 4, - "description": "Serial of defender" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingCombatPackets.cs", - "line": 23 - } - }, - { - "id": "0x72", - "name": "Set War Mode", - "description": "Sets the client\u0027s war/peace mode state.", - "direction": "outgoing", - "isDynamic": false, - "size": 5, - "fields": [ - { - "name": "Packet ID", - "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" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingCombatPackets.cs", - "line": 40 - } - }, - { - "id": "0xAA", - "name": "Change Combatant", - "description": "Notifies client of current combat target.", - "direction": "outgoing", - "isDynamic": false, - "size": 5, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xAA", - "description": "Packet identifier" - }, - { - "name": "Combatant Serial", - "type": "uint", - "size": 4, - "description": "Serial of current combatant (0 = none)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingCombatPackets.cs", - "line": 43 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/container.json b/docs/packets/outgoing/container.json deleted file mode 100644 index f7a375753..000000000 --- a/docs/packets/outgoing/container.json +++ /dev/null @@ -1,594 +0,0 @@ -{ - "category": "Container", - "packets": [ - { - "id": "0x24", - "name": "Display Container", - "description": "Opens a container gump on the client.", - "direction": "outgoing", - "isDynamic": false, - "size": "Varies", - "variants": [ - { - "name": "Classic", - "size": 7, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x24", - "description": "Packet identifier" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of the container" - }, - { - "name": "Gump ID", - "type": "ushort", - "size": 2, - "description": "Gump graphic ID" - } - ] - }, - { - "name": "High Seas Extended", - "condition": "Client version \u003e= 7.0.9.0 (HighSeas)", - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x24", - "description": "Packet identifier" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of the container" - }, - { - "name": "Gump ID", - "type": "ushort", - "size": 2, - "description": "Gump graphic ID" - }, - { - "name": "Container Type", - "type": "short", - "size": 2, - "value": "0x007D", - "description": "Container type (125)" - } - ] - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "HighSeas (7.0.9.0+) adds containerType field" - }, - "source": { - "file": "Projects/Server/Network/Packets/OutgoingContainerPackets.cs", - "line": 108 - } - }, - { - "id": "0x25", - "name": "Container Content Update", - "description": "Updates a single item in a container.", - "direction": "outgoing", - "isDynamic": false, - "size": "Varies", - "variants": [ - { - "name": "Classic", - "size": 20, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x25", - "description": "Packet identifier" - }, - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of the item" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID" - }, - { - "name": "Item ID Offset", - "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": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of parent container" - }, - { - "name": "Hue", - "type": "ushort", - "size": 2, - "description": "Item hue" - } - ] - }, - { - "name": "Container Grid Lines", - "condition": "Client version \u003e= 6.0.1.7 (ContainerGridLines)", - "size": 21, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x25", - "description": "Packet identifier" - }, - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of the item" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID" - }, - { - "name": "Item ID Offset", - "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": "Grid Location", - "type": "byte", - "size": 1, - "description": "Grid slot position" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of parent container" - }, - { - "name": "Hue", - "type": "ushort", - "size": 2, - "description": "Item hue" - } - ] - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "ContainerGridLines (6.0.1.7+) adds gridLocation byte" - }, - "source": { - "file": "Projects/Server/Network/Packets/OutgoingContainerPackets.cs", - "line": 127 - } - }, - { - "id": "0x3C", - "name": "Container \u0026 Old Spellbook Content", - "description": "Sends full contents of a container. Also used for corpse contents and old-style spellbook content (pre-AOS clients). For AOS+ spellbooks, use 0xBF/0x1B instead.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "tags": ["Spellbook", "Corpse"], - "variants": [ - { - "name": "Classic Format", - "condition": "Client version \u003c 6.0.1.7", - "size": "5 + (itemCount x 19)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x3C", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Item Count", - "type": "ushort", - "size": 2, - "description": "Number of items" - }, - { - "name": "Items", - "type": "loop", - "description": "Item entries (19 bytes each)", - "loop": { - "countField": "itemCount", - "itemSize": 19, - "fields": [ - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of the item" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID" - }, - { - "name": "Item ID Offset", - "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": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of parent container" - }, - { - "name": "Hue", - "type": "ushort", - "size": 2, - "description": "Item hue" - } - ] - } - } - ] - }, - { - "name": "Grid Location Format", - "condition": "Client version \u003e= 6.0.1.7 (ContainerGridLines)", - "size": "5 + (itemCount x 20)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x3C", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Item Count", - "type": "ushort", - "size": 2, - "description": "Number of items" - }, - { - "name": "Items", - "type": "loop", - "description": "Item entries (20 bytes each)", - "loop": { - "countField": "itemCount", - "itemSize": 20, - "fields": [ - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of the item" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID" - }, - { - "name": "Item ID Offset", - "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": "Grid Location", - "type": "byte", - "size": 1, - "description": "Grid slot position in container" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of parent container" - }, - { - "name": "Hue", - "type": "ushort", - "size": 2, - "description": "Item hue" - } - ] - } - } - ] - } - ], - "related": [ - { - "id": "0xBF/0x1B", - "relationship": "variant", - "note": "New Spellbook Content for AOS+ clients" - }, - { - "id": "0x89", - "relationship": "related", - "note": "Corpse Equipment (layer mappings for corpse items)" - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "ContainerGridLines (6.0.1.7+) adds gridLocation byte per item" - }, - "notes": "Also used for corpse contents. Corpses are special containers that display equipped items on a body graphic. Use with 0x89 Corpse Equipment for full corpse display.", - "source": { - "file": "Projects/Server/Network/Packets/OutgoingContainerPackets.cs", - "line": 169 - } - }, - { - "id": "0xBF", - "subId": "0x1B", - "name": "New Spellbook Content", - "description": "Sends spellbook contents using AOS format with a 64-bit bitmask of known spells.", - "direction": "outgoing", - "isDynamic": false, - "size": 23, - "tags": ["Spell", "Spellbook", "Extended Commands (0xBF)"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0017", - "description": "Packet length (23)" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x001B", - "description": "Subcommand (New Spellbook Content)" - }, - { - "name": "Command", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Command (always 1)" - }, - { - "name": "Book Serial", - "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": "Spell Bits", - "type": "ulong", - "size": 8, - "description": "64-bit mask of known spells (written byte-by-byte, Little Endian)" - } - ], - "related": [ - { - "id": "0x3C", - "relationship": "variant", - "note": "Old Spellbook Content for pre-AOS clients" - } - ], - "clientVersion": { - "classic": { - "min": "5.0.0a" - }, - "enhanced": {}, - "notes": "NewSpellbook feature (Core.AOS)" - }, - "notes": "Used when Core.AOS \u0026\u0026 ns.NewSpellbook. Otherwise, old 0x3C format is used with spells as pseudo-items.", - "source": { - "file": "Projects/Server/Network/Packets/OutgoingContainerPackets.cs", - "line": 46 - } - }, - { - "id": "0xF7", - "name": "Packet Container", - "description": "Container packet for batching multiple entity packets. Used for sending groups of related entities efficiently, such as all items and mobiles visible on a boat.", - "direction": "outgoing", - "tags": ["Boat"], - "isDynamic": true, - "size": "5+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF7", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Total packet length" - }, - { - "name": "Packet Count", - "type": "ushort", - "size": 2, - "description": "Number of embedded packets" - }, - { - "name": "Packets", - "type": "array", - "description": "Embedded packets (typically 0xF3 World Entity packets)", - "loop": { - "countField": "packetCount", - "fields": [ - { - "name": "Embedded Packet", - "type": "bytes", - "size": "var", - "description": "Complete embedded packet (typically 24-26 byte 0xF3 World Entity)" - } - ] - } - } - ], - "related": [ - { - "id": "0xF3", - "relationship": "contains", - "note": "Typically contains World Entity packets" - }, - { - "id": "0xF6", - "relationship": "variant", - "note": "Used alongside Move Boat HS for boat display" - } - ], - "clientVersion": { - "classic": { - "min": "7.0.9.0" - }, - "enhanced": {}, - "notes": "HighSeas expansion feature" - }, - "notes": "Uses PacketContainerBuilder for efficient dynamic growth. Commonly used by boat system to batch all visible entities on deck. Minimum packet length is 5 bytes (header only).", - "source": { - "file": "Projects/Server/Network/Packets/PacketContainerBuilder.cs", - "line": 23 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/contextmenu.json b/docs/packets/outgoing/contextmenu.json deleted file mode 100644 index 6249e70da..000000000 --- a/docs/packets/outgoing/contextmenu.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "category": "Context Menu", - "packets": [ - { - "id": "0xBF", - "subId": "0x14", - "name": "Display Context Menu", - "description": "Displays a context menu for an entity.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Old Format", - "condition": "command == 0x01 (pre-NewHaven)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0014", - "description": "Context Menu subcommand" - }, - { - "name": "Command", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Old format command" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of the target entity" - }, - { - "name": "Entry Count", - "type": "byte", - "size": 1, - "description": "Number of menu entries" - }, - { - "name": "Entries", - "type": "loop", - "description": "Menu entries", - "loop": { - "countField": "entryCount", - "fields": [ - { - "name": "Index", - "type": "short", - "size": 2, - "description": "Entry index" - }, - { - "name": "Cliloc Offset", - "type": "ushort", - "size": 2, - "description": "Cliloc number - 3000000" - }, - { - "name": "Flags", - "type": "bitfield", - "size": 2, - "description": "Entry flags", - "flags": [ - { - "bit": "0", - "name": "Disabled", - "description": "Entry is disabled" - }, - { - "bit": "1", - "name": "Arrow", - "description": "Show arrow" - }, - { - "bit": "2", - "name": "Highlighted", - "description": "Entry is highlighted" - }, - { - "bit": "5", - "name": "Colored", - "description": "Entry uses custom color" - } - ] - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Text hue (if Colored flag set)", - "condition": "flags \u0026 0x20" - } - ] - } - } - ] - }, - { - "name": "New Format", - "condition": "command == 0x02 (NewHaven+)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0014", - "description": "Context Menu subcommand" - }, - { - "name": "Command", - "type": "short", - "size": 2, - "value": "0x0002", - "description": "New format command" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of the target entity" - }, - { - "name": "Entry Count", - "type": "byte", - "size": 1, - "description": "Number of menu entries" - }, - { - "name": "Entries", - "type": "loop", - "description": "Menu entries", - "loop": { - "countField": "entryCount", - "fields": [ - { - "name": "Cliloc Number", - "type": "int", - "size": 4, - "description": "Full cliloc number" - }, - { - "name": "Index", - "type": "short", - "size": 2, - "description": "Entry index" - }, - { - "name": "Flags", - "type": "short", - "size": 2, - "description": "Entry flags (see Old Format)" - } - ] - } - } - ] - } - ], - "related": [ - { - "id": "0xBF/0x13", - "relationship": "request", - "note": "Context Menu Request from client" - }, - { - "id": "0xBF/0x15", - "relationship": "response", - "note": "Context Menu Response from client" - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "NewHaven clients (6.0.0.0+) use command 0x02" - }, - "source": { - "file": "Projects/UOContent/Context Menus/ContextMenuSystem.cs", - "line": 142 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/corpse.json b/docs/packets/outgoing/corpse.json deleted file mode 100644 index 951fe8f09..000000000 --- a/docs/packets/outgoing/corpse.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "category": "Corpse", - "packets": [ - { - "id": "0x89", - "name": "Corpse Equipment", - "description": "Sends the equipment layer mapping for items on a corpse, including virtual hair and facial hair items.", - "direction": "outgoing", - "isDynamic": true, - "size": "8+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x89", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Corpse Serial", - "type": "uint", - "size": 4, - "description": "Serial of the corpse" - }, - { - "name": "Equipment", - "type": "loop", - "description": "Equipment layer mappings (5 bytes each, until terminator)", - "loop": { - "terminator": "Layer == 0", - "fields": [ - { - "name": "Layer", - "type": "byte", - "size": 1, - "description": "Equipment layer + 1 (0 = terminator)" - }, - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of item in this layer" - } - ] - } - }, - { - "name": "Terminator", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Layer.Invalid (0) marks end of list" - } - ], - "notes": "Layer values are offset by +1 (e.g., Layer.Hair (0x0B) is sent as 0x0C). Hair and facial hair use virtual serials.", - "related": [ - { - "id": "0x3C", - "direction": "outgoing", - "relationship": "related", - "note": "Container Content (also used for corpse items)" - } - ], - "source": { - "file": "Projects/UOContent/Items/Misc/Corpses/CorpsePackets.cs", - "line": 24 - } - } - ] -} diff --git a/docs/packets/outgoing/damage.json b/docs/packets/outgoing/damage.json deleted file mode 100644 index 24f927fbe..000000000 --- a/docs/packets/outgoing/damage.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "category": "Combat", - "packets": [ - { - "id": "0x0B", - "name": "Damage", - "description": "Shows damage dealt to a mobile (client 5.0.0a+).", - "direction": "outgoing", - "isDynamic": false, - "size": 7, - "fields": [ - { - "name": "Packet ID", - "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": { - "classic": { - "min": "5.0.0a" - }, - "enhanced": {}, - "notes": "Used by Enhanced Client (all versions) and Classic Client 5.0.0a+" - }, - "notes": "For pre-5.0.0a clients, use 0xBF/0x22 instead. Enhanced Client always uses this packet format (ushort damage allows values up to 65535).", - "source": { - "file": "Projects/Server/Network/Packets/OutgoingDamagePackets.cs", - "line": 34 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "11", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "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": { - "classic": { - "max": "5.0.0a" - }, - "notes": "For Classic Client before DamagePacket feature. Not used by Enhanced Client." - }, - "notes": "Damage is capped at 255 for old clients. Classic Client only; Enhanced Client uses 0x0B packet.", - "source": { - "file": "Projects/Server/Network/Packets/OutgoingDamagePackets.cs", - "line": 40 - } - } - ] -} diff --git a/docs/packets/outgoing/effects.json b/docs/packets/outgoing/effects.json deleted file mode 100644 index 47af65187..000000000 --- a/docs/packets/outgoing/effects.json +++ /dev/null @@ -1,459 +0,0 @@ -{ - "category": "Effects", - "packets": [ - { - "id": "0x54", - "name": "Sound Effect", - "description": "Plays a sound effect at a location.", - "direction": "outgoing", - "isDynamic": false, - "size": 12, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x54", - "description": "Packet identifier" - }, - { - "name": "Flags", - "type": "byte", - "size": 1, - "value": "0x01", - "description": "Sound flags" - }, - { - "name": "Sound ID", - "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 - } - }, - { - "id": "0x70", - "name": "Screen Effect", - "description": "Triggers a screen-wide visual effect (fade in/out).", - "direction": "outgoing", - "isDynamic": false, - "size": 28, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x70", - "description": "Packet identifier" - }, - { - "name": "Effect Type", - "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": "Fade Out", - "description": "Fade screen to black" - }, - { - "value": 1, - "name": "Fade In", - "description": "Fade screen from black" - }, - { - "value": 2, - "name": "Light Flash", - "description": "Light flash effect" - }, - { - "value": 3, - "name": "Fade In Out", - "description": "Fade out then in" - }, - { - "value": 4, - "name": "Darken Screen", - "description": "Darken screen" - } - ] - }, - { - "name": "Padding2", - "type": "byte[]", - "size": 16, - "description": "Padding (zeros)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingEffectPackets.cs", - "line": 322 - } - }, - { - "id": "0xC0", - "name": "Hued Effect", - "description": "Displays a graphical effect with hue and render mode.", - "direction": "outgoing", - "isDynamic": false, - "size": 36, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xC0", - "description": "Packet identifier" - }, - { - "name": "Effect Type", - "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": "Fixed XYZ", - "description": "Effect at fixed location" - }, - { - "value": 3, - "name": "Fixed From", - "description": "Effect attached to source" - } - ] - }, - { - "name": "Source Serial", - "type": "uint", - "size": 4, - "description": "Serial of source entity" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of target entity" - }, - { - "name": "Item ID", - "type": "short", - "size": 2, - "description": "Effect graphic ID" - }, - { - "name": "Src X", - "type": "short", - "size": 2, - "description": "Source X coordinate" - }, - { - "name": "Src Y", - "type": "short", - "size": 2, - "description": "Source Y coordinate" - }, - { - "name": "Src Z", - "type": "sbyte", - "size": 1, - "description": "Source Z coordinate" - }, - { - "name": "Dst X", - "type": "short", - "size": 2, - "description": "Destination X coordinate" - }, - { - "name": "Dst Y", - "type": "short", - "size": 2, - "description": "Destination Y coordinate" - }, - { - "name": "Dst Z", - "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": "Fixed Direction", - "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": "Render Mode", - "type": "int", - "size": 4, - "description": "Render mode" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingEffectPackets.cs", - "line": 175 - } - }, - { - "id": "0xC7", - "name": "Particle Effect", - "description": "Displays an advanced particle effect with extended parameters.", - "direction": "outgoing", - "isDynamic": false, - "size": 49, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xC7", - "description": "Packet identifier" - }, - { - "name": "Effect Type", - "type": "byte", - "size": 1, - "description": "Effect type (see 0xC0)" - }, - { - "name": "Source Serial", - "type": "uint", - "size": 4, - "description": "Serial of source entity" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of target entity" - }, - { - "name": "Item ID", - "type": "short", - "size": 2, - "description": "Effect graphic ID" - }, - { - "name": "Src X", - "type": "short", - "size": 2, - "description": "Source X coordinate" - }, - { - "name": "Src Y", - "type": "short", - "size": 2, - "description": "Source Y coordinate" - }, - { - "name": "Src Z", - "type": "sbyte", - "size": 1, - "description": "Source Z coordinate" - }, - { - "name": "Dst X", - "type": "short", - "size": 2, - "description": "Destination X coordinate" - }, - { - "name": "Dst Y", - "type": "short", - "size": 2, - "description": "Destination Y coordinate" - }, - { - "name": "Dst Z", - "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": "Fixed Direction", - "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": "Render Mode", - "type": "int", - "size": 4, - "description": "Render mode" - }, - { - "name": "Effect", - "type": "short", - "size": 2, - "description": "Particle effect ID" - }, - { - "name": "Explode Effect", - "type": "short", - "size": 2, - "description": "Explosion effect ID" - }, - { - "name": "Explode Sound", - "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 - } - } - ] -} diff --git a/docs/packets/outgoing/entity.json b/docs/packets/outgoing/entity.json deleted file mode 100644 index b0627f7e6..000000000 --- a/docs/packets/outgoing/entity.json +++ /dev/null @@ -1,403 +0,0 @@ -{ - "category": "Item", - "tags": ["Mobile"], - "packets": [ - { - "id": "0xD6", - "name": "Object Property List", - "description": "Sends the full Object Property List (tooltip) for an entity. Contains a hash for client caching and a list of localized property entries.", - "direction": "outgoing", - "isDynamic": true, - "size": "15+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD6", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Unknown1", - "type": "ushort", - "size": 2, - "value": "0x0001", - "description": "Unknown (always 1)" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Entity serial" - }, - { - "name": "Unknown2", - "type": "ushort", - "size": 2, - "value": "0x0000", - "description": "Unknown (always 0)" - }, - { - "name": "Hash", - "type": "int", - "size": 4, - "description": "XOR hash of all properties (computed with 26-bit mask)" - }, - { - "name": "Properties", - "type": "array", - "description": "Property entries, terminated by number=0", - "loop": { - "terminator": "number == 0", - "fields": [ - { - "name": "Number", - "type": "int", - "size": 4, - "description": "Cliloc number (0 = end of list)" - }, - { - "name": "String Length", - "type": "ushort", - "size": 2, - "description": "Length of arguments in bytes (0 if no arguments)" - }, - { - "name": "Arguments", - "type": "utf16le", - "size": "var", - "description": "Unicode LE string with tab-separated cliloc arguments. Length = String Length field" - } - ] - } - } - ], - "related": [ - { - "id": "0xDC", - "relationship": "notification", - "note": "OPL Info notifies client of hash change, triggering 0xD6 request" - } - ], - "clientVersion": { - "classic": { - "min": "4.0.0a" - }, - "enhanced": {}, - "notes": "AOS tooltips feature" - }, - "notes": "Hash is calculated by XORing each property\u0027s cliloc number with ((hash \u003e\u003e 31) \u0026 1) ^ (hash \u003c\u003c 1). Properties are cliloc entries with optional Unicode LE arguments separated by tabs.", - "source": { - "file": "Projects/Server/PropertyList/ObjectPropertyList.cs", - "line": 19 - } - }, - { - "id": "0x1D", - "name": "Remove Entity", - "description": "Removes an entity (item, mobile, or multi) from the client\u0027s view.", - "direction": "outgoing", - "isDynamic": false, - "size": 5, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0xDC", - "name": "OPL Info (Object Property List)", - "description": "Notifies the client of an entity\u0027s Object Property List hash. Client compares hash to cached version and requests full OPL if different.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "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" - } - ], - "related": [ - { - "id": "0xD6", - "direction": "outgoing", - "relationship": "data", - "note": "Full Object Property List packet" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingEntityPackets.cs", - "line": 33 - } - }, - { - "id": "0xF3", - "name": "World Entity (SA+)", - "description": "Unified entity packet for items, mobiles, and multis. Replaces older 0x1A World Item packet for Stygian Abyss+ clients. High Seas clients add 2 extra bytes.", - "direction": "outgoing", - "isDynamic": false, - "size": "Varies", - "variants": [ - { - "version": "Stygian Abyss", - "name": "SA Format", - "condition": "Client version 7.0.0.0 - 7.0.8.x (StygianAbyss, pre-HighSeas)", - "size": 24, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF3", - "description": "Packet identifier" - }, - { - "name": "Command", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Command (always 1)" - }, - { - "name": "Entity Type", - "type": "enum", - "size": 1, - "description": "Entity type", - "values": [ - { "value": "0", "name": "Item", "description": "World item" }, - { "value": "1", "name": "Mobile", "description": "Mobile/creature" }, - { "value": "2", "name": "Multi", "description": "Multi/structure" } - ] - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Entity serial" - }, - { - "name": "Graphic ID", - "type": "ushort", - "size": 2, - "description": "Graphic/Body ID (masked with 0x7FFF)" - }, - { - "name": "Direction", - "type": "byte", - "size": 1, - "description": "Direction (mobiles) or 0" - }, - { - "name": "Amount Min", - "type": "short", - "size": 2, - "description": "Minimum amount (items) or 1" - }, - { - "name": "Amount Max", - "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.)" - } - ] - }, - { - "version": "High Seas+", - "name": "HS Format", - "condition": "Client version \u003e= 7.0.9.0 (HighSeas)", - "size": 26, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF3", - "description": "Packet identifier" - }, - { - "name": "Command", - "type": "short", - "size": 2, - "value": "0x0001", - "description": "Command (always 1)" - }, - { - "name": "Entity Type", - "type": "enum", - "size": 1, - "description": "Entity type", - "values": [ - { "value": "0", "name": "Item", "description": "World item" }, - { "value": "1", "name": "Mobile", "description": "Mobile/creature" }, - { "value": "2", "name": "Multi", "description": "Multi/structure" } - ] - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Entity serial" - }, - { - "name": "Graphic ID", - "type": "ushort", - "size": 2, - "description": "Graphic/Body ID (masked with 0xFFFF, supports higher IDs)" - }, - { - "name": "Direction", - "type": "byte", - "size": 1, - "description": "Direction (mobiles) or 0" - }, - { - "name": "Amount Min", - "type": "short", - "size": 2, - "description": "Minimum amount (items) or 1" - }, - { - "name": "Amount Max", - "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, - "value": "0x0000", - "description": "Unknown (always 0)" - } - ] - } - ], - "related": [ - { - "id": "0x1A", - "relationship": "variant", - "note": "Legacy World Item packet for pre-SA clients" - } - ], - "clientVersion": { - "classic": { - "min": "7.0.0.0" - }, - "enhanced": {}, - "notes": "StygianAbyss expansion feature" - }, - "source": { - "file": "Projects/Server/Network/Packets/OutgoingEntityPackets.cs", - "line": 88 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/equipment.json b/docs/packets/outgoing/equipment.json deleted file mode 100644 index a86595f27..000000000 --- a/docs/packets/outgoing/equipment.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "category": "Equipment", - "packets": [ - { - "id": "0x2E", - "name": "Equip Update", - "description": "Notifies client that an item has been equipped on a mobile.", - "direction": "outgoing", - "isDynamic": false, - "size": 15, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x2E", - "description": "Packet identifier" - }, - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of the equipped item" - }, - { - "name": "Item ID", - "type": "short", - "size": 2, - "description": "Item graphic ID" - }, - { - "name": "Layer", - "type": "ushort", - "size": 2, - "description": "Equipment layer" - }, - { - "name": "Mobile Serial", - "type": "uint", - "size": 4, - "description": "Serial of the mobile wearing the item" - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Item hue (may be overridden by SolidHueOverride)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs", - "line": 86 - } - }, - { - "id": "0xBF", - "subId": "0x10", - "name": "Display Equipment Info", - "description": "Displays detailed equipment information including crafter name and magical properties.", - "direction": "outgoing", - "isDynamic": true, - "size": "17+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0010", - "description": "Display Equipment Info subcommand" - }, - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Serial of the item" - }, - { - "name": "Cliloc Number", - "type": "int", - "size": 4, - "description": "Base cliloc number for item name" - }, - { - "name": "Crafter Info", - "type": "conditional", - "description": "Crafter information (if present)", - "condition": "crafterName.Length \u003e 0", - "fields": [ - { - "name": "Crafted By", - "type": "int", - "size": 4, - "value": "-3", - "description": "Crafter marker" - }, - { - "name": "Crafter Name Length", - "type": "ushort", - "size": 2, - "description": "Length of crafter name" - }, - { - "name": "Crafter Name", - "type": "ascii", - "description": "Crafter name" - } - ] - }, - { - "name": "Unidentified", - "type": "conditional", - "description": "Unidentified marker", - "condition": "unidentified", - "fields": [ - { - "name": "Unidentified Marker", - "type": "int", - "size": 4, - "value": "-4", - "description": "Unidentified marker" - } - ] - }, - { - "name": "Attributes", - "type": "loop", - "description": "Equipment attributes", - "loop": { - "countField": "variable", - "fields": [ - { - "name": "Attribute Number", - "type": "int", - "size": 4, - "description": "Attribute cliloc number" - }, - { - "name": "Charges", - "type": "short", - "size": 2, - "description": "Charges (-1 if not applicable)" - } - ] - } - }, - { - "name": "Terminator", - "type": "int", - "size": 4, - "value": "-1", - "description": "End of attributes marker" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs", - "line": 37 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/freeshard.json b/docs/packets/outgoing/freeshard.json deleted file mode 100644 index 38bb5a6af..000000000 --- a/docs/packets/outgoing/freeshard.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "category": "FreeShard Protocol", - "packets": [ - { - "id": "0x51", - "name": "Compact Shard Stats", - "description": "Server response to compact shard stats query (0xF1/0xFE).", - "direction": "outgoing", - "isDynamic": false, - "size": 27, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x51", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x001B", - "description": "Packet length (27)" - }, - { - "name": "Clients", - "type": "int", - "size": 4, - "description": "Current client count" - }, - { - "name": "Items", - "type": "int", - "size": 4, - "description": "Total item count" - }, - { - "name": "Mobiles", - "type": "int", - "size": 4, - "description": "Total mobile count" - }, - { - "name": "Age", - "type": "uint", - "size": 4, - "description": "Server uptime in seconds" - }, - { - "name": "Memory", - "type": "long", - "size": 8, - "description": "Memory usage in bytes" - } - ], - "related": [ - { - "id": "0xF1/0xFE", - "relationship": "request", - "note": "Query Compact Shard Stats request" - } - ], - "source": { - "file": "Projects/UOContent/Network/UOGateway.cs", - "line": 60 - } - } - ] -} diff --git a/docs/packets/outgoing/gump.json b/docs/packets/outgoing/gump.json deleted file mode 100644 index 21b338ae9..000000000 --- a/docs/packets/outgoing/gump.json +++ /dev/null @@ -1,1060 +0,0 @@ -{ - "category": "Gump", - "packets": [ - { - "id": "0x8B", - "name": "Display Sign Gump", - "description": "Displays a sign gump with text to the client.", - "direction": "outgoing", - "isDynamic": true, - "size": "15+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x8B", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Sign serial" - }, - { - "name": "Gump ID", - "type": "short", - "size": 2, - "description": "Gump graphic ID" - }, - { - "name": "Unknown Length", - "type": "short", - "size": 2, - "description": "Length of unknown text + 1" - }, - { - "name": "Unknown", - "type": "ascii-t", - "description": "Unknown text" - }, - { - "name": "Caption Length", - "type": "short", - "size": 2, - "description": "Length of caption + 1" - }, - { - "name": "Caption", - "type": "ascii-t", - "description": "Caption text" - } - ], - "source": { - "file": "Projects/UOContent/Gumps/Base/OutgoingGumpPackets.cs", - "line": 58 - } - }, - { - "id": "0xBF", - "subId": "0x04", - "name": "Close Gump", - "description": "Instructs client to close a specific gump.", - "direction": "outgoing", - "isDynamic": false, - "size": 13, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "13", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0004", - "description": "Close Gump subcommand" - }, - { - "name": "Gump Type ID", - "type": "int", - "size": 4, - "description": "Gump type ID to close" - }, - { - "name": "Button ID", - "type": "int", - "size": 4, - "description": "Button ID (0 to close without response)" - } - ], - "source": { - "file": "Projects/UOContent/Gumps/Base/OutgoingGumpPackets.cs", - "line": 83 - } - }, - { - "id": "0xDD", - "name": "Dynamic Gump (Compressed)", - "description": "Sends a custom gump dialog with compressed layout and text strings. Uses raw DEFLATE compression (no zlib headers).", - "direction": "outgoing", - "isDynamic": true, - "size": "23+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDD", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Gump serial (unique per gump instance)" - }, - { - "name": "Type ID", - "type": "uint", - "size": 4, - "description": "Gump type ID (identifies the gump class)" - }, - { - "name": "X", - "type": "int", - "size": 4, - "description": "Screen X position" - }, - { - "name": "Y", - "type": "int", - "size": 4, - "description": "Screen Y position" - }, - { - "name": "Layout Compressed Length", - "type": "int", - "size": 4, - "description": "Compressed layout data length (includes +4)" - }, - { - "name": "Layout Uncompressed Length", - "type": "int", - "size": 4, - "description": "Uncompressed layout data length" - }, - { - "name": "Layout Data", - "type": "bytes", - "size": "var", - "description": "DEFLATE compressed layout commands (ASCII, no zlib header/footer). Length = Layout Compressed Length - 4" - }, - { - "name": "String Count", - "type": "int", - "size": 4, - "description": "Number of text strings" - }, - { - "name": "Strings Compressed Length", - "type": "int", - "size": 4, - "description": "Compressed strings data length (includes +4)" - }, - { - "name": "Strings Uncompressed Length", - "type": "int", - "size": 4, - "description": "Uncompressed strings data length" - }, - { - "name": "Strings Data", - "type": "bytes", - "size": "var", - "description": "DEFLATE compressed strings (no zlib header/footer). Length = Strings Compressed Length - 4" - } - ], - "compression": { - "algorithm": "DEFLATE (raw)", - "notes": "Uses libdeflate. NO zlib header (0x78 0x9C) or footer (adler32 checksum). Layout and strings are compressed separately." - }, - "layoutFormat": { - "description": "Layout is a custom ASCII text format. Each command is brace-wrapped: { command param1 param2 ... }", - "encoding": "ASCII (arguments must be ASCII characters only)", - "commands": [ - { - "name": "Noclose", - "description": "Prevent closing via right-click or ESC" - }, - { - "name": "Nomove", - "description": "Prevent dragging the gump" - }, - { - "name": "Noresize", - "description": "Prevent resizing (Enhanced Client)", - "tags": ["EC"], - "notes": "Enhanced Client only" - }, - { - "name": "Nodispose", - "description": "Prevent server-side disposal" - }, - { - "name": "Page", - "description": "Define page (0=base visible on all pages)", - "args": [ - { - "name": "N", - "type": "int", - "description": "Page number (0 = always visible)" - } - ] - }, - { - "name": "Group", - "description": "Radio button group ID", - "args": [ - { - "name": "Group ID", - "type": "int", - "description": "Group identifier for radio buttons" - } - ] - }, - { - "name": "Resizepic", - "description": "Resizable background panel (9-slice)", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Gump ID", - "type": "int", - "description": "Gump graphic ID for the background" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - } - ] - }, - { - "name": "Gumppic", - "description": "Static gump image", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Gump ID", - "type": "int", - "description": "Gump graphic ID" - }, - { - "name": "Hue=N", - "type": "int", - "description": "Optional hue override", - "optional": true - }, - { - "name": "Class=S", - "type": "string", - "description": "Optional CSS class (Enhanced Client)", - "optional": true - } - ] - }, - { - "name": "Gumppictiled", - "description": "Tiled gump image", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - }, - { - "name": "Gump ID", - "type": "int", - "description": "Gump graphic ID to tile" - } - ] - }, - { - "name": "Tilepic", - "description": "Item/tile graphic from art.mul", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Item ID", - "type": "int", - "description": "Item graphic ID from art.mul" - } - ] - }, - { - "name": "Tilepichue", - "description": "Item graphic with hue", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Item ID", - "type": "int", - "description": "Item graphic ID" - }, - { - "name": "Hue", - "type": "int", - "description": "Color hue" - } - ] - }, - { - "name": "Picinpic", - "description": "Cropped sprite from gump (sprite image rendering)", - "tags": ["EC"], - "notes": "Also known as GumpSpriteImage. EC-compatible.", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Gump ID", - "type": "int", - "description": "Gump graphic ID" - }, - { - "name": "W", - "type": "int", - "description": "Display width" - }, - { - "name": "H", - "type": "int", - "description": "Display height" - }, - { - "name": "Sprite X", - "type": "int", - "description": "X offset within sprite" - }, - { - "name": "Sprite Y", - "type": "int", - "description": "Y offset within sprite" - } - ] - }, - { - "name": "Checkertrans", - "description": "Checkerboard transparency region", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - } - ] - }, - { - "name": "Text", - "description": "Static text label", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Hue", - "type": "int", - "description": "Text color hue" - }, - { - "name": "String Index", - "type": "int", - "description": "Index into strings array" - } - ] - }, - { - "name": "Croppedtext", - "description": "Cropped/clipped text", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Crop width" - }, - { - "name": "H", - "type": "int", - "description": "Crop height" - }, - { - "name": "Hue", - "type": "int", - "description": "Text color hue" - }, - { - "name": "String Index", - "type": "int", - "description": "Index into strings array" - } - ] - }, - { - "name": "Htmlgump", - "description": "HTML text area", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - }, - { - "name": "String Index", - "type": "int", - "description": "Index into strings array (HTML content)" - }, - { - "name": "BG", - "type": "bool", - "description": "Display background panel" - }, - { - "name": "Scroll", - "type": "bool", - "description": "Display scrollbar" - } - ] - }, - { - "name": "Xmfhtmlgump", - "description": "Localized HTML from cliloc", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - }, - { - "name": "Cliloc", - "type": "int", - "description": "Cliloc string number" - }, - { - "name": "BG", - "type": "bool", - "description": "Display background panel" - }, - { - "name": "Scroll", - "type": "bool", - "description": "Display scrollbar" - } - ] - }, - { - "name": "Xmfhtmlgumpcolor", - "description": "Localized HTML with color", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - }, - { - "name": "Cliloc", - "type": "int", - "description": "Cliloc string number" - }, - { - "name": "BG", - "type": "bool", - "description": "Display background panel" - }, - { - "name": "Scroll", - "type": "bool", - "description": "Display scrollbar" - }, - { - "name": "Color", - "type": "int", - "description": "Text color (RGB format)" - } - ] - }, - { - "name": "Xmfhtmltok", - "description": "Localized HTML with arguments", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - }, - { - "name": "BG", - "type": "bool", - "description": "Display background panel" - }, - { - "name": "Scroll", - "type": "bool", - "description": "Display scrollbar" - }, - { - "name": "Color", - "type": "int", - "description": "Text color (RGB format)" - }, - { - "name": "Cliloc", - "type": "int", - "description": "Cliloc string number" - }, - { - "name": "@Args@", - "type": "string", - "description": "Tab-separated cliloc arguments" - } - ] - }, - { - "name": "Button", - "description": "Clickable button", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Normal ID", - "type": "int", - "description": "Gump ID for normal state" - }, - { - "name": "Pressed ID", - "type": "int", - "description": "Gump ID for pressed state" - }, - { - "name": "Type", - "type": "enum", - "description": "Button type", - "values": [ - { "value": "0", "name": "PageChange", "description": "Navigate to different page" }, - { "value": "1", "name": "ServerReply", "description": "Send response to server" } - ] - }, - { - "name": "Param", - "type": "int", - "description": "Page number (Type=0) or unused (Type=1)" - }, - { - "name": "Button ID", - "type": "int", - "description": "Button ID sent to server on click" - } - ] - }, - { - "name": "Buttontileart", - "description": "Button with item overlay", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Normal ID", - "type": "int", - "description": "Gump ID for normal state" - }, - { - "name": "Pressed ID", - "type": "int", - "description": "Gump ID for pressed state" - }, - { - "name": "Type", - "type": "enum", - "description": "Button type", - "values": [ - { "value": "0", "name": "PageChange", "description": "Navigate to different page" }, - { "value": "1", "name": "ServerReply", "description": "Send response to server" } - ] - }, - { - "name": "Param", - "type": "int", - "description": "Page number (Type=0) or unused (Type=1)" - }, - { - "name": "Button ID", - "type": "int", - "description": "Button ID sent to server on click" - }, - { - "name": "Item ID", - "type": "int", - "description": "Item graphic ID to overlay" - }, - { - "name": "Hue", - "type": "int", - "description": "Item hue" - }, - { - "name": "W", - "type": "int", - "description": "Item display width" - }, - { - "name": "H", - "type": "int", - "description": "Item display height" - } - ] - }, - { - "name": "Checkbox", - "description": "Checkbox toggle", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Inactive ID", - "type": "int", - "description": "Gump ID when unchecked" - }, - { - "name": "Active ID", - "type": "int", - "description": "Gump ID when checked" - }, - { - "name": "State", - "type": "bool", - "description": "Initial checked state" - }, - { - "name": "Switch ID", - "type": "int", - "description": "Switch ID sent to server" - } - ] - }, - { - "name": "Radio", - "description": "Radio button (use with group)", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "Inactive ID", - "type": "int", - "description": "Gump ID when unselected" - }, - { - "name": "Active ID", - "type": "int", - "description": "Gump ID when selected" - }, - { - "name": "State", - "type": "bool", - "description": "Initial selected state" - }, - { - "name": "Switch ID", - "type": "int", - "description": "Switch ID sent to server" - } - ] - }, - { - "name": "Textentry", - "description": "Text input field", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - }, - { - "name": "Hue", - "type": "int", - "description": "Text color hue" - }, - { - "name": "Entry ID", - "type": "int", - "description": "Entry ID for server response" - }, - { - "name": "String Index", - "type": "int", - "description": "Index into strings array (default text)" - } - ] - }, - { - "name": "Textentrylimited", - "description": "Text input with max length", - "args": [ - { - "name": "X", - "type": "int", - "description": "X coordinate" - }, - { - "name": "Y", - "type": "int", - "description": "Y coordinate" - }, - { - "name": "W", - "type": "int", - "description": "Width in pixels" - }, - { - "name": "H", - "type": "int", - "description": "Height in pixels" - }, - { - "name": "Hue", - "type": "int", - "description": "Text color hue" - }, - { - "name": "Entry ID", - "type": "int", - "description": "Entry ID for server response" - }, - { - "name": "String Index", - "type": "int", - "description": "Index into strings array (default text)" - }, - { - "name": "Max Len", - "type": "int", - "description": "Maximum character length" - } - ] - }, - { - "name": "Tooltip", - "description": "Tooltip on previous element (GumpTooltip)", - "tags": ["EC"], - "notes": "EC-compatible tooltip display.", - "args": [ - { - "name": "Cliloc", - "type": "int", - "description": "Cliloc string number for tooltip" - }, - { - "name": "@Args@", - "type": "string", - "description": "Optional cliloc arguments", - "optional": true - } - ] - }, - { - "name": "Itemproperty", - "description": "Display item's OPL tooltip (GumpItemProperty)", - "tags": ["EC"], - "notes": "EC-compatible property display for items.", - "args": [ - { - "name": "Serial", - "type": "int", - "description": "Item serial number" - } - ] - }, - { - "name": "Mastergump", - "description": "Master gump ID override", - "args": [ - { - "name": "Gump ID", - "type": "int", - "description": "Master gump identifier" - } - ] - }, - { - "name": "Echandleinput", - "description": "EC-specific input handler", - "tags": ["EC"], - "notes": "Enhanced Client only" - } - ] - }, - "stringsFormat": { - "description": "Array of UTF-16 BE encoded strings for text/textentry elements", - "encoding": "UTF-16 Big Endian", - "entryFormat": [ - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "String length in characters (Big Endian)" - }, - { - "name": "Text", - "type": "utf16be", - "size": "var", - "description": "UTF-16 BE encoded text. Length = Length field * 2 bytes" - } - ] - }, - "related": [ - { - "id": "0xB1", - "relationship": "response", - "note": "Gump Response - client reply to button/checkbox/text" - } - ], - "clientVersion": { - "classic": { - "min": "3.0.0" - }, - "enhanced": {}, - "notes": "Compressed gumps supported since Classic Client 3.0.0" - }, - "notes": "Layout uses ASCII encoding only. The compressed lengths include a +4 offset. Decompression produces: layout as ASCII text, strings as length-prefixed UTF-16 BE entries.", - "source": { - "file": "Projects/UOContent/Gumps/Base/DynamicGump.cs", - "line": 105 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/house.json b/docs/packets/outgoing/house.json deleted file mode 100644 index 3fff90eed..000000000 --- a/docs/packets/outgoing/house.json +++ /dev/null @@ -1,309 +0,0 @@ -{ - "category": "House", - "packets": [ - { - "id": "0xD8", - "name": "House Design State Detailed", - "description": "Sends detailed house customization design data. Contains compressed plane data organized by floor level and component type. Tiles are encoded using grid-based or coordinate-based formats depending on their Z-height.", - "direction": "outgoing", - "isDynamic": true, - "size": "18+", - "tags": ["House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD8", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Compression Type", - "type": "byte", - "size": 1, - "value": "0x03", - "description": "Compression type (always 3 = compressed)" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Unknown (always 0)" - }, - { - "name": "House Serial", - "type": "uint", - "size": 4, - "description": "Serial of the house foundation" - }, - { - "name": "Revision", - "type": "int", - "size": 4, - "description": "Design revision number" - }, - { - "name": "Tile Count", - "type": "ushort", - "size": 2, - "description": "Total number of tiles in the design" - }, - { - "name": "Buffer Length", - "type": "ushort", - "size": 2, - "description": "Length of remaining data (plane count + all plane sections)" - }, - { - "name": "Plane Count", - "type": "byte", - "size": 1, - "description": "Number of plane/buffer sections that follow" - }, - { - "name": "Plane Sections", - "type": "array", - "description": "Each section has a 4-byte header followed by compressed tile data", - "loop": { - "countField": "Plane Count", - "fields": [ - { - "name": "Section Header", - "type": "uint", - "size": 4, - "description": "Packed header: bits 28-31=mode, bits 24-27=planeZ, bits 16-23+(bits 4-7<<8)=decompLen, bits 8-15+(bits 0-3<<8)=compLen" - }, - { - "name": "Compressed Data", - "type": "bytes", - "size": "var", - "description": "DEFLATE compressed tile data (length from header)" - } - ] - } - } - ], - "planeFormat": { - "description": "Tiles are organized into planes based on Z-height. Planes 0-8 use grid encoding; planes 9+ use explicit coordinates for overflow items.", - "headerDecoding": { - "mode": "(header >> 28) & 0x0F", - "planeZ": "(header >> 24) & 0x0F", - "decompLen": "((header & 0xFF0000) >> 16) | ((header & 0xF0) << 4)", - "compLen": "((header & 0xFF00) >> 8) | ((header & 0x0F) << 8)" - }, - "planeZMapping": [ - { "plane": 0, "z": 0, "description": "Ground floor" }, - { "plane": 1, "z": 7, "description": "1st storey (floor items)" }, - { "plane": 2, "z": 27, "description": "2nd storey (floor items)" }, - { "plane": 3, "z": 47, "description": "3rd storey (floor items)" }, - { "plane": 4, "z": 67, "description": "4th storey (floor items)" }, - { "plane": "5-8", "z": "7/27/47/67", "description": "Non-floor items per storey" }, - { "plane": "9+", "z": "varies", "description": "Overflow/stair buffers (explicit coords)" } - ], - "encodingModes": [ - { - "mode": 0, - "name": "Full Coordinates", - "bytesPerTile": 5, - "format": "ushort itemId, sbyte x, sbyte y, sbyte z", - "description": "Used for overflow buffers with non-standard Z heights" - }, - { - "mode": 1, - "name": "XY Coordinates", - "bytesPerTile": 4, - "format": "ushort itemId, sbyte x, sbyte y", - "description": "Z calculated: ((planeZ - 1) % 4) * 20 + 7" - }, - { - "mode": 2, - "name": "Grid-Based", - "bytesPerTile": 2, - "format": "ushort itemId (0x0000 = empty)", - "description": "X,Y from grid index: x = i / gridHeight, y = i % gridHeight" - } - ], - "gridSizes": [ - { "plane": 0, "width": "width", "height": "height", "notes": "Full foundation footprint" }, - { "plane": "1-4", "width": "width - 1", "height": "height - 2", "notes": "Interior (floor items), offset by (1,1)" }, - { "plane": "5-8", "width": "width", "height": "height - 1", "notes": "Interior (non-floor items)" } - ] - }, - "compression": { - "algorithm": "DEFLATE", - "notes": "Raw DEFLATE compression (no zlib header/footer). Each plane buffer compressed independently. Max 750 items per overflow buffer (splits into multiple buffers if exceeded)." - }, - "related": [ - { - "id": "0xBF/0x1D", - "relationship": "related", - "note": "Design State General provides revision info only" - }, - { - "id": "0xBF/0x20", - "relationship": "related", - "note": "Begin/End House Customization commands" - } - ], - "clientVersion": { - "classic": { - "min": "4.0.0a" - }, - "enhanced": {}, - "notes": "AOS House Customization feature" - }, - "source": { - "file": "Projects/UOContent/Multis/Houses/HousePackets.cs", - "line": 93 - } - }, - { - "id": "0xBF", - "subId": "0x1D", - "name": "Design State General", - "description": "Sends house design revision information. Client requests full details if revision differs.", - "direction": "outgoing", - "isDynamic": false, - "size": 13, - "tags": ["Extended Commands (0xBF)", "House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x000D", - "description": "Packet length (13)" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x001D", - "description": "Design State General subcommand" - }, - { - "name": "House Serial", - "type": "uint", - "size": 4, - "description": "Serial of the house" - }, - { - "name": "Revision", - "type": "int", - "size": 4, - "description": "Design revision number" - } - ], - "related": [ - { - "id": "0xD8", - "relationship": "related", - "note": "Full design details requested if revision differs" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HousePackets.cs", - "line": 72 - } - }, - { - "id": "0xBF", - "subId": "0x20", - "name": "Begin House Customization", - "description": "Notifies client to enter house customization mode.", - "direction": "outgoing", - "isDynamic": false, - "size": 17, - "tags": ["Extended Commands (0xBF)", "House"], - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0011", - "description": "Packet length (17)" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0020", - "description": "House Customization subcommand" - }, - { - "name": "House Serial", - "type": "uint", - "size": 4, - "description": "Serial of the house" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x04", - "description": "Begin customization command" - }, - { - "name": "Unknown 1", - "type": "ushort", - "size": 2, - "value": "0x0000", - "description": "Unknown (always 0)" - }, - { - "name": "Unknown 2", - "type": "ushort", - "size": 2, - "value": "0xFFFF", - "description": "Unknown (always 0xFFFF)" - }, - { - "name": "Unknown 3", - "type": "ushort", - "size": 2, - "value": "0xFFFF", - "description": "Unknown (always 0xFFFF)" - }, - { - "name": "Unknown 4", - "type": "byte", - "size": 1, - "value": "0xFF", - "description": "Unknown (always 0xFF)" - } - ], - "related": [ - { - "id": "0xBF/0x20", - "relationship": "variant", - "note": "End House Customization uses command 0x05" - } - ], - "source": { - "file": "Projects/UOContent/Multis/Houses/HousePackets.cs", - "line": 30 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/items.json b/docs/packets/outgoing/items.json deleted file mode 100644 index 2c9f6e0f7..000000000 --- a/docs/packets/outgoing/items.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "category": "Items", - "packets": [ - { - "id": "0x1A", - "name": "World Item", - "description": "Displays an item in the world (pre-Stygian Abyss clients).", - "direction": "outgoing", - "isDynamic": true, - "size": "14+", - "fields": [ - { - "name": "Packet ID", - "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": "Item ID", - "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 \u0026 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 \u0026 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 \u0026 0x8000" - }, - { - "name": "Flags", - "type": "byte", - "size": 1, - "description": "Packet flags (if y bit 14 set)", - "condition": "y \u0026 0x4000" - } - ], - "related": [ - { - "id": "0xF3", - "relationship": "variant", - "note": "World Entity packet for SA+ clients" - } - ], - "notes": "For Stygian Abyss+ clients, use 0xF3 World Entity instead.", - "clientVersion": { - "classic": { - "max": "6.0.14.2" - }, - "notes": "Replaced by 0xF3 for SA+ clients" - }, - "source": { - "file": "Projects/Server/Network/Packets/OutgoingItemPackets.cs", - "line": 24 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/light.json b/docs/packets/outgoing/light.json deleted file mode 100644 index 0958046b4..000000000 --- a/docs/packets/outgoing/light.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "category": "Light", - "packets": [ - { - "id": "0x4E", - "name": "Personal Light Level", - "description": "Sets the light level for a specific entity.", - "direction": "outgoing", - "isDynamic": false, - "size": 6, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0x4F", - "name": "Global Light Level", - "description": "Sets the global ambient light level for the client.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "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 - } - } - ] -} diff --git a/docs/packets/outgoing/mahjong.json b/docs/packets/outgoing/mahjong.json deleted file mode 100644 index 5b9f3b9a9..000000000 --- a/docs/packets/outgoing/mahjong.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "category": "Mahjong", - "packets": [ - { - "id": "0xDA", - "subId": "0x19", - "name": "Mahjong Join Game", - "description": "Notifies client to open the Mahjong game interface.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0009", - "description": "Packet length (9)" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "value": "0x0019", - "description": "Join Game command" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 288 - } - }, - { - "id": "0xDA", - "subId": "0x03", - "name": "Mahjong Tile Info", - "description": "Sends information about a single Mahjong tile.", - "direction": "outgoing", - "isDynamic": false, - "size": 18, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0012", - "description": "Packet length (18)" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "value": "0x0003", - "description": "Tile Info command" - }, - { - "name": "Tile Number", - "type": "byte", - "size": 1, - "description": "Tile index number" - }, - { - "name": "Tile Value", - "type": "byte", - "size": 1, - "description": "Tile face value (0 if hidden)" - }, - { - "name": "Y Position", - "type": "short", - "size": 2, - "description": "Tile Y coordinate" - }, - { - "name": "X Position", - "type": "short", - "size": 2, - "description": "Tile X coordinate" - }, - { - "name": "Stack Level", - "type": "byte", - "size": 1, - "description": "Stack level for overlapping tiles" - }, - { - "name": "Direction", - "type": "byte", - "size": 1, - "description": "Tile direction (0=Up, 1=Left, 2=Down, 3=Right)" - }, - { - "name": "Flipped", - "type": "byte", - "size": 1, - "description": "0x10 if flipped/face-up, 0x00 if face-down" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 362 - } - }, - { - "id": "0xDA", - "subId": "0x04", - "name": "Mahjong Tiles Info", - "description": "Sends information about all tiles in the Mahjong game.", - "direction": "outgoing", - "isDynamic": true, - "size": "11+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "value": "0x0004", - "description": "Tiles Info command" - }, - { - "name": "Tile Count", - "type": "short", - "size": 2, - "description": "Number of tiles" - }, - { - "name": "Tiles", - "type": "loop", - "description": "Tile data for each tile", - "loop": { - "countField": "Tile Count", - "fields": [ - { - "name": "Tile Number", - "type": "byte", - "size": 1, - "description": "Tile index number" - }, - { - "name": "Tile Value", - "type": "byte", - "size": 1, - "description": "Tile face value (0 if hidden)" - }, - { - "name": "Y Position", - "type": "short", - "size": 2, - "description": "Tile Y coordinate" - }, - { - "name": "X Position", - "type": "short", - "size": 2, - "description": "Tile X coordinate" - }, - { - "name": "Stack Level", - "type": "byte", - "size": 1, - "description": "Stack level" - }, - { - "name": "Direction", - "type": "byte", - "size": 1, - "description": "Tile direction" - }, - { - "name": "Flipped", - "type": "byte", - "size": 1, - "description": "0x10 if flipped, 0x00 otherwise" - } - ] - } - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 408 - } - }, - { - "id": "0xDA", - "subId": "0x02", - "name": "Mahjong Players Info", - "description": "Sends information about all players in the Mahjong game.", - "direction": "outgoing", - "isDynamic": true, - "size": "11+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "value": "0x0002", - "description": "Players Info command" - }, - { - "name": "Seat Count", - "type": "ushort", - "size": 2, - "description": "Number of seats with data" - }, - { - "name": "Players", - "type": "loop", - "description": "Player data for each seat", - "loop": { - "countField": "Seat Count", - "fields": [ - { - "name": "Player Serial", - "type": "uint", - "size": 4, - "description": "Serial of player (0 if empty)" - }, - { - "name": "Dealer Flag", - "type": "byte", - "size": 1, - "description": "1=Dealer, 2=Not dealer" - }, - { - "name": "Position", - "type": "byte", - "size": 1, - "description": "Seat position index" - }, - { - "name": "Score", - "type": "int", - "size": 4, - "description": "Player\u0027s current score" - }, - { - "name": "Reserved", - "type": "short", - "size": 2, - "value": "0", - "description": "Reserved (always 0)" - }, - { - "name": "Reserved 2", - "type": "byte", - "size": 1, - "value": "0", - "description": "Reserved (always 0)" - }, - { - "name": "Public Hand", - "type": "bool", - "size": 1, - "description": "True if hand is visible to others" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Player name" - }, - { - "name": "Empty Seat", - "type": "bool", - "size": 1, - "description": "True if seat is empty or not in game" - } - ] - } - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 304 - } - }, - { - "id": "0xDA", - "subId": "0x05", - "name": "Mahjong General Info", - "description": "Sends general game state including dice values, dealer indicator, and wall break position.", - "direction": "outgoing", - "isDynamic": false, - "size": 25, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0019", - "description": "Packet length (25)" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "value": "0x0005", - "description": "General Info command" - }, - { - "name": "Reserved", - "type": "short", - "size": 2, - "value": "0", - "description": "Reserved" - }, - { - "name": "Reserved 2", - "type": "byte", - "size": 1, - "value": "0", - "description": "Reserved" - }, - { - "name": "Options", - "type": "byte", - "size": 1, - "description": "Bit 0: Show Scores, Bit 1: Spectator Vision" - }, - { - "name": "Dice 1", - "type": "byte", - "size": 1, - "description": "First dice value" - }, - { - "name": "Dice 2", - "type": "byte", - "size": 1, - "description": "Second dice value" - }, - { - "name": "Dealer Wind", - "type": "enum", - "size": 1, - "description": "Dealer indicator wind direction", - "values": [ - { "value": "0", "name": "North", "description": "North wind" }, - { "value": "1", "name": "East", "description": "East wind" }, - { "value": "2", "name": "South", "description": "South wind" }, - { "value": "3", "name": "West", "description": "West wind" } - ] - }, - { - "name": "Dealer Y", - "type": "short", - "size": 2, - "description": "Dealer indicator Y position" - }, - { - "name": "Dealer X", - "type": "short", - "size": 2, - "description": "Dealer indicator X position" - }, - { - "name": "Dealer Direction", - "type": "byte", - "size": 1, - "description": "Dealer indicator direction" - }, - { - "name": "Wall Break Y", - "type": "short", - "size": 2, - "description": "Wall break indicator Y position" - }, - { - "name": "Wall Break X", - "type": "short", - "size": 2, - "description": "Wall break indicator X position" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 461 - } - }, - { - "id": "0xDA", - "subId": "0x1A", - "name": "Mahjong Relieve", - "description": "Notifies client to close the Mahjong game interface.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xDA", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0009", - "description": "Packet length (9)" - }, - { - "name": "Game Serial", - "type": "uint", - "size": 4, - "description": "Serial of the Mahjong game" - }, - { - "name": "Command", - "type": "ushort", - "size": 2, - "value": "0x001A", - "description": "Relieve command" - } - ], - "source": { - "file": "Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs", - "line": 504 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/map.json b/docs/packets/outgoing/map.json deleted file mode 100644 index e9e77376b..000000000 --- a/docs/packets/outgoing/map.json +++ /dev/null @@ -1,427 +0,0 @@ -{ - "category": "Map", - "packets": [ - { - "id": "0xC6", - "name": "Invalid Map", - "description": "Notifies client that the current map is invalid.", - "direction": "outgoing", - "isDynamic": false, - "size": 1, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xC6", - "description": "Packet identifier" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMapPackets.cs", - "line": 53 - } - }, - { - "id": "0xBF", - "subId": "0x08", - "name": "Map Change", - "description": "Notifies client of a facet/map change.", - "direction": "outgoing", - "isDynamic": false, - "size": 6, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0006", - "description": "Packet length (6)" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0008", - "description": "Map Change subcommand" - }, - { - "name": "Map ID", - "type": "enum", - "enumType": "sequential", - "size": 1, - "description": "Map/Facet ID", - "values": [ - { - "value": 0, - "name": "Felucca", - "description": "Felucca facet" - }, - { - "value": 1, - "name": "Trammel", - "description": "Trammel facet" - }, - { - "value": 2, - "name": "Ilshenar", - "description": "Ilshenar facet" - }, - { - "value": 3, - "name": "Malas", - "description": "Malas facet" - }, - { - "value": 4, - "name": "Tokuno", - "description": "Tokuno Islands facet" - }, - { - "value": 5, - "name": "Ter Mur", - "description": "Ter Mur facet" - } - ] - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMapPackets.cs", - "line": 55 - } - }, - { - "id": "0xBF", - "subId": "0x18", - "name": "Map Patches", - "description": "Sends map patch information for static and land blocks.", - "direction": "outgoing", - "isDynamic": false, - "size": 41, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0029", - "description": "Packet length (41)" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0018", - "description": "Map Patches subcommand" - }, - { - "name": "Map Count", - "type": "int", - "size": 4, - "value": "4", - "description": "Number of maps (always 4)" - }, - { - "name": "Patches", - "type": "loop", - "description": "Patch counts for each map (Felucca, Trammel, Ilshenar, Malas)", - "loop": { - "countField": "4", - "fields": [ - { - "name": "Static Blocks", - "type": "int", - "size": 4, - "description": "Number of patched static blocks" - }, - { - "name": "Land Blocks", - "type": "int", - "size": 4, - "description": "Number of patched land blocks" - } - ] - } - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMapPackets.cs", - "line": 25 - } - }, - { - "id": "0x56", - "name": "Map Command", - "description": "Server sends map pin commands to update the client\u0027s map display.", - "direction": "outgoing", - "isDynamic": false, - "size": 11, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x56", - "description": "Packet identifier" - }, - { - "name": "Map Serial", - "type": "uint", - "size": 4, - "description": "Serial of the map item" - }, - { - "name": "Command", - "type": "enum", - "size": 1, - "description": "Map command type", - "values": [ - { "value": "1", "name": "AddPin", "description": "Add a pin to the map" }, - { "value": "5", "name": "DisplayMap", "description": "Display the map to client" }, - { "value": "7", "name": "SetEditable", "description": "Set map editable state" } - ] - }, - { - "name": "Editable", - "type": "bool", - "size": 1, - "description": "True if map is editable (for command 7)" - }, - { - "name": "X", - "type": "short", - "size": 2, - "description": "X coordinate of pin" - }, - { - "name": "Y", - "type": "short", - "size": 2, - "description": "Y coordinate of pin" - } - ], - "related": [ - { - "id": "0x56", - "direction": "incoming", - "relationship": "related", - "note": "Client map pin commands" - }, - { - "id": "0x90", - "relationship": "related", - "note": "Map Details packet (old)" - }, - { - "id": "0xF5", - "relationship": "related", - "note": "Map Details packet (new)" - } - ], - "source": { - "file": "Projects/UOContent/Items/Maps/MapItemPackets.cs", - "line": 106 - } - }, - { - "id": "0x90", - "name": "Map Details", - "description": "Sends map details including bounds, dimensions, and graphic ID. Pre-NewCharacterList clients.", - "direction": "outgoing", - "isDynamic": false, - "size": 19, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x90", - "description": "Packet identifier" - }, - { - "name": "Map Serial", - "type": "uint", - "size": 4, - "description": "Serial of the map item" - }, - { - "name": "Graphic ID", - "type": "short", - "size": 2, - "value": "0x139D", - "description": "Map gump graphic ID" - }, - { - "name": "Start X", - "type": "short", - "size": 2, - "description": "Map bounds start X coordinate" - }, - { - "name": "Start Y", - "type": "short", - "size": 2, - "description": "Map bounds start Y coordinate" - }, - { - "name": "End X", - "type": "short", - "size": 2, - "description": "Map bounds end X coordinate" - }, - { - "name": "End Y", - "type": "short", - "size": 2, - "description": "Map bounds end Y coordinate" - }, - { - "name": "Width", - "type": "short", - "size": 2, - "description": "Map width in pixels" - }, - { - "name": "Height", - "type": "short", - "size": 2, - "description": "Map height in pixels" - } - ], - "related": [ - { - "id": "0x56", - "direction": "both", - "relationship": "related", - "note": "Map pin commands (client and server)" - }, - { - "id": "0xF5", - "relationship": "variant", - "note": "New Map Details for NewCharacterList clients" - } - ], - "source": { - "file": "Projects/UOContent/Items/Maps/MapItemPackets.cs", - "line": 78 - } - }, - { - "id": "0xF5", - "name": "Map Details (New)", - "description": "Sends map details for NewCharacterList clients. Includes facet ID.", - "direction": "outgoing", - "isDynamic": false, - "size": 21, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF5", - "description": "Packet identifier" - }, - { - "name": "Map Serial", - "type": "uint", - "size": 4, - "description": "Serial of the map item" - }, - { - "name": "Graphic ID", - "type": "short", - "size": 2, - "value": "0x139D", - "description": "Map gump graphic ID" - }, - { - "name": "Start X", - "type": "short", - "size": 2, - "description": "Map bounds start X coordinate" - }, - { - "name": "Start Y", - "type": "short", - "size": 2, - "description": "Map bounds start Y coordinate" - }, - { - "name": "End X", - "type": "short", - "size": 2, - "description": "Map bounds end X coordinate" - }, - { - "name": "End Y", - "type": "short", - "size": 2, - "description": "Map bounds end Y coordinate" - }, - { - "name": "Width", - "type": "short", - "size": 2, - "description": "Map width in pixels" - }, - { - "name": "Height", - "type": "short", - "size": 2, - "description": "Map height in pixels" - }, - { - "name": "Facet ID", - "type": "enum", - "size": 2, - "description": "Map facet/world identifier", - "values": [ - { "value": "0", "name": "Felucca", "description": "Felucca facet" }, - { "value": "1", "name": "Trammel", "description": "Trammel facet" }, - { "value": "2", "name": "Ilshenar", "description": "Ilshenar facet" }, - { "value": "3", "name": "Malas", "description": "Malas facet" }, - { "value": "4", "name": "Tokuno", "description": "Tokuno Islands" }, - { "value": "5", "name": "TerMur", "description": "Ter Mur facet" } - ] - } - ], - "related": [ - { - "id": "0x56", - "direction": "both", - "relationship": "related", - "note": "Map pin commands (client and server)" - }, - { - "id": "0x90", - "relationship": "variant", - "note": "Old Map Details for pre-NewCharacterList clients" - } - ], - "clientVersion": { - "classic": { - "min": "7.0.13.0" - }, - "enhanced": {}, - "notes": "NewCharacterList feature" - }, - "source": { - "file": "Projects/UOContent/Items/Maps/MapItemPackets.cs", - "line": 78 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/menu.json b/docs/packets/outgoing/menu.json deleted file mode 100644 index e69969a11..000000000 --- a/docs/packets/outgoing/menu.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "category": "Menu", - "packets": [ - { - "id": "0x7C", - "name": "Display Menu", - "description": "Displays an item list menu or question menu to the client.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Item List Menu", - "condition": "Menu is ItemListMenu", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x7C", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Menu Serial", - "type": "uint", - "size": 4, - "description": "Menu serial" - }, - { - "name": "Menu ID", - "type": "ushort", - "size": 2, - "value": "0x0000", - "description": "Menu ID (always 0)" - }, - { - "name": "Question Length", - "type": "byte", - "size": 1, - "description": "Length of question text" - }, - { - "name": "Question", - "type": "ascii", - "description": "Question text" - }, - { - "name": "Entry Count", - "type": "byte", - "size": 1, - "description": "Number of menu entries" - }, - { - "name": "Entries", - "type": "loop", - "description": "Menu entries", - "loop": { - "countField": "entryCount", - "fields": [ - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID" - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Item hue" - }, - { - "name": "Name Length", - "type": "byte", - "size": 1, - "description": "Length of entry name" - }, - { - "name": "Name", - "type": "ascii", - "description": "Entry name" - } - ] - } - } - ] - }, - { - "name": "Question Menu", - "condition": "Menu is QuestionMenu", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x7C", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Menu Serial", - "type": "uint", - "size": 4, - "description": "Menu serial" - }, - { - "name": "Menu ID", - "type": "ushort", - "size": 2, - "value": "0x0000", - "description": "Menu ID (always 0)" - }, - { - "name": "Question Length", - "type": "byte", - "size": 1, - "description": "Length of question text" - }, - { - "name": "Question", - "type": "ascii", - "description": "Question text" - }, - { - "name": "Answer Count", - "type": "byte", - "size": 1, - "description": "Number of answers" - }, - { - "name": "Answers", - "type": "loop", - "description": "Answer options", - "loop": { - "countField": "answerCount", - "fields": [ - { - "name": "Padding", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused padding" - }, - { - "name": "Answer Length", - "type": "byte", - "size": 1, - "description": "Length of answer text" - }, - { - "name": "Answer", - "type": "ascii", - "description": "Answer text" - } - ] - } - } - ] - } - ], - "related": [ - { - "id": "0x7D", - "relationship": "response", - "note": "Menu Response from client" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMenuPackets.cs", - "line": 36 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/message.json b/docs/packets/outgoing/message.json deleted file mode 100644 index df69402d9..000000000 --- a/docs/packets/outgoing/message.json +++ /dev/null @@ -1,534 +0,0 @@ -{ - "category": "Message", - "packets": [ - { - "id": "0x15", - "name": "Follow Message", - "description": "Instructs client to follow one entity with another.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x15", - "description": "Packet identifier" - }, - { - "name": "Follower Serial", - "type": "uint", - "size": 4, - "description": "Serial of the follower" - }, - { - "name": "Target Serial", - "type": "uint", - "size": 4, - "description": "Serial of the target to follow" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMessagePackets.cs", - "line": 231 - } - }, - { - "id": "0x1C", - "name": "ASCII Message", - "description": "Server sends ASCII-encoded message to client.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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-t", - "description": "Message text" - } - ], - "related": [ - { - "id": "0x03", - "relationship": "request", - "note": "ASCII Speech from client" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMessagePackets.cs", - "line": 180 - } - }, - { - "id": "0xAE", - "name": "Unicode Message", - "description": "Server sends Unicode-encoded message to client.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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., \u0027ENU\u0027)" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Speaker name" - }, - { - "name": "Text", - "type": "utf16be-t", - "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 - } - }, - { - "id": "0xB7", - "name": "Help Response", - "description": "Server sends help text response to client.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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": "utf16be-t", - "description": "Help text" - } - ], - "related": [ - { - "id": "0xB6", - "relationship": "request", - "note": "Object Help Request from client" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMessagePackets.cs", - "line": 263 - } - }, - { - "id": "0xC1", - "name": "Localized Message", - "description": "Server sends a localized (cliloc) message to client.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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": "Cliloc Number", - "type": "int", - "size": 4, - "description": "Cliloc entry number" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Speaker name" - }, - { - "name": "Arguments", - "type": "utf16le-t", - "description": "Tab-separated arguments for cliloc" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMessagePackets.cs", - "line": 55 - } - }, - { - "id": "0xC2", - "name": "Unicode Prompt", - "description": "Server requests text input from client.", - "direction": "outgoing", - "isDynamic": false, - "size": 21, - "tags": ["Menu"], - "fields": [ - { - "name": "Packet ID", - "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": "Prompt ID", - "type": "uint", - "size": 4, - "description": "Prompt ID (same as serial)" - }, - { - "name": "Padding", - "type": "byte[]", - "size": 10, - "description": "Unused padding (zeros)" - } - ], - "related": [ - { - "id": "0x9A", - "direction": "incoming", - "relationship": "response", - "note": "ASCII Prompt Response" - }, - { - "id": "0xC2", - "direction": "incoming", - "relationship": "response", - "note": "Unicode Prompt Response" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMessagePackets.cs", - "line": 246 - } - }, - { - "id": "0xCC", - "name": "Localized Message Affix", - "description": "Server sends a localized message with text prefix/suffix.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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": "Cliloc Number", - "type": "int", - "size": 4, - "description": "Cliloc entry number" - }, - { - "name": "Affix Type", - "type": "enum", - "size": 1, - "description": "How to apply the affix", - "values": [ - { - "value": 0, - "name": "Append", - "description": "Append affix to end" - }, - { - "value": 1, - "name": "Prepend", - "description": "Prepend affix to start" - }, - { - "value": 2, - "name": "System", - "description": "System message style" - } - ] - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Speaker name" - }, - { - "name": "Affix", - "type": "ascii-t", - "description": "Text to prepend/append" - }, - { - "name": "Arguments", - "type": "utf16be-t", - "description": "Tab-separated arguments for cliloc" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMessagePackets.cs", - "line": 112 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/mobile.json b/docs/packets/outgoing/mobile.json deleted file mode 100644 index ea8bc6910..000000000 --- a/docs/packets/outgoing/mobile.json +++ /dev/null @@ -1,2102 +0,0 @@ -{ - "category": "Mobile", - "packets": [ - { - "id": "0x11", - "name": "Mobile Status", - "description": "Detailed status information for a mobile. Version 0 (compact) is sent when viewing other mobiles. Versions 3-6 are sent for self based on expansion.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "version": "Version 0 (Compact)", - "name": "Other Mobile Status", - "condition": "Viewing another mobile (not self)", - "size": 43, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x11", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "43", - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Mobile name" - }, - { - "name": "Hits", - "type": "short", - "size": 2, - "description": "Current hits (normalized 0-100)" - }, - { - "name": "Hits Max", - "type": "short", - "size": 2, - "value": "100", - "description": "Maximum hits (always 100 for normalized)" - }, - { - "name": "Can Be Renamed", - "type": "bool", - "size": 1, - "description": "Whether the mobile can be renamed by viewer" - }, - { - "name": "Version", - "type": "byte", - "size": 1, - "value": "0", - "description": "Status version (0 = compact)" - } - ] - }, - { - "version": "Version 3 (Basic)", - "name": "Self Status (Pre-AOS)", - "condition": "Viewing self, pre-AOS expansion", - "size": 70, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x11", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "70", - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Mobile name" - }, - { - "name": "Hits", - "type": "short", - "size": 2, - "description": "Current hits" - }, - { - "name": "Hits Max", - "type": "short", - "size": 2, - "description": "Maximum hits" - }, - { - "name": "Can Be Renamed", - "type": "bool", - "size": 1, - "description": "Whether the mobile can be renamed" - }, - { - "name": "Version", - "type": "byte", - "size": 1, - "value": "3", - "description": "Status version" - }, - { - "name": "Female", - "type": "bool", - "size": 1, - "description": "Gender flag (true = female)" - }, - { - "name": "Str", - "type": "short", - "size": 2, - "description": "Strength" - }, - { - "name": "Dex", - "type": "short", - "size": 2, - "description": "Dexterity" - }, - { - "name": "Int", - "type": "short", - "size": 2, - "description": "Intelligence" - }, - { - "name": "Stam", - "type": "short", - "size": 2, - "description": "Current stamina" - }, - { - "name": "Stam Max", - "type": "short", - "size": 2, - "description": "Maximum stamina" - }, - { - "name": "Mana", - "type": "short", - "size": 2, - "description": "Current mana" - }, - { - "name": "Mana Max", - "type": "short", - "size": 2, - "description": "Maximum mana" - }, - { - "name": "Gold", - "type": "int", - "size": 4, - "description": "Total gold in backpack" - }, - { - "name": "Armor Rating", - "type": "short", - "size": 2, - "description": "Armor rating" - }, - { - "name": "Weight", - "type": "short", - "size": 2, - "description": "Current weight (body weight + carried)" - }, - { - "name": "Stat Cap", - "type": "short", - "size": 2, - "description": "Total stat cap" - }, - { - "name": "Followers", - "type": "byte", - "size": 1, - "description": "Current follower count" - }, - { - "name": "Followers Max", - "type": "byte", - "size": 1, - "description": "Maximum follower slots" - } - ] - }, - { - "version": "Version 4 (AOS)", - "name": "Self Status (Age of Shadows)", - "condition": "Viewing self, AOS expansion", - "size": 88, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x11", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "88", - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Mobile name" - }, - { - "name": "Hits", - "type": "short", - "size": 2, - "description": "Current hits" - }, - { - "name": "Hits Max", - "type": "short", - "size": 2, - "description": "Maximum hits" - }, - { - "name": "Can Be Renamed", - "type": "bool", - "size": 1, - "description": "Whether the mobile can be renamed" - }, - { - "name": "Version", - "type": "byte", - "size": 1, - "value": "4", - "description": "Status version" - }, - { - "name": "Female", - "type": "bool", - "size": 1, - "description": "Gender flag (true = female)" - }, - { - "name": "Str", - "type": "short", - "size": 2, - "description": "Strength" - }, - { - "name": "Dex", - "type": "short", - "size": 2, - "description": "Dexterity" - }, - { - "name": "Int", - "type": "short", - "size": 2, - "description": "Intelligence" - }, - { - "name": "Stam", - "type": "short", - "size": 2, - "description": "Current stamina" - }, - { - "name": "Stam Max", - "type": "short", - "size": 2, - "description": "Maximum stamina" - }, - { - "name": "Mana", - "type": "short", - "size": 2, - "description": "Current mana" - }, - { - "name": "Mana Max", - "type": "short", - "size": 2, - "description": "Maximum mana" - }, - { - "name": "Gold", - "type": "int", - "size": 4, - "description": "Total gold in backpack" - }, - { - "name": "Physical Resist", - "type": "short", - "size": 2, - "description": "Physical resistance" - }, - { - "name": "Weight", - "type": "short", - "size": 2, - "description": "Current weight" - }, - { - "name": "Stat Cap", - "type": "short", - "size": 2, - "description": "Total stat cap" - }, - { - "name": "Followers", - "type": "byte", - "size": 1, - "description": "Current follower count" - }, - { - "name": "Followers Max", - "type": "byte", - "size": 1, - "description": "Maximum follower slots" - }, - { - "name": "Fire Resist", - "type": "short", - "size": 2, - "description": "Fire resistance" - }, - { - "name": "Cold Resist", - "type": "short", - "size": 2, - "description": "Cold resistance" - }, - { - "name": "Poison Resist", - "type": "short", - "size": 2, - "description": "Poison resistance" - }, - { - "name": "Energy Resist", - "type": "short", - "size": 2, - "description": "Energy resistance" - }, - { - "name": "Luck", - "type": "short", - "size": 2, - "description": "Luck" - }, - { - "name": "Damage Min", - "type": "short", - "size": 2, - "description": "Minimum weapon damage" - }, - { - "name": "Damage Max", - "type": "short", - "size": 2, - "description": "Maximum weapon damage" - }, - { - "name": "Tithing Points", - "type": "int", - "size": 4, - "description": "Tithing points (for Chivalry)" - } - ] - }, - { - "version": "Version 5 (ML)", - "name": "Self Status (Mondain\u0027s Legacy)", - "condition": "Viewing self, ML expansion", - "size": 91, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x11", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "91", - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Mobile name" - }, - { - "name": "Hits", - "type": "short", - "size": 2, - "description": "Current hits" - }, - { - "name": "Hits Max", - "type": "short", - "size": 2, - "description": "Maximum hits" - }, - { - "name": "Can Be Renamed", - "type": "bool", - "size": 1, - "description": "Whether the mobile can be renamed" - }, - { - "name": "Version", - "type": "byte", - "size": 1, - "value": "5", - "description": "Status version" - }, - { - "name": "Female", - "type": "bool", - "size": 1, - "description": "Gender flag (true = female)" - }, - { - "name": "Str", - "type": "short", - "size": 2, - "description": "Strength" - }, - { - "name": "Dex", - "type": "short", - "size": 2, - "description": "Dexterity" - }, - { - "name": "Int", - "type": "short", - "size": 2, - "description": "Intelligence" - }, - { - "name": "Stam", - "type": "short", - "size": 2, - "description": "Current stamina" - }, - { - "name": "Stam Max", - "type": "short", - "size": 2, - "description": "Maximum stamina" - }, - { - "name": "Mana", - "type": "short", - "size": 2, - "description": "Current mana" - }, - { - "name": "Mana Max", - "type": "short", - "size": 2, - "description": "Maximum mana" - }, - { - "name": "Gold", - "type": "int", - "size": 4, - "description": "Total gold in backpack" - }, - { - "name": "Physical Resist", - "type": "short", - "size": 2, - "description": "Physical resistance" - }, - { - "name": "Weight", - "type": "short", - "size": 2, - "description": "Current weight" - }, - { - "name": "Max Weight", - "type": "short", - "size": 2, - "description": "Maximum carry weight" - }, - { - "name": "Race", - "type": "byte", - "size": 1, - "description": "Race ID + 1 (1=Human, 2=Elf, 0=none)" - }, - { - "name": "Stat Cap", - "type": "short", - "size": 2, - "description": "Total stat cap" - }, - { - "name": "Followers", - "type": "byte", - "size": 1, - "description": "Current follower count" - }, - { - "name": "Followers Max", - "type": "byte", - "size": 1, - "description": "Maximum follower slots" - }, - { - "name": "Fire Resist", - "type": "short", - "size": 2, - "description": "Fire resistance" - }, - { - "name": "Cold Resist", - "type": "short", - "size": 2, - "description": "Cold resistance" - }, - { - "name": "Poison Resist", - "type": "short", - "size": 2, - "description": "Poison resistance" - }, - { - "name": "Energy Resist", - "type": "short", - "size": 2, - "description": "Energy resistance" - }, - { - "name": "Luck", - "type": "short", - "size": 2, - "description": "Luck" - }, - { - "name": "Damage Min", - "type": "short", - "size": 2, - "description": "Minimum weapon damage" - }, - { - "name": "Damage Max", - "type": "short", - "size": 2, - "description": "Maximum weapon damage" - }, - { - "name": "Tithing Points", - "type": "int", - "size": 4, - "description": "Tithing points (for Chivalry)" - } - ] - }, - { - "version": "Version 6 (HS)", - "name": "Self Status (High Seas)", - "condition": "Viewing self, High Seas expansion with ExtendedStatus", - "size": 121, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x11", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "121", - "description": "Packet length" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Name", - "type": "ascii", - "size": 30, - "description": "Mobile name" - }, - { - "name": "Hits", - "type": "short", - "size": 2, - "description": "Current hits" - }, - { - "name": "Hits Max", - "type": "short", - "size": 2, - "description": "Maximum hits" - }, - { - "name": "Can Be Renamed", - "type": "bool", - "size": 1, - "description": "Whether the mobile can be renamed" - }, - { - "name": "Version", - "type": "byte", - "size": 1, - "value": "6", - "description": "Status version" - }, - { - "name": "Female", - "type": "bool", - "size": 1, - "description": "Gender flag (true = female)" - }, - { - "name": "Str", - "type": "short", - "size": 2, - "description": "Strength" - }, - { - "name": "Dex", - "type": "short", - "size": 2, - "description": "Dexterity" - }, - { - "name": "Int", - "type": "short", - "size": 2, - "description": "Intelligence" - }, - { - "name": "Stam", - "type": "short", - "size": 2, - "description": "Current stamina" - }, - { - "name": "Stam Max", - "type": "short", - "size": 2, - "description": "Maximum stamina" - }, - { - "name": "Mana", - "type": "short", - "size": 2, - "description": "Current mana" - }, - { - "name": "Mana Max", - "type": "short", - "size": 2, - "description": "Maximum mana" - }, - { - "name": "Gold", - "type": "int", - "size": 4, - "description": "Total gold in backpack" - }, - { - "name": "Physical Resist", - "type": "short", - "size": 2, - "description": "Physical resistance" - }, - { - "name": "Weight", - "type": "short", - "size": 2, - "description": "Current weight" - }, - { - "name": "Max Weight", - "type": "short", - "size": 2, - "description": "Maximum carry weight" - }, - { - "name": "Race", - "type": "byte", - "size": 1, - "description": "Race ID + 1 (1=Human, 2=Elf, 3=Gargoyle)" - }, - { - "name": "Stat Cap", - "type": "short", - "size": 2, - "description": "Total stat cap" - }, - { - "name": "Followers", - "type": "byte", - "size": 1, - "description": "Current follower count" - }, - { - "name": "Followers Max", - "type": "byte", - "size": 1, - "description": "Maximum follower slots" - }, - { - "name": "Fire Resist", - "type": "short", - "size": 2, - "description": "Fire resistance" - }, - { - "name": "Cold Resist", - "type": "short", - "size": 2, - "description": "Cold resistance" - }, - { - "name": "Poison Resist", - "type": "short", - "size": 2, - "description": "Poison resistance" - }, - { - "name": "Energy Resist", - "type": "short", - "size": 2, - "description": "Energy resistance" - }, - { - "name": "Luck", - "type": "short", - "size": 2, - "description": "Luck" - }, - { - "name": "Damage Min", - "type": "short", - "size": 2, - "description": "Minimum weapon damage" - }, - { - "name": "Damage Max", - "type": "short", - "size": 2, - "description": "Maximum weapon damage" - }, - { - "name": "Tithing Points", - "type": "int", - "size": 4, - "description": "Tithing points (for Chivalry)" - }, - { - "name": "Aos Statuses", - "type": "short[15]", - "size": 30, - "description": "Extended AOS status values. Array of 15 shorts indexed by status type.", - "values": [ - { - "value": 0, - "name": "Max Physical Resist", - "description": "Maximum physical resistance cap" - }, - { - "value": 1, - "name": "Max Fire Resist", - "description": "Maximum fire resistance cap" - }, - { - "value": 2, - "name": "Max Cold Resist", - "description": "Maximum cold resistance cap" - }, - { - "value": 3, - "name": "Max Poison Resist", - "description": "Maximum poison resistance cap" - }, - { - "value": 4, - "name": "Max Energy Resist", - "description": "Maximum energy resistance cap" - }, - { - "value": 5, - "name": "Defense Chance Increase", - "description": "Current defense chance increase %" - }, - { - "value": 6, - "name": "Defense Chance Cap", - "description": "Maximum defense chance cap (always 45)" - }, - { - "value": 7, - "name": "Hit Chance Increase", - "description": "Hit chance increase %" - }, - { - "value": 8, - "name": "Swing Speed Increase", - "description": "Swing speed increase %" - }, - { - "value": 9, - "name": "Damage Increase", - "description": "Damage increase %" - }, - { - "value": 10, - "name": "Lower Reagent Cost", - "description": "Lower reagent cost %" - }, - { - "value": 11, - "name": "Spell Damage Increase", - "description": "Spell damage increase %" - }, - { - "value": 12, - "name": "Faster Cast Recovery", - "description": "Faster cast recovery" - }, - { - "value": 13, - "name": "Faster Casting", - "description": "Faster casting" - }, - { - "value": 14, - "name": "Lower Mana Cost", - "description": "Lower mana cost %" - } - ] - } - ], - "notes": "Enhanced Client supports additional status indices 15-28 (HP/Stam/Mana regen, Reflect Physical, Enhance Potions, Stat Increases). ModernUO does not support Enhanced Client." - } - ], - "notes": "ModernUO supports 15 AOS status values (indices 0-14). Enhanced Client extends this to 29 values (indices 0-28), but ModernUO does not support Enhanced Client.", - "related": [ - { - "id": "0x34", - "direction": "incoming", - "relationship": "request", - "note": "Mobile Query (stats) triggers this response" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMobilePackets.cs", - "line": 497 - } - }, - { - "id": "0x20", - "name": "Mobile Update", - "description": "Updates a mobile\u0027s basic display information (body, hue, position, flags).", - "direction": "outgoing", - "isDynamic": false, - "size": 19, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "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": "Packet ID", - "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": "enum", - "enumType": "sequential", - "size": 1, - "description": "Notoriety flag", - "values": [ - { - "value": 0, - "name": "Innocent", - "description": "Blue - innocent player" - }, - { - "value": 1, - "name": "Friend", - "description": "Green - ally/friend" - }, - { - "value": 2, - "name": "Attackable", - "description": "Gray - can be attacked" - }, - { - "value": 3, - "name": "Criminal", - "description": "Gray - criminal flag" - }, - { - "value": 4, - "name": "Enemy", - "description": "Orange - enemy" - }, - { - "value": 5, - "name": "Murderer", - "description": "Red - murderer" - }, - { - "value": 6, - "name": "Invulnerable", - "description": "Yellow - invulnerable" - } - ] - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMobilePackets.cs", - "line": 104 - } - }, - { - "id": "0x78", - "name": "Mobile Incoming", - "description": "Full mobile information including equipped items. Sent when a mobile enters view range. Structure varies by client version.", - "direction": "outgoing", - "isDynamic": true, - "size": "23+", - "variants": [ - { - "name": "Pre-Stygian Abyss", - "condition": "Classic client < 7.0.0.0", - "size": "23+", - "fields": [ - { - "name": "Packet ID", - "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": "enum", - "enumType": "sequential", - "size": 1, - "description": "Notoriety flag", - "values": [ - { - "value": 0, - "name": "Innocent", - "description": "Blue - innocent player" - }, - { - "value": 1, - "name": "Friend", - "description": "Green - ally/friend" - }, - { - "value": 2, - "name": "Attackable", - "description": "Gray - can be attacked" - }, - { - "value": 3, - "name": "Criminal", - "description": "Gray - criminal flag" - }, - { - "value": 4, - "name": "Enemy", - "description": "Orange - enemy" - }, - { - "value": 5, - "name": "Murderer", - "description": "Red - murderer" - }, - { - "value": 6, - "name": "Invulnerable", - "description": "Yellow - invulnerable" - } - ] - }, - { - "name": "Equipment", - "type": "array", - "description": "Equipped items (terminated by 0x00000000)", - "loop": { - "countField": "variable (until terminator)", - "fields": [ - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Item serial (0 = end of list)" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID (15-bit, 0x7FFF mask). Bit 0x8000 indicates hue follows." - }, - { - "name": "Layer", - "type": "byte", - "size": 1, - "description": "Equipment layer" - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Item hue (only present if bit 0x8000 set on Item ID)", - "condition": "Item ID & 0x8000" - } - ] - } - }, - { - "name": "Terminator", - "type": "int", - "size": 4, - "value": "0x00000000", - "description": "Equipment list terminator" - } - ] - }, - { - "name": "Stygian Abyss", - "condition": "Classic client 7.0.0.0 - 7.0.33.0, or Enhanced Client", - "size": "23+", - "fields": [ - { - "name": "Packet ID", - "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 (SA format)" - }, - { - "name": "Notoriety", - "type": "enum", - "enumType": "sequential", - "size": 1, - "description": "Notoriety flag", - "values": [ - { - "value": 0, - "name": "Innocent", - "description": "Blue - innocent player" - }, - { - "value": 1, - "name": "Friend", - "description": "Green - ally/friend" - }, - { - "value": 2, - "name": "Attackable", - "description": "Gray - can be attacked" - }, - { - "value": 3, - "name": "Criminal", - "description": "Gray - criminal flag" - }, - { - "value": 4, - "name": "Enemy", - "description": "Orange - enemy" - }, - { - "value": 5, - "name": "Murderer", - "description": "Red - murderer" - }, - { - "value": 6, - "name": "Invulnerable", - "description": "Yellow - invulnerable" - } - ] - }, - { - "name": "Equipment", - "type": "array", - "description": "Equipped items (terminated by 0x00000000)", - "loop": { - "countField": "variable (until terminator)", - "fields": [ - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Item serial (0 = end of list)" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID (15-bit, 0x7FFF mask). Bit 0x8000 indicates hue follows." - }, - { - "name": "Layer", - "type": "byte", - "size": 1, - "description": "Equipment layer" - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Item hue (only present if bit 0x8000 set on Item ID)", - "condition": "Item ID & 0x8000" - } - ] - } - }, - { - "name": "Terminator", - "type": "int", - "size": 4, - "value": "0x00000000", - "description": "Equipment list terminator" - } - ] - }, - { - "name": "NewMobileIncoming", - "condition": "Classic client >= 7.0.33.1", - "size": "23+", - "fields": [ - { - "name": "Packet ID", - "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 (SA format)" - }, - { - "name": "Notoriety", - "type": "enum", - "enumType": "sequential", - "size": 1, - "description": "Notoriety flag", - "values": [ - { - "value": 0, - "name": "Innocent", - "description": "Blue - innocent player" - }, - { - "value": 1, - "name": "Friend", - "description": "Green - ally/friend" - }, - { - "value": 2, - "name": "Attackable", - "description": "Gray - can be attacked" - }, - { - "value": 3, - "name": "Criminal", - "description": "Gray - criminal flag" - }, - { - "value": 4, - "name": "Enemy", - "description": "Orange - enemy" - }, - { - "value": 5, - "name": "Murderer", - "description": "Red - murderer" - }, - { - "value": 6, - "name": "Invulnerable", - "description": "Yellow - invulnerable" - } - ] - }, - { - "name": "Equipment", - "type": "array", - "description": "Equipped items (terminated by 0x00000000). Always includes hue field.", - "loop": { - "countField": "variable (until terminator)", - "fields": [ - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Item serial (0 = end of list)" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID (full 16-bit, 0xFFFF mask)" - }, - { - "name": "Layer", - "type": "byte", - "size": 1, - "description": "Equipment layer" - }, - { - "name": "Hue", - "type": "short", - "size": 2, - "description": "Item hue (always present)" - } - ] - } - }, - { - "name": "Terminator", - "type": "int", - "size": 4, - "value": "0x00000000", - "description": "Equipment list terminator" - } - ] - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMobilePackets.cs", - "line": 601 - } - }, - { - "id": "0xA1", - "name": "Mobile Hits", - "description": "Updates a mobile\u0027s hit points. Can be normalized to 0-100 scale for non-self mobiles.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA1", - "description": "Packet identifier" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Hits Max", - "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 - } - }, - { - "id": "0xA2", - "name": "Mobile Mana", - "description": "Updates a mobile\u0027s mana points.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA2", - "description": "Packet identifier" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Mana Max", - "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 - } - }, - { - "id": "0xA3", - "name": "Mobile Stamina", - "description": "Updates a mobile\u0027s stamina points.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA3", - "description": "Packet identifier" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Stam Max", - "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 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x2D", - "description": "Packet identifier" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Hits Max", - "type": "short", - "size": 2, - "description": "Maximum hits" - }, - { - "name": "Hits", - "type": "short", - "size": 2, - "description": "Current hits" - }, - { - "name": "Mana Max", - "type": "short", - "size": 2, - "description": "Maximum mana" - }, - { - "name": "Mana", - "type": "short", - "size": 2, - "description": "Current mana" - }, - { - "name": "Stam Max", - "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 - } - }, - { - "id": "0x98", - "name": "Mobile Name", - "description": "Returns a mobile\u0027s name in response to a name request.", - "direction": "outgoing", - "isDynamic": false, - "size": 37, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0x6E", - "name": "Mobile Animation", - "description": "Triggers an animation on a mobile.", - "direction": "outgoing", - "isDynamic": false, - "size": 14, - "fields": [ - { - "name": "Packet ID", - "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": "Frame Count", - "type": "short", - "size": 2, - "description": "Number of frames" - }, - { - "name": "Repeat Count", - "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 - } - }, - { - "id": "0xE2", - "name": "New Mobile Animation", - "description": "Simplified animation packet for newer clients.", - "direction": "outgoing", - "isDynamic": false, - "size": 10, - "fields": [ - { - "name": "Packet ID", - "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": "Frame Count", - "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 - } - }, - { - "id": "0x17", - "name": "Mobile Healthbar", - "description": "Updates a mobile\u0027s healthbar status (poison level, yellow bar for invulnerability).", - "direction": "outgoing", - "isDynamic": false, - "size": 12, - "fields": [ - { - "name": "Packet ID", - "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": "Show Bar", - "type": "enum", - "size": 2, - "description": "Show bar flag. If 0, packet ends here (no subsequent fields sent).", - "values": [ - { "value": "0", "name": "Hide", "description": "Hide healthbar, packet ends here" }, - { "value": "1", "name": "Show", "description": "Show healthbar, following fields included" } - ] - }, - { - "name": "Healthbar Type", - "type": "enum", - "size": 2, - "description": "Type of healthbar overlay (only sent if Show Bar = 1)", - "values": [ - { "value": "1", "name": "Poison", "description": "Poison status bar (green)" }, - { "value": "2", "name": "Yellow", "description": "Yellow/invulnerable bar" } - ] - }, - { - "name": "Level", - "type": "enum", - "size": 1, - "description": "Status level (only sent if Show Bar = 1)", - "values": [ - { "value": "0", "name": "Off", "description": "Status disabled" }, - { "value": "1", "name": "Level1/On", "description": "Poison level 1 or yellow on" }, - { "value": "2", "name": "Level2", "description": "Poison level 2 (Greater)" }, - { "value": "3", "name": "Level3", "description": "Poison level 3 (Deadly)" }, - { "value": "4", "name": "Level4", "description": "Poison level 4 (Lethal)" } - ] - } - ], - "related": [ - { - "id": "0x16", - "relationship": "variant", - "note": "Mobile Healthbar (EC) - Enhanced Client version" - } - ], - "clientVersion": { - "classic": {}, - "notes": "Classic Client only. EC uses 0x16 instead." - }, - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMobilePackets.cs", - "line": 419 - }, - "notes": "When Show Bar is 0, the packet is only 9 bytes (no Healthbar Type or Level fields). Poison (green) overrides yellow coloring." - }, - { - "id": "0x16", - "name": "Mobile Healthbar", - "description": "Updates a mobile's healthbar status for Enhanced Client (poison level, yellow bar for invulnerability).", - "direction": "outgoing", - "isDynamic": true, - "implemented": false, - "size": "9 or 12", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x16", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length (9 or 12)" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Mobile serial" - }, - { - "name": "Show Bar", - "type": "enum", - "size": 2, - "description": "Show bar flag. If 0, packet ends here (no subsequent fields sent).", - "values": [ - { "value": "0", "name": "Hide", "description": "Hide healthbar, packet ends here" }, - { "value": "1", "name": "Show", "description": "Show healthbar, following fields included" } - ] - }, - { - "name": "Healthbar Type", - "type": "enum", - "size": 2, - "description": "Type of healthbar overlay (only sent if Show Bar = 1)", - "values": [ - { "value": "1", "name": "Poison", "description": "Poison status bar (green)" }, - { "value": "2", "name": "Yellow", "description": "Yellow/invulnerable bar" } - ] - }, - { - "name": "Level", - "type": "enum", - "size": 1, - "description": "Status level (only sent if Show Bar = 1)", - "values": [ - { "value": "0", "name": "Off", "description": "Status disabled" }, - { "value": "1", "name": "Level1/On", "description": "Poison level 1 or yellow on" }, - { "value": "2", "name": "Level2", "description": "Poison level 2 (Greater)" }, - { "value": "3", "name": "Level3", "description": "Poison level 3 (Deadly)" }, - { "value": "4", "name": "Level4", "description": "Poison level 4 (Lethal)" } - ] - } - ], - "related": [ - { - "id": "0x17", - "relationship": "variant", - "note": "Mobile Healthbar (Classic) - Classic Client version" - } - ], - "clientVersion": { - "enhanced": {}, - "notes": "Enhanced Client only. Classic uses 0x17 instead." - }, - "notes": "When Show Bar is 0, the packet is only 9 bytes (no Healthbar Type or Level fields). Poison (green) overrides yellow coloring. ModernUO currently sends 0x17 to all clients; this EC variant needs implementation." - }, - { - "id": "0xAF", - "name": "Death Animation", - "description": "Triggers the death animation and corpse creation for a mobile.", - "direction": "outgoing", - "isDynamic": false, - "size": 13, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xAF", - "description": "Packet identifier" - }, - { - "name": "Killed Serial", - "type": "uint", - "size": 4, - "description": "Serial of the killed mobile" - }, - { - "name": "Corpse Serial", - "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 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/movement.json b/docs/packets/outgoing/movement.json deleted file mode 100644 index 8d7632686..000000000 --- a/docs/packets/outgoing/movement.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "category": "Movement", - "packets": [ - { - "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": "Packet ID", - "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 - } - }, - { - "id": "0x22", - "name": "Movement Acknowledgment", - "description": "Sent by the server to confirm successful player movement. Includes the player\u0027s current notoriety for display purposes.", - "direction": "outgoing", - "noMerge": true, - "isDynamic": false, - "size": 3, - "fields": [ - { - "name": "Packet ID", - "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": "enum", - "enumType": "sequential", - "size": 1, - "description": "Player\u0027s current notoriety flag", - "values": [ - { - "value": 0, - "name": "Innocent", - "description": "Blue - innocent player" - }, - { - "value": 1, - "name": "Friend", - "description": "Green - ally/friend" - }, - { - "value": 2, - "name": "Attackable", - "description": "Gray - can be attacked" - }, - { - "value": 3, - "name": "Criminal", - "description": "Gray - criminal flag" - }, - { - "value": 4, - "name": "Enemy", - "description": "Orange - enemy" - }, - { - "value": 5, - "name": "Murderer", - "description": "Red - murderer" - }, - { - "value": 6, - "name": "Invulnerable", - "description": "Yellow - invulnerable" - } - ] - } - ], - "related": [ - { - "id": "0x02", - "relationship": "request", - "note": "The movement request that was accepted" - } - ], - "notes": "Not related to incoming 0x22 (Resynchronize) despite sharing the same packet ID.", - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMovementPackets.cs", - "line": 42 - } - }, - { - "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": "Packet ID", - "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 - } - }, - { - "id": "0xBF", - "subId": "0x26", - "name": "Speed Control", - "description": "Controls the player\u0027s movement speed. Used for mount speed changes, walk/run restrictions, etc.", - "direction": "outgoing", - "isDynamic": false, - "size": 6, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "0x0006", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0026", - "description": "Sub-command for speed control" - }, - { - "name": "Speed Setting", - "type": "enum", - "size": 1, - "description": "Movement speed mode", - "values": [ - { "value": "0", "name": "Disable", "description": "Normal speed (remove override)" }, - { "value": "1", "name": "MountSpeed", "description": "Force mounted movement speed" }, - { "value": "2", "name": "WalkOnly", "description": "Force walk speed only" } - ] - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMovementPackets.cs", - "line": 31 - } - }, - { - "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": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xF2", - "description": "Packet identifier" - }, - { - "name": "Tick Count1", - "type": "long", - "size": 8, - "description": "Server tick count" - }, - { - "name": "Tick Count2", - "type": "long", - "size": 8, - "description": "Server tick count" - }, - { - "name": "Tick Count3", - "type": "long", - "size": 8, - "description": "Server tick count" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingMovementPackets.cs", - "line": 63 - } - } - ] -} diff --git a/docs/packets/outgoing/party.json b/docs/packets/outgoing/party.json deleted file mode 100644 index 1fce9525a..000000000 --- a/docs/packets/outgoing/party.json +++ /dev/null @@ -1,276 +0,0 @@ -{ - "category": "Party", - "packets": [ - { - "id": "0xBF", - "subId": "0x06", - "name": "Party Message", - "description": "Party system messages with various subcommands.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Member List", - "condition": "command == 0x01", - "size": "7 + (memberCount x 4)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0006", - "description": "Party subcommand" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x01", - "description": "Member list command" - }, - { - "name": "Member Count", - "type": "byte", - "size": 1, - "description": "Number of party members" - }, - { - "name": "Members", - "type": "loop", - "description": "Party members", - "loop": { - "countField": "memberCount", - "fields": [ - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Member\u0027s serial" - } - ] - } - } - ] - }, - { - "name": "Remove Member", - "condition": "command == 0x02", - "size": "11 + (memberCount x 4)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0006", - "description": "Party subcommand" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x02", - "description": "Remove member command" - }, - { - "name": "Member Count", - "type": "byte", - "size": 1, - "description": "Number of remaining members" - }, - { - "name": "Removed Serial", - "type": "uint", - "size": 4, - "description": "Serial of removed member" - }, - { - "name": "Members", - "type": "loop", - "description": "Remaining party members", - "loop": { - "countField": "memberCount", - "fields": [ - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Member\u0027s serial" - } - ] - } - } - ] - }, - { - "name": "Private Message", - "condition": "command == 0x03", - "size": "12 + (text.Length x 2)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0006", - "description": "Party subcommand" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x03", - "description": "Private message command" - }, - { - "name": "Sender Serial", - "type": "uint", - "size": 4, - "description": "Serial of message sender" - }, - { - "name": "Text", - "type": "utf16be-t", - "description": "Message text" - } - ] - }, - { - "name": "Public Message", - "condition": "command == 0x04", - "size": "12 + (text.Length x 2)", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0006", - "description": "Party subcommand" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x04", - "description": "Public message command" - }, - { - "name": "Sender Serial", - "type": "uint", - "size": 4, - "description": "Serial of message sender" - }, - { - "name": "Text", - "type": "utf16be-t", - "description": "Message text" - } - ] - }, - { - "name": "Party Invitation", - "condition": "command == 0x07", - "size": 10, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "10", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0006", - "description": "Party subcommand" - }, - { - "name": "Command", - "type": "byte", - "size": 1, - "value": "0x07", - "description": "Invitation command" - }, - { - "name": "Leader Serial", - "type": "uint", - "size": 4, - "description": "Serial of party leader" - } - ] - } - ], - "related": [ - { - "id": "0xBF/0x06", - "relationship": "request", - "note": "Party Message from client" - } - ], - "source": { - "file": "Projects/UOContent/Engines/Party/PartyPackets.cs", - "line": 28 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/player.json b/docs/packets/outgoing/player.json deleted file mode 100644 index cf42eed14..000000000 --- a/docs/packets/outgoing/player.json +++ /dev/null @@ -1,1211 +0,0 @@ -{ - "category": "Player", - "packets": [ - { - "id": "0x23", - "name": "Drag Effect", - "description": "Displays a drag/drop visual effect between two points.", - "direction": "outgoing", - "isDynamic": false, - "size": 26, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x23", - "description": "Packet identifier" - }, - { - "name": "Item ID", - "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": "Src Serial", - "type": "uint", - "size": 4, - "description": "Source entity serial" - }, - { - "name": "Src X", - "type": "short", - "size": 2, - "description": "Source X coordinate" - }, - { - "name": "Src Y", - "type": "short", - "size": 2, - "description": "Source Y coordinate" - }, - { - "name": "Src Z", - "type": "sbyte", - "size": 1, - "description": "Source Z coordinate" - }, - { - "name": "Dst Serial", - "type": "uint", - "size": 4, - "description": "Destination entity serial" - }, - { - "name": "Dst X", - "type": "short", - "size": 2, - "description": "Destination X coordinate" - }, - { - "name": "Dst Y", - "type": "short", - "size": 2, - "description": "Destination Y coordinate" - }, - { - "name": "Dst Z", - "type": "sbyte", - "size": 1, - "description": "Destination Z coordinate" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 198 - } - }, - { - "id": "0x27", - "name": "Lift Reject", - "description": "Server rejects a lift/pick up request.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x27", - "description": "Packet identifier" - }, - { - "name": "Reason", - "type": "enum", - "enumType": "sequential", - "size": 1, - "description": "Rejection reason", - "values": [ - { - "value": 0, - "name": "Cannot Lift", - "description": "You cannot pick that up" - }, - { - "value": 1, - "name": "Out Of Range", - "description": "That is out of range" - }, - { - "value": 2, - "name": "Out Of Sight", - "description": "That is out of sight" - }, - { - "value": 3, - "name": "Try To Steal", - "description": "That does not belong to you" - }, - { - "value": 4, - "name": "Are Holding", - "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 - } - }, - { - "id": "0x2C", - "name": "Death Status", - "description": "Notifies client of death/resurrection state.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0x38", - "name": "Pathfind Message", - "description": "Instructs client to pathfind to a location.", - "direction": "outgoing", - "isDynamic": false, - "size": 7, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0x3A", - "name": "Skills Update", - "description": "Sends full skills list or single skill update to client.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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": "Full No Caps", - "description": "Full list without caps" - }, - { - "value": "0x02", - "name": "Full With Caps", - "description": "Full list with skill caps" - }, - { - "value": "0xDF", - "name": "Single With Caps", - "description": "Single skill update with cap" - }, - { - "value": "0xFF", - "name": "Single No Caps", - "description": "Single skill update" - } - ] - }, - { - "name": "Skills", - "type": "loop", - "loop": { - "until": "skillId == 0", - "fields": [ - { - "name": "Skill ID", - "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)" - } - ] - } - } - ], - "related": [ - { - "id": "0x34", - "direction": "incoming", - "relationship": "request", - "note": "Mobile Query (skills) triggers this response" - }, - { - "id": "0x3A", - "direction": "incoming", - "relationship": "related", - "note": "Change Skill Lock may trigger update" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 121 - } - }, - { - "id": "0x5B", - "name": "Current Time", - "description": "Sends current server time to client.", - "direction": "outgoing", - "isDynamic": false, - "size": 4, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0x65", - "name": "Weather", - "description": "Sets weather conditions for client.", - "direction": "outgoing", - "isDynamic": false, - "size": 4, - "fields": [ - { - "name": "Packet ID", - "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": "Storm Brewing", - "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 - } - }, - { - "id": "0x6D", - "name": "Play Music", - "description": "Plays background music on client.", - "direction": "outgoing", - "isDynamic": false, - "size": 3, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6D", - "description": "Packet identifier" - }, - { - "name": "Music ID", - "type": "short", - "size": 2, - "description": "Music track ID (0x1FFF = stop)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 275 - } - }, - { - "id": "0x73", - "name": "Ping Ack", - "description": "Server acknowledges ping request.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x73", - "description": "Packet identifier" - }, - { - "name": "Sequence", - "type": "byte", - "size": 1, - "description": "Ping sequence (echoed from request)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 336 - } - }, - { - "id": "0x76", - "name": "Server Change", - "description": "Notifies client of server/map transition.", - "direction": "outgoing", - "isDynamic": false, - "size": 16, - "fields": [ - { - "name": "Packet ID", - "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": "Map Width", - "type": "short", - "size": 2, - "description": "Map width" - }, - { - "name": "Map Height", - "type": "short", - "size": 2, - "description": "Map height" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 100 - } - }, - { - "id": "0x7B", - "name": "Sequence", - "description": "Sends sequence number to client for synchronization.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0x88", - "name": "Display Paperdoll", - "description": "Opens paperdoll window for a mobile.", - "direction": "outgoing", - "isDynamic": false, - "size": 66, - "fields": [ - { - "name": "Packet ID", - "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": "0", - "name": "Warmode", - "description": "Mobile is in war mode" - }, - { - "bit": "1", - "name": "Can Lift", - "description": "Viewer can lift equipment" - } - ] - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 247 - } - }, - { - "id": "0x95", - "name": "Display Hue Picker", - "description": "Opens hue picker dialog on client.", - "direction": "outgoing", - "isDynamic": false, - "size": 9, - "fields": [ - { - "name": "Packet ID", - "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": "Item ID", - "type": "short", - "size": 2, - "description": "Item graphic to preview hue on" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 338 - } - }, - { - "id": "0xA5", - "name": "Launch Browser", - "description": "Opens a URL in client\u0027s web browser.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xA5", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "URL", - "type": "ascii-t", - "description": "URL to open" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 180 - } - }, - { - "id": "0xA6", - "name": "Scroll Message", - "description": "Displays a scrollable tips/message window.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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": "Tip Number", - "type": "int", - "size": 4, - "description": "Tip/message number" - }, - { - "name": "Text Length", - "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 - } - }, - { - "id": "0xB8", - "name": "Display Profile", - "description": "Displays a mobile\u0027s profile.", - "direction": "outgoing", - "isDynamic": true, - "size": "var", - "fields": [ - { - "name": "Packet ID", - "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-t", - "description": "Profile header" - }, - { - "name": "Footer", - "type": "utf16be-t", - "description": "Profile footer" - }, - { - "name": "Body", - "type": "utf16be-t", - "description": "Profile body text" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 66 - } - }, - { - "id": "0xBC", - "name": "Season Change", - "description": "Changes the visual season on client.", - "direction": "outgoing", - "isDynamic": false, - "size": 3, - "fields": [ - { - "name": "Packet ID", - "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": "Play Sound", - "type": "bool", - "size": 1, - "description": "Play season change sound" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 244 - } - }, - { - "id": "0xBF/0x19", - "name": "Extended Status", - "description": "Multi-purpose status packet. The Type byte determines the payload: Type 0 for pet bonded status, Type 2/5 for player stat locks.", - "direction": "outgoing", - "isDynamic": false, - "size": "Varies", - "fields": [], - "variants": [ - { - "name": "Bonded Status (Type 0)", - "condition": "Type = 0: Pet bonding status", - "size": 11, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "11", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0019", - "description": "Extended Status subcommand" - }, - { - "name": "Type", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Type 0 = Bonded Status" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Pet mobile serial" - }, - { - "name": "Bonded", - "type": "bool", - "size": 1, - "description": "True if pet is bonded to owner" - } - ], - "notes": "Sent when a pet's bonded status changes or when pet info is requested." - }, - { - "name": "Stat Lock Info - Classic (Type 2)", - "condition": "Type = 2: Classic Client stat locks", - "size": 12, - "clientVersion": { - "classic": {} - }, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "12", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0019", - "description": "Extended Status subcommand" - }, - { - "name": "Type", - "type": "byte", - "size": 1, - "value": "0x02", - "description": "Type 2 = Stat Lock Info (Classic Client)" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Player mobile serial" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Unknown (always 0)" - }, - { - "name": "Lock Bits", - "type": "bitfield", - "size": 1, - "description": "Packed stat lock states (00SSDDII)", - "flags": [ - { - "bit": "5-4", - "name": "Str Lock", - "description": "Strength lock (value << 4)" - }, - { - "bit": "3-2", - "name": "Dex Lock", - "description": "Dexterity lock (value << 2)" - }, - { - "bit": "1-0", - "name": "Int Lock", - "description": "Intelligence lock (value << 0)" - } - ], - "values": [ - { - "value": 0, - "name": "Up", - "description": "Stat gains enabled" - }, - { - "value": 1, - "name": "Down", - "description": "Stat decreases enabled" - }, - { - "value": 2, - "name": "Locked", - "description": "Stat locked" - } - ], - "notes": "Formula: (StrLock << 4) | (DexLock << 2) | IntLock" - } - ] - }, - { - "name": "Stat Lock Info - Enhanced (Type 5)", - "condition": "Type = 5: Enhanced Client stat locks", - "size": 12, - "clientVersion": { - "enhanced": {} - }, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "12", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0019", - "description": "Extended Status subcommand" - }, - { - "name": "Type", - "type": "byte", - "size": 1, - "value": "0x05", - "description": "Type 5 = Stat Lock Info (Enhanced Client)" - }, - { - "name": "Serial", - "type": "uint", - "size": 4, - "description": "Player mobile serial" - }, - { - "name": "Unknown", - "type": "byte", - "size": 1, - "value": "0x00", - "description": "Unknown (always 0)" - }, - { - "name": "Lock Bits", - "type": "bitfield", - "size": 1, - "description": "Packed stat lock states (00SSDDII)", - "flags": [ - { - "bit": "5-4", - "name": "Str Lock", - "description": "Strength lock (value << 4)" - }, - { - "bit": "3-2", - "name": "Dex Lock", - "description": "Dexterity lock (value << 2)" - }, - { - "bit": "1-0", - "name": "Int Lock", - "description": "Intelligence lock (value << 0)" - } - ], - "values": [ - { - "value": 0, - "name": "Up", - "description": "Stat gains enabled" - }, - { - "value": 1, - "name": "Down", - "description": "Stat decreases enabled" - }, - { - "value": 2, - "name": "Locked", - "description": "Stat locked" - } - ], - "notes": "Formula: (StrLock << 4) | (DexLock << 2) | IntLock" - } - ], - "notes": "Enhanced Client uses Type 5 instead of Type 2" - } - ], - "tags": ["Player", "Mobile"], - "notes": "The Type byte after the sub-command determines the packet structure. Type 0 is for pet bonding, Types 2/5 are for player stat locks (Classic/Enhanced Client respectively).", - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 36 - } - }, - { - "id": "0xC8", - "name": "Change Update Range", - "description": "Sets the client\u0027s update range.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "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 - } - }, - { - "id": "0xD1", - "name": "Logout Ack", - "description": "Server acknowledges logout request.", - "direction": "outgoing", - "isDynamic": false, - "size": 2, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xD1", - "description": "Packet identifier" - }, - { - "name": "Ack", - "type": "byte", - "size": 1, - "value": "0x01", - "description": "Acknowledgment (1 = OK)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingPlayerPackets.cs", - "line": 94 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/securetrade.json b/docs/packets/outgoing/securetrade.json deleted file mode 100644 index 46d046f2a..000000000 --- a/docs/packets/outgoing/securetrade.json +++ /dev/null @@ -1,275 +0,0 @@ -{ - "category": "Secure Trade", - "packets": [ - { - "id": "0x6F", - "name": "Secure Trade", - "description": "Manages secure trade windows between players.", - "direction": "outgoing", - "isDynamic": true, - "size": "Varies", - "variants": [ - { - "name": "Display Trade Window", - "condition": "flag == Display (0)", - "size": 47, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "47", - "description": "Packet length" - }, - { - "name": "Flag", - "type": "enum", - "enumType": "sequential", - "size": 1, - "value": "0", - "description": "Trade action flag", - "values": [ - { - "value": 0, - "name": "Display", - "description": "Open trade window" - }, - { - "value": 1, - "name": "Close", - "description": "Close trade window" - }, - { - "value": 2, - "name": "Update", - "description": "Update accept status" - }, - { - "value": 3, - "name": "Update Gold", - "description": "Update gold amounts" - }, - { - "value": 4, - "name": "Update Ledger", - "description": "Update ledger" - } - ] - }, - { - "name": "Partner Serial", - "type": "uint", - "size": 4, - "description": "Serial of trading partner" - }, - { - "name": "First Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of your trade container" - }, - { - "name": "Second Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of partner\u0027s trade container" - }, - { - "name": "Has Name", - "type": "bool", - "size": 1, - "value": "true", - "description": "Name field follows" - }, - { - "name": "Partner Name", - "type": "ascii", - "size": 30, - "description": "Trading partner\u0027s name" - } - ] - }, - { - "name": "Close Trade Window", - "condition": "flag == Close (1)", - "size": 17, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "17", - "description": "Packet length" - }, - { - "name": "Flag", - "type": "byte", - "size": 1, - "value": "1", - "description": "Close flag" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Trade container serial" - }, - { - "name": "Unused1", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - }, - { - "name": "Unused2", - "type": "int", - "size": 4, - "value": "0", - "description": "Unused" - }, - { - "name": "Has Name", - "type": "bool", - "size": 1, - "value": "false", - "description": "No name follows" - } - ] - }, - { - "name": "Update Accept Status", - "condition": "flag == Update (2)", - "size": 17, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "17", - "description": "Packet length" - }, - { - "name": "Flag", - "type": "byte", - "size": 1, - "value": "2", - "description": "Update flag" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Trade container serial" - }, - { - "name": "Your Accept", - "type": "int", - "size": 4, - "description": "Your accept status (0 or 1)" - }, - { - "name": "Partner Accept", - "type": "int", - "size": 4, - "description": "Partner\u0027s accept status (0 or 1)" - }, - { - "name": "Has Name", - "type": "bool", - "size": 1, - "value": "false", - "description": "No name follows" - } - ] - }, - { - "name": "Update Gold/Platinum", - "condition": "flag == UpdateGold (3)", - "size": 17, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6F", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "17", - "description": "Packet length" - }, - { - "name": "Flag", - "type": "byte", - "size": 1, - "value": "3", - "description": "UpdateGold flag" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Trade container serial" - }, - { - "name": "Gold", - "type": "int", - "size": 4, - "description": "Gold amount" - }, - { - "name": "Platinum", - "type": "int", - "size": 4, - "description": "Platinum amount" - }, - { - "name": "Has Name", - "type": "bool", - "size": 1, - "value": "false", - "description": "No name follows" - } - ] - } - ], - "related": [ - { - "id": "0x6F", - "direction": "incoming", - "relationship": "request", - "note": "Client trade actions" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingSecureTradePackets.cs", - "line": 32 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/targeting.json b/docs/packets/outgoing/targeting.json deleted file mode 100644 index c6bbabb5a..000000000 --- a/docs/packets/outgoing/targeting.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "category": "Targeting", - "packets": [ - { - "id": "0x6C", - "name": "Target Request", - "description": "Requests the client to select a target.", - "direction": "outgoing", - "isDynamic": false, - "size": 19, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x6C", - "description": "Packet identifier" - }, - { - "name": "Allow Ground", - "type": "bool", - "size": 1, - "description": "True = allow ground targeting" - }, - { - "name": "Target ID", - "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)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingTargetPackets.cs", - "line": 57 - } - }, - { - "id": "0x99", - "name": "Multi Target Request", - "description": "Requests the client to place a multi (house/boat) structure.", - "direction": "outgoing", - "isDynamic": false, - "size": "Varies", - "variants": [ - { - "version": "pre-HighSeas", - "name": "Pre-HighSeas (26 bytes)", - "size": 26, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x99", - "description": "Packet identifier" - }, - { - "name": "Allow Ground", - "type": "bool", - "size": 1, - "description": "Allow ground targeting" - }, - { - "name": "Target ID", - "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": "Multi ID", - "type": "short", - "size": 2, - "description": "Multi graphic ID" - }, - { - "name": "Offset X", - "type": "short", - "size": 2, - "description": "X offset for placement" - }, - { - "name": "Offset Y", - "type": "short", - "size": 2, - "description": "Y offset for placement" - }, - { - "name": "Offset Z", - "type": "short", - "size": 2, - "description": "Z offset for placement" - } - ] - }, - { - "version": "HighSeas+", - "name": "HighSeas / Enhanced (30 bytes)", - "condition": "Classic >= 7.0.9.0, or Enhanced Client (any version)", - "size": 30, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x99", - "description": "Packet identifier" - }, - { - "name": "Allow Ground", - "type": "bool", - "size": 1, - "description": "Allow ground targeting" - }, - { - "name": "Target ID", - "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": "Multi ID", - "type": "short", - "size": 2, - "description": "Multi graphic ID" - }, - { - "name": "Offset X", - "type": "short", - "size": 2, - "description": "X offset for placement" - }, - { - "name": "Offset Y", - "type": "short", - "size": 2, - "description": "Y offset for placement" - }, - { - "name": "Offset Z", - "type": "short", - "size": 2, - "description": "Z offset for placement" - }, - { - "name": "Unknown", - "type": "int", - "size": 4, - "description": "Unknown (HighSeas extension)" - } - ] - } - ], - "clientVersion": { - "classic": {}, - "enhanced": {}, - "notes": "HighSeas (7.0.9.0+) adds 4 bytes. EC always uses 30-byte variant." - }, - "source": { - "file": "Projects/Server/Network/Packets/OutgoingTargetPackets.cs", - "line": 23 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/vendor.json b/docs/packets/outgoing/vendor.json deleted file mode 100644 index 5c55b7f0e..000000000 --- a/docs/packets/outgoing/vendor.json +++ /dev/null @@ -1,216 +0,0 @@ -{ - "category": "Vendor", - "packets": [ - { - "id": "0x3B", - "name": "End Vendor Transaction", - "description": "Ends a vendor buy or sell transaction.", - "direction": "outgoing", - "isDynamic": false, - "size": 8, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x3B", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "8", - "description": "Packet length" - }, - { - "name": "Vendor Serial", - "type": "uint", - "size": 4, - "description": "Serial of the vendor" - }, - { - "name": "Item Count", - "type": "byte", - "size": 1, - "value": "0", - "description": "Item count (0 = end transaction)" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs", - "line": 111 - } - }, - { - "id": "0x74", - "name": "Vendor Buy List", - "description": "Sends the list of items available for purchase from a vendor with prices.", - "direction": "outgoing", - "isDynamic": true, - "size": "8+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x74", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Container Serial", - "type": "uint", - "size": 4, - "description": "Serial of vendor\u0027s buy container" - }, - { - "name": "Item Count", - "type": "byte", - "size": 1, - "description": "Number of items" - }, - { - "name": "Items", - "type": "loop", - "description": "Buy items with prices", - "loop": { - "countField": "itemCount", - "fields": [ - { - "name": "Price", - "type": "int", - "size": 4, - "description": "Item price" - }, - { - "name": "Desc Length", - "type": "byte", - "size": 1, - "description": "Description length + 1" - }, - { - "name": "Description", - "type": "ascii-t", - "description": "Item description" - } - ] - } - } - ], - "related": [ - { - "id": "0x3C", - "relationship": "request", - "note": "Container Content with items" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingVendorBuyPackets.cs", - "line": 77 - } - }, - { - "id": "0x9E", - "name": "Vendor Sell List", - "description": "Sends the list of items the vendor will buy from the player.", - "direction": "outgoing", - "isDynamic": true, - "size": "9+", - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0x9E", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "description": "Packet length" - }, - { - "name": "Vendor Serial", - "type": "uint", - "size": 4, - "description": "Serial of the vendor" - }, - { - "name": "Item Count", - "type": "ushort", - "size": 2, - "description": "Number of items" - }, - { - "name": "Items", - "type": "loop", - "description": "Sell items with prices", - "loop": { - "countField": "itemCount", - "fields": [ - { - "name": "Item Serial", - "type": "uint", - "size": 4, - "description": "Item serial" - }, - { - "name": "Item ID", - "type": "ushort", - "size": 2, - "description": "Item graphic ID" - }, - { - "name": "Hue", - "type": "ushort", - "size": 2, - "description": "Item hue" - }, - { - "name": "Amount", - "type": "ushort", - "size": 2, - "description": "Item amount" - }, - { - "name": "Price", - "type": "ushort", - "size": 2, - "description": "Price per unit" - }, - { - "name": "Name Length", - "type": "ushort", - "size": 2, - "description": "Name length" - }, - { - "name": "Name", - "type": "ascii", - "description": "Item name" - } - ] - } - } - ], - "related": [ - { - "id": "0x9F", - "relationship": "response", - "note": "Vendor Sell Reply from client" - } - ], - "source": { - "file": "Projects/Server/Network/Packets/OutgoingVendorSellPackets.cs", - "line": 25 - } - } - ] -} \ No newline at end of file diff --git a/docs/packets/outgoing/weaponability.json b/docs/packets/outgoing/weaponability.json deleted file mode 100644 index 79f3ce907..000000000 --- a/docs/packets/outgoing/weaponability.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "category": "Weapon Ability", - "packets": [ - { - "id": "0xBF", - "subId": "0x21", - "name": "Clear Weapon Ability", - "description": "Clears the currently selected weapon ability.", - "direction": "outgoing", - "isDynamic": false, - "size": 5, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "5", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0021", - "description": "Clear Weapon Ability subcommand" - } - ], - "source": { - "file": "Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs", - "line": 37 - } - }, - { - "id": "0xBF", - "subId": "0x25", - "name": "Toggle Special Ability", - "description": "Toggles a special weapon ability on or off.", - "direction": "outgoing", - "isDynamic": false, - "size": 8, - "fields": [ - { - "name": "Packet ID", - "type": "byte", - "size": 1, - "value": "0xBF", - "description": "Packet identifier" - }, - { - "name": "Length", - "type": "ushort", - "size": 2, - "value": "8", - "description": "Packet length" - }, - { - "name": "Sub-Command", - "type": "ushort", - "size": 2, - "value": "0x0025", - "description": "Toggle Special Ability subcommand" - }, - { - "name": "Ability ID", - "type": "short", - "size": 2, - "description": "Ability ID" - }, - { - "name": "Active", - "type": "bool", - "size": 1, - "description": "True if ability is active" - } - ], - "source": { - "file": "Projects/UOContent/Items/Weapons/Abilities/WeaponAbilityPackets.cs", - "line": 40 - } - } - ] -} diff --git a/docs/packets/template.html b/docs/packets/template.html deleted file mode 100644 index a97b51649..000000000 --- a/docs/packets/template.html +++ /dev/null @@ -1,1910 +0,0 @@ - - - - - - - - - ModernUO Packet Documentation - - - - - - - -
- -
-
-
- -
-

- Packet Documentation - -

- -
-
-
- - -
-
-
- - -
- - - - - - - -
-
- - - - -
-
📦
-

Select a Packet

-

Choose a packet from the list to view its documentation.

-

Use the search box to find packets by ID (0x02), name, or field names.

-
- - - -
-
-
-
- - - - - - - - - - diff --git a/docs/readme.md b/docs/readme.md deleted file mode 100644 index fcc0f5972..000000000 --- a/docs/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -# ModernUO Website - -## Development - -1. Install Python's `pip` package manager -1. Install MkDocs: `pip install mkdocs` -1. Install Required Extensions - * `pip install pymdown-extensions` - * `pip install mkdocs-material` -1. Launch development server: `mkdocs` diff --git a/docs/scripting-guide/serialization.md b/docs/scripting-guide/serialization.md deleted file mode 100644 index ccca4ae62..000000000 --- a/docs/scripting-guide/serialization.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -title: Serialization ---- - -# Serialization / Savings - -=== "Generic persistence" - ```Persistence.Serialize``` and ```Persistence.Deserialize``` is replaced with GenericPersistence class - - Example of how to persist a custom system. - - ```cs - namespace Server.ExampleSystem - { - public static class ExampleSerialization - { - public static void Configure() - { - GenericPersistence.Register("ExampleSystem", Serialize, Deserialize); - } - - public static void Serialize(IGenericWriter writer) - { - // Do serialization here - writer.WriteEncodedInt(0); // version - } - - public static void Deserialize(IGenericReader reader) - { - // Do deserialization here - var version = reader.ReadEncodedInt(); - } - } - } - ``` - -=== "Codegen" - ### Basic info - ModernUO can programatically generate migrations. This feature is based on internal C# Source generators [More info](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/) - - Old way of serializing objects: - ```cs - public class ExampleItem : Item - { - private string _exampleText; - - [CommandProperty(AccessLevel.GameMaster)] - public string ExampleText - { - get => _exampleText; - set - { - if (value != _exampleText) - { - _exampleText = value; - this.MarkDirty(); - } - } - } - - [Constructible] - public ExampleItem(string text) : base(0) - { - Example = text; - } - - public ExampleItem(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); //Version - writer.Write(_exampleText); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - // version 0 - _exampleText = reader.ReadString(); - } - } - ``` - - Same class serialized with codegen - ```cs - [SerializationGenerator(0)] - public partial class ExampleItem : Item - { - [SerializableField(0)] - [SerializedCommandProperty(AccessLevel.GameMaster)] - private string _exampleText; - - [Constructible] - public ExampleItem(string text) : base(0) - { - _exampleText = text; - } - } - ``` - - ### Step by step - 1. Add ```SerializationGenerator(versionNumber)``` to your class and make the class ```partial``` - ```cs - [SerializationGenerator(0)] - public partial class ExampleItem : Item - ``` - 1. Delete the constructor with ```Serial serial``` - 1. Delete the ```Serialize``` and ```Deserialize``` methods. - 1. Add ```SerializableField(fieldOrder)``` attribute to all field you want to serialize. - ```cs - [SerializableField(0)] - private string _exampleText; - ``` - 1. Run `publish.cmd`. - - ModernUO will create migration files for you. In this case "Server.Items.ExampleItem.v0.json" and "Server.Items.ExampleItem.Serialization.cs". - These files contains all information and classes needed for ModernUO to serialize/deserialize your objects. - - ### Migrations - When new field is added to the serialization, you need to increment `versionNumber` and run `publish.cmd` again to generate a migration file for the new version. - Here is little example. - - New class code will look like this: - ```cs - [SerializationGenerator(1)] - public partial class ExampleItem : Item - { - [SerializableField(0)] - private string _exampleText; - - [SerializableField(1)] - [SerializedCommandProperty(AccessLevel.GameMaster)] - private string _addedExampleTest; - - [Constructible] - public ExampleItem(string text, string addedText) : base(0) - { - _exampleText = text; - _addedExampleTest = addedText; - } - } - ``` - - Your IDE (Visual Studio, Rider, or VSCode), will show errors and the ModernUO will not compile. - This happens because the code generator builds a migration from V0 to V1 and a new struct `V0Content` with all of the V0 fields is generated. - ModernUO is expecting the developer to create a migration from the old version to the new. - Now create a `MigrateFrom` method for each of the older versions, in this case V0, to the new version. - - ```cs - private void MigrateFrom(V0Content content) - { - _exampleText = content.ExampleText; - } - ``` - - !!! Tip - Since the class is `partial`, you can create a standalone file for migrations to keep them organized. For example "ExampleItem.Migrations.cs" - - Your migration is now complete. - - ### Migrating from pre-codegen - To migrate from pre-codegen serialization, change the old Deserialize method to this: - ```cs - private void Deserialize(IGenericReader reader, int version) - ``` - - This method will be automatically called when the serialization generator doesn't have a migration for for that older version. - In this method you can make old fashioned deserializations that are mostly compatible with RunUO. - - ### After Deserialization - To execute code after the deserialization, add the `AfterDeserialization()` attribute to a method. - ```cs - [AfterDeserialization] - private void AfterDeserialization() - { - // Some code here - } - ``` - - !!! Tip - By default, `AfterDeserialization` is executed synchronously right after the actual deserialization. Passing `false` to the attribute will make it execute after all deserializations. - - ### Serializing Non-Entity Classes - Sometimes you might need to serialize a nested object that is not an `ISerializable`. The syntax is largely the same except you must also mark the *parent* object for dirty tracking by using the `DirtyTrackingEntity` attribute. - A good example of this is ["AquariumState"](https://github.com/modernuo/ModernUO/blob/main/Projects/UOContent/Items/Aquarium/AquariumState.cs). - - - !!! Note - Non-entity classes cannot be serialized by reference since that would require a reference Serial or ID. This means if the object is a serializable property on multiple objects, it will be serialized - multiple times and will effectively get duplicated on world load. Consider either making it an `ISerializable` type and building world load/save mechanisms, or do not serialize the nested object directly. - Instead opt for a global lookup, serialize with generic persistence, and then reattach to the objects using the `WorldLoad` event sink. diff --git a/docs/scripting-guide/timers.md b/docs/scripting-guide/timers.md deleted file mode 100644 index 443291e14..000000000 --- a/docs/scripting-guide/timers.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Timers ---- - -# Timers - -ModernUO completely changed the timer system to use an optimized data structure called a timer wheel. This will allow shards to add thousands of timers without slowing down the server. Traditionally the timer system used a thread and locked to add/remove/process timers. All of this is gone. -With the new timer system there is no TimerPriority. This can be deleted entirely from your scripts. diff --git a/docs/starting-server.md b/docs/starting-server.md deleted file mode 100644 index e0da2a6c2..000000000 --- a/docs/starting-server.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Starting the server ---- - -# Starting the server - -Now that the software has been built, all you need to do is run it! -Everything is run from the _Distribution_ folder. - -=== "Windows" - Using _windows terminal_, _git bash_, or _powershell_, run: - ```bash - cd Distribution - ModernUO.exe - ``` - -=== "OSX/Linux" - Using _terminal_, run: - ```bash - cd Distribution - dotnet ModernUO.dll - ``` - -=== "Game Files" - !!! Note - Game files are required to initiate a server. Upon the initial launch, you will encounter a prompt asking for the location of your game files or ClassicUO installation. ClassicUO installations should be configured to reference game files directory within settings.json file. - - - !!! Tip - Game files are not directly distributed in ModernUO, find the latest version to download these at [client download](https://uo.com/Client-Download/) diff --git a/docs/tools/build-packets.ps1 b/docs/tools/build-packets.ps1 deleted file mode 100644 index 1e93dbc89..000000000 --- a/docs/tools/build-packets.ps1 +++ /dev/null @@ -1,194 +0,0 @@ -# build-packets.ps1 -# Combines all packet JSON files with the HTML template to generate the final documentation page. -# -# Usage: -# .\build-packets.ps1 -# .\build-packets.ps1 -OutputPath "C:\custom\output\packets.html" - -param( - [string]$OutputPath = "" -) - -$ErrorActionPreference = "Stop" - -# Determine paths -$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path -$docsDir = (Resolve-Path (Join-Path $scriptDir "..")).Path -$packetsDir = Join-Path $docsDir "packets" -$templateFile = Join-Path $packetsDir "template.html" - -if (-not $OutputPath) { - $OutputPath = Join-Path $packetsDir "packets.html" -} - -Write-Host "ModernUO Packet Documentation Builder" -ForegroundColor Cyan -Write-Host "======================================" -ForegroundColor Cyan -Write-Host "" - -# Verify template exists -if (-not (Test-Path $templateFile)) { - Write-Error "Template file not found: $templateFile" - exit 1 -} - -# Collect all packet JSON files -$allPackets = @{ - incoming = @() - outgoing = @() -} - -$incomingDir = Join-Path $packetsDir "incoming" -$outgoingDir = Join-Path $packetsDir "outgoing" - -# Read incoming packets -if (Test-Path $incomingDir) { - $incomingFiles = Get-ChildItem "$incomingDir\*.json" -ErrorAction SilentlyContinue | Sort-Object Name - foreach ($file in $incomingFiles) { - Write-Host " Reading: $($file.Name)" -ForegroundColor Gray - try { - $content = Get-Content $file.FullName -Raw -Encoding UTF8 - $data = $content | ConvertFrom-Json - if ($data.packets) { - # Add category and merge tags for each packet - foreach ($packet in $data.packets) { - # Add category if not present (backward compatibility) - if (-not $packet.category -and $data.category) { - $packet | Add-Member -NotePropertyName "category" -NotePropertyValue $data.category -Force - } - - # Merge tags: file-level + packet-level - $fileTags = @() - if ($data.tags) { $fileTags = @($data.tags) } - - $packetTags = @() - if ($packet.tags) { $packetTags = @($packet.tags) } - - $allTags = @($fileTags + $packetTags) | Select-Object -Unique - - # Always include the primary category as a tag (first position) - if ($data.category -and $data.category -notin $allTags) { - $allTags = @($data.category) + $allTags - } - - # Ensure tags is always an array (PowerShell can collapse single-element arrays) - $allTags = @($allTags) - - $packet | Add-Member -NotePropertyName "tags" -NotePropertyValue $allTags -Force - } - $allPackets.incoming += $data.packets - } - } catch { - Write-Warning "Failed to parse $($file.Name): $_" - } - } - Write-Host " Found $($allPackets.incoming.Count) incoming packets" -ForegroundColor Green -} else { - Write-Host " No incoming packets directory found" -ForegroundColor Yellow -} - -# Read outgoing packets -if (Test-Path $outgoingDir) { - $outgoingFiles = Get-ChildItem "$outgoingDir\*.json" -ErrorAction SilentlyContinue | Sort-Object Name - foreach ($file in $outgoingFiles) { - Write-Host " Reading: $($file.Name)" -ForegroundColor Gray - try { - $content = Get-Content $file.FullName -Raw -Encoding UTF8 - $data = $content | ConvertFrom-Json - if ($data.packets) { - # Add category and merge tags for each packet - foreach ($packet in $data.packets) { - # Add category if not present (backward compatibility) - if (-not $packet.category -and $data.category) { - $packet | Add-Member -NotePropertyName "category" -NotePropertyValue $data.category -Force - } - - # Merge tags: file-level + packet-level - $fileTags = @() - if ($data.tags) { $fileTags = @($data.tags) } - - $packetTags = @() - if ($packet.tags) { $packetTags = @($packet.tags) } - - $allTags = @($fileTags + $packetTags) | Select-Object -Unique - - # Always include the primary category as a tag (first position) - if ($data.category -and $data.category -notin $allTags) { - $allTags = @($data.category) + $allTags - } - - # Ensure tags is always an array (PowerShell can collapse single-element arrays) - $allTags = @($allTags) - - $packet | Add-Member -NotePropertyName "tags" -NotePropertyValue $allTags -Force - } - $allPackets.outgoing += $data.packets - } - } catch { - Write-Warning "Failed to parse $($file.Name): $_" - } - } - Write-Host " Found $($allPackets.outgoing.Count) outgoing packets" -ForegroundColor Green -} else { - Write-Host " No outgoing packets directory found" -ForegroundColor Yellow -} - -$totalPackets = $allPackets.incoming.Count + $allPackets.outgoing.Count -Write-Host "" -Write-Host "Total packets: $totalPackets" -ForegroundColor Cyan - -if ($totalPackets -eq 0) { - Write-Warning "No packets found! The output will have empty documentation." -} - -# Sort packets by ID for deterministic output -# Handle IDs like "0x02" and "0xBF/0x05" (split on / and parse first part) -$allPackets.incoming = @($allPackets.incoming | Sort-Object { - $baseId = $_.id -split '/' | Select-Object -First 1 - [Convert]::ToInt32($baseId, 16) -}, { - if ($_.subId) { [Convert]::ToInt32($_.subId, 16) } - elseif ($_.id -match '/') { [Convert]::ToInt32(($_.id -split '/' | Select-Object -Last 1), 16) } - else { 0 } -}) -$allPackets.outgoing = @($allPackets.outgoing | Sort-Object { - $baseId = $_.id -split '/' | Select-Object -First 1 - [Convert]::ToInt32($baseId, 16) -}, { - if ($_.subId) { [Convert]::ToInt32($_.subId, 16) } - elseif ($_.id -match '/') { [Convert]::ToInt32(($_.id -split '/' | Select-Object -Last 1), 16) } - else { 0 } -}) - -# Convert to JSON -$packetsJson = $allPackets | ConvertTo-Json -Depth 20 -Compress - -# HTML entity escape the JSON to safely embed in HTML -$packetsJson = $packetsJson -replace '<', '<' -replace '>', '>' - -# Read template and inject JSON -Write-Host "" -Write-Host "Reading template..." -ForegroundColor Gray -$template = Get-Content $templateFile -Raw -Encoding UTF8 - -Write-Host "Injecting packet data..." -ForegroundColor Gray -$output = $template -replace '', $packetsJson - -# Ensure output directory exists -$outputDir = Split-Path $OutputPath -Parent -if (-not (Test-Path $outputDir)) { - Write-Host "Creating output directory: $outputDir" -ForegroundColor Gray - New-Item -ItemType Directory -Path $outputDir -Force | Out-Null -} - -# Write output -Write-Host "Writing output..." -ForegroundColor Gray -$output | Set-Content $OutputPath -Encoding UTF8 - -$outputSize = (Get-Item $OutputPath).Length -$outputSizeKB = [math]::Round($outputSize / 1024, 2) - -Write-Host "" -Write-Host "Success!" -ForegroundColor Green -Write-Host " Output: $OutputPath" -ForegroundColor White -Write-Host " Size: $outputSizeKB KB" -ForegroundColor White -Write-Host " Packets: $totalPackets" -ForegroundColor White diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index 8891e4187..000000000 --- a/mkdocs.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Exclude non-documentation files from build output -exclude_docs: | - commands/ - packets/ - tools/ - -# Project -site_name: ModernUO -site_author: Kamron Batman -site_url: https://modernuo.com -edit_uri: edit/main/docs/ - -# Repository -repo_name: modernuo/modernuo -repo_url: https://github.com/modernuo/modernuo -site_description: The Ultima Online Server Emulator for the modern era! -copyright: Copyright 2019-2025 ModernUO Development Team -theme: - name: material - favicon: branding/favicon.png - icon: - logo: modernuo/logo - custom_dir: docs/overrides/ - features: - - navigation.tabs - - navigation.instant -extra_css: - - assets/stylesheets/extra.css -extra: - social: - - icon: fontawesome/brands/github - link: https://muo.gg/github - name: ModernUO on Github - - icon: fontawesome/brands/discord - link: https://muo.gg/discord - name: ModernUO on Discord - - icon: fontawesome/brands/patreon - link: https://muo.gg/patreon - name: Sponsor ModernUO on Patreon - - icon: fontawesome/brands/reddit - link: https://muo.gg/reddit - name: /r/modernuo - - icon: fontawesome/brands/twitter - link: https://muo.gg/twitter - name: "@modernuo" -markdown_extensions: - - admonition - - footnotes - - meta - - toc: - toc_depth: "1-1" - permalink: true - - attr_list - - pymdownx.highlight - - pymdownx.inlinehilite - - pymdownx.superfences - - pymdownx.snippets - - pymdownx.tabbed: - alternate_style: true - - pymdownx.caret - - pymdownx.mark - - pymdownx.tilde - - pymdownx.critic: - mode: view - - pymdownx.betterem: - smart_enable: all - - pymdownx.emoji: - emoji_index: !!python/name:material.extensions.emoji.twemoji - emoji_generator: !!python/name:material.extensions.emoji.to_svg - options: - custom_icons: - - docs/overrides/.icons - -# Pages -nav: - - Home: 'index.md' - - 'Get Started': - - 'installation.md' - - 'building-server.md' - - 'starting-server.md' - - 'Scripting guide': - - 'scripting-guide/timers.md' - - 'scripting-guide/serialization.md'