Compare commits

...

12 commits

Author SHA1 Message Date
Kelsi
22518f0936 Suppress third-party header warnings and Vulkan struct init noise
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
- Add -Wno-missing-field-initializers for GCC (Vulkan designated
  initializer patterns in valid C++20 trigger this)
- Mark extern/ and vk-bootstrap as SYSTEM includes to suppress
  warnings from vendored headers (VMA, stb, miniaudio, nlohmann)
2026-02-23 19:20:55 -08:00
Kelsi
997318ae06 Fix all build warnings
- vk_utils.hpp: mark unused 'msg' parameter with [[maybe_unused]]
- world_packets.cpp: write exactMatch field to auction list packet
  (was accepted as parameter but never serialized)
- game_screen.cpp: remove unused bagIcons array and unused info variable
- talent_screen.cpp: remove unused nextRank and pMin variables
2026-02-23 19:16:47 -08:00
Kelsi
a825450048 Enable MSYS2 update on windows-arm64 to fix stale PGP keyring
The CLANGARM64 runner's cached MSYS2 install has outdated PGP keys,
causing "signature is unknown trust" errors. Setting update: true
refreshes the keyring before installing packages.
2026-02-23 18:57:49 -08:00
Kelsi
de6983e385 Track VulkanMemoryAllocator header in extern/
vk_mem_alloc.h was in extern/ but gitignored, causing macOS CI to fail
with 'vk_mem_alloc.h' file not found. Whitelist it alongside the other
vendored headers.
2026-02-23 18:54:00 -08:00
Kelsi
0210c24186 Pin vk-bootstrap to v1.3.302 for Vulkan 1.3 header compatibility
Latest vk-bootstrap HEAD uses Vulkan 1.4 types
(VkPhysicalDeviceVertexAttributeDivisorFeatures) that don't exist in
the Vulkan 1.3.275 headers shipped by Ubuntu 24.04. Pin to v1.3.302,
the latest release compatible with Vulkan 1.3 headers.
2026-02-23 18:51:33 -08:00
Kelsi
42b8e3141a Add Vulkan and shaderc packages to security workflow
CodeQL and sanitizer jobs were missing libvulkan-dev, vulkan-tools,
and glslc — same fix as the build workflow.
2026-02-23 18:49:15 -08:00
Kelsi
b5f754a9cc Add pkg-config fallback for Vulkan discovery
Some distros and CMake versions fail to find Vulkan via FindVulkan.cmake
even when libvulkan-dev is installed. Fall back to pkg-config (vulkan.pc)
and create the Vulkan::Vulkan imported target manually if needed.
2026-02-23 18:47:42 -08:00
Kelsi
22fa771d00 Fix CI failures: add vk-bootstrap submodule and fix MSYS2 stormlib
- Add vk-bootstrap as a git submodule (was in extern/ but not tracked,
  causing "vk-bootstrap not found" on all CI jobs)
- Whitelist extern/vk-bootstrap in .gitignore
- Move stormlib to a separate optional install step on both Windows CI
  jobs (mingw-w64-x86_64-stormlib doesn't exist in MSYS2 repos)
2026-02-23 18:45:39 -08:00
Kelsi
ebab8f3ccc Add missing Vulkan and shaderc packages to Linux CI and docs
Linux CI was missing libvulkan-dev, vulkan-tools, and glslc, causing
find_package(Vulkan REQUIRED) to fail. Also update BUILD_INSTRUCTIONS
Ubuntu and Arch sections to include Vulkan/shaderc packages.
2026-02-23 18:42:00 -08:00
Kelsi
685736fa16 Fix macOS asset extraction auto-build and docs
- extract_assets.sh: detect Homebrew and pass CMAKE_PREFIX_PATH,
  OPENSSL_ROOT_DIR, and PKG_CONFIG_PATH when auto-building on macOS
  (bare cmake couldn't find Homebrew deps)
- README.md: fix macOS brew command that had comments after line
  continuations (breaks shell execution)
- BUILD_INSTRUCTIONS.md: expand macOS asset extraction section with
  auto-build note and expansion targets
2026-02-23 18:40:26 -08:00
Kelsi
f66b9eb154 Fix macOS build process and make shell scripts cross-platform
- Add vulkan-loader, vulkan-headers, shaderc to macOS CI brew install
- Add vulkan-loader and shaderc to macOS PKG_CONFIG_PATH
- Replace Linux-only `nproc` with portable fallback in build.sh,
  rebuild.sh, extract_assets.sh, and tools/backup_assets.sh
- Replace `ldconfig` StormLib check with portable detection
  (ldconfig, pkg-config, brew lib) in extract_assets.sh
- Update BUILD_INSTRUCTIONS.md macOS section with vulkan/shaderc
  packages and MoltenVK explanation
- Add macOS prerequisites to README.md
2026-02-23 18:35:53 -08:00
Kelsi
eb549a9b7a Fix Windows build process and add Windows asset extraction scripts
- Add missing MSYS2 packages to CI: vulkan-loader, vulkan-headers,
  shaderc, stormlib (both x86-64 and arm64), unicorn (arm64)
- Make vulkan-1.dll copy conditional via find_file (fixes MSYS2 builds)
- Use find_library for wininet/bz2 in asset_extract (graceful fallback)
- Add extract_assets.ps1 and extract_assets.bat for Windows users
- Expand BUILD_INSTRUCTIONS.md with MSYS2, vcpkg, and macOS sections
- Update README.md to reference Windows scripts and platforms
2026-02-23 18:32:47 -08:00
19 changed files with 20239 additions and 42 deletions

View file

@ -46,6 +46,9 @@ jobs:
libglm-dev \ libglm-dev \
libssl-dev \ libssl-dev \
zlib1g-dev \ zlib1g-dev \
libvulkan-dev \
vulkan-tools \
glslc \
libavformat-dev \ libavformat-dev \
libavcodec-dev \ libavcodec-dev \
libswscale-dev \ libswscale-dev \
@ -89,14 +92,14 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
brew install cmake pkg-config sdl2 glew glm openssl@3 zlib ffmpeg unicorn \ brew install cmake pkg-config sdl2 glew glm openssl@3 zlib ffmpeg unicorn \
stormlib dylibbundler || true stormlib vulkan-loader vulkan-headers shaderc dylibbundler || true
# dylibbundler may not be in all brew mirrors; install separately to not block others # dylibbundler may not be in all brew mirrors; install separately to not block others
brew install dylibbundler 2>/dev/null || true brew install dylibbundler 2>/dev/null || true
- name: Configure - name: Configure
run: | run: |
BREW=$(brew --prefix) BREW=$(brew --prefix)
export PKG_CONFIG_PATH="$BREW/lib/pkgconfig:$(brew --prefix ffmpeg)/lib/pkgconfig:$(brew --prefix openssl@3)/lib/pkgconfig" export PKG_CONFIG_PATH="$BREW/lib/pkgconfig:$(brew --prefix ffmpeg)/lib/pkgconfig:$(brew --prefix openssl@3)/lib/pkgconfig:$(brew --prefix vulkan-loader)/lib/pkgconfig:$(brew --prefix shaderc)/lib/pkgconfig"
cmake -S . -B build \ cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$BREW" \ -DCMAKE_PREFIX_PATH="$BREW" \
@ -170,7 +173,7 @@ jobs:
uses: msys2/setup-msys2@v2 uses: msys2/setup-msys2@v2
with: with:
msystem: CLANGARM64 msystem: CLANGARM64
update: false update: true
install: >- install: >-
mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-cmake
mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-clang
@ -182,8 +185,16 @@ jobs:
mingw-w64-clang-aarch64-openssl mingw-w64-clang-aarch64-openssl
mingw-w64-clang-aarch64-zlib mingw-w64-clang-aarch64-zlib
mingw-w64-clang-aarch64-ffmpeg mingw-w64-clang-aarch64-ffmpeg
mingw-w64-clang-aarch64-unicorn
mingw-w64-clang-aarch64-vulkan-loader
mingw-w64-clang-aarch64-vulkan-headers
mingw-w64-clang-aarch64-shaderc
git git
- name: Install optional packages
shell: msys2 {0}
run: pacman -S --noconfirm --needed mingw-w64-clang-aarch64-stormlib || true
- name: Configure - name: Configure
shell: msys2 {0} shell: msys2 {0}
run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
@ -237,9 +248,16 @@ jobs:
mingw-w64-x86_64-zlib mingw-w64-x86_64-zlib
mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-ffmpeg
mingw-w64-x86_64-unicorn mingw-w64-x86_64-unicorn
mingw-w64-x86_64-vulkan-loader
mingw-w64-x86_64-vulkan-headers
mingw-w64-x86_64-shaderc
mingw-w64-x86_64-nsis mingw-w64-x86_64-nsis
git git
- name: Install optional packages
shell: msys2 {0}
run: pacman -S --noconfirm --needed mingw-w64-x86_64-stormlib || true
- name: Configure - name: Configure
shell: msys2 {0} shell: msys2 {0}
run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release

View file

@ -36,6 +36,9 @@ jobs:
libglm-dev \ libglm-dev \
libssl-dev \ libssl-dev \
zlib1g-dev \ zlib1g-dev \
libvulkan-dev \
vulkan-tools \
glslc \
libavformat-dev \ libavformat-dev \
libavcodec-dev \ libavcodec-dev \
libswscale-dev \ libswscale-dev \
@ -105,6 +108,9 @@ jobs:
libglm-dev \ libglm-dev \
libssl-dev \ libssl-dev \
zlib1g-dev \ zlib1g-dev \
libvulkan-dev \
vulkan-tools \
glslc \
libavformat-dev \ libavformat-dev \
libavcodec-dev \ libavcodec-dev \
libswscale-dev \ libswscale-dev \

6
.gitignore vendored
View file

@ -42,10 +42,12 @@ wowee
*~ *~
.DS_Store .DS_Store
# External dependencies (except submodules) # External dependencies (except submodules and vendored headers)
extern/* extern/*
!extern/.gitkeep !extern/.gitkeep
!extern/imgui !extern/imgui
!extern/vk-bootstrap
!extern/vk_mem_alloc.h
# ImGui state # ImGui state
imgui.ini imgui.ini
@ -64,7 +66,7 @@ cache/
saves/ saves/
wowee_[0-9][0-9][0-9][0-9] wowee_[0-9][0-9][0-9][0-9]
# Extracted assets (run ./extract_assets.sh to generate) # Extracted assets (run ./extract_assets.sh or .\extract_assets.ps1 to generate)
Data/db/ Data/db/
Data/character/ Data/character/
Data/creature/ Data/creature/

4
.gitmodules vendored
View file

@ -2,3 +2,7 @@
path = extern/imgui path = extern/imgui
url = https://github.com/ocornut/imgui.git url = https://github.com/ocornut/imgui.git
shallow = true shallow = true
[submodule "extern/vk-bootstrap"]
path = extern/vk-bootstrap
url = https://github.com/charles-lunarg/vk-bootstrap.git
shallow = true

View file

@ -10,7 +10,13 @@ This document provides platform-specific build instructions for WoWee.
```bash ```bash
sudo apt update sudo apt update
sudo apt install -y build-essential cmake pkg-config git libsdl2-dev libglew-dev libglm-dev libssl-dev zlib1g-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libunicorn-dev libstorm-dev sudo apt install -y \
build-essential cmake pkg-config git \
libsdl2-dev libglew-dev libglm-dev \
libssl-dev zlib1g-dev \
libvulkan-dev vulkan-tools glslc \
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev \
libunicorn-dev libstorm-dev libx11-dev
``` ```
--- ---
@ -20,7 +26,11 @@ sudo apt install -y build-essential cmake pkg-config git libsdl2-dev libglew
### Install Dependencies ### Install Dependencies
```bash ```bash
sudo pacman -S --needed base-devel cmake pkgconf git sdl2 glew glm openssl zlib ffmpeg unicorn stormlib sudo pacman -S --needed \
base-devel cmake pkgconf git \
sdl2 glew glm openssl zlib \
vulkan-devel vulkan-tools shaderc \
ffmpeg unicorn stormlib
``` ```
--- ---
@ -49,15 +59,119 @@ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j"$(nproc)" cmake --build build -j"$(nproc)"
``` ```
### Asset Extraction (Linux)
After building, extract assets from your WoW client:
```bash
./extract_assets.sh /path/to/WoW/Data wotlk
```
Supports `classic`, `tbc`, `wotlk` targets (auto-detected if omitted).
---
## 🍎 macOS
### Install Dependencies
Vulkan on macOS is provided via MoltenVK (a Vulkan-to-Metal translation layer),
which is included in the `vulkan-loader` Homebrew package.
```bash
brew install cmake pkg-config sdl2 glew glm openssl@3 zlib ffmpeg unicorn \
stormlib vulkan-loader vulkan-headers shaderc
```
Optional (for creating redistributable `.app` bundles):
```bash
brew install dylibbundler
```
### Clone & Build
```bash
git clone --recurse-submodules https://github.com/Kelsidavis/WoWee.git
cd WoWee
BREW=$(brew --prefix)
export PKG_CONFIG_PATH="$BREW/lib/pkgconfig:$(brew --prefix ffmpeg)/lib/pkgconfig:$(brew --prefix openssl@3)/lib/pkgconfig:$(brew --prefix vulkan-loader)/lib/pkgconfig:$(brew --prefix shaderc)/lib/pkgconfig"
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$BREW" \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
cmake --build build -j"$(sysctl -n hw.logicalcpu)"
```
### Asset Extraction (macOS)
The script will auto-build `asset_extract` if needed (requires `stormlib`).
It automatically detects Homebrew and passes the correct paths to CMake.
```bash
./extract_assets.sh /path/to/WoW/Data wotlk
```
Supports `classic`, `tbc`, `wotlk` targets (auto-detected if omitted).
---
## 🪟 Windows (MSYS2 — Recommended)
MSYS2 provides all dependencies as pre-built packages.
### Install MSYS2
Download and install from <https://www.msys2.org/>, then open a **MINGW64** shell.
### Install Dependencies
```bash
pacman -S --needed \
mingw-w64-x86_64-cmake \
mingw-w64-x86_64-gcc \
mingw-w64-x86_64-ninja \
mingw-w64-x86_64-pkgconf \
mingw-w64-x86_64-SDL2 \
mingw-w64-x86_64-glew \
mingw-w64-x86_64-glm \
mingw-w64-x86_64-openssl \
mingw-w64-x86_64-zlib \
mingw-w64-x86_64-ffmpeg \
mingw-w64-x86_64-unicorn \
mingw-w64-x86_64-vulkan-loader \
mingw-w64-x86_64-vulkan-headers \
mingw-w64-x86_64-shaderc \
mingw-w64-x86_64-stormlib \
git
```
### Clone & Build
```bash
git clone --recurse-submodules https://github.com/Kelsidavis/WoWee.git
cd WoWee
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel $(nproc)
```
--- ---
## 🪟 Windows (Visual Studio 2022) ## 🪟 Windows (Visual Studio 2022)
For users who prefer Visual Studio over MSYS2.
### Install ### Install
- Visual Studio 2022 - Visual Studio 2022 with **Desktop development with C++** workload
- Desktop development with C++ - CMake tools for Windows (included in VS workload)
- CMake tools for Windows - [LunarG Vulkan SDK](https://vulkan.lunarg.com/) (provides Vulkan headers, loader, and glslc)
### vcpkg Dependencies
```powershell
vcpkg install sdl2 glew glm openssl zlib ffmpeg stormlib --triplet x64-windows
```
### Clone ### Clone
@ -72,12 +186,25 @@ Open the folder in Visual Studio (it will detect CMake automatically)
or build from Developer PowerShell: or build from Developer PowerShell:
```powershell ```powershell
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="[vcpkg root]/scripts/buildsystems/vcpkg.cmake"
cmake --build build --config Release cmake --build build --config Release
``` ```
--- ---
## 🪟 Asset Extraction (Windows)
After building (via either MSYS2 or Visual Studio), extract assets from your WoW client:
```powershell
.\extract_assets.ps1 "C:\Games\WoW-3.3.5a\Data"
```
Or double-click `extract_assets.bat` and provide the path when prompted.
You can also specify an expansion: `.\extract_assets.ps1 "C:\Games\WoW\Data" wotlk`
---
## ⚠️ Notes ## ⚠️ Notes
- Case matters on Linux (`WoWee` not `wowee`). - Case matters on Linux (`WoWee` not `wowee`).

View file

@ -35,7 +35,30 @@ endif()
# Find required packages # Find required packages
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)
find_package(Vulkan REQUIRED) find_package(Vulkan QUIET)
if(NOT Vulkan_FOUND)
# Fallback: some distros / CMake versions need pkg-config to locate Vulkan.
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(VULKAN_PKG vulkan)
if(VULKAN_PKG_FOUND)
add_library(Vulkan::Vulkan INTERFACE IMPORTED)
set_target_properties(Vulkan::Vulkan PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${VULKAN_PKG_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${VULKAN_PKG_LIBRARIES}"
)
if(VULKAN_PKG_LIBRARY_DIRS)
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
INTERFACE_LINK_DIRECTORIES "${VULKAN_PKG_LIBRARY_DIRS}")
endif()
set(Vulkan_FOUND TRUE)
message(STATUS "Found Vulkan via pkg-config: ${VULKAN_PKG_LIBRARIES}")
endif()
endif()
if(NOT Vulkan_FOUND)
message(FATAL_ERROR "Could not find Vulkan. Install libvulkan-dev (Linux), vulkan-loader (macOS), or the Vulkan SDK (Windows).")
endif()
endif()
# GL/GLEW kept temporarily for unconverted sub-renderers during Vulkan migration. # GL/GLEW kept temporarily for unconverted sub-renderers during Vulkan migration.
# These files compile against GL types but their code is never called — the Vulkan # These files compile against GL types but their code is never called — the Vulkan
# path is the only active rendering backend. Remove in Phase 7 when all renderers # path is the only active rendering backend. Remove in Phase 7 when all renderers
@ -446,6 +469,9 @@ endif()
target_include_directories(wowee PRIVATE target_include_directories(wowee PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Vendored headers as SYSTEM to suppress third-party warnings
target_include_directories(wowee SYSTEM PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/extern ${CMAKE_CURRENT_SOURCE_DIR}/extern
${CMAKE_CURRENT_SOURCE_DIR}/extern/vk-bootstrap/src ${CMAKE_CURRENT_SOURCE_DIR}/extern/vk-bootstrap/src
) )
@ -520,7 +546,7 @@ endif()
if(MSVC) if(MSVC)
target_compile_options(wowee PRIVATE /W4) target_compile_options(wowee PRIVATE /W4)
else() else()
target_compile_options(wowee PRIVATE -Wall -Wextra -Wpedantic) target_compile_options(wowee PRIVATE -Wall -Wextra -Wpedantic -Wno-missing-field-initializers)
endif() endif()
# Debug build flags # Debug build flags
@ -592,12 +618,18 @@ add_custom_command(TARGET wowee POST_BUILD
# which does NOT include System32. Copy vulkan-1.dll into the output directory so # which does NOT include System32. Copy vulkan-1.dll into the output directory so
# SDL_Vulkan_LoadLibrary can locate it without needing a full system PATH search. # SDL_Vulkan_LoadLibrary can locate it without needing a full system PATH search.
if(WIN32) if(WIN32)
find_file(VULKAN_DLL vulkan-1.dll
PATHS "$ENV{SystemRoot}/System32" "$ENV{VULKAN_SDK}/Bin"
NO_DEFAULT_PATH)
if(VULKAN_DLL)
add_custom_command(TARGET wowee POST_BUILD add_custom_command(TARGET wowee POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$ENV{SystemRoot}/System32/vulkan-1.dll" "${VULKAN_DLL}" "$<TARGET_FILE_DIR:wowee>/vulkan-1.dll"
"$<TARGET_FILE_DIR:wowee>/vulkan-1.dll"
COMMENT "Copying vulkan-1.dll to output directory" COMMENT "Copying vulkan-1.dll to output directory"
) )
else()
message(STATUS " vulkan-1.dll not found — skipping copy (MSYS2 provides it via PATH)")
endif()
endif() endif()
# Install targets # Install targets
@ -659,7 +691,14 @@ if(STORMLIB_LIBRARY AND STORMLIB_INCLUDE_DIR)
Threads::Threads Threads::Threads
) )
if(WIN32) if(WIN32)
target_link_libraries(asset_extract PRIVATE wininet bz2) find_library(WININET_LIB wininet)
find_library(BZ2_LIB bz2)
if(WININET_LIB)
target_link_libraries(asset_extract PRIVATE ${WININET_LIB})
endif()
if(BZ2_LIB)
target_link_libraries(asset_extract PRIVATE ${BZ2_LIB})
endif()
endif() endif()
set_target_properties(asset_extract PROPERTIES set_target_properties(asset_extract PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin

View file

@ -36,7 +36,7 @@ Protocol Compatible with **Vanilla (Classic) 1.12 + TBC 2.4.3 + WotLK 3.3.5a**.
### Asset Pipeline ### Asset Pipeline
- Extracted loose-file **`Data/`** tree indexed by **`manifest.json`** (fast lookup + caching) - Extracted loose-file **`Data/`** tree indexed by **`manifest.json`** (fast lookup + caching)
- Optional **overlay layers** for multi-expansion asset deduplication - Optional **overlay layers** for multi-expansion asset deduplication
- `asset_extract` + `extract_assets.sh` for MPQ extraction (StormLib tooling) - `asset_extract` + `extract_assets.sh` (Linux/macOS) / `extract_assets.ps1` (Windows) for MPQ extraction (StormLib tooling)
- File formats: **BLP** (DXT1/3/5), **ADT**, **M2**, **WMO**, **DBC** (Spell/Item/Faction/etc.) - File formats: **BLP** (DXT1/3/5), **ADT**, **M2**, **WMO**, **DBC** (Spell/Item/Faction/etc.)
### Gameplay Systems ### Gameplay Systems
@ -84,6 +84,14 @@ sudo pacman -S sdl2 glm openssl \
ffmpeg zlib cmake base-devel libx11 \ ffmpeg zlib cmake base-devel libx11 \
unicorn # optional: Warden module execution unicorn # optional: Warden module execution
# StormLib: install from AUR for asset_extract tool # StormLib: install from AUR for asset_extract tool
# macOS (Homebrew)
brew install cmake pkg-config sdl2 glew glm openssl@3 zlib ffmpeg \
vulkan-loader vulkan-headers shaderc \
unicorn \
stormlib
# unicorn is optional (Warden module execution)
# stormlib is optional (asset_extract tool)
``` ```
### Container build ### Container build
@ -101,8 +109,12 @@ Wowee loads assets via an extracted loose-file tree indexed by `manifest.json` (
#### 1) Extract MPQs into `./Data/` #### 1) Extract MPQs into `./Data/`
```bash ```bash
# WotLK 3.3.5a example # Linux / macOS
./extract_assets.sh /path/to/WoW/Data wotlk ./extract_assets.sh /path/to/WoW/Data wotlk
# Windows (PowerShell)
.\extract_assets.ps1 "C:\Games\WoW-3.3.5a\Data" wotlk
# Or double-click extract_assets.bat
``` ```
``` ```
@ -117,7 +129,7 @@ Data/
Notes: Notes:
- `StormLib` is required to build/run the extractor (`asset_extract`), but the main client does not require StormLib at runtime. - `StormLib` is required to build/run the extractor (`asset_extract`), but the main client does not require StormLib at runtime.
- `extract_assets.sh` supports `classic`, `tbc`, `wotlk` targets. - `extract_assets.sh` / `extract_assets.ps1` support `classic`, `tbc`, `wotlk` targets.
#### 2) Point wowee at the extracted data #### 2) Point wowee at the extracted data
@ -206,7 +218,7 @@ make -j$(nproc)
## Technical Details ## Technical Details
- **Platform**: Linux (primary), C++20, CMake 3.15+ - **Platform**: Linux (primary), Windows (MSYS2/MSVC), macOS — C++20, CMake 3.15+
- **Dependencies**: SDL2, Vulkan, GLM, OpenSSL, ImGui, FFmpeg, Unicorn Engine (StormLib for asset extraction tooling) - **Dependencies**: SDL2, Vulkan, GLM, OpenSSL, ImGui, FFmpeg, Unicorn Engine (StormLib for asset extraction tooling)
- **Architecture**: Modular design with clear separation (core, rendering, networking, game logic, asset pipeline, UI, audio) - **Architecture**: Modular design with clear separation (core, rendering, networking, game logic, asset pipeline, UI, audio)
- **Networking**: Non-blocking TCP, SRP6a authentication, RC4 encryption, WoW 3.3.5a protocol - **Networking**: Non-blocking TCP, SRP6a authentication, RC4 encryption, WoW 3.3.5a protocol

View file

@ -16,8 +16,9 @@ echo "Configuring with CMake..."
cmake .. -DCMAKE_BUILD_TYPE=Release cmake .. -DCMAKE_BUILD_TYPE=Release
# Build with all cores # Build with all cores
echo "Building with $(nproc) cores..." NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
cmake --build . --parallel $(nproc) echo "Building with $NPROC cores..."
cmake --build . --parallel "$NPROC"
# Ensure Data symlink exists in bin directory # Ensure Data symlink exists in bin directory
cd bin cd bin

1
extern/vk-bootstrap vendored Submodule

@ -0,0 +1 @@
Subproject commit 2e7c8e8323c0fe7efc96dc241610fcba35d8f530

19845
extern/vk_mem_alloc.h vendored Normal file

File diff suppressed because it is too large Load diff

4
extract_assets.bat Normal file
View file

@ -0,0 +1,4 @@
@echo off
REM Convenience wrapper — launches the PowerShell asset extraction script.
REM Usage: extract_assets.bat C:\Games\WoW\Data [expansion]
powershell -ExecutionPolicy Bypass -File "%~dp0extract_assets.ps1" %*

120
extract_assets.ps1 Normal file
View file

@ -0,0 +1,120 @@
<#
.SYNOPSIS
Extracts WoW MPQ archives for use with wowee (Windows equivalent of extract_assets.sh).
.DESCRIPTION
Builds the asset_extract tool (if needed) and runs it against a WoW Data directory.
.PARAMETER MpqDir
Path to the WoW client's Data directory containing .MPQ files.
.PARAMETER Expansion
Expansion hint: classic, turtle, tbc, wotlk. Auto-detected if omitted.
.EXAMPLE
.\extract_assets.ps1 "C:\Games\WoW-3.3.5a\Data"
.\extract_assets.ps1 "C:\Games\WoW-1.12\Data" classic
.\extract_assets.ps1 "D:\TurtleWoW\Data" turtle
#>
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$MpqDir,
[Parameter(Position=1)]
[string]$Expansion = "auto"
)
$ErrorActionPreference = "Stop"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$BuildDir = Join-Path $ScriptDir "build"
$Binary = Join-Path $BuildDir "bin\asset_extract.exe"
$OutputDir = Join-Path $ScriptDir "Data"
# --- Validate arguments ---
if (-not (Test-Path $MpqDir -PathType Container)) {
Write-Error "Error: Directory not found: $MpqDir"
exit 1
}
# Check for .MPQ files
$mpqFiles = Get-ChildItem -Path $MpqDir -Filter "*.MPQ" -ErrorAction SilentlyContinue
$mpqFilesLower = Get-ChildItem -Path $MpqDir -Filter "*.mpq" -ErrorAction SilentlyContinue
if (-not $mpqFiles -and -not $mpqFilesLower) {
Write-Error "Error: No .MPQ files found in: $MpqDir`nMake sure this is the WoW Data/ directory (not the WoW root)."
exit 1
}
# Note about existing CSV DBCs
if (Test-Path (Join-Path $OutputDir "expansions")) {
$csvPattern = $null
if ($Expansion -ne "auto") {
$csvPattern = Join-Path $OutputDir "expansions\$Expansion\db\*.csv"
} else {
$csvPattern = Join-Path $OutputDir "expansions\*\db\*.csv"
}
if ($csvPattern -and (Get-ChildItem -Path $csvPattern -ErrorAction SilentlyContinue)) {
Write-Host "Note: Found CSV DBCs. DBC extraction is optional; visual assets are still required.`n"
}
}
# --- Build asset_extract if needed ---
if (-not (Test-Path $Binary)) {
Write-Host "Building asset_extract..."
# Check for cmake
if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) {
Write-Error "Error: cmake not found. Install CMake and ensure it is on your PATH."
exit 1
}
if (-not (Test-Path $BuildDir)) {
& cmake -S $ScriptDir -B $BuildDir -DCMAKE_BUILD_TYPE=Release
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
$numProcs = $env:NUMBER_OF_PROCESSORS
if (-not $numProcs) { $numProcs = 4 }
& cmake --build $BuildDir --target asset_extract --parallel $numProcs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Write-Host ""
}
if (-not (Test-Path $Binary)) {
Write-Error "Error: Failed to build asset_extract"
exit 1
}
# --- Run extraction ---
Write-Host "Extracting assets from: $MpqDir"
Write-Host "Output directory: $OutputDir"
Write-Host ""
$extraArgs = @("--mpq-dir", $MpqDir, "--output", $OutputDir)
if ($Expansion -ne "auto") {
$extraArgs += "--expansion"
$extraArgs += $Expansion
}
# Skip DBC extraction if CSVs already present
$skipDbc = $false
if ($Expansion -ne "auto") {
$csvPath = Join-Path $OutputDir "expansions\$Expansion\db\*.csv"
if (Get-ChildItem -Path $csvPath -ErrorAction SilentlyContinue) { $skipDbc = $true }
} else {
$csvPath = Join-Path $OutputDir "expansions\*\db\*.csv"
if (Get-ChildItem -Path $csvPath -ErrorAction SilentlyContinue) { $skipDbc = $true }
}
if ($skipDbc) {
$extraArgs += "--skip-dbc"
}
& $Binary @extraArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Write-Host ""
Write-Host "Done! Assets extracted to $OutputDir"
Write-Host "You can now run wowee."

View file

@ -63,18 +63,39 @@ fi
# --- Build asset_extract if needed --- # --- Build asset_extract if needed ---
if [ ! -f "$BINARY" ]; then if [ ! -f "$BINARY" ]; then
# --- Check for StormLib (only required to build) --- # --- Check for StormLib (only required to build) ---
if ! ldconfig -p 2>/dev/null | grep -qi stormlib; then STORMLIB_FOUND=false
if ldconfig -p 2>/dev/null | grep -qi stormlib; then
STORMLIB_FOUND=true
elif pkg-config --exists stormlib 2>/dev/null; then
STORMLIB_FOUND=true
elif [ -f "$(brew --prefix 2>/dev/null)/lib/libstorm.dylib" ] 2>/dev/null; then
STORMLIB_FOUND=true
fi
if [ "$STORMLIB_FOUND" = false ]; then
echo "Error: StormLib not found." echo "Error: StormLib not found."
echo "Install it with: sudo apt install libstormlib-dev" echo " Ubuntu/Debian: sudo apt install libstormlib-dev"
echo " or build from source: https://github.com/ladislav-zezula/StormLib" echo " macOS: brew install stormlib"
echo " From source: https://github.com/ladislav-zezula/StormLib"
exit 1 exit 1
fi fi
echo "Building asset_extract..." echo "Building asset_extract..."
if [ ! -d "$BUILD_DIR" ]; then if [ ! -d "$BUILD_DIR" ]; then
cmake -S "$SCRIPT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release CMAKE_EXTRA_ARGS=()
# On macOS, Homebrew installs to a non-default prefix that CMake
# can't find automatically — pass it explicitly.
if command -v brew &>/dev/null; then
BREW="$(brew --prefix)"
CMAKE_EXTRA_ARGS+=(
"-DCMAKE_PREFIX_PATH=$BREW"
"-DOPENSSL_ROOT_DIR=$(brew --prefix openssl@3)"
)
export PKG_CONFIG_PATH="$BREW/lib/pkgconfig:$(brew --prefix ffmpeg)/lib/pkgconfig:$(brew --prefix openssl@3)/lib/pkgconfig:$(brew --prefix vulkan-loader 2>/dev/null)/lib/pkgconfig:$(brew --prefix shaderc 2>/dev/null)/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
fi fi
cmake --build "$BUILD_DIR" --target asset_extract -- -j"$(nproc)" cmake -S "$SCRIPT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release "${CMAKE_EXTRA_ARGS[@]}"
fi
NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
cmake --build "$BUILD_DIR" --target asset_extract -- -j"$NPROC"
echo "" echo ""
fi fi

View file

@ -48,7 +48,7 @@ AllocatedBuffer uploadBuffer(VkContext& ctx, const void* data, VkDeviceSize size
VkBufferUsageFlags usage); VkBufferUsageFlags usage);
// Check VkResult and log on failure // Check VkResult and log on failure
inline bool vkCheck(VkResult result, const char* msg) { inline bool vkCheck(VkResult result, [[maybe_unused]] const char* msg) {
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
// Caller should log the message // Caller should log the message
return false; return false;

View file

@ -22,8 +22,9 @@ echo "Configuring with CMake..."
cmake .. -DCMAKE_BUILD_TYPE=Release cmake .. -DCMAKE_BUILD_TYPE=Release
# Build with all cores # Build with all cores
echo "Building with $(nproc) cores..." NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
cmake --build . --parallel $(nproc) echo "Building with $NPROC cores..."
cmake --build . --parallel "$NPROC"
# Create Data symlink in bin directory # Create Data symlink in bin directory
echo "Creating Data symlink..." echo "Creating Data symlink..."

View file

@ -4276,6 +4276,7 @@ network::Packet AuctionListItemsPacket::build(
p.writeUInt32(quality); p.writeUInt32(quality);
p.writeUInt8(usableOnly); p.writeUInt8(usableOnly);
p.writeUInt8(0); // getAll (0 = normal search) p.writeUInt8(0); // getAll (0 = normal search)
p.writeUInt8(exactMatch);
// Sort columns (0 = none) // Sort columns (0 = none)
p.writeUInt8(0); p.writeUInt8(0);
return p; return p;

View file

@ -3766,7 +3766,6 @@ void GameScreen::renderBagBar(game::GameHandler& gameHandler) {
// Track bag slot screen rects for drop detection // Track bag slot screen rects for drop detection
ImVec2 bagSlotMins[4], bagSlotMaxs[4]; ImVec2 bagSlotMins[4], bagSlotMaxs[4];
VkDescriptorSet bagIcons[4] = {};
// Slots 1-4: Bag slots (leftmost) // Slots 1-4: Bag slots (leftmost)
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
@ -3780,8 +3779,6 @@ void GameScreen::renderBagBar(game::GameHandler& gameHandler) {
if (!bagItem.empty() && bagItem.item.displayInfoId != 0) { if (!bagItem.empty() && bagItem.item.displayInfoId != 0) {
bagIcon = inventoryScreen.getItemIcon(bagItem.item.displayInfoId); bagIcon = inventoryScreen.getItemIcon(bagItem.item.displayInfoId);
} }
bagIcons[i] = bagIcon;
// Render the slot as an invisible button so we control all interaction // Render the slot as an invisible button so we control all interaction
ImVec2 cpos = ImGui::GetCursorScreenPos(); ImVec2 cpos = ImGui::GetCursorScreenPos();
ImGui::InvisibleButton("##bagSlot", ImVec2(slotSize, slotSize)); ImGui::InvisibleButton("##bagSlot", ImVec2(slotSize, slotSize));
@ -7483,7 +7480,6 @@ void GameScreen::renderBankWindow(game::GameHandler& gameHandler) {
if (slot.empty()) { if (slot.empty()) {
ImGui::Button("##bank", ImVec2(42, 42)); ImGui::Button("##bank", ImVec2(42, 42));
} else { } else {
auto* info = gameHandler.getItemInfo(slot.item.itemId);
ImVec4 qc = InventoryScreen::getQualityColor(slot.item.quality); ImVec4 qc = InventoryScreen::getQualityColor(slot.item.quality);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(qc.x * 0.3f, qc.y * 0.3f, qc.z * 0.3f, 0.8f)); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(qc.x * 0.3f, qc.y * 0.3f, qc.z * 0.3f, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(qc.x * 0.5f, qc.y * 0.5f, qc.z * 0.5f, 0.9f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(qc.x * 0.5f, qc.y * 0.5f, qc.z * 0.5f, 0.9f));

View file

@ -202,7 +202,6 @@ void TalentScreen::renderTalent(game::GameHandler& gameHandler,
auto* assetManager = core::Application::getInstance().getAssetManager(); auto* assetManager = core::Application::getInstance().getAssetManager();
uint8_t currentRank = gameHandler.getTalentRank(talent.talentId); uint8_t currentRank = gameHandler.getTalentRank(talent.talentId);
uint8_t nextRank = currentRank + 1;
// Check if can learn // Check if can learn
bool canLearn = currentRank < talent.maxRank && bool canLearn = currentRank < talent.maxRank &&
@ -297,7 +296,6 @@ void TalentScreen::renderTalent(game::GameHandler& gameHandler,
// Rank indicator overlay // Rank indicator overlay
if (talent.maxRank > 1) { if (talent.maxRank > 1) {
ImVec2 pMin = ImGui::GetItemRectMin();
ImVec2 pMax = ImGui::GetItemRectMax(); ImVec2 pMax = ImGui::GetItemRectMax();
auto* drawList = ImGui::GetWindowDrawList(); auto* drawList = ImGui::GetWindowDrawList();

View file

@ -50,7 +50,8 @@ if command -v zstd &>/dev/null; then
tar cf - -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" | zstd -T0 -3 -o "$ARCHIVE" tar cf - -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" | zstd -T0 -3 -o "$ARCHIVE"
elif command -v pigz &>/dev/null; then elif command -v pigz &>/dev/null; then
ARCHIVE="$BACKUP_DIR/wowee_assets_$TIMESTAMP.tar.gz" ARCHIVE="$BACKUP_DIR/wowee_assets_$TIMESTAMP.tar.gz"
tar cf - -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" | pigz -p "$(nproc)" > "$ARCHIVE" NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
tar cf - -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" | pigz -p "$NPROC" > "$ARCHIVE"
else else
ARCHIVE="$BACKUP_DIR/wowee_assets_$TIMESTAMP.tar.gz" ARCHIVE="$BACKUP_DIR/wowee_assets_$TIMESTAMP.tar.gz"
tar czf "$ARCHIVE" -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" tar czf "$ARCHIVE" -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")"