Skip to content

Refactor build system and add missing header includes#7

Open
gavinlinasd wants to merge 6 commits into
masterfrom
claude/sleepy-galileo-xbljv5
Open

Refactor build system and add missing header includes#7
gavinlinasd wants to merge 6 commits into
masterfrom
claude/sleepy-galileo-xbljv5

Conversation

@gavinlinasd

Copy link
Copy Markdown
Owner

Summary

This PR modernizes the build system by replacing individual makefiles with a unified non-recursive Makefile, adds missing header includes to fix compilation issues, and includes game data files.

Key Changes

  • Build System Refactor: Replaced separate gmsv/char/makefile, gmsv/battle/makefile, and gmsv/char/makefile.bak with a single unified gmsv/Makefile and top-level Makefile
  • Dependency Tracking: Generated .d dependency files for all source files to enable proper incremental compilation
  • Header Includes: Added missing #include directives:
    • char_angel.h in char_item.c, callfromcli.c, and callfromac.c
    • magic.h in battle_item.c
  • Code Cleanup: Removed backup files (*.bak) that were cluttering the repository
  • Documentation: Added BUILDING.md with build and run instructions
  • Game Data: Added game data files including maps, configuration files, and NPC dialogue data (Dengon directory)
  • Git Configuration: Added .gitignore to exclude build artifacts and binaries

Implementation Details

The new build system uses a non-recursive make approach with centralized dependency management, improving build performance and maintainability. All source files now have explicit dependency tracking through generated .d files. The header include additions fix compilation errors related to undefined symbols from the angel summon and magic systems.

https://claude.ai/code/session_01TJAC2vUVUgWthfgtnsE5gP

claude added 6 commits June 10, 2026 06:37
The 2005 codebase carried three text strata: original Japanese
comments in EUC-JP, that same Japanese fossilized into GBK by a
historical Big5->GB2312 conversion, and genuine Chinese comments
written directly in GBK - sometimes all three in one file.

Re-encode every text file to UTF-8 using per-line detection that
scores candidate decodings (gb18030/big5/euc-jp/cp932) by
common-character readability, with two-pass majority voting per
file. Raw EUC-JP survivors (e.g. char/defaultPlayer.h) now read as
proper Japanese; Chinese comments are unchanged. 14 characters
across 3 files were already destroyed in the source bytes (orphan
lead bytes) and are now explicit U+FFFD.

Also normalize CRLF to LF, delete .bak backups, 1998-era .o
objects and Visual SourceSafe litter, and add a .gitignore.

https://claude.ai/code/session_01TJAC2vUVUgWthfgtnsE5gP
Most of the original Japanese comments were destroyed long ago by a
historical conversion that read EUC-JP bytes as Big5 and then mapped
Big5 to GB2312 with traditional->simplified folding, leaving hanzi
soup like "玄永皿互NULL井升丹井及民尼永弁".

Reverse that exact chain (simplified->traditional via OpenCC, encode
cp950, decode EUC-JP) for comment text only - string literals are
never touched, so runtime behavior is unchanged. Each candidate is
triple-gated: only attempted on text that scores as unreadable,
accepted only when the result scores as readable Japanese (kana or
common kanji present) with low damage. 2646 comment lines across 129
files recovered, e.g. the line above is now
"トップがNULLかどうかのチェック". Genuine Chinese comments are
untouched, verified by scan. A lexical pass (gcc -fpreprocessed -E)
confirms comment/string structure is intact in all files.

A few characters remain imperfect where the original folding was
ambiguous; those lines are still vastly more readable than before.

https://claude.ai/code/session_01TJAC2vUVUgWthfgtnsE5gP
Replace the 1998 recursive makefiles with three small non-recursive
GNU Makefiles (root, gmsv, saac) with header dependency tracking,
-std=gnu17, -fno-strict-aliasing -fwrapv for 1990s C semantics, and
warnings promoted to errors for the 64-bit killers: implicit
function declarations, implicit int, pointer/int casts, return-type.
MySQL comes from mariadb_config/pkg-config instead of a hardcoded
/usr/lib/mysql path. genver.sh now emits one quoted string literal
per line (multi-line literals died with GCC 3) via printf, not echo.

The interesting fixes behind getting this to link:

- saac/sasql.h gated its API behind #ifdef _SASQL but version.h
  defines _SASQL1, so every sasql_* call compiled as implicit int.
  Also main.c included the gated header before version.h.
- saac/sasql.c readConfig() had fclose+return nested inside the
  AutoReg else-if: config lines after AutoReg were silently skipped
  and the file leaked when AutoReg was absent.
- lock.h declared DeleteChangeGalaxyLock but lock.c defines
  DeleteGalaxyChangeLock; callers used the latter, unprototyped.
- gmsv npc_quiz.c stored calloc'd struct pl pointers in CHAR
  work-int slots (truncation on 64-bit). Replaced with a small
  registry table; slots now hold an index and keep -1 as sentinel.
- ~30 globals were defined in headers or duplicated across .c files
  (BS, CHAR_effect, HACK_TYPE and BATTLE_RET were anonymous-enum
  *variables*, window-NPC scratch i/j/buf/w/buttonproc, ...). All
  now extern-declared with a single owning definition, or static
  where they were per-file scratch. Pre-C17 common-symbol merging
  had silently fused them - including one genuine bug: char.c
  defined CHAR_effect inside #ifndef _SEND_EFFECT while all users
  sit inside #ifdef _SEND_EFFECT; commons masked it for 20 years.
- INLINE now expands to nothing: the definitions live in .c files,
  so C99 inline semantics produced undefined references.
- Broke the item.h -> char.h -> char_data.h -> item.h include cycle
  (item.h needs only util.h and char_base.h types).
- npc_door.c and npc_roomadminnew.c join the build: npc_doorman.c
  (always compiled) calls NPC_DoorOpen/NPC_DoorSearchByName, which
  only archive-link selectivity let the 2005 build omit.
- Missing prototypes distributed to their natural headers
  (configfile.h getters, new char_angel.h / npc_exchangeman.h), K&R
  parameter lists given types, missing returns added.

Binaries: gmsv/gmsv, saac/saac, saac/wk/acwk.

https://claude.ai/code/session_01TJAC2vUVUgWthfgtnsE5gP
Real bugs surfaced by gcc 13 diagnostics, all reachable at runtime:

- npc_petshop.c NPC_DepotPet_Get filled int workindex[15]
  (CHAR_MAXPOOLPETHAVE) in loops bounded by CHAR_MAXDEPOTPETHAVE
  (30): a guaranteed stack smash when a player retrieves a depot
  pet. Array now sized by the loop bound.
- family.c read one past the end of fmdplevelexp[] when computing
  family level from accumulated DP.
- battle_magic.c PROFESSION_MAGIC_TOLIST_SORT cleared 8 bytes of
  the 84-byte target list (memset with sizeof of a pointer); same
  class in npc_stoneserviceman.c (bzero of pointer instead of
  struct) and saac lock.c.
- npc_quiz.c bounded a strncpy by the source field size (512)
  instead of the destination buffer.
- 13 strncat calls in npc_itemshop.c and chatroom.c bounded the
  append by the SOURCE size rather than remaining destination
  space, overflowing item-list and chatroom-list assembly buffers.
- ~30 printf-family calls passed config/player-controlled strings
  as the format argument (snprintf(buf, n, param) and log(retdata)
  patterns) - any '%' in an item name or config value would read or
  write through garbage varargs. All now go through "%s".
- saac db.c/mail.c logged realloc'd-away pointers (use after free,
  benign but flagged); dropped the stale operand.

Remaining warnings are cosmetic classes (unused variables,
stringop-truncation on intentionally-tight buffers, misleading
indentation) left for a future pass.

https://claude.ai/code/session_01TJAC2vUVUgWthfgtnsE5gP
Recover the game data (5,295 files: maps, NPC scripts, item/enemy
tables, Dengon dungeon data) and the setup.cf/acserv.cf configs from
the old master attempt, re-encoded to UTF-8 to match the sources
(binary files untouched). Document build, database schema and run
procedure in BUILDING.md.

Runtime fixes found by booting:

- npc_quiz.c NPC_GetQuestion returned a pointer to a stack VLA;
  2005 compilers happened to tolerate it, gcc 13 -O2 reuses the
  frame immediately and gmsv segfaulted in NPC_QuizInit during NPC
  initialization. Now a growable static buffer.
- buf.c memory pool: all size arithmetic was int (UNIT*UNITNUMBER
  overflows beyond 16.7M units) - now size_t - and the pool is
  sized 40M units in setup.cf because pointer-heavy structures
  roughly double on 64-bit; the historical 1.9GB setting exhausted
  during map loading (368 of 1284 maps).
- npcutil.c built NPC file paths in a 32-byte buffer with sprintf+
  strcat (the crash the 2018 attempt hit); now snprintf into 256.
- data/raceman.txt was absent from the recovered data and its
  absence aborts boot; committed a minimal documented stub. Same
  for the LOCKIP file.
- saac runtime directory skeletons (char/, lock/, mail/, ...) with
  .gitkeep; runtime-generated state is gitignored.

Verified end to end: MariaDB up, saac listening on 9300/9400, gmsv
binds 1234, loads the world, authenticates to saac ("服务器密码正确"),
runs its main loop with a steady heartbeat, accepts TCP connections,
and both daemons shut down cleanly on SIGTERM (gmsv saves state).

Known data caveat: ~1.4k of 10.7k itemset6.txt entries are from a
newer patch level than this server source and fail its validators
(identical with the original GB bytes); they are skipped at boot.

https://claude.ai/code/session_01TJAC2vUVUgWthfgtnsE5gP
Two corrections from review feedback:

1. Revert gmsv/data to the exact original GB18030 bytes. The earlier
   UTF-8 conversion of data files was a regression: the 2005 parsers
   read fields into fixed 64-byte buffers sized for 2-byte CJK, so
   3-byte UTF-8 silently rejected 10,247 of 10,743 itemset6 entries
   (the [ITEM data Error] flood) and broke 619 NPC enemy-spawn
   params. A/B boots confirm: GB data = 0 errors, UTF-8 data = 10k+.
   Era clients also expect GB on the wire. The encoding policy is now
   documented in BUILDING.md (sources UTF-8, data GB18030).

2. Translate the restored Japanese comments to Simplified Chinese,
   since that matches the rest of the codebase and its audience:
   2,184 comment lines across 128 files (チェック -> 检查,
   返り値 -> 返回值, アイテム -> 道具, following the codebase's own
   vocabulary). Replacements preserve each line's exact comment-marker
   shell and never touch string literals; verified lexically intact
   (gcc -fpreprocessed) on every file. Katakana monster names and a
   few dozen undecipherable fossil fragments are left as-is.

Verified end to end on the final tree: clean build, both daemons up,
gmsv loads with zero item/enemy data errors (7,978 NPCs), connects
and authenticates to saac, accepts TCP connections on 1234, and
shuts down gracefully.

https://claude.ai/code/session_01TJAC2vUVUgWthfgtnsE5gP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants