def createLevelIter(self, level, box, simulate=False, **kw): if isinstance(level, basestring): filename = level level = worldeditor.WorldEditor(filename, create=True, **kw) assert isinstance(level, worldeditor.WorldEditor) 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 = worldeditor.WorldEditor(tempWorld.filename) tempWorldRW.getWorldMetadata().Spawn = cx * 16, 64, cz * 16 tempWorldRW.saveChanges() tempWorldRW.close() del tempWorldRW tempWorld.unload() startTime = time.time() proc = self.runServer(tempDir) while proc.poll() is None: line = proc.stderr.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 = worldeditor.WorldEditor( tempWorldDir, create=not os.path.exists(tempWorldDir), random_seed=level.RandomSeed) tempWorld.close() tempWorldRO = worldeditor.WorldEditor(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
def showWorld(self, filename): if filename == self._currentFilename: return self._currentFilename = filename self.removeWorldView() try: worldEditor = worldeditor.WorldEditor(filename, readonly=True) except Exception as e: self.errorWidget = QtGui.QWidget() setWidgetError( self.errorWidget, e, "An error occurred while reading the file %s. This file might not be a Minecraft world. If it is, please file a bug report." % filename) self.stackedWidget.addWidget(self.errorWidget) self.stackedWidget.setCurrentWidget(self.errorWidget) else: dim = worldEditor.getDimension() self.setWorldView(MinimapWorldView(dim)) self.chunkLoader = ChunkLoader(dim) self.chunkLoader.addClient(self.worldView) self.chunkLoader.chunkCompleted.connect(self.worldView.update) try: try: player = worldEditor.getPlayer() log.info("Centering on single-player player.") except (PlayerNotFound, NBTFormatError): try: center = worldEditor.getWorldMetadata().Spawn log.info("Centering on spawn position.") except AttributeError: log.info("Centering on world center") center = dim.bounds.origin + (dim.bounds.size * 0.5) else: if player.dimName == dim.dimName: center = Vector(*player.Position) self.worldView.centerOnPoint(center) else: center = dim.bounds.origin + (dim.bounds.size * 0.5) self.worldView.centerOnPoint(center) except Exception as e: log.exception("Error while centering view in world list: %s", e) log.info("Switched world view")
def worldListItemClicked(self, i): if self.selectedWorldIndex == i: return self.selectedWorldIndex = i import gc gc.collect() models = {} try: worldEditor = worldeditor.WorldEditor(self.itemWidgets[i].filename, readonly=True) except (EnvironmentError, LevelFormatError) as e: setWidgetError(self.errorWidget, e) while self.stackedWidget.count(): self.stackedWidget.removeWidget(self.stackedWidget.widget(0)) self.worldViewBox.addWidget(self.errorWidget) else: i, v, p = self.getSelectedIVP() blockModels = models.get(worldEditor.blocktypes) resLoader = i.getResourceLoader(v, p) if blockModels is None: models[worldEditor.blocktypes] = blockModels = BlockModels( worldEditor.blocktypes, resLoader) textureAtlas = TextureAtlas(worldEditor, resLoader, blockModels) dim = worldEditor.getDimension() self.setWorldView(MinimapWorldView(dim, textureAtlas)) self.chunkLoader = ChunkLoader(dim) self.chunkLoader.addClient(self.worldView) self.chunkLoader.chunkCompleted.connect(self.worldView.update) try: player = worldEditor.getPlayer() log.info("Centering on single-player player.") except PlayerNotFound: try: center = worldEditor.worldSpawnPosition() log.info("Centering on spawn position.") except AttributeError: log.info("Centering on world center") center = dim.bounds.origin + (dim.bounds.size * 0.5) else: if player.dimName == dim.dimName: center = Vector(*player.Position) self.worldView.centerOnPoint(center) else: center = dim.bounds.origin + (dim.bounds.size * 0.5) self.worldView.centerOnPoint(center) log.info("Switched world view")
def showWorld(self, filename): self.removeWorldView() try: worldEditor = worldeditor.WorldEditor(filename, readonly=True) resLoader = QtGui.qApp.getResourceLoaderForFilename(filename) blockModels = BlockModels(worldEditor.blocktypes, resLoader) textureAtlas = TextureAtlas(worldEditor, resLoader, blockModels) except (EnvironmentError, LevelFormatError, zipfile.BadZipfile) as e: self.errorWidget = QtGui.QWidget() setWidgetError(self.errorWidget, e) self.stackedWidget.addWidget(self.errorWidget) self.stackedWidget.setCurrentWidget(self.errorWidget) else: dim = worldEditor.getDimension() self.setWorldView(MinimapWorldView(dim, textureAtlas)) self.chunkLoader = ChunkLoader(dim) self.chunkLoader.addClient(self.worldView) self.chunkLoader.chunkCompleted.connect(self.worldView.update) try: try: player = worldEditor.getPlayer() log.info("Centering on single-player player.") except PlayerNotFound: try: center = worldEditor.getWorldMetadata().Spawn log.info("Centering on spawn position.") except AttributeError: log.info("Centering on world center") center = dim.bounds.origin + (dim.bounds.size * 0.5) else: if player.dimName == dim.dimName: center = Vector(*player.Position) self.worldView.centerOnPoint(center) else: center = dim.bounds.origin + (dim.bounds.size * 0.5) self.worldView.centerOnPoint(center) except Exception as e: log.exception("Error while centering view in world list: %s", e) log.info("Switched world view")