def createLevelIter(self, level, box, simulate=False, **kw): if isinstance(level, basestring): filename = level level = infiniteworld.MCInfdevOldLevel(filename, create=True, **kw) assert isinstance(level, infiniteworld.MCInfdevOldLevel) minRadius = self.minRadius genPositions = list( itertools.product(xrange(box.mincx, box.maxcx, minRadius * 2), xrange(box.mincz, box.maxcz, minRadius * 2))) for i, (cx, cz) in enumerate(genPositions): log.info("Generating at %s" % ((cx, cz), )) parentDir = dirname(os.path.abspath(level.worldFolder.filename)) propsFile = join(parentDir, "server.properties") props = readProperties( join(dirname(self.serverJarFile), "server.properties")) props["level-name"] = basename(level.worldFolder.filename) props["server-port"] = int(32767 + random.random() * 32700) saveProperties(propsFile, props) for p in self.generateAtPositionIter(level, parentDir, cx, cz, simulate): yield i, len(genPositions), p level.close()
def generateAtPositionIter(self, tempWorld, tempDir, cx, cz, simulate=False): tempWorldRW = infiniteworld.MCInfdevOldLevel(tempWorld.filename) tempWorldRW.setPlayerSpawnPosition((cx * 16, 64, cz * 16)) tempWorldRW.saveInPlace() tempWorldRW.close() del tempWorldRW tempWorld.unload() self.addEULA(tempDir) startTime = time.time() proc = self.runServer(tempDir) while proc.poll() is None: line = proc.stdout.readline().strip() log.info(line) yield line # Forge and FML change stderr output, causing MCServerChunkGenerator to wait endlessly. # # Vanilla: # 2012-11-13 11:29:19 [INFO] Done (9.962s)! # # Forge/FML: # 2012-11-13 11:47:13 [INFO] [Minecraft] Done (8.020s)! if "INFO" in line and "Done" in line: if simulate: duration = time.time() - startTime simSeconds = max(8, int(duration) + 1) for i in range(simSeconds): # process tile ticks yield "%2d/%2d: Simulating the world for a little bit..." % ( i, simSeconds) time.sleep(1) proc.stdin.write("stop\n") proc.wait() break if "FAILED TO BIND" in line: proc.kill() proc.wait() raise RuntimeError("Server failed to bind to port!") stdout, _ = proc.communicate() if "Could not reserve enough space" in stdout and not MCServerChunkGenerator.lowMemory: MCServerChunkGenerator.lowMemory = True for i in self.generateAtPositionIter(tempWorld, tempDir, cx, cz): yield i (tempWorld.parentWorld or tempWorld).loadLevelDat() # reload version number
def tempWorldForLevel(self, level): # tempDir = tempfile.mkdtemp("mclevel_servergen") tempDir = os.path.join( self.worldCacheDir, self.jarStorage.checksumForVersion(self.serverVersion), str(level.RandomSeed)) propsFile = os.path.join(tempDir, "server.properties") properties = readProperties(propsFile) tempWorld = self.tempWorldCache.get( (self.serverVersion, level.RandomSeed)) if tempWorld is None: if not os.path.exists(tempDir): os.makedirs(tempDir) self.createReadme() worldName = "world" worldName = properties.setdefault("level-name", worldName) tempWorldDir = os.path.join(tempDir, worldName) tempWorld = infiniteworld.MCInfdevOldLevel( tempWorldDir, create=True, random_seed=level.RandomSeed) tempWorld.close() tempWorldRO = infiniteworld.MCInfdevOldLevel(tempWorldDir, readonly=True) self.tempWorldCache[self.serverVersion, level.RandomSeed] = tempWorldRO if level.dimNo == 0: properties["allow-nether"] = "false" else: tempWorld = tempWorld.getDimension(level.dimNo) properties["allow-nether"] = "true" properties["server-port"] = int(32767 + random.random() * 32700) saveProperties(propsFile, properties) return tempWorld, tempDir