diff --git a/include/decl.h b/include/decl.h index 7a34be6f1..1ea39d6f9 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1174,6 +1174,8 @@ struct instance_globals_saved_m { struct instance_globals_saved_n { /* dungeon.c */ int n_dgns; /* number of dungeons (also used in mklev.c and do.c) */ + /* files.c */ + char nhuuid[37]; /* mkroom.c */ int nroom; /* region.c */ diff --git a/include/extern.h b/include/extern.h index c5cac33cf..d17497325 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1128,6 +1128,8 @@ extern boolean Death_quote(char *, int) NONNULLARG1; extern void livelog_add(long ll_type, const char *) NONNULLARG2; ATTRNORETURN extern void do_deferred_showpaths(int) NORETURN; extern boolean contains_directory(const char *); +extern void get_nhuuid(void); +extern void free_nhuuid(void); /* ### fountain.c ### */ @@ -4031,6 +4033,8 @@ extern char *get_port_id(char *); #ifdef RUNTIME_PASTEBUF_SUPPORT extern void port_insert_pastebuf(char *); #endif +extern void get_nhuuid(void); +extern void free_nhuuid(void); #endif /* !MAKEDEFS_C && !MDLIB_C */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 75e1d3311..d9f25fea4 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 140 +#define EDITLEVEL 141 /* * Development status possibilities. diff --git a/src/allmain.c b/src/allmain.c index 4ac564c87..530840a1a 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -780,6 +780,7 @@ newgame(void) svc.context.next_attrib_check = 600L; /* arbitrary first setting */ svc.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ svc.context.tribute.tributesz = sizeof(struct tribute_info); + get_nhuuid(); for (i = LOW_PM; i < NUMMONS; i++) svm.mvitals[i].mvflags = mons[i].geno & G_NOCORPSE; diff --git a/src/bones.c b/src/bones.c index 5afb0cbcd..2a3358678 100644 --- a/src/bones.c +++ b/src/bones.c @@ -611,6 +611,7 @@ savebones(int how, time_t when, struct obj *corpse) nhfp->mode = WRITING; store_version(nhfp); + Sfo_char(nhfp, &svn.nhuuid[0], "ancestor-nhuuid", sizeof svn.nhuuid); /* if a bones pool digit is in use, it precedes the bonesid string and isn't recorded in the file */ Sfo_char(nhfp, &c, "bones_count", 1); @@ -632,6 +633,7 @@ getbones(void) NHFILE *nhfp = (NHFILE *) 0; char c = 0, *bonesid, oldbonesid[40] = { 0 }; /* was [10]; more should be safer */ + char ancestor_nhuuid[SIZE(svn.nhuuid)]; #ifndef SFCTOOL if (discover) /* save bones files for real games */ @@ -670,6 +672,8 @@ getbones(void) return 0; } } + Sfi_char(nhfp, &ancestor_nhuuid[0], "ancestor-nhuuid", + sizeof ancestor_nhuuid); Sfi_char(nhfp, &c, "bones_count", 1); /* length incl. '\0' */ if ((unsigned) c <= sizeof oldbonesid) { Sfi_char(nhfp, oldbonesid, "bonesid", (int) c); diff --git a/src/decl.c b/src/decl.c index 14a92abb3..43d7143b9 100644 --- a/src/decl.c +++ b/src/decl.c @@ -929,6 +929,11 @@ static const struct instance_globals_saved_m init_svm = { static const struct instance_globals_saved_n init_svn = { /* dungeon.c */ 0, /* n_dgns */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 + }, /* nhuuid */ /* mkroom.c */ 0, /* nroom */ /* region.c */ diff --git a/src/files.c b/src/files.c index ae45f6c07..74f600ef2 100644 --- a/src/files.c +++ b/src/files.c @@ -1529,6 +1529,7 @@ free_saved_games(char **saved) free((genericptr_t) saved); } } + #endif /* !SFCTOOL */ /* ---------- END SAVE FILE HANDLING ----------- */ diff --git a/src/restore.c b/src/restore.c index 83e2ca546..35ebaee10 100644 --- a/src/restore.c +++ b/src/restore.c @@ -537,6 +537,8 @@ restgamestate(NHFILE *nhfp) #endif Sfi_ulong(nhfp, &uid, "gamestate-uid"); + Sfi_char(nhfp, &svn.nhuuid[0], "nhuuid", sizeof svn.nhuuid); + Sfi_long(nhfp, &svm.moves, "gamestate-moves"); #ifndef SFCTOOL if (SYSOPT_CHECK_SAVE_UID && uid != (unsigned long) getuid()) { /* strange ... */ @@ -676,7 +678,6 @@ restgamestate(NHFILE *nhfp) restore_dungeon(nhfp); restlevchn(nhfp); - Sfi_long(nhfp, &svm.moves, "gamestate-moves"); /* hero_seq isn't saved and restored because it can be recalculated */ gh.hero_seq = svm.moves << 3; /* normally handled in moveloop() */ Sfi_q_score(nhfp, &svq.quest_status, "gamestate-quest_status"); diff --git a/src/save.c b/src/save.c index a93ae35a4..b6d09f432 100644 --- a/src/save.c +++ b/src/save.c @@ -292,6 +292,8 @@ savegamestate(NHFILE *nhfp) program_state.saving++; /* caller should/did already set this... */ uid = (unsigned long) getuid(); Sfo_ulong(nhfp, &uid, "gamestate-uid"); + Sfo_char(nhfp, &svn.nhuuid[0], "nhuuid", sizeof svn.nhuuid); + Sfo_long(nhfp, &svm.moves, "gamestate-moves"); moves_to_relative_time(&svc.context.seer_turn); moves_to_relative_time(&svc.context.digging.lastdigtime); Sfo_context_info(nhfp, &svc.context, "gamestate-context"); @@ -322,7 +324,6 @@ savegamestate(NHFILE *nhfp) save_dungeon(nhfp, (boolean) !!update_file(nhfp), (boolean) !!release_data(nhfp)); savelevchn(nhfp); - Sfo_long(nhfp, &svm.moves, "gamestate-moves"); Sfo_q_score(nhfp, &svq.quest_status, "gamestate-quest_status"); for (i = 0; i < (MAXSPELL + 1); ++i) { Sfo_spell(nhfp, &svs.spl_book[i], "gamestate-spl_book"); @@ -1177,6 +1178,7 @@ freedynamicdata(void) release_runtime_info(); /* build-time options and version stuff */ free_convert_filenames(); #endif /* FREE_ALL_MEMORY */ + free_nhuuid(); if (VIA_WINDOWPORT()) status_finish(); diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 07cab8e42..c2f3aa2dd 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -143,6 +143,30 @@ append_slash(char *name) return; } +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (svn.nhuuid[0]) + return; + + /* FIXME: fill in a useful valie UUID somehow */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + void getreturn(const char *str) { diff --git a/sys/unix/hints/include/multiw-2.370 b/sys/unix/hints/include/multiw-2.370 index e1cf1633d..ca732f6c8 100644 --- a/sys/unix/hints/include/multiw-2.370 +++ b/sys/unix/hints/include/multiw-2.370 @@ -168,6 +168,10 @@ CPLUSPLUS_NEED_DEPSUPPRESS = 1 endif # WANT_WIN_QT6 endif # WANT_WIN_QT +ifdef WANT_NHUUID +USE_UUIDLIB=1 +endif + ifeq "$(GIT)" "1" ifndef GITSUBMODULES GITSUBMODULES=1 diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.370 index 8b402350c..ea239260e 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.370 @@ -227,6 +227,10 @@ ifdef MAKEFILE_SRC ifdef CURSESLIB WINLIB += $(CURSESLIB) endif #CURSESLIB +ifdef WANT_NHUUID +CFLAGS+= -DNHUUID +LIBS+=-luuid +endif #NHUUID endif #MAKEFILE_SRC ifdef WANT_WIN_X11 diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index ad2cef7de..90577fde0 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -15,6 +15,13 @@ #include #endif +#ifdef NHUUID +/* for uuid */ +#ifdef LINUX +#include +#endif +#endif /* NHUUID */ + #if !defined(_BULL_SOURCE) && !defined(__sgi) && !defined(_M_UNIX) #if !defined(SUNOS4) && !(defined(ULTRIX) && defined(__GNUC__)) #if defined(POSIX_TYPES) || defined(SVR4) || defined(HPUX) @@ -833,5 +840,36 @@ sys_random_seed(void) } return seed; } +void +get_nhuuid(void) +{ + char struuid[37] = { 0 }; +#if defined(LINUX) && defined(NHUUID) + uuid_t binuuid; +#endif +#if defined(MACOS) && defined(NHUUID) + extern char *get_mac_uuid(char **); /* sys/unix/macuuid.m */ +#endif + if (svn.nhuuid[0]) + return; + +#if defined(MACOS) && defined(NHUUID) + get_mac_uuid(&struuid[0]); +#elif defined(LINUX) && defined(NHUUID) + uuid_generate_random(binuuid); + uuid_unparse(binuuid, struuid); +#endif /* MACOS || LINUX */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", &struuid[0]); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} /*unixmain.c*/ diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index f540d3190..d69c4de4d 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -513,4 +513,28 @@ sys_random_seed(void) return seed; } +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (svn.nhuuid[0]) + return; + + /* FIXME: fill in a useful valie UUID somehow */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + /*vmsmain.c*/ diff --git a/sys/windows/vs/NetHack/NetHack.vcxproj b/sys/windows/vs/NetHack/NetHack.vcxproj index c6f2df87c..fc2604af1 100644 --- a/sys/windows/vs/NetHack/NetHack.vcxproj +++ b/sys/windows/vs/NetHack/NetHack.vcxproj @@ -78,7 +78,7 @@ stdclatest - hacklib.lib;lualib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;UserEnv.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;UserEnv.lib;Rpcrt4.lib;bcrypt.lib;%(AdditionalDependencies) $(SndWavDir);$(SysWindDir);%(AdditionalIncludeDirectories) diff --git a/sys/windows/vs/NetHackW/NetHackW.vcxproj b/sys/windows/vs/NetHackW/NetHackW.vcxproj index cc3ec2563..6b7ecc097 100644 --- a/sys/windows/vs/NetHackW/NetHackW.vcxproj +++ b/sys/windows/vs/NetHackW/NetHackW.vcxproj @@ -100,7 +100,7 @@ Windows - hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;Rpcrt4.lib;bcrypt.lib;%(AdditionalDependencies) $(WinWin32Dir)NethackW.exe.manifest;%(AdditionalManifestFiles) diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 83e63d608..8826c33e4 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -28,6 +28,7 @@ #include #ifdef WIN32 +#include #include #include @@ -530,6 +531,36 @@ nethack_exit(int code) exit(code); } +void +get_nhuuid(void) +{ + UUID binuuid; + unsigned char *stmp; + RPC_STATUS rpcstatus; + + if (svn.nhuuid[0]) + return; + + rpcstatus = UuidCreate(&binuuid); + if (rpcstatus == RPC_S_OK) { + rpcstatus = UuidToStringA(&binuuid, &stmp); + if (rpcstatus == RPC_S_OK) { + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); + RpcStringFree(&stmp); + } + } +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + #ifdef WIN32CON #undef kbhit #include