Skip to content

Commit 1a12db4

Browse files
authored
Send biome updates for chunks when possible (#2443)
* Send biome updates [WIP] * Add other platforms * Ensure that the iterable won't be iterated twice
1 parent e7c9e64 commit 1a12db4

File tree

10 files changed

+111
-1
lines changed

10 files changed

+111
-1
lines changed

worldedit-bukkit/adapters/adapter-1.19.4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/v1_19_R3/PaperweightAdapter.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.common.cache.CacheLoader;
2424
import com.google.common.cache.LoadingCache;
2525
import com.google.common.collect.ImmutableList;
26+
import com.google.common.collect.Lists;
2627
import com.google.common.collect.Sets;
2728
import com.google.common.util.concurrent.Futures;
2829
import com.mojang.datafixers.util.Either;
@@ -174,6 +175,7 @@
174175
import java.nio.file.Files;
175176
import java.nio.file.Path;
176177
import java.util.ArrayList;
178+
import java.util.Collection;
177179
import java.util.HashMap;
178180
import java.util.List;
179181
import java.util.Locale;
@@ -969,6 +971,17 @@ public boolean generateStructure(StructureType type, World world, EditSession se
969971
}
970972
}
971973

974+
@Override
975+
public void sendBiomeUpdates(World world, Iterable<BlockVector2> chunks) {
976+
ServerLevel originalWorld = ((CraftWorld) world).getHandle();
977+
978+
List<ChunkAccess> nativeChunks = chunks instanceof Collection<BlockVector2> chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList();
979+
for (BlockVector2 chunk : chunks) {
980+
nativeChunks.add(originalWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ(), ChunkStatus.BIOMES, false));
981+
}
982+
originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
983+
}
984+
972985
// ------------------------------------------------------------------------
973986
// Code that is less likely to break
974987
// ------------------------------------------------------------------------

worldedit-bukkit/adapters/adapter-1.20.2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/v1_20_R2/PaperweightAdapter.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.common.cache.CacheLoader;
2424
import com.google.common.cache.LoadingCache;
2525
import com.google.common.collect.ImmutableList;
26+
import com.google.common.collect.Lists;
2627
import com.google.common.collect.Sets;
2728
import com.google.common.util.concurrent.Futures;
2829
import com.mojang.datafixers.util.Either;
@@ -174,6 +175,7 @@
174175
import java.nio.file.Files;
175176
import java.nio.file.Path;
176177
import java.util.ArrayList;
178+
import java.util.Collection;
177179
import java.util.HashMap;
178180
import java.util.List;
179181
import java.util.Locale;
@@ -970,6 +972,17 @@ public boolean generateStructure(StructureType type, World world, EditSession se
970972
}
971973
}
972974

975+
@Override
976+
public void sendBiomeUpdates(World world, Iterable<BlockVector2> chunks) {
977+
ServerLevel originalWorld = ((CraftWorld) world).getHandle();
978+
979+
List<ChunkAccess> nativeChunks = chunks instanceof Collection<BlockVector2> chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList();
980+
for (BlockVector2 chunk : chunks) {
981+
nativeChunks.add(originalWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ(), ChunkStatus.BIOMES, false));
982+
}
983+
originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
984+
}
985+
973986
// ------------------------------------------------------------------------
974987
// Code that is less likely to break
975988
// ------------------------------------------------------------------------

worldedit-bukkit/adapters/adapter-1.20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/v1_20_R1/PaperweightAdapter.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.common.cache.CacheLoader;
2424
import com.google.common.cache.LoadingCache;
2525
import com.google.common.collect.ImmutableList;
26+
import com.google.common.collect.Lists;
2627
import com.google.common.collect.Sets;
2728
import com.google.common.util.concurrent.Futures;
2829
import com.mojang.datafixers.util.Either;
@@ -174,6 +175,7 @@
174175
import java.nio.file.Files;
175176
import java.nio.file.Path;
176177
import java.util.ArrayList;
178+
import java.util.Collection;
177179
import java.util.HashMap;
178180
import java.util.List;
179181
import java.util.Locale;
@@ -970,6 +972,17 @@ public boolean generateStructure(StructureType type, World world, EditSession se
970972
}
971973
}
972974

975+
@Override
976+
public void sendBiomeUpdates(World world, Iterable<BlockVector2> chunks) {
977+
ServerLevel originalWorld = ((CraftWorld) world).getHandle();
978+
979+
List<ChunkAccess> nativeChunks = chunks instanceof Collection<BlockVector2> chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList();
980+
for (BlockVector2 chunk : chunks) {
981+
nativeChunks.add(originalWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ(), ChunkStatus.BIOMES, false));
982+
}
983+
originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
984+
}
985+
973986
// ------------------------------------------------------------------------
974987
// Code that is less likely to break
975988
// ------------------------------------------------------------------------

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ public void fixAfterFastMode(Iterable<BlockVector2> chunks) {
329329
}
330330
}
331331

332+
@Override
333+
public void sendBiomeUpdates(Iterable<BlockVector2> chunks) {
334+
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
335+
if (adapter != null) {
336+
adapter.sendBiomeUpdates(getWorld(), chunks);
337+
}
338+
}
339+
332340
@Override
333341
public boolean playEffect(Vector3 position, int type, int data) {
334342
World world = getWorld();

worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.sk89q.worldedit.entity.BaseEntity;
2626
import com.sk89q.worldedit.extent.Extent;
2727
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
28+
import com.sk89q.worldedit.math.BlockVector2;
2829
import com.sk89q.worldedit.math.BlockVector3;
2930
import com.sk89q.worldedit.regions.Region;
3031
import com.sk89q.worldedit.registry.state.Property;
@@ -314,4 +315,17 @@ default boolean generateStructure(StructureType feature, World world, EditSessio
314315
default void initializeRegistries() {
315316

316317
}
318+
319+
/**
320+
* Sends biome updates for the given chunks.
321+
*
322+
* <p>This doesn't modify biomes at all, it just sends the current state of the biomes
323+
* in the world to all of the nearby players, updating the visual representation of the
324+
* biomes on their clients.</p>
325+
*
326+
* @param world the world
327+
* @param chunks a list of chunk coordinates to send biome updates for
328+
*/
329+
default void sendBiomeUpdates(World world, Iterable<BlockVector2> chunks) {
330+
}
317331
}

worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.sk89q.worldedit.util.SideEffectSet;
3030
import com.sk89q.worldedit.util.collection.BlockMap;
3131
import com.sk89q.worldedit.world.World;
32+
import com.sk89q.worldedit.world.biome.BiomeType;
3233
import com.sk89q.worldedit.world.block.BlockState;
3334
import com.sk89q.worldedit.world.block.BlockStateHolder;
3435

@@ -50,6 +51,7 @@ public class SideEffectExtent extends AbstractDelegateExtent {
5051
private final World world;
5152
private final Map<BlockVector3, BlockState> positions = BlockMap.create();
5253
private final Set<BlockVector2> dirtyChunks = new HashSet<>();
54+
private final Set<BlockVector2> dirtyBiomes = new HashSet<>();
5355
private SideEffectSet sideEffectSet = SideEffectSet.defaults();
5456
private boolean postEditSimulation;
5557

@@ -97,8 +99,14 @@ public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B
9799
return world.setBlock(location, block, postEditSimulation ? INTERNAL_NONE : sideEffectSet);
98100
}
99101

102+
@Override
103+
public boolean setBiome(BlockVector3 position, BiomeType biome) {
104+
dirtyBiomes.add(BlockVector2.at(position.getBlockX() >> 4, position.getBlockZ() >> 4));
105+
return world.setBiome(position, biome);
106+
}
107+
100108
public boolean commitRequired() {
101-
return postEditSimulation || !dirtyChunks.isEmpty();
109+
return postEditSimulation || !dirtyChunks.isEmpty() || !dirtyBiomes.isEmpty();
102110
}
103111

104112
@Override
@@ -113,6 +121,10 @@ public Operation resume(RunContext run) throws WorldEditException {
113121
world.fixAfterFastMode(dirtyChunks);
114122
}
115123

124+
if (!dirtyBiomes.isEmpty()) {
125+
world.sendBiomeUpdates(dirtyBiomes);
126+
}
127+
116128
if (postEditSimulation) {
117129
Iterator<Map.Entry<BlockVector3, BlockState>> positionIterator = positions.entrySet().iterator();
118130
while (run.shouldContinue() && positionIterator.hasNext()) {

worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ public void checkLoadedChunk(BlockVector3 pt) {
9494
public void fixAfterFastMode(Iterable<BlockVector2> chunks) {
9595
}
9696

97+
@Override
98+
public void sendBiomeUpdates(Iterable<BlockVector2> chunks) {
99+
}
100+
97101
@Override
98102
public void fixLighting(Iterable<BlockVector2> chunks) {
99103
}

worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,17 @@ default boolean generateFeature(ConfiguredFeatureType type, EditSession editSess
311311
*/
312312
void fixAfterFastMode(Iterable<BlockVector2> chunks);
313313

314+
/**
315+
* Sends biome updates for the given chunks.
316+
*
317+
* <p>This doesn't modify biomes at all, it just sends the current state of the biomes
318+
* in the world to all of the nearby players, updating the visual representation of the
319+
* biomes on their clients.</p>
320+
*
321+
* @param chunks a list of chunk coordinates to send biome updates for
322+
*/
323+
void sendBiomeUpdates(Iterable<BlockVector2> chunks);
324+
314325
/**
315326
* Relight the given chunks if possible.
316327
*

worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.common.cache.CacheLoader;
2424
import com.google.common.cache.LoadingCache;
2525
import com.google.common.collect.ImmutableList;
26+
import com.google.common.collect.Lists;
2627
import com.google.common.collect.Sets;
2728
import com.google.common.collect.Streams;
2829
import com.google.common.util.concurrent.Futures;
@@ -115,6 +116,7 @@
115116
import java.nio.file.Files;
116117
import java.nio.file.Path;
117118
import java.util.ArrayList;
119+
import java.util.Collection;
118120
import java.util.Collections;
119121
import java.util.HashMap;
120122
import java.util.List;
@@ -526,6 +528,15 @@ public void fixAfterFastMode(Iterable<BlockVector2> chunks) {
526528
fixLighting(chunks);
527529
}
528530

531+
@Override
532+
public void sendBiomeUpdates(Iterable<BlockVector2> chunks) {
533+
List<ChunkAccess> nativeChunks = chunks instanceof Collection<BlockVector2> chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList();
534+
for (BlockVector2 chunk : chunks) {
535+
nativeChunks.add(getWorld().getChunk(chunk.getBlockX(), chunk.getBlockZ(), ChunkStatus.BIOMES, false));
536+
}
537+
((ServerLevel) getWorld()).getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
538+
}
539+
529540
@Override
530541
public void fixLighting(Iterable<BlockVector2> chunks) {
531542
Level world = getWorld();

worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.common.cache.CacheLoader;
2424
import com.google.common.cache.LoadingCache;
2525
import com.google.common.collect.ImmutableList;
26+
import com.google.common.collect.Lists;
2627
import com.google.common.collect.Sets;
2728
import com.google.common.collect.Streams;
2829
import com.google.common.util.concurrent.Futures;
@@ -113,6 +114,7 @@
113114
import java.nio.file.Files;
114115
import java.nio.file.Path;
115116
import java.util.ArrayList;
117+
import java.util.Collection;
116118
import java.util.HashMap;
117119
import java.util.List;
118120
import java.util.Map;
@@ -508,6 +510,15 @@ public void fixAfterFastMode(Iterable<BlockVector2> chunks) {
508510
fixLighting(chunks);
509511
}
510512

513+
@Override
514+
public void sendBiomeUpdates(Iterable<BlockVector2> chunks) {
515+
List<ChunkAccess> nativeChunks = chunks instanceof Collection<BlockVector2> chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList();
516+
for (BlockVector2 chunk : chunks) {
517+
nativeChunks.add(getWorld().getChunk(chunk.getBlockX(), chunk.getBlockZ(), ChunkStatus.BIOMES, false));
518+
}
519+
((ServerLevel) getWorld()).getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
520+
}
521+
511522
@Override
512523
public void fixLighting(Iterable<BlockVector2> chunks) {
513524
ServerLevel world = getWorld();

0 commit comments

Comments
 (0)