Alexiy Posted July 11, 2017 Posted July 11, 2017 Let's say I have a server command which starts a Thread @Override void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { WorldServer world=sender.entityWorld as WorldServer if(args) { if(args.size()==1) { String action=args[0] ChunkPos chunkPos=new ChunkPos(sender.position) int chunkx=chunkPos.chunkXPos int chunkz=chunkPos.chunkZPos if(action==STOP_GENERATION) { if(landGenerator && landGenerator.isAlive()){ landGenerator.interrupt() sender.sendMessage(new TextComponentString('Sent stop signal')) } } } else if(args.size()==2) { BlockPos startposition=sender.position String action=String.valueOf(args[0]) if(action==START_GENERATION) { int range = parseInt(args[1]) landGenerator = new LandGenerator(world, range, startposition,sender) world.addScheduledTask(landGenerator) } } else if (args.size()==3) { String s=String.valueOf(args[0]) int cx=parseInt(args[1]) int cz=parseInt(args[2]) } } } This is a thread which generates world chunks (don't ask me why) class LandGenerator extends Thread{ WorldServer serverWorld int range BlockPos centerPosititon int x1=0,x2=0,z1=0,z2=0 ICommandSender commander Runtime runtime=Runtime.getRuntime() LandGenerator(WorldServer worldServer, int radius,BlockPos center,ICommandSender sender) { super("Land generator") Chunk centerchunk=worldServer.getChunkFromBlockCoords(center) ChunkPos chunkPos=centerchunk.getPos() serverWorld=worldServer range=radius centerPosititon=center int x=chunkPos.chunkXPos int z= chunkPos.chunkZPos x1=x-range z1=z-range x2=x+range z2=z+range commander=sender } @Override void run() { commander.sendMessage(new TextComponentString("Started generation in $range chunk range")) IChunkGenerator chunkGenerator= serverWorld.getChunkProvider().chunkGenerator int chunkamount=0; ChunkPos chunkPos=new ChunkPos(centerPosititon) d: for (int xx = x1; xx < x2; xx++) { for (int zz = z1; zz <z2 ; zz++) { ChunkPos curpos=new ChunkPos(xx,zz) boolean generated= serverWorld.isChunkGeneratedAt(xx,zz) if(!generated){ Chunk chunk=chunkGenerator.provideChunk(xx,zz) serverWorld.chunkProvider.chunkLoader.saveChunk(serverWorld,chunk) generated=serverWorld.isChunkGeneratedAt(xx,zz) if(generated) { println("Generated chunk at $xx, $zz") chunkamount++; long freememory=runtime.maxMemory()-(runtime.totalMemory()-runtime.freeMemory()) float freeMBs=freememory/1024/1024 println(freeMBs+" MB") if(freeMBs<300){ commander.sendMessage(new TextComponentString("Generation terminated due to low free memory")) break d } } } } } commander.sendMessage(new TextComponentString("Generated $chunkamount chunks")) } @Override void interrupt() { super.interrupt() commander.sendMessage(new TextComponentString('Generation interrupted')) } } While the thread is working, I can't execute any other commands. Is there a solution to this? Quote
Choonster Posted July 11, 2017 Posted July 11, 2017 IThreadListener#addScheduledTask is intended to be called from a background thread (usually a Netty thread) to schedule a task to run on the main thread next tick. When called from the main thread, it executes the task immediately. You're not actually starting a new thread, you're just calling the LandGenerator#run method on the main thread. As diesieben07 said, you can't safely interact with the world from a separate thread. Side note: You can't compare Strings with the == operator, use the Object#equals method. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.