@@ -96,15 +96,20 @@ def _new_dl_linux(vardir):
9696
9797def _new_dl (vardir ):
9898 """Creates a copied .so file to allow for multiple independent NLE instances"""
99- if sys .platform == "linux" :
100- return _new_dl_linux (vardir )
99+ # if sys.platform == "linux":
100+ # return _new_dl_linux(vardir)
101101
102102 # MacOS has no memfd_create or O_TMPFILE. Using /dev/fd/{FD} as an argument
103103 # to dlopen doesn't work after unlinking from the file system. So let's copy
104104 # instead and hope vardir gets properly deleted at some point.
105- dl = tempfile .NamedTemporaryFile (suffix = "libnethack.so" , dir = vardir )
105+ # dl = tempfile.NamedTemporaryFile(suffix="libnethack.so", dir=vardir)
106+ # shutil.copyfile(DLPATH, dl.name) # Might use fcopyfile.
107+ # return dl, dl.name
108+
109+ dlpath = os .path .join (vardir , "libnethack.so" )
110+ dl = open (dlpath , "w" )
106111 shutil .copyfile (DLPATH , dl .name ) # Might use fcopyfile.
107- return dl , dl . name
112+ return dl , dlpath
108113
109114
110115def _close (pynethack , dl , tempdir , warn = True ):
@@ -168,7 +173,11 @@ def __init__(
168173 hackdir = HACKDIR ,
169174 spawn_monsters = True ,
170175 scoreprefix = "" ,
176+ gamesavedir = None ,
177+ gameloaddir = None ,
171178 ):
179+ self .gamesavedir = gamesavedir
180+ self .gameloaddir = gameloaddir
172181 self ._copy = copy
173182
174183 if not os .path .exists (hackdir ) or not os .path .exists (
@@ -182,24 +191,31 @@ def __init__(
182191 self ._tempdir = tempfile .TemporaryDirectory (prefix = "nle" )
183192 self ._vardir = self ._tempdir .name
184193
185- # Symlink a nhdat.
186- os .symlink (os .path .join (hackdir , "nhdat" ), os .path .join (self ._vardir , "nhdat" ))
194+ if self .gameloaddir :
195+ # restore files (save) from directory
196+ shutil .copytree (self .gameloaddir , self ._vardir , dirs_exist_ok = True )
187197
188- # Touch files, so lock_file() in files.c passes.
189- for fn in ["perm" , "record" , "logfile" ]:
190- os .close (os .open (os .path .join (self ._vardir , fn ), os .O_CREAT ))
191- if scoreprefix :
192- os .close (os .open (scoreprefix + "xlogfile" , os .O_CREAT ))
198+ self .dlpath = os .path .join (self ._vardir , "libnethack.so" )
199+ self ._dl = open (self .dlpath , "r" )
193200 else :
194- os .close (os .open (os .path .join (self ._vardir , "xlogfile" ), os .O_CREAT ))
201+ # Symlink a nhdat.
202+ os .symlink (os .path .join (hackdir , "nhdat" ), os .path .join (self ._vardir , "nhdat" ))
203+
204+ # Touch files, so lock_file() in files.c passes.
205+ for fn in ["perm" , "record" , "logfile" ]:
206+ os .close (os .open (os .path .join (self ._vardir , fn ), os .O_CREAT ))
207+ if scoreprefix :
208+ os .close (os .open (scoreprefix + "xlogfile" , os .O_CREAT ))
209+ else :
210+ os .close (os .open (os .path .join (self ._vardir , "xlogfile" ), os .O_CREAT ))
195211
196- os .mkdir (os .path .join (self ._vardir , "save" ))
212+ os .mkdir (os .path .join (self ._vardir , "save" ))
197213
198- # An assortment of hacks:
199- # Copy our .so into self._vardir to load several copies of the dl.
200- # (Or use a memfd_create hack to create a file that gets deleted on
201- # process exit.)
202- self ._dl , self .dlpath = _new_dl (self ._vardir )
214+ # An assortment of hacks:
215+ # Copy our .so into self._vardir to load several copies of the dl.
216+ # (Or use a memfd_create hack to create a file that gets deleted on
217+ # process exit.)
218+ self ._dl , self .dlpath = _new_dl (self ._vardir )
203219
204220 # Finalize even when the rest of this constructor fails.
205221 self ._finalizer = weakref .finalize (self , _close , None , self ._dl , self ._tempdir )
@@ -323,3 +339,15 @@ def in_normal_game(self):
323339
324340 def how_done (self ):
325341 return self ._pynethack .how_done ()
342+
343+ def save (self , gamesavedir = None ):
344+ if gamesavedir :
345+ savedir = gamesavedir
346+ else :
347+ savedir = self .gamesavedir
348+
349+ assert savedir is not None
350+
351+ success = self ._pynethack .save ()
352+ shutil .copytree (self ._vardir , savedir , dirs_exist_ok = True )
353+ return success
0 commit comments