add support for a unique game identifier
A 37 character field for holding a unique identifier is added to the save file, as well as to an ancestor field in bones files. Since it requires installation of libuuid package on Linux, it requires an exlicit WANT_NHUUID=1 on the Make command line there. Without the libuuid support, the saved nhuuid is empty, which should be harmless. This also moves the save and restore of gm.moves higher up so that it already has a value the first time it is used against a relative saved timestamp. Invalidates savefiles and bones files due to new fields. I need to get this committed before I can test out the macOS portion, so there may be some build issues there briefly (hopefully), and follow-up commits to resolve them. Increments EDITLEVEL.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1529,6 +1529,7 @@ free_saved_games(char **saved)
|
||||
free((genericptr_t) saved);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !SFCTOOL */
|
||||
|
||||
/* ---------- END SAVE FILE HANDLING ----------- */
|
||||
|
||||
+2
-1
@@ -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");
|
||||
|
||||
+3
-1
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -15,6 +15,13 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef NHUUID
|
||||
/* for uuid */
|
||||
#ifdef LINUX
|
||||
#include <uuid/uuid.h>
|
||||
#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*/
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<LanguageStandard_C>stdclatest</LanguageStandard_C>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<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;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<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)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>$(SndWavDir);$(SysWindDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalDependencies>hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;Rpcrt4.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>$(WinWin32Dir)NethackW.exe.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <rpc.h>
|
||||
#include <VersionHelpers.h>
|
||||
#include <UserEnv.h>
|
||||
|
||||
@@ -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 <conio.h>
|
||||
|
||||
Reference in New Issue
Block a user