-
-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API: Way to remove CustomBlocks faster #3445
Comments
Hello, Thanks a lot for your patience. |
Post a link of your implementation of where you remove blocks, so that I can know how to structure the new API to fast remove blocks. |
Thanks for the quick reply. Islands are deleted chunk by chunk. The start point is DeleteIslandChunks.java. but regeneration is done by obtaining a replacement chunk from the GameMode, which for games like BSkyBlock is just empty air chunks, and writing the blocks in a x,y,z nested loop. For other gamemodes, it may be chunks copied from a seed world. You can find the key method here that does the looping to paste the blocks and on line 203 and 204 you can find the calls I make to Slimeworld and your plugin to delete the custom blocks. Slimeworld has a similar issue, but it does have a very quick check available that enables me to query if there's a block at the location before attempting any removal. However, what would be better would be to get a collection of blocks in a chunk (or some other space), similar to how Entities/TileEntities can be obtained, and then deal with them outside of this loop. Note that island borders can be in the middle of a chunk, so I can't always just delete everything in a chunk (although I wish it was possible). In terms of the actual block writer, it's usually done using NMS to paste the blocks, with a Bukkit fallback in the NMS version isn't available, e.g., this for 1.20.4. |
Would a method that deletes a all the custom blocks data for a chunk or a world be what you need? |
Unfortunately it is possible for chunks to be in more than one island - admins can set islands to abut each other so that players can build right up to the edge and bridge, so deleting everything in a chunk could accidentally delete CustomBlocks in the Nextdoor island. The ultimate would be to have a method that takes a World and a BoundingBox and delete all the CustomBlocks in that space. However, I suspect that's a bit too much wishful thinking! If you can provide all the CustomBlocks in a Chunk or a World I could iterate over them checking their location and delete them. I don't expect there will be that many. |
Sorry to bump, but were you able to add anything at all? If getting the CustomBlocks in a chunk is possible, that could work. |
I'm also looking for a way to iterate over all custom blocks in a chunk in order to tick them. |
I will add some methods under public static void deleteAllCustomBlocksInChunk(Chunk chunk)
@Nullable
public List<Location> getAllBlocksLocationsList(Chunk chunk)
@Nullable
public Map<String, Location> getAllBlocksLocations(Chunk chunk)
public void runActionOnBlocks(Chunk chunk, BiConsumer<String, Location> action) |
Some dumb code to test the new API. Tested and working fine on 1.20.4. @EventHandler
private void test(AsyncPlayerChatEvent e)
{
if(e.getMessage().contains("deleteAllCustomBlocksInChunk2"))
{
CustomBlock.Advanced.deleteAllCustomBlocksInChunk(e.getPlayer().getChunk(), true, true);
}
else if(e.getMessage().contains("deleteAllCustomBlocksInChunk"))
{
CustomBlock.Advanced.deleteAllCustomBlocksInChunk(e.getPlayer().getChunk());
}
else if(e.getMessage().contains("getAllBlocksLocationsList"))
{
List<Location> list = CustomBlock.Advanced.getAllBlocksLocationsList(e.getPlayer().getChunk());
if(list == null)
return;
for (int i = 0; i < list.size(); i++)
{
Location location = list.get(i);
System.out.println(location);
if(i > 10)
{
System.out.println("and more...");
break;
}
}
}
else if(e.getMessage().contains("getAllBlocksLocations"))
{
@org.jetbrains.annotations.Nullable Map<Location, String> list = CustomBlock.Advanced.getAllBlocksLocations(e.getPlayer().getChunk());
if(list == null)
return;
AtomicInteger i = new AtomicInteger();
for (Map.Entry<Location, String> entry : list.entrySet())
{
String s = entry.getValue();
Location location = entry.getKey();
System.out.println(s + " | " + location);
if (i.get() > 10)
{
System.out.println("and more...");
break;
}
i.getAndIncrement();
}
}
else if(e.getMessage().contains("runActionOnBlocks"))
{
AtomicInteger i = new AtomicInteger();
CustomBlock.Advanced.runActionOnBlocks(e.getPlayer().getChunk(), (s, location) -> {
System.out.println(s + " | " + location);
if (i.get() > 10)
{
System.out.println("and more...");
return;
}
i.getAndIncrement();
});
}
} |
Fantastic work! Thanks! |
Terms
Discord tag (optional)
tastybento
Describe the solution you'd like
I would like a way to obtain a collection of CustomBlocks in a World, Chunk, or in a BoundingBox, so I can iterate through them and delete the ones that need to be deleted by Location.
Is your feature request related to a problem?
Yes. I maintain the BentoBox/BSkyBlock/AcidIsland/AOneBlock, etc. plugin. It needs to delete islands which it does on a chunk by chunk basis. We have a problem where IA custom blocks remain in the world even though Blocks have been deleted. If a new player used the old space, the IA blocks could be obtained by players placing a block and then breaking it where the old one was.
Describe alternatives you've considered
Currently, I use
CustomBlock.remove(location)
but when run on multiple locations, e.g., a cube of size 800 x 800 x world height, it will lag the server. I've had to remove the support for ItemsAdder because I currently cannot find a streamlined way to delete the CustomBlocks. There are rarely more than a few on any one island, but I currently have to remove every location in the whole island because I have no way to find out where they are. I'd like to be able to optimize somehow, by for example, checking if there is a block at that location first, or having a way to obtain all the CustomBlocks in a World, or Chunk, etc.The only other option is to ask admins to change deletion settings in the BentoBox config to delete chunks a lot slower than normal, e.g., 1 chunk per tick. This is just a workaround.
Additional context
The code to the IA hook in BentoBox is here: https://github.com/BentoBoxWorld/BentoBox/blob/f81354fa3e5187f87efe48f6bc72bb9f127a9f22/src/main/java/world/bentobox/bentobox/hooks/ItemsAdderHook.java#L78
Currently, it's commented out because of the lag spikes.
I have asked on your Discord on itemsadder-chat but there were no replies.
The text was updated successfully, but these errors were encountered: