# CypherCore → WoW 12.0.7 (build 68453) — Handoff / Continuation Documento para retomar el port desde otra máquina/sesión sin perder contexto. Última actualización: 2026-07-12. --- ## Objetivo Adaptar **CypherCore** (emulador C# de WoW) de cliente **11.2.5.63796** a **12.0.7.68453**, porque 11.x ya no conecta con el cliente 12.x. Se usa **TrinityCore** (que ya soporta 12.0.7) como **referencia byte-exacta** para opcodes, estructuras DB2, UpdateFields, auth keys y fragments. ## Entorno / repos - **CypherCore** (este repo). Base de partida: 11.2.5.63796 (commit `c968aa3c3`). - **TrinityCore master** = referencia 12.0.7. **Hay que clonarlo aparte** en la nueva máquina: `git clone --depth 1 https://github.com/TrinityCore/TrinityCore.git` (contiene los datos de build 68453: opcodes, DB2Structure.h/DB2LoadInfo.h, UpdateFields.h/.cpp, auth keys en sql/base/auth_database.sql, BaseEntity.h/.cpp, WowCSEntityDefinitions.h). - .NET 10 SDK (target net9.0). Build: `dotnet build CypherCore.sln -c Release`. - Git remote de trabajo: `nightspire` → https://git.nightspire.gg/Inna/CypherCore.git ## Estado: COMPILA 0 ERRORES. Fases 1-4 + fundación de features hechas. --- ## Metodología clave (para continuar el estilo) 1. **TC es la referencia byte-exacta.** Todo cambio de wire-format se copia campo a campo de TC. 2. **Compilar tras cada cambio** (`dotnet build ... -c Release`). Nunca dejar el build roto. 3. **Lector DB2 (WDC5) de Cypher**: lee el ancho de bits del *archivo*, no del tipo C#. Y `1 campo de struct = 1 fieldIndex = 1 columna`. Por eso, en DB2, solo el **nº de campos agrupados** causa corrupción en cascada; ancho de tipo/longitud de array son solo corrección de valor. (Ver `Source/Game/DataStorage/ClientReader/DBReader.cs`.) 4. **UpdateFields**: serialización manual con `new(block, bit)`; añadir un campo obliga a renumerar bits y actualizar `WriteCreate`/`WriteUpdate`/`ClearChangesMask` + el contador `HasChangesMask(N)` + (multi-bloque) `GetBlocksMask(0), NUMBLOCKS` y el loop. Ver `GameObjectFieldData` en `UpdateFields.cs` como ejemplo trabajado. 5. **Verificación real solo con cliente** (Fase 5) — los byte-mismatches no se ven al compilar. --- ## Lo hecho (por fase) — todo commiteado en `f58dbf775` ### Fase 1 — Gate de build ✅ - `sql/updates/auth/master/2026_07_12_00_auth.sql`: build 68453 en `build_info` (12,0,7) + `build_auth_key` (7 keys copiadas de TC) + `realmlist.gamebuild=68453`. El gate es data-driven (no hay constante de build en código). Ver `Source/Framework/Realm/ClientBuildInfo.cs`. ### Fase 2 — Opcodes ✅ - `Source/Framework/Constants/Network/Opcodes.cs` remapeado **por nombre** a valores 12.0.7 de TC (885 client + 1233 server, 0 duplicados). OJO: solo se remapearon los opcodes que Cypher YA tenía; los ~287 opcodes nuevos de 12.0.7 (housing, etc.) NO se añadieron. - `CompressedPacket`/`MultiplePackets` fijados a 0x49000e/0x49000d (estaban atados a AuthChallenge+offset). ### Fase 3 — DB2 + hotfix ✅ - 32 structs DB2 alineadas a 12.0.7 (`Source/Game/DataStorage/Structs/*_Records.cs`). - `HotfixDatabase.cs`: ~29 SELECT re-alineados al orden de campos del struct (script determinista, no copia de TC porque TC parte racemasks en columnas y Cypher usa 1 long). - Refs de código arregladas: `ReputationManager.cs` (propiedad `ReputationRaceMask` en FactionRecord), `SpellInfo.cs` (campo `ScalesFromItemLevel` retirado en 12.0.7). - PENDIENTE datos: esquemas de las tablas hotfix (world DB) necesitan columnas nuevas 12.0.7. ### Fase 4 — UpdateFields ✅ - Top-level: GameObject(+FlagsB), Conversation(+1), AreaTrigger(+3), Player(+2), Unit(+5, 7→8 bloques), ActivePlayer(+12: Housing/TransmogOutfits/PVP mods). - Anidados: VisibleItem(6→11), QuestLog(30→31), BitVectors, CraftingOrderItem(7→12), SkillInfo(256→300). - ~29 clases de serialización de features Midnight añadidas (INERTES, sin cablear). ### Fixes críticos de protocolo base ✅ (fáciles de olvidar) - **CreateObject header** (`WorldObject.cs` ~línea 313): 12.0.7 añade 3 bits `Room, Decor, MeshObject` tras `Conversation`. Afecta a TODO create. Verificado vs TC `BaseEntity.cpp`. - **`EntityFragment` enum** (`WowCSEntityDefinitions.cs`): valores RENUMERADOS en 12.0.7 (se escriben en cada paquete). CGObject 0→2, tags al rango 200+ (Tag_Unit 5→204, Tag_Player 6→205), FVendor_C 117→17, FEntityPosition 112→1. Sin esto el cliente NO parsea ningún objeto. Ya a valores 12.0.7. ### Proyecto B — features Midnight desde cero (el usuario lo pidió explícitamente) Contexto: 12.0.7="Midnight" añadió Housing/Neighborhoods/PlayerInitiative/Mesh. **Ni TC las implementó como gameplay** — solo wire-format (structs, opcodes, DB2). Gameplay = diseño original sin referencia ni forma de validar. - **B-A0 (fundación) ✅**: `TypeId.MeshObject=14` (Max→15), `TypeMask.MeshObject=0x4000`, `HighGuid` Housing=55/MeshObject=56/Entity=57, tags de fragment (Tag_MeshObject=221, Housing/etc.) en `ObjectConst.cs` y `WowCSEntityDefinitions.cs`. (Todo mirroring TC.) - **B1 (MeshObject) ✅**: `Source/Game/Entities/MeshObject.cs` — entidad `: WorldObject` con el patrón de **fragmento Vendor** (MeshObjectData es fragmento `FMeshObjectData_C`, no data del bloque CGObject). Wiring en `Map.cs` (GetMeshObject) y `ObjectGuid.cs`. INERTE hasta que Housing la instancie. Referencia del patrón: `Creature.cs` (vendor, ~líneas 3140-3190, 3815-3845). --- ## PENDIENTE (tareas abiertas) ### Fase 5 — validar con cliente real (SIGUIENTE PASO) Ver **`PORTING_12.0.7_FASE5.md`** (guía completa): extraer datos 12.0.7 (extractores de TC), montar 4 DBs (auth/characters auto; world/hotfixes = dump completo de CypherCore), config, arranque bnet→world, cliente vía launcher tipo Arctium, y **depuración reactiva** por packet log (`.pkt` + WowPacketParser). Aquí se validan/arreglan Fases 3-4. ### B2/B3/B4 — gameplay de features Midnight (opcional, especulativo) - B2 Housing: ~111 opcodes (46 CMSG + 65 SMSG), packet structs (TC no las tiene), handlers, entidades PlayerHouse/Room/Decor (patrón MeshObject), tablas DB. Sin referencia de gameplay. - B3 Neighborhoods (73 opcodes) + B4 PlayerInitiative (12 opcodes, componente en Player). - Recomendación: tratarlas como features independientes; NO son port. El servidor NO crashea con opcodes sin handler (los loguea). --- ## Cómo retomar en otra máquina 1. Clonar este repo (rama `master`) desde nightspire. 2. Clonar TrinityCore master aparte (referencia 12.0.7). 3. `dotnet build CypherCore.sln -c Release` → confirmar 0 errores. 4. Leer este doc + `PORTING_12.0.7_FASE5.md`. 5. Continuar por Fase 5 (validación) o B2+ (features), según prioridad. 6. Al depurar un mismatch: coger el opcode/struct del log, comparar con TC, arreglar, recompilar.