Patch Notes

Changes to the Iserle core, grouped by the server build they first shipped in.

Our commits
62
Builds tracked
16
TrinityCore commits merged
0
TrinityCore commits not merged
0

Upstream is upstream/master as last fetched (newest commit 2026-09-24).

Not deployed yet

3 commit(s) on main that no server build has run yet

iserle-web

  • public HTTPS listener, invite code, launcher download, GM command wiki 426444bd83 · 2026-10-01 22:13
    Public test server (SETUP.md section 9):
    - Optional second listener, HTTPS only (rustls + ring via axum-server, Let's
      Encrypt cert re-read every 6 h), with Secure cookies. With admin.local_only
      (default) it has no /login, /logout or /admin routes; staff keep using the
      loopback listener. Each router stamps requests with the listener they came
      in on, overwriting whatever the client sent.
    - registration.invite_code gates sign-up (case-insensitive, constant time,
      10 tries per 15 min per IP).
    - Passwords are capped at 16 characters: the game's login box cuts longer
      ones (a 20-character password failed in game with error 317, 12 worked).
    - /download/launcher serves the tester launcher zip (downloads.launcher).
    - configure-web.ps1 fills these in when ISERLE_PUBLIC_HOST is set and the
      hostname, its certificate and the firewall rule are in place; env.ps1 gets
      the shared helpers (public host, cert dir, readiness check, dist dir).
    
    /commands: every GM command grouped by the account level that unlocks it,
    with usage, help text and a search box. Command names and permissions are
    parsed from the core's ChatCommandTable entries (both table formats), levels
    from auth.rbac_default_permissions + rbac_linked_permissions, help from
    world.trinity_string or world.command (iserle_web gets SELECT on those two
    tables). A test checks that every command in the real sources is parsed.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    21 file(s) changed

    • iserle/scripts/configure-web.ps1
    • iserle/scripts/env.ps1
    • iserle/web/Cargo.lock
    • iserle/web/Cargo.toml
    • iserle/web/README.md
    • iserle/web/iserle-web.toml.dist
    • iserle/web/src/accounts.rs
    • iserle/web/src/commands.rs
    • iserle/web/src/config.rs
    • iserle/web/src/db.rs
    • iserle/web/src/lib.rs
    • iserle/web/src/main.rs
    • iserle/web/src/security.rs
    • iserle/web/src/web.rs
    • iserle/web/static/app.js
    • iserle/web/static/style.css
    • iserle/web/templates/base.html
    • iserle/web/templates/commands.html
    • iserle/web/templates/index.html
    • iserle/web/templates/register.html
    • iserle/web/templates/registered.html

    Owl

Forever

  • CMSG_SET_ACTION_BUTTON index is uint16 Forever sends 10-byte packets (uint64 action + uint16 index; retail 12.1.0 uses a uint8 index), which left a 1-byte unprocessed tail and wrong indices. Indices at or above TC's 180 buttons are ignored: the core and characters.character_action keep 180 buttons. Verified in game (run 13): no unprocessed tail for SET_ACTION_BUTTON. adbbc23a35 · 2026-10-01 20:50

    2 file(s) changed

    • src/server/game/Handlers/MiscHandler.cpp
    • src/server/game/Server/Packets/SpellPackets.h

    Owl

Forever update fields

  • GameObjectData and the GameObject create part Decoded from the client's readers in memory images and the transport crash of runs 11 and 12 (ASSERT(endPos < Size()) on a transport create): - GameObject create part: the int32 behind bit8 comes before the transport part, not after it (create bits reader WowB 0x999C30). - GameObjectData: one more int32 after FactionTemplate (create reader 0x43EEEB0, write site 0x43EF5B5), purpose unknown (ForeverUnk_74). - GameObjectData update mask is 28 bits; TC bits 16..26 move to 17..27 (WriteForeverChangesMaskBlock, update reader 0x43EFF10). uf-re re-encode of the run 11 packet: transport values block 117 -> 121 bytes, consumed exactly. In game (run 13) the client enters the world next to transports and stays there for 30 minutes without a crash. 23f6fa4622 · 2026-10-01 20:50

    3 file(s) changed

    • src/server/game/Entities/Object/BaseEntity.cpp
    • src/server/game/Entities/Object/Updates/UpdateFields.cpp
    • src/server/game/Entities/Object/Updates/UpdateFields.h

    Owl

Build 16 · 2026-10-01 20:04

current d7dfba0252bd uncommitted changes 3 run(s), 1h 52m online, peak 3 player(s)

Docs

  • main branch, GitHub mirror, website, duplicate spawns d7dfba0252 · 2026-10-01 19:46
    CLAUDE.md: work branch is main (was forever), origin is published with publish-github.ps1 (never a plain
    push), the website in the architecture/disk layout, and the 2026-10-01 progress log. SETUP.md: branch name.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    2 file(s) changed

    • CLAUDE.md
    • SETUP.md

    Owl

Forever world DB

  • remove exact duplicate creature spawns 648ab2c2d5 · 2026-10-01 19:46
    TDB has ~5.9k creature spawns that duplicate another spawn of the same creature (same map, phases,
    difficulties and terrain swap, < 1 yd apart), e.g. three Conservator Ilthalaine in Shadowglen. Remove
    them, keeping the most recently verified spawn, only when neither spawn of a pair is referenced by
    scripts, game events, pools, script-controlled spawn groups, spawn tracking, formations, linked
    respawns or vehicle accessories. Also removes the third Ilthalaine 14 yd away. 5,519 spawns on TDB
    1210.26091; tested on a copy of the world tables.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • sql/updates/world/forever/2026_10_01_00_world_forever.sql

    Owl

publish-github.ps1

  • publish main to GitHub as a mirror from the fork point 9f172ceba2 · 2026-10-01 19:46
    GitHub rejects TrinityCore's full history in a new repository (20 commits from 2010 have a malformed
    author line). The script publishes a deterministic, linear mirror instead: a snapshot of TrinityCore at
    our fork point, then our first-parent commits with identical trees, authors, dates and messages plus an
    Iserle-Commit trailer. Re-running gives the same hashes, so every publish is a fast-forward.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • iserle/scripts/publish-github.ps1

    Owl

Scripts

  • start iserle-web with the servers, log installed builds 04d27046ab · 2026-10-01 19:46
    - start-servers.ps1 / stop-servers.ps1 also manage iserle-web once it is installed and configured;
      start-servers.ps1 -Only starts single servers.
    - build.ps1 appends each installed build to <server>\builds.jsonl (the revision the binaries report, plus
      the uncommitted files) for the website's build history.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • iserle/scripts/build.ps1
    • iserle/scripts/start-servers.ps1
    • iserle/scripts/stop-servers.ps1

    Owl

iserle-web

  • website with registration, realm status, patch notes and admin dashboard 9dff824226 · 2026-10-01 19:46
    Rust (axum + askama + sqlx) site on 127.0.0.1:8090: one binary, templates and assets compiled in.
    
    - Registration writes what `bnetaccount create` writes (srp_version 2 Battle.net account, game account
      <id>#1, realmcharacters) in one transaction. src/srp.rs mirrors SRP6.cpp; tests/tc_compat.rs checks it
      against an account TrinityCore created.
    - Realm status from realmlist/build_info, the worldserver's uptime rows and a TCP probe of the world and
      login ports.
    - Patch notes: our commits (upstream/master..main) grouped by the server build that first ran them
      (builds.jsonl + uptime table); upstream merges list the TrinityCore commits they brought in.
    - Admin dashboard (GM level 3): accounts, registrations, characters, online players, server runs, staff,
      bans, build/source status.
    - Loopback-only bind, least-privilege MySQL user (configure-web.ps1), CSRF tokens, rate limits, strict CSP.
    - WoW: Forever inspired theme with original art; Cinzel (SIL OFL) is served by the site itself.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    44 file(s) changed

    • .gitignore
    • iserle/scripts/configure-web.ps1
    • iserle/web/Cargo.lock
    • iserle/web/Cargo.toml
    • iserle/web/README.md
    • iserle/web/build.ps1
    • iserle/web/iserle-web.toml.dist
    • iserle/web/src/accounts.rs
    • iserle/web/src/admin.rs
    • iserle/web/src/builds.rs
    • iserle/web/src/chart.rs
    • iserle/web/src/config.rs
    • iserle/web/src/db.rs
    • iserle/web/src/fmt.rs
    • iserle/web/src/git.rs
    • iserle/web/src/lib.rs
    • iserle/web/src/main.rs
    • iserle/web/src/names.rs
    • iserle/web/src/realm.rs
    • iserle/web/src/security.rs
    • iserle/web/src/srp.rs
    • iserle/web/src/web.rs
    • iserle/web/static/app.js
    • iserle/web/static/error.html
    • iserle/web/static/favicon.svg
    • iserle/web/static/fonts/OFL.txt
    • iserle/web/static/fonts/cinzel-latin.woff2
    • iserle/web/static/style.css
    • iserle/web/templates/admin.html
    • iserle/web/templates/base.html
    • iserle/web/templates/changes.html
    • iserle/web/templates/index.html
    • iserle/web/templates/login.html
    • iserle/web/templates/merge.html
    • iserle/web/templates/not_found.html
    • iserle/web/templates/partials/area_group.html
    • iserle/web/templates/partials/commit.html
    • iserle/web/templates/partials/emblem.html
    • iserle/web/templates/partials/horizon.html
    • iserle/web/templates/partials/status_badge.html
    • iserle/web/templates/register.html
    • iserle/web/templates/registered.html
    • iserle/web/templates/status.html
    • iserle/web/tests/tc_compat.rs

    Owl

iserle-ctl

  • live-test harness for the client and worldserver 97a8a6f11d · 2026-10-01 18:22
    Runs worldserver console commands (console input injection), captures the
    client window, sends input only while the client is the foreground window,
    waits for log lines, closes the client and summarizes crash reports. Used
    to drive the patched client against our own server during protocol work.

    2 file(s) changed

    • iserle/tools/iserle-ctl/IserleCtl.cs
    • iserle/tools/iserle-ctl/build.ps1

    Owl

uf-re

  • update-field layout recovery tool 1a3cdf7c45 · 2026-10-01 18:22
    Parses SMSG_UPDATE_OBJECT from our server's packet log with TC's writer
    model (interpreting UpdateFields.cpp), traces the Forever client's reader
    functions in memory images, re-encodes a logged packet with an edited
    layout, and inspects client crash dumps (registers, data stores, captured
    heap). Used to derive the update-field fixes; see its README.

    10 file(s) changed

    • iserle/tools/uf-re/Buf.cs
    • iserle/tools/uf-re/Dmp.cs
    • iserle/tools/uf-re/KnownNames.cs
    • iserle/tools/uf-re/Mem.cs
    • iserle/tools/uf-re/Pkt.cs
    • iserle/tools/uf-re/Program.cs
    • iserle/tools/uf-re/README.md
    • iserle/tools/uf-re/TcUf.cs
    • iserle/tools/uf-re/Trace.cs
    • iserle/tools/uf-re/build.ps1

    Owl

Forever query packets

  • player names and quest info 95b5eb4f9e · 2026-10-01 18:22
    - PlayerGuidLookupData has two 9-bit strings after the name (surname and an
      unknown one, sent empty). TC's layout made the client crash on a bad
      pointer while parsing SMSG_QUERY_PLAYER_NAMES_RESPONSE.
    - QuestInfo reads 11 int32 before RewardXPMultiplier (TC writes 9); the two
      extra ones are sent as 0. TC's layout made the client read the objectives
      count from AllowableRaces and request 1.4 TB of memory.
    
    Which fields are new is inferred from position; the readers are partly
    still encrypted in the memory images.

    4 file(s) changed

    • src/server/game/Server/Packets/QueryPackets.cpp
    • src/server/game/Server/Packets/QueryPackets.h
    • src/server/game/Server/Packets/QuestPackets.cpp
    • src/server/game/Server/Packets/QuestPackets.h

    Owl

Forever update fields

  • item, unit, player and active player layouts 4eb7b63f94 · 2026-10-01 18:22
    Decoded from the client's create and update readers in memory images and
    checked against its crash dumps (parsed mirror values and read position):
    
    - ItemData: 14 enchantment slots (TC 13).
    - AzeriteEmpoweredItemData: not read by Forever, no longer written.
    - VisibleItem: a 4th int32; 12-bit update mask.
    - UnitData: extra fields (u8, 2x u16, i32, float, float, guid, i32,
      float); ModHaste is owner-only.
    - PlayerData: extra structs and a second string after the name.
    - ActivePlayerData: 145 inventory slots (TC 105), extra fields, 4-bit bank
      tab settings sizes.
    - Changes masks of UnitData, PlayerData and ActivePlayerData are renumbered
      (WriteForeverChangesMask); field data stays in TC's order.
    
    Names and exact positions of most new fields are unknown or inferred; the
    comments say which. In game the self-create packet now parses and the
    client enters the world.

    2 file(s) changed

    • src/server/game/Entities/Object/Updates/UpdateFields.cpp
    • src/server/game/Entities/Object/Updates/UpdateFields.h

    Owl

Forever

  • entity fragment ids are one higher below 200 742def2dbc · 2026-10-01 18:22
    Read from the client's runtime fragment registry (id and name per entry).
    With TC's ids the client called a null create callback for the first object
    in SMSG_UPDATE_OBJECT. The Tag_* ids (200+) are unchanged.

    1 file(s) changed

    • src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h

    Owl

  • 360 action buttons in SMSG_UPDATE_ACTION_BUTTONS 342941b10b · 2026-10-01 18:22
    The client's reader asserts datasize == 8 * NUM_SAVED_ACTION_BUTTONS + 1
    with 360 buttons (2881 bytes); TC sends 180. Slots 180..359 stay empty.

    1 file(s) changed

    • src/server/game/Server/Packets/SpellPackets.h

    Owl

Forever character list

  • entry layout and surnames a076145175 · 2026-10-01 18:22
    Forever's character entry has one more 4-byte field between
    LastLoginVersion and the customizations, and the surname length is 6 bits
    (we sent 9). Decoded from four client crash dumps by comparing the packet
    bytes with the client's parsed entry. Which slot is the new one and what it
    means is unknown; it is sent as 0.
    
    Surnames are read from characters.surname.
    
    Tested in game: the list shows "Iserle Acosta, Level 1 Druid" without the
    earlier crash.

    3 file(s) changed

    • src/server/game/Handlers/CharacterHandler.cpp
    • src/server/game/Server/Packets/CharacterPackets.cpp
    • src/server/game/Server/Packets/CharacterPackets.h

    Owl

Forever opcodes

  • generated server and client overrides 1aceac1c05 · 2026-10-01 18:22
    Server: index drift in groups 0x45 (two ranges), 0x4A (chat, +2 from
    SMSG_MOTD) and 0x51 (guild, -1); HEALTH_UPDATE doesn't exist in Forever.
    Client: drift ranges for CliPlayer, CliPlayerGameEvent and CliUserClient,
    plus guards that send Forever-only messages to unused core indices.
    Unknown client opcodes are dropped instead of disconnecting.
    
    TUTORIAL_FLAGS and SERVER_TIME_OFFSET are sent again: the client's decoded
    fixed-size readers take exactly TC's 32 / 8 bytes.
    
    Generated by iserle/tools/opcode-re. Tested in game on 2026-10-01: login,
    character list and entering the world.

    1 file(s) changed

    • iserle/scripts/configure-server.ps1

    Owl

opcode-re

  • offline Forever opcode map tools (server and client) be156c4c91 · 2026-10-01 18:22
    opcode-re (server messages): finds the message classes by vtable shape in
    .rdata, reads GetOpcode anchors and dispatcher cases from memory images and
    client crash dumps, aligns Forever against retail 12.1.0 (= TC master) on
    .pdata fingerprints, runs regression checks and generates
    Opcodes.ServerOverrides / Opcodes.ServerDrop.
    
    cmsg (client messages): the same for client messages (GetOpcode/Write
    immediates, per-protocol range checks, live opcodes from World.pkt and
    Server.log) and generates Opcodes.ClientOverrides.
    
    Inputs are read-only; outputs go to F:\iserle\re\, never into git.
    Built with Windows' csc and the Iced disassembler; see the READMEs.

    34 file(s) changed

    • iserle/tools/opcode-re/Align.cs
    • iserle/tools/opcode-re/Calib.cs
    • iserle/tools/opcode-re/Containers.cs
    • iserle/tools/opcode-re/Disasm.cs
    • iserle/tools/opcode-re/Dispatch.cs
    • iserle/tools/opcode-re/Eh.cs
    • iserle/tools/opcode-re/Find.cs
    • iserle/tools/opcode-re/FixedSize.cs
    • iserle/tools/opcode-re/Groups.cs
    • iserle/tools/opcode-re/Indels.cs
    • iserle/tools/opcode-re/Layout.cs
    • iserle/tools/opcode-re/Minidump.cs
    • iserle/tools/opcode-re/Msgs.cs
    • iserle/tools/opcode-re/Pe.cs
    • iserle/tools/opcode-re/Program.cs
    • iserle/tools/opcode-re/README.md
    • iserle/tools/opcode-re/Report.cs
    • iserle/tools/opcode-re/Robust.cs
    • iserle/tools/opcode-re/SmsgMap.cs
    • iserle/tools/opcode-re/Tc.cs
    • iserle/tools/opcode-re/build.ps1
    • iserle/tools/opcode-re/cmsg/Cmsg.cs
    • iserle/tools/opcode-re/cmsg/Compact.cs
    • iserle/tools/opcode-re/cmsg/Evidence.cs
    • iserle/tools/opcode-re/cmsg/Explore.cs
    • iserle/tools/opcode-re/cmsg/Groups.cs
    • iserle/tools/opcode-re/cmsg/Pages.cs
    • iserle/tools/opcode-re/cmsg/Pe.cs
    • iserle/tools/opcode-re/cmsg/README.md
    • iserle/tools/opcode-re/cmsg/Report.cs
    • iserle/tools/opcode-re/cmsg/Solve.cs
    • iserle/tools/opcode-re/cmsg/Tc.cs
    • iserle/tools/opcode-re/cmsg/Translation.cs
    • iserle/tools/opcode-re/cmsg/build.ps1

    Owl

worldserver

  • Opcodes.DropUnknownClient and wire-level opcode trace 958c6d50f2 · 2026-10-01 18:22
    A client build with more messages than the core's opcode table (WoW:
    Forever) sends opcodes the core has no slot for, and TC disconnects on
    them. Opcodes.DropUnknownClient = 1 logs and skips such packets once the
    session is authenticated (default 0 keeps TC's behaviour).
    
    With opcode translation active, network.opcode TRACE also logs the wire
    value and payload size of every packet:
      C->S wire 0x... size N -> [CMSG_...]
      S->C wire 0x... size N <- [SMSG_...]

    4 file(s) changed

    • src/server/game/Server/Protocol/OpcodeTranslation.cpp
    • src/server/game/Server/Protocol/OpcodeTranslation.h
    • src/server/game/Server/WorldSocket.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Kiro steering

  • project context and opcode RE rules 70711e3ef1 · 2026-10-01 18:22
    Always-included steering for Kiro sessions: layout, commands and guardrails
    (offline only, nothing written under the client install, no client-derived
    bytes in git, no history-reading git commands in this blobless clone), plus
    the opcode reverse-engineering method and how findings are verified.

    2 file(s) changed

    • .kiro/steering/opcode-re.md
    • .kiro/steering/project.md

    Owl

11 uncommitted file(s) at build time
  • CLAUDE.md
  • docs/protocol-notes.md
  • iserle/tools/uf-re/KnownNames.cs
  • iserle/tools/uf-re/Pkt.cs
  • iserle/tools/uf-re/Program.cs
  • iserle/tools/uf-re/README.md
  • src/server/game/Entities/Object/BaseEntity.cpp
  • src/server/game/Entities/Object/Updates/UpdateFields.cpp
  • src/server/game/Entities/Object/Updates/UpdateFields.h
  • src/server/game/Handlers/MiscHandler.cpp
  • src/server/game/Server/Packets/SpellPackets.h

Build 15 · 2026-10-01 09:11

0da32c849b61 uncommitted changes 9 run(s), 10h 05m online, peak 1 player(s)

gitignore

  • Python bytecode caches 0da32c849b · 2026-10-01 02:27
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • .gitignore

    Owl

import-vmangos.ps1

  • import into hotfixes_forever, never the live hotfixes DB 4b37604933 · 2026-09-27 20:20
    -Reset now also copies `hotfixes` to `hotfixes_forever`, and the importer's
    hotfix connection points there (an earlier run targeted the live DB; it wrote
    nothing because every VMaNGOS broadcast text ID already existed).
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • iserle/scripts/import-vmangos.ps1

    Owl

VMaNGOS import

  • record all failing writes; keep Forever's broadcast texts 8c76ea7ccf · 2026-09-25 01:04
    - Report mode records every failed write per table and message (e.g. TC
      master's world_safe_locs.ID has no AUTO_INCREMENT) and carries on.
    - Broadcast text: skipped for Forever (VMI_SKIP_BROADCAST_TEXT=1, set by
      import-vmangos.ps1) so the client's BroadcastText.db2 isn't overridden by
      vanilla hotfix rows; the HermesProxy CSV is optional.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • contrib/vmangos_db_import/database.py
    • contrib/vmangos_db_import/importer/broadcast.py
    • iserle/scripts/import-vmangos.ps1

    Owl

  • schema-report mode, fix inverted teleport branch 2149c4b9ab · 2026-09-25 00:58
    - VMI_SCHEMA_REPORT=1 (import-vmangos.ps1 -SchemaReport): writes to TC
      tables/columns that don't exist are recorded and skipped; the full list is
      printed at the end, so one run shows every schema difference.
    - area.py: upstream deleted teleports VMaNGOS has and updated from a missing
      VMaNGOS row for the others (crash); branches swapped.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • contrib/vmangos_db_import/database.py
    • contrib/vmangos_db_import/db_import.py
    • contrib/vmangos_db_import/importer/area.py
    • iserle/scripts/import-vmangos.ps1

    Owl

  • configurable connection, import-vmangos.ps1 0730171911 · 2026-09-25 00:52
    - database.py: host/port/credentials/database names from VMI_* environment
      variables (upstream values stay the defaults).
    - import-vmangos.ps1: copies `world` to `world_forever` (-Reset), runs the
      importer with the portable Python (D:\iserle\deps\python) against the
      `vmangos` schema; never touches the live `world` DB.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    2 file(s) changed

    • contrib/vmangos_db_import/database.py
    • iserle/scripts/import-vmangos.ps1

    Owl

contrib

  • vendor TrinityCoreClassic's VMaNGOS -> TrinityCore world DB importer 35fd23bd42 · 2026-09-25 00:51
    Unmodified copy of contrib/vmangos_db_import from Frostshake/TrinityCoreClassic
    (GPL-2.0, same as TrinityCore) at 1fc8f1eb; see UPSTREAM. Adapted for our
    schema in following commits.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    26 file(s) changed

    • contrib/vmangos_db_import/UPSTREAM
    • contrib/vmangos_db_import/constants.py
    • contrib/vmangos_db_import/database.py
    • contrib/vmangos_db_import/db_import.py
    • contrib/vmangos_db_import/db_verify.py
    • contrib/vmangos_db_import/importer/area.py
    • contrib/vmangos_db_import/importer/battleground.py
    • contrib/vmangos_db_import/importer/broadcast.py
    • contrib/vmangos_db_import/importer/cleanup.py
    • contrib/vmangos_db_import/importer/creature.py
    • contrib/vmangos_db_import/importer/event.py
    • contrib/vmangos_db_import/importer/gameobject.py
    • contrib/vmangos_db_import/importer/gossip.py
    • contrib/vmangos_db_import/importer/graveyard.py
    • contrib/vmangos_db_import/importer/item.py
    • contrib/vmangos_db_import/importer/loot.py
    • contrib/vmangos_db_import/importer/misc.py
    • contrib/vmangos_db_import/importer/npc.py
    • contrib/vmangos_db_import/importer/player.py
    • contrib/vmangos_db_import/importer/pool.py
    • contrib/vmangos_db_import/importer/quest.py
    • contrib/vmangos_db_import/importer/skill.py
    • contrib/vmangos_db_import/importer/spell.py
    • contrib/vmangos_db_import/importer/trainer.py
    • contrib/vmangos_db_import/importer/transport.py
    • contrib/vmangos_db_import/importer/waypoint.py

    Owl

check-upstream.ps1

  • watch public sources for 12.1.5 / Forever protocol data a401b7fc5a · 2026-09-25 00:47
    Retail 12.1.5.69952 (the engine generation Forever runs on) is on the
    experimental PTR; WowPacketParser and TrinityCore don't support it yet. The
    script reports new builds, WPP version folders, matching TC/WPP commits and
    public Forever server projects.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    2 file(s) changed

    • docs/protocol-notes.md
    • iserle/scripts/check-upstream.ps1

    Owl

Forever

  • store character surnames bfa8913913 · 2026-09-25 00:46
    characters.surname (varchar 24), written in the create transaction. Surnames
    follow the same character rules as names (name check and create); uniqueness
    stays on the first name.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • sql/updates/characters/forever/2026_09_25_00_characters_forever.sql
    • src/server/database/Database/Implementation/CharacterDatabase.cpp
    • src/server/database/Database/Implementation/CharacterDatabase.h
    • src/server/game/Handlers/CharacterHandler.cpp

    Owl

Build 14 · 2026-09-27 20:19

482ff2a342df uncommitted changes 2 run(s), 8h 31m online, peak 1 player(s)

General

  • Progress log; character list entry: empty surname field (unverified) 482ff2a342 · 2026-09-24 23:34
    Character creation works. The client still asserts parsing the character list
    once it has an entry; the surname-after-name placement in the entry is a guess
    that didn't fix it. See CLAUDE.md progress log.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • CLAUDE.md
    • src/server/game/Server/Packets/CharacterPackets.cpp
    • src/server/game/Server/Packets/CharacterPackets.h

    Owl

Build 13 · 2026-09-24 23:25

d588c4c4adf6 uncommitted changes 2 run(s), 10m online, peak 0 player(s)

Forever

  • default specialization is the class's only spec d588c4c4ad · 2026-09-24 23:22
    Forever's ChrSpecialization has one spec per class at OrderIndex 0 and no
    retail "initial" spec (index 4), so Player::Create asserted in
    ResetTalentSpecialization and took the worldserver down on character create.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • src/server/game/DataStores/DB2Stores.cpp

    Owl

Build 12 · 2026-09-24 23:21

df4cc68572c2 uncommitted changes 1 run(s), 0s online, peak 0 player(s)

General

  • Desktop shortcuts for the server and the client df4cc68572 · 2026-09-24 23:16
    - install-shortcut.ps1 creates "Iserle Server" (start-servers.ps1) and
      "Iserle Client" (play.ps1) on the desktop.
    - start-servers.ps1 takes a named mutex, so two runs at once no longer start
      every server twice.
    - play.ps1 refuses to launch when bnetserver/worldserver aren't listening, and
      can start them itself with -StartServers; -PauseOnError keeps the window open.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • iserle/scripts/install-shortcut.ps1
    • iserle/scripts/play.ps1
    • iserle/scripts/start-servers.ps1

    Owl

Forever character creation

  • surnames and request layout b757fe84f0 · 2026-09-24 23:08
    WoW: Forever characters have a name and a surname.
    - CMSG_CHECK_CHARACTER_NAME_AVAILABILITY: 6-bit name length, 9-bit surname
      length, then both strings (TC read garbage and answered "name taken").
    - CMSG_CREATE_CHARACTER: the surname length follows the template/trial/NPE
      flags, and an extra int32 (-1 seen) precedes TimerunningSeasonID. Decoded
      from a client request; the end-to-end create is not verified in-game yet.
    - The surname is parsed but not stored; names stay unique by first name.
    - Undead Paladin (new in Forever) starts where Undead Warriors do.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • sql/updates/world/forever/2026_09_24_02_world_forever.sql
    • src/server/game/Handlers/CharacterHandler.cpp
    • src/server/game/Server/Packets/CharacterPackets.cpp
    • src/server/game/Server/Packets/CharacterPackets.h

    Owl

Build 11 · 2026-09-24 22:28

27b94d7b89d2 uncommitted changes 4 run(s), 20m online, peak 0 player(s)

Forever character list

  • send account data times and item collection data 27b94d7b89 · 2026-09-24 22:23
    The client never finished "Retrieving character list" until
    SMSG_ACCOUNT_DATA_TIMES and SMSG_ACCOUNT_ITEM_COLLECTION_DATA were sent again
    (now at their corrected wire numbers 0x4601B5 / 0x460362). Which of the two
    it waits for is not isolated yet.
    
    Also adds Realm.SendGameRules (configure-server.ps1 sets 0 while the meaning
    of TC's retail rule IDs in Forever is unverified).
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • iserle/scripts/configure-server.ps1
    • src/server/game/Handlers/AuthHandler.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Build 10 · 2026-09-24 22:01

1f26e19c6093 uncommitted changes 2 run(s), 11m online, peak 0 player(s)

Forever character screen

  • opcode remap, game mode, new-player ruleset flow 1f26e19c60 · 2026-09-24 21:49
    - Opcodes.ServerOverrides accepts ranges; configure-server.ps1 remaps server
      group 0x45 (-> wire 0x46) where Forever's message numbering drifts, from
      the client's message classes aligned against retail 12.1.0 (method and
      table in docs/protocol-notes.md).
    - Glue screen: Realm.ContentSetID / Realm.GameModeIDs. Forever ties
      GameMode.db2 rows to rulesets (Normal = content set 137 / game mode 15);
      with retail's standard mode 8 the client hung at "Retrieving character list".
    - bnetserver: an account without a last played character gets no realm from
      LastCharPlayed until it has asked for the ruleset list in that session, so
      the client shows "Choose Your Gameplay Style" first. Forever's character
      screen only opens character creation for an empty list after a ruleset was
      picked (GlueXML: loginState.hasSelectedExperiencePreset).
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    8 file(s) changed

    • docs/protocol-notes.md
    • iserle/scripts/configure-server.ps1
    • src/server/bnetserver/Server/Session.h
    • src/server/bnetserver/Services/GameUtilitiesService.cpp
    • src/server/bnetserver/Services/GameUtilitiesService.h
    • src/server/game/Handlers/AuthHandler.cpp
    • src/server/game/Server/Protocol/OpcodeTranslation.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Build 9 · 2026-09-24 21:24

a58d3c85a3a9 uncommitted changes 2 run(s), 32m online, peak 0 player(s)

Forever glue screen

  • packet layout, race unlocks, race/class data a58d3c85a3 · 2026-09-24 21:18
    - SMSG_FEATURE_SYSTEM_STATUS_GLUE_SCREEN: Forever's reader (decoded from the
      client) has 2 fewer flags before the Europa optional, one more flag after
      the RealmHiddenAlert length and no KioskSessionDurationMinutes. With TC's
      layout the client misread everything after the bits (e.g. showed a
      "Remix: Mists of Pandaria" timerunning season).
    - Races that need no achievement are sent as unlocked; the Forever client
      otherwise says "complete an achievement to unlock this race".
    - World DB: race/class availability from Forever's CharBaseInfo.db2 (classic
      combos plus Skyborne 95/96, Dwarf Shaman, Undead Paladin).
    - Drop SMSG_SERVER_TIME_OFFSET too (null read in the client).
    - stop-servers.ps1 / start-servers.ps1 -Restart close the server windows and
      wait for the exe to be released.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    6 file(s) changed

    • iserle/scripts/configure-server.ps1
    • iserle/scripts/start-servers.ps1
    • iserle/scripts/stop-servers.ps1
    • sql/updates/world/forever/2026_09_24_01_world_forever.sql
    • src/server/game/Handlers/CharacterHandler.cpp
    • src/server/game/Server/Packets/SystemPackets.cpp

    Owl

Build 8 · 2026-09-24 21:17

e961a8939b4f uncommitted changes 1 run(s), 0s online, peak 0 player(s)

launcher

  • --dump-image for offline protocol analysis; mmaps script e961a8939b · 2026-09-24 20:38
    WowB.exe's code section is encrypted on disk and only decrypted at runtime,
    so opcode tables can only be recovered from memory. --dump-image (implies
    --attach, read-only) writes the mapped module to a file outside the repo;
    *.image.bin and *.dmp are gitignored.
    
    Launcher messages now describe the real timing: the key store is built during
    login and the first world connection may lose the race (reason 24), after
    which the client retries by itself.
    
    mmaps.ps1 generates movement maps at below-normal priority into a staging
    folder (running its own copy of the generator so installs aren't blocked) and
    installs them with -Install.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • .gitignore
    • SETUP.md
    • iserle/launcher/IserleLauncher.cs
    • iserle/scripts/mmaps.ps1

    Owl

Core/Network

  • Opcodes.ServerDrop to hold back server packets 9c9e93dcaf · 2026-09-24 20:38
    Forever's client reached character enumeration, then asserted on
    SMSG_ACCOUNT_DATA_TIMES: core 0x4501B6 -> wire 0x4601B6 is a 16-byte message
    in the client, so indices inside server group 0x45 drift even though the group
    shift is right. Until that group is mapped, configure-server.ps1 drops the
    optional glue-screen packets from it.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    5 file(s) changed

    • iserle/scripts/configure-server.ps1
    • src/server/game/Server/Protocol/OpcodeTranslation.cpp
    • src/server/game/Server/Protocol/OpcodeTranslation.h
    • src/server/game/Server/WorldSocket.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Build 7 · 2026-09-24 20:32

a4edb7021512 uncommitted changes 3 run(s), 32m online, peak 0 player(s)

Core/Network

  • send the realm's region group in SMSG_ENTER_ENCRYPTED_MODE a4edb70215 · 2026-09-24 20:19
    The client verifies the ENTER_ENCRYPTED_MODE signature with the certificate
    store key whose id equals the packet's RegionGroup. TC never sets it (0), so
    the Forever client rejected the packet with CMSG_LOG_DISCONNECT reason 24 even
    though its key #8 had our public key.
    
    New option EnterEncryptedMode.RegionGroup: -1 (default) looks up the group of
    the realm's region in Cfg_Regions (Forever beta: region 70 -> group 8).
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • CLAUDE.md
    • docs/protocol-notes.md
    • src/server/game/Server/WorldSocket.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Build 6 · 2026-09-24 20:17

fa01c331a86c uncommitted changes 1 run(s), 10m online, peak 0 player(s)

launcher

  • rescan continuously; add --attach and --scan-only fa01c331a8 · 2026-09-24 20:16
    The client can build a new certificate store per login, so the watch loop now
    patches every valid store that still has the original key #8 instead of
    stopping after the first one.
    
    --attach patches an already running WowB.exe, but only one whose command line
    carries our -config file (read via WMI). --scan-only reports the stores and
    changes nothing.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    2 file(s) changed

    • iserle/launcher/IserleLauncher.cs
    • iserle/launcher/build.ps1

    Owl

Core/Network

  • config-driven opcode translation at the socket 9e8081fcff · 2026-09-24 20:05
    The Forever client reached the worldserver and answered our
    SMSG_AUTH_CHALLENGE (0x4C0000) with 0x450007 = CMSG_LOG_DISCONNECT
    (core 0x440007) one group higher. Opcodes are (group << 16) | index and
    whole groups move between builds, so translate on the wire instead of
    renumbering Opcodes.h:
    
    - OpcodeTranslation: Opcodes.ClientGroupShift / ServerGroupShift
      ("first-last:+delta" over core groups) plus exact Client/ServerOverrides;
      identity when nothing is configured
    - WorldSocket: translate incoming opcodes (incl. the hotfix size check),
      outgoing opcodes, SMSG_COMPRESSED_PACKET and the compressed inner opcode;
      "wrong opcode" errors log wire and core values
    - configure-server: first hypothesis, every group +1 in both directions
    - protocol-notes: login/realm flow findings (sub-region 70-1-70, last
      played char params, JSONUtilityInfo, super districts, no realm list)
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    7 file(s) changed

    • docs/protocol-notes.md
    • iserle/scripts/configure-server.ps1
    • src/server/game/Server/Protocol/OpcodeTranslation.cpp
    • src/server/game/Server/Protocol/OpcodeTranslation.h
    • src/server/game/Server/WorldSocket.cpp
    • src/server/game/World/World.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Build 5 · 2026-09-24 20:04

e2ec6e518be4 uncommitted changes 1 run(s), 10m online, peak 0 player(s)

bnetserver

  • include Param_LastPlayedTime in the Forever fallback realm reply e2ec6e518b · 2026-09-24 19:50
    Forever's client param list (binary strings) has Param_RealmEntry,
    Param_LastPlayedTime and Param_UtilityInfo but no Param_CharacterName /
    Param_CharacterGUID; with no Param_LastPlayedTime it logged
    numRegionsWithData=0 and ignored the reply (WOW51900309).
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • src/server/bnetserver/Services/GameUtilitiesService.cpp

    Owl

  • send Forever-shaped JSONUtilityInfo (realmPermissions + loginLicenses) 13415380ff · 2026-09-24 19:49
    The Forever client's JSONUtilityInfo is { realmPermissions, loginLicenses }
    (from its JSON reflection table), TrinityCore's is { realmPermissions,
    entitlements }. The client logged realmPermissions=0 / licensesCount=0 for
    our response and refused the realm with WOW51900309.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • src/server/bnetserver/Services/GameUtilitiesService.cpp

    Owl

  • let Forever connect to a realm of the chosen ruleset 7b61dc45cb · 2026-09-24 19:42
    After the ruleset is picked the Forever client has no realm list: it
    connects to the realm returned by Command_LastCharPlayedRequest_v1 and
    fails with WOW51900309 ("No realms are currently available") if there is
    none (Aurora.log: "Requesting connection to a super district realm").
    
    - LastCharPlayed: without a last played character, return the first
      available realm of the sub-region (Param_RealmEntry + UtilityInfo)
    - realm entries get "superDistrictID" (RealmList.SuperDistrictID), which
      Forever's JamJSONRealmEntry has and TC's RealmEntry proto doesn't
    - sub-regions are matched on region + site: the beta client always asks
      for "70-1-70" (region 70 = Cfg_Regions "Beta"); realm moved to region 70
    - worldserver RealmZone 186 ("Beta"): it rewrites realmlist.timezone
      on start, which undid the earlier SQL update
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    6 file(s) changed

    • iserle/scripts/configure-server.ps1
    • sql/updates/auth/forever/2026_09_24_03_auth_forever.sql
    • src/server/bnetserver/Services/GameUtilitiesService.cpp
    • src/server/bnetserver/bnetserver.conf.dist
    • src/server/shared/Realm/RealmList.cpp
    • src/server/shared/Realm/RealmList.h

    Owl

Build 4 · 2026-09-24 19:43

5de71bdb713e uncommitted changes 1 run(s), 11m online, peak 0 player(s)

No new commits: a rebuild with local, uncommitted changes.

Build 3 · 2026-09-24 19:35

5de71bdb713e 1 run(s), 0s online, peak 0 player(s)

General

  • Match the official Forever beta ruleset screen: Normal + PvP, Beta category 5de71bdb71 · 2026-09-24 19:35
    - realm category (realmlist.timezone -> cfgCategoriesID) = 186 "Beta"
    - SuperDistricts = 2,1 (Normal, PvP), as on the official beta screen
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    2 file(s) changed

    • iserle/scripts/configure-server.ps1
    • sql/updates/auth/forever/2026_09_24_02_auth_forever.sql

    Owl

  • Rebrand the server as Iserle 578da0fade · 2026-09-24 19:33
    User-visible names only: startup banner (new ASCII art), "Iserle rev."
    version string, Windows exe version info and service names, OS-version
    abort message, default MOTD, config file headers, realm name (auth update)
    and one server message (world update). README rewritten for Iserle with
    credit to TrinityCore.
    
    Upstream GPL copyright/license notices (source headers, AUTHORS, COPYING)
    stay as required, and internal identifiers (Trinity:: namespace, TC_LOG_*,
    TRINITY_* macros, file names) are unchanged to keep upstream merges viable.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    15 file(s) changed

    • CLAUDE.md
    • README.md
    • revision_data.h.in.cmake
    • sql/updates/auth/forever/2026_09_24_01_auth_forever.sql
    • sql/updates/world/forever/2026_09_24_00_world_forever.sql
    • src/common/Banner.cpp
    • src/common/GitRevision.cpp
    • src/common/Utilities/Util.cpp
    • src/server/bnetserver/Main.cpp
    • src/server/bnetserver/bnetserver.conf.dist
    • src/server/bnetserver/bnetserver.rc
    • src/server/game/World/World.cpp
    • src/server/worldserver/Main.cpp
    • src/server/worldserver/worldserver.conf.dist
    • src/server/worldserver/worldserver.rc

    Owl

  • Use a real hostname portal with a Let's Encrypt certificate 88400cb4df · 2026-09-24 19:19
    In-game findings: the client rejects IP portals (BLZ51901015, CN mismatch
    even with CN "*.*") and rewrites dotless portals ("localhost" became
    "localhost.actual.battle.net"). So the portal is now a hostname on the
    owner's domain that resolves to 127.0.0.1, with a publicly trusted cert.
    
    - env.ps1: $Iserle.Portal (ISERLE_PORTAL), loads gitignored
      iserle/local.settings.ps1 for machine-specific values
    - acme.ps1: Let's Encrypt DNS-01 via Posh-ACME (-Begin/-Complete), classic
      profile (keeps the Common Name), state under the certs folder
    - configure-server.ps1: bnetserver uses certs\public if present;
      LoginREST addresses = portal hostname
    - launcher: portal defaults to ISERLE_PORTAL; refuses dotless portals
      (the client would turn them into *.actual.battle.net)
    - play.ps1: start the client via the launcher with the configured portal
    - certs.ps1: local-CA server cert is a tooling fallback (CN=localhost)
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    7 file(s) changed

    • .gitignore
    • iserle/launcher/IserleLauncher.cs
    • iserle/scripts/acme.ps1
    • iserle/scripts/certs.ps1
    • iserle/scripts/configure-server.ps1
    • iserle/scripts/env.ps1
    • iserle/scripts/play.ps1

    Owl

  • Add iserle-launcher for the Forever beta client; own keys; TLS trust docs 1805043ac0 · 2026-09-24 17:45
    - iserle/launcher: C# console launcher (built with Windows' csc) adapted from
      defexnicolas/wow-classic-launcher (MIT, see THIRD_PARTY_NOTICES.md). Starts
      WowB.exe -config iserle.wtf with a loopback portal and swaps the client's
      in-heap CertStore key #8 for our EnterEncryptedMode public key. Refuses
      non-loopback portals and clients it didn't start; no network access.
    - certs.ps1: CA is now name-constrained to 127.0.0.0/8 and localhost;
      generates the Ed25519 EnterEncryptedMode key (+ public key hex);
      -Regenerate option
    - configure-server.ps1: EnterEncryptedMode.PrivateKeyFile -> our key
    - SETUP.md: launcher, per-user CA trust (with undo), optional firewall rules
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    7 file(s) changed

    • CLAUDE.md
    • SETUP.md
    • iserle/launcher/IserleLauncher.cs
    • iserle/launcher/THIRD_PARTY_NOTICES.md
    • iserle/launcher/build.ps1
    • iserle/scripts/certs.ps1
    • iserle/scripts/configure-server.ps1

    Owl

bnetserver

  • offer Forever rulesets (super districts) and place the realm cbf5c4040f · 2026-09-24 19:32
    Format recovered from the client binary's JSON reflection table (field
    count 2): JamJSONSuperDistrictEntry { superDistrictID, disallowLogin }.
    Rulesets come from Cfg_SuperDistrict / AvailableSuperDistrict (1 PvP,
    2 Normal, 3 Roleplay, 4 Hardcore); realms join one through the realm
    entry's cfgContentSetID (Cfg_SuperDistrict.ContentSetID, Normal = 137).
    
    - SuperDistricts: comma separated Cfg_SuperDistrict IDs to offer
    - RealmList.ContentSetID: cfgContentSetID for realms (was hardcoded 0)
    - configure-server: offer Normal (2), realm content set 137
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • iserle/scripts/configure-server.ps1
    • src/server/bnetserver/Services/GameUtilitiesService.cpp
    • src/server/bnetserver/bnetserver.conf.dist
    • src/server/shared/Realm/RealmList.cpp

    Owl

  • answer Forever's SuperDistrictListRequest; launcher requires firewall 072ce799b6 · 2026-09-24 19:25
    - GameUtilities: handle Command_SuperDistrictListRequest_v1 (sent by the
      Forever client right after login, before the realm list) with an empty
      Param_SuperDistrictList (JSONSuperDistrictList { superDistricts: [] },
      names from the client binary) and log its request parameters.
    - iserle-launcher: refuse to start unless Windows Firewall is on and an
      enabled outbound block rule exists for this WowB.exe (the client opened
      443 connections to Blizzard / Google Cloud hosts during the first login
      test). --no-firewall-check overrides.
    - play.ps1 rebuilds the launcher before starting it.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    5 file(s) changed

    • iserle/launcher/IserleLauncher.cs
    • iserle/launcher/build.ps1
    • iserle/scripts/play.ps1
    • src/server/bnetserver/Services/GameUtilitiesService.cpp
    • src/server/bnetserver/Services/GameUtilitiesService.h

    Owl

certs

  • issue the bnetserver certificate with CN "*.*" 5495b7f811 · 2026-09-24 18:51
    First in-game test: the Forever client connected to 127.0.0.1:1119 and
    dropped with BLZ51901015 = ERROR_NETWORK_MODULE_SSL_COMMON_NAME_DOES_NOT_
    MATCH_REMOTE_ENDPOINT (Aurora.log: result="1015"), i.e. the chain (our CA,
    trusted per-user) was accepted but the client's own Common Name check
    rejected CN=127.0.0.1. Use TC's wildcard CN convention; SANs and the
    name-constrained CA stay as they were.
    
    -NetworkDebug for bnetserver now traces session/RPC/REST loggers instead of
    setting root to debug (which mostly logged SQL).
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    2 file(s) changed

    • iserle/scripts/certs.ps1
    • iserle/scripts/configure-server.ps1

    Owl

configure-server

  • keep DB errors out of the worldserver console deb57d694a · 2026-09-24 18:47
    Printing ~6M retail-content DB errors to a console window made startup take
    ~2.5 min instead of ~45 s. They still go to DBErrors.log.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • iserle/scripts/configure-server.ps1

    Owl

Core/Auth

  • Allow an own EnterEncryptedMode signing key (PEM file) 9a1efa0fa9 · 2026-09-24 17:45
    New worldserver option EnterEncryptedMode.PrivateKeyFile: load the Ed25519
    key that signs SMSG_ENTER_ENCRYPTED_MODE from a PEM file instead of the
    built-in, publicly known TrinityCore key. Startup now fails loudly if the
    signer can't be initialized instead of continuing without one.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • src/server/game/Server/Packets/AuthenticationPackets.cpp
    • src/server/game/World/World.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Build 2 · 2026-09-24 17:40

9421b5aefba7 uncommitted changes 4 run(s), 1h 02m online, peak 0 player(s)

docs

  • record client-side requirements learned from the Classic Forever launcher 9421b5aefb · 2026-09-24 17:35
    Portal via -config file, one in-heap Ed25519 key swap (CertStore entry 8,
    TrinityCore's default EnterEncryptedMode public key), no TLS patching.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • docs/protocol-notes.md

    Owl

CLAUDE.md

  • log worldserver startup milestone a05ec89a15 · 2026-09-24 17:30
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    1 file(s) changed

    • CLAUDE.md

    Owl

General

  • Add start-servers script, network debug config; document startup findings 15c23f6950 · 2026-09-24 17:29
    - configure-server.ps1: Expansion 0, Auth.DevAllowMissingBuildKey 1,
      DBErrors.log overwrite mode, -NetworkDebug (opcode trace + World.pkt,
      bnetserver debug), support for appending keys commented out in .dist
    - start-servers.ps1: MySQL + bnetserver + worldserver in their own windows
    - protocol-notes: game data shape (powers, races incl. Skyborne 95/96,
      Classic talents, spell/transmog enums), startup compatibility fixes
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • CLAUDE.md
    • docs/protocol-notes.md
    • iserle/scripts/configure-server.ps1
    • iserle/scripts/start-servers.ps1

    Owl

Core

  • Start up on WoW: Forever 1.60.1 client data 959c7a6b25 · 2026-09-24 17:29
    The worldserver now reaches "ready" with Forever DB2s, maps and vmaps:
    
    - Powers: add POWER_HAPPINESS = 27 (Classic pet happiness, present in
      Forever's PowerType.db2), MAX_POWERS 28, matching UnitMods/EnumUtils
    - Spells: add SPELL_EFFECT_360, SPELL_AURA_665..668, TARGET_UNK_153
      (12.1.5-era values used by Forever's SpellEffect.db2), NULL handlers
    - Transmog: add Cloth/Leather/Mail/Plate outfit slot options (12-15)
    - FlightCapability.db2 is empty in Forever: return instead of AssertEntry(1)
    - Missing retail bank tab bag items is a warning, not a load error
    - Skip transports whose taxi path has no nodes (crash on retail TDB rows)
    - Missing script hotswap visual spell is a warning, not an assert
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    13 file(s) changed

    • src/server/game/DataStores/DB2Stores.cpp
    • src/server/game/DataStores/DBCEnums.h
    • src/server/game/Entities/Unit/StatSystem.cpp
    • src/server/game/Entities/Unit/Unit.cpp
    • src/server/game/Entities/Unit/Unit.h
    • src/server/game/Maps/TransportMgr.cpp
    • src/server/game/Miscellaneous/SharedDefines.h
    • src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp
    • src/server/game/Scripting/ScriptMgr.cpp
    • src/server/game/Spells/Auras/SpellAuraDefines.h
    • src/server/game/Spells/Auras/SpellAuraEffects.cpp
    • src/server/game/Spells/SpellEffects.cpp
    • src/server/game/Spells/SpellInfo.cpp

    Owl

Core/Auth

  • Add WoW: Forever 1.60.1.69977 build info and dev build-key bypass 3906c4cad6 · 2026-09-24 17:29
    - auth update: build_info (69977, 1.60.1) and realmlist gamebuild 69977
    - worldserver option Auth.DevAllowMissingBuildKey (default 0): when the
      client's build variant has no build_auth_key row, log a warning and skip
      only the CMSG_AUTH_SESSION digest comparison. The build key does not feed
      session/encryption key derivation, so a valid Battle.net login ticket and
      session key are still required. The Forever beta's key isn't known yet.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • sql/updates/auth/forever/2026_09_24_00_auth_forever.sql
    • src/server/game/Server/WorldSocket.cpp
    • src/server/worldserver/worldserver.conf.dist

    Owl

Build 1 · 2026-09-24 17:19

8885e02a1b3a uncommitted changes 2 run(s), 0s online, peak 0 player(s)

General

  • Add SETUP.md; configure worldserver for an expansion 0 client 8885e02a1b · 2026-09-24 16:46
    SETUP.md documents the no-admin Windows toolchain (VS Build Tools MSVC
    14.44, CMake, Ninja, Boost 1.84, OpenSSL 3.5.8, MySQL 8.4), disk layout,
    scripts, data extraction and how to revert everything.
    
    configure-server.ps1 now sets Expansion = 0: WoW: Forever is a Classic
    client, so TBC+ content and starting-zone map checks (map 530) don't apply.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    2 file(s) changed

    • SETUP.md
    • iserle/scripts/configure-server.ps1

    Owl

  • Add local TLS, server config and DB2 layout check scripts 3db5041b39 · 2026-09-24 16:29
    - iserle/scripts/certs.ps1: private "iserle Local CA" + bnetserver cert
      (SAN 127.0.0.1/localhost) under F:\iserle\certs; no trust-store changes
    - iserle/scripts/configure-server.ps1: deploy MySQL/OpenSSL runtime DLLs
      (incl. legacy provider) and generate bnetserver/worldserver .conf from
      .conf.dist with 127.0.0.1 binds, our DB port/credentials, our cert,
      data/log dirs and DB updater paths
    - iserle/tools/db2-check.ps1: compare extracted WDC5 headers (layout hash,
      field counts) against DB2Metadata.h; the build-bump checklist generator
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • iserle/scripts/certs.ps1
    • iserle/scripts/configure-server.ps1
    • iserle/tools/db2-check.ps1

    Owl

  • Add Windows build and portable MySQL scripts 57e63777dc · 2026-09-24 16:20
    - iserle/scripts/env.ps1: single source of paths (overridable via ISERLE_*
      env vars) and an MSVC 14.44 (v143) dev-shell importer
    - iserle/scripts/build.ps1: CMake/Ninja configure, build, install into
      F:\iserle\server (Boost 1.84 vc143 static, OpenSSL 3.5.8, MySQL 8.4 client)
    - iserle/scripts/db.ps1: init/start/stop/status/shell for a service-less
      MySQL 8.4 bound to 127.0.0.1:3307 (X Protocol off); random root/trinity
      passwords written to option files next to the datadir, never the repo
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    3 file(s) changed

    • iserle/scripts/build.ps1
    • iserle/scripts/db.ps1
    • iserle/scripts/env.ps1

    Owl

  • Add iserle-core project docs and ignore rules for the Forever fork 4fb674862c · 2026-09-24 16:10
    - CLAUDE.md: goals, hard constraints (offline, 127.0.0.1 only, no client
      files in git, own keys), disk layout, build-tracking policy, progress log
    - docs/phase0-findings.md: Phase 0 investigation (branch choice, tooling
      survey, risks, decisions)
    - docs/protocol-notes.md: 1.60.1.69977 client identification, DB2 layout
      deltas vs 12.1.0.69933, world auth / opcode encoding notes
    - .gitignore: anchored rules for client files, extracted data, sniffs,
      DB dumps, certificates/keys and live configs
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • .gitignore
    • CLAUDE.md
    • docs/phase0-findings.md
    • docs/protocol-notes.md

    Owl

Core/DataStores

  • Port DB2 layouts to WoW: Forever 1.60.1.69977 04c4fb9348 · 2026-09-24 16:46
    18 of the 370 DB2 files the worldserver loads differ from retail
    12.1.0.69933 (verified against the extracted WDC5 headers with
    iserle/tools/db2-check.ps1; now 370/370 match):
    
    AreaTable, Cfg_Regions (+ localized Name, new locale statement/table),
    CharacterLoadout, CurrencyTypes, Faction, GlobalCurve, Item, ItemSparse,
    Map, NameGen, PlayerDataElementAccount/Character, SkillLineAbility,
    SpellItemEnchantment (Classic-style layout, 32-bit fields),
    SpellProcsPerMinuteMod, SpellVisualMissile, TraitCurrency,
    TraitCurrencySource.
    
    Updates DB2Metadata/DB2LoadInfo/DB2Structure, hotfix statements, the
    extractor's Map.db2 definition and adds the matching hotfixes schema update
    under sql/updates/hotfixes/forever/. Field mapping notes, including the
    inferred SpellItemEnchantment ConditionID position, are in
    docs/protocol-notes.md.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    8 file(s) changed

    • docs/protocol-notes.md
    • sql/updates/hotfixes/forever/2026_09_24_00_hotfixes_forever.sql
    • src/server/database/Database/Implementation/HotfixDatabase.cpp
    • src/server/database/Database/Implementation/HotfixDatabase.h
    • src/server/game/DataStores/DB2LoadInfo.h
    • src/server/game/DataStores/DB2Metadata.h
    • src/server/game/DataStores/DB2Structure.h
    • src/tools/extractor_common/ExtractorDB2LoadInfo.h

    Owl

  • Add Hotfixes.LoadVerified option (default off) b6af4667a8 · 2026-09-24 16:46
    Hotfix DB rows with VerifiedBuild > 0 are data sniffed from the official
    servers of the client TrinityCore master targets (retail). For the WoW:
    Forever client they would overlay wrong records on its own DB2 data and be
    pushed to clients as hotfixes. With Hotfixes.LoadVerified = 0 only custom
    rows (VerifiedBuild <= 0) are loaded into DB2 stores and into the
    hotfix_data / hotfix_blob / hotfix_optional_data lists.
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    4 file(s) changed

    • src/server/game/DataStores/DB2Stores.cpp
    • src/server/shared/DataStores/DB2Store.cpp
    • src/server/shared/DataStores/DB2Store.h
    • src/server/worldserver/worldserver.conf.dist

    Owl