Skip to content

Commit 0eab0b3

Browse files
CursedFlamesNotStirred
authored andcommitted
fix broadcasting block changes to client
1 parent 9c7c6fe commit 0eab0b3

File tree

7 files changed

+59
-12
lines changed

7 files changed

+59
-12
lines changed

src/main/java/io/github/opencubicchunks/cubicchunks/mixin/core/common/server/level/MixinChunkHolder.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.github.notstirred.dasm.api.annotations.selector.MethodSig;
1616
import io.github.notstirred.dasm.api.annotations.selector.Ref;
1717
import io.github.notstirred.dasm.api.annotations.transform.TransformFromMethod;
18+
import io.github.opencubicchunks.cc_core.api.CubePos;
1819
import io.github.opencubicchunks.cc_core.utils.Coords;
1920
import io.github.opencubicchunks.cc_core.world.level.CloPos;
2021
import io.github.opencubicchunks.cubicchunks.exception.DasmFailedToApply;
@@ -29,6 +30,7 @@
2930
import io.github.opencubicchunks.cubicchunks.world.level.cube.LevelCube;
3031
import it.unimi.dsi.fastutil.shorts.ShortSet;
3132
import net.minecraft.core.BlockPos;
33+
import net.minecraft.core.SectionPos;
3234
import net.minecraft.server.level.ChunkHolder;
3335
import net.minecraft.server.level.ChunkMap;
3436
import net.minecraft.server.level.FullChunkStatus;
@@ -120,8 +122,24 @@ public void cc_onSectionLightChanged(LightLayer lightLayer, int sectionY, Callba
120122

121123
@Shadow public abstract void broadcastChanges(LevelChunk chunk);
122124

125+
// region [cc_broadcastCubeChanges dasm + mixin]
123126
@AddTransformToSets(ChunkToCubeSet.class) @TransformFromMethod(owner = @Ref(ChunkHolder.class), value = @MethodSig("broadcastChanges(Lnet/minecraft/world/level/chunk/LevelChunk;)V"))
124127
public native void cc_broadcastCubeChanges(LevelCube cube);
128+
// TODO (P2) lighting - ClientboundLightUpdatePacket branch is currently never reached; once we have lighting it will have to be a CC packet, and this.broadcast will need to redirect to a CC method
129+
130+
@Dynamic @Redirect(method = "cc_dasm$cc_broadcastCubeChanges", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelHeightAccessor;getSectionYFromSectionIndex(I)I"))
131+
private int cc_onBroadcastCubeChanges_indexToSectionY(LevelHeightAccessor instance, int sectionIndex) {
132+
// The vanilla method uses SectionPos.of(ChunkPos, sectionY), but we want SectionPos.of(CubePos, sectionIndex).
133+
// The easiest way to accomplish this is to turn `getSectionYFromSectionIndex` into a no-op so that we get sectionIndex instead of sectionY.
134+
// (We could do local captures, but it'd be more brittle)
135+
return sectionIndex;
136+
}
137+
138+
@Dynamic @Redirect(method = "cc_dasm$cc_broadcastCubeChanges", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/SectionPos;of(Lio/github/opencubicchunks/cc_core/api/CubePos;I)Lnet/minecraft/core/SectionPos;"))
139+
private SectionPos cc_onBroadcastCubeChanges_sectionPos(CubePos cubePos, int sectionIndex) {
140+
return Coords.sectionPosByIndex(cubePos, sectionIndex);
141+
}
142+
// endregion
125143

126144
@AddMethodToSets(sets = ChunkToCloSet.class, owner = @Ref(ChunkHolder.class), method = @MethodSig("broadcastChanges(Lnet/minecraft/world/level/chunk/LevelChunk;)V"))
127145
public void cc_broadcastCloChanges(LevelClo clo) {

src/main/java/io/github/opencubicchunks/cubicchunks/mixin/core/common/server/level/MixinChunkMap.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@
3939
import io.github.opencubicchunks.cubicchunks.mixin.dasmsets.GlobalSet;
4040
import io.github.opencubicchunks.cubicchunks.mixin.dasmsets.SectionPosToCubeSet;
4141
import io.github.opencubicchunks.cubicchunks.network.CCClientboundSetCubeCacheCenterPacket;
42+
import io.github.opencubicchunks.cubicchunks.server.level.CCServerPlayer;
4243
import io.github.opencubicchunks.cubicchunks.server.level.CloGenerationTask;
4344
import io.github.opencubicchunks.cubicchunks.server.level.CloHolder;
4445
import io.github.opencubicchunks.cubicchunks.server.level.CloTrackingView;
46+
import io.github.opencubicchunks.cubicchunks.server.level.CubeHolder;
4547
import io.github.opencubicchunks.cubicchunks.server.level.CubicChunkMap;
4648
import io.github.opencubicchunks.cubicchunks.server.level.GeneratingCubeMap;
4749
import io.github.opencubicchunks.cubicchunks.server.level.progress.CloProgressListener;
@@ -94,7 +96,7 @@
9496
*/
9597
@Dasm(ChunkToCloSet.class)
9698
@Mixin(ChunkMap.class)
97-
public abstract class MixinChunkMap extends MixinChunkStorage implements GeneratingCubeMap, CubicChunkMap {
99+
public abstract class MixinChunkMap extends MixinChunkStorage implements GeneratingCubeMap, CubicChunkMap, CubeHolder.PlayerProvider {
98100
@Shadow public abstract ReportedException debugFuturesAndCreateReportedException(IllegalStateException exception, String details);
99101

100102
@Shadow protected abstract ChunkHolder getUpdatingChunkIfPresent(long aLong);
@@ -155,7 +157,7 @@ private static double cc_euclideanDistanceSquared(CloPos cloPos, Vec3 vec3) {
155157
// These methods are not copied due to taking 3 ints instead of 2
156158
@Override
157159
public boolean cc_isChunkTracked(ServerPlayer player, int x, int y, int z) {
158-
return ((CloTrackingView) player.getChunkTrackingView()).cc_contains(x, y, z)
160+
return ((CCServerPlayer) player).cc_getCloTrackingView().cc_contains(x, y, z)
159161
// TODO this requires PlayerChunkSender to accept Clo longs
160162
&& !player.connection.chunkSender.isPending(CloPos.cubeAsLong(x, y, z));
161163
}
@@ -496,6 +498,11 @@ private boolean cc_getPlayers_isChunkTracked(ChunkMap instance, ServerPlayer pla
496498
}
497499
//endregion
498500

501+
@AddMethodToSets(sets = ChunkToCubeSet.class, owner = @Ref(ChunkMap.class), method = @MethodSig("getPlayers(Lnet/minecraft/world/level/ChunkPos;Z)Ljava/util/List;"))
502+
@Override public List<ServerPlayer> cc_getPlayers(CubePos pos, boolean boundaryOnly) {
503+
return cc_getPlayers(CloPos.cube(pos), boundaryOnly);
504+
}
505+
499506
// Replace `SectionPos.chunk()` with `SectionPos.cc_cube()` unconditionally here
500507
@AddTransformToSets(GlobalSet.class) @TransformFromMethod(value = @MethodSig("tick(Ljava/util/function/BooleanSupplier;)V"), useRedirectSets = { ChunkToCloSet.class, SectionPosToCubeSet.class })
501508
protected native void cc_tick(BooleanSupplier hasMoreTime);

src/main/java/io/github/opencubicchunks/cubicchunks/mixin/core/common/server/level/MixinServerChunkCache.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.opencubicchunks.cubicchunks.mixin.core.common.server.level;
22

33
import java.util.List;
4+
import java.util.Set;
45
import java.util.concurrent.CompletableFuture;
56
import java.util.concurrent.Executor;
67
import java.util.function.BooleanSupplier;
@@ -105,6 +106,8 @@ public abstract class MixinServerChunkCache extends MixinChunkSource implements
105106

106107
@Shadow protected abstract void getFullChunk(long p_8371_, Consumer<LevelChunk> p_8372_);
107108

109+
@Shadow @Final private Set<ChunkHolder> chunkHoldersToBroadcast;
110+
108111
@Inject(method = "<init>", at = @At("CTOR_HEAD"))
109112
private void cc_onInit(ServerLevel level, LevelStorageSource.LevelStorageAccess levelStorageAccess, DataFixer fixerUpper, StructureTemplateManager structureManager, Executor dispatcher,
110113
ChunkGenerator generator, int viewDistance, int simulationDistance, boolean sync, ChunkProgressListener progressListener,
@@ -243,17 +246,18 @@ private void cc_tickSpawningClo(LevelClo levelClo, long timeInhabited, List<MobC
243246
// TODO (P2)
244247
}
245248

246-
// TODO just inject and do this in vanilla method?
247-
// needs manual impl because needs to use cube rather than chunk
248-
@Override
249-
@AddMethodToSets(sets = GlobalSet.class, owner = @Ref(ServerChunkCache.class), method = @MethodSig("blockChanged(Lnet/minecraft/core/BlockPos;)V"))
250-
public void cc_blockChanged(BlockPos pos) {
249+
@Inject(method = "blockChanged", at = @At("HEAD"), cancellable = true)
250+
public void cc_onBlockChanged(BlockPos pos, CallbackInfo ci) {
251+
if (!this.cc_isCubic) {
252+
return;
253+
}
254+
ci.cancel();
251255
int x = Coords.blockToCube(pos.getX());
252256
int y = Coords.blockToCube(pos.getY());
253257
int z = Coords.blockToCube(pos.getZ());
254258
ChunkHolder chunkholder = this.getVisibleChunkIfPresent(CloPos.cubeAsLong(x, y, z));
255-
if (chunkholder != null) {
256-
chunkholder.blockChanged(pos);
259+
if (chunkholder != null && chunkholder.blockChanged(pos)) {
260+
this.chunkHoldersToBroadcast.add(chunkholder);
257261
}
258262
}
259263

src/main/java/io/github/opencubicchunks/cubicchunks/mixin/core/common/server/level/MixinServerPlayer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import io.github.opencubicchunks.cubicchunks.mixin.core.common.world.entity.MixinEntity;
1717
import io.github.opencubicchunks.cubicchunks.mixin.dasmsets.ChunkToCloSet;
1818
import io.github.opencubicchunks.cubicchunks.mixin.dasmsets.ChunkToCubeSet;
19+
import io.github.opencubicchunks.cubicchunks.server.level.CCServerPlayer;
1920
import io.github.opencubicchunks.cubicchunks.server.level.CloTrackingView;
2021
import io.github.opencubicchunks.cubicchunks.server.level.ServerCubeCache;
2122
import net.minecraft.core.BlockPos;
@@ -29,7 +30,7 @@
2930

3031
@Dasm(ChunkToCloSet.class)
3132
@Mixin(ServerPlayer.class)
32-
public abstract class MixinServerPlayer extends MixinEntity {
33+
public abstract class MixinServerPlayer extends MixinEntity implements CCServerPlayer {
3334
@AddFieldToSets(sets = ChunkToCloSet.class, owner = @Ref(ServerPlayer.class), field = @FieldSig(type = @Ref(ChunkTrackingView.class), name = "chunkTrackingView"))
3435
private CloTrackingView cc_cloTrackingView = CloTrackingView.EMPTY;
3536

src/main/java/io/github/opencubicchunks/cubicchunks/mixin/dasmsets/ChunkToCubeSet.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.opencubicchunks.cubicchunks.mixin.dasmsets;
22

3+
import java.util.List;
34
import java.util.concurrent.CompletableFuture;
45

56
import io.github.notstirred.dasm.api.annotations.redirect.redirects.ConstructorToFactoryRedirect;
@@ -36,6 +37,7 @@
3637
import net.minecraft.server.level.ChunkHolder;
3738
import net.minecraft.server.level.GeneratingChunkMap;
3839
import net.minecraft.server.level.GenerationChunkHolder;
40+
import net.minecraft.server.level.ServerPlayer;
3941
import net.minecraft.util.StaticCache2D;
4042
import net.minecraft.world.level.ChunkPos;
4143
import net.minecraft.world.level.chunk.ChunkAccess;
@@ -156,7 +158,10 @@ abstract class ChunkPyramid$Builder_to_CubePyramid$Builder_redirects { }
156158
interface ChunkHolder$LevelChangeListener_to_CubeHolder$LevelChangeListener_redirects { }
157159

158160
@TypeRedirect(from = @Ref(ChunkHolder.PlayerProvider.class), to = @Ref(CubeHolder.PlayerProvider.class))
159-
interface ChunkHolder$PlayerProvider_to_CubeHolder$PlayerProvider_redirects { }
161+
interface ChunkHolder$PlayerProvider_to_CubeHolder$PlayerProvider_redirects {
162+
@MethodRedirect(@MethodSig("getPlayers(Lnet/minecraft/world/level/ChunkPos;Z)Ljava/util/List;"))
163+
List<ServerPlayer> cc_getPlayers(CubePos pos, boolean boundaryOnly);
164+
}
160165

161166
@TypeRedirect(from = @Ref(GeneratingChunkMap.class), to = @Ref(GeneratingCubeMap.class))
162167
interface GeneratingChunkMap_to_GeneratingCubeMap_redirects {
@@ -176,6 +181,13 @@ abstract class ChunkGenerationTask_redirects {
176181
@TypeRedirect(from = @Ref(LevelChunk.UnsavedListener.class), to = @Ref(LevelCube.UnsavedListener.class))
177182
interface LevelChunk$UnsavedListener_to_LevelCube$UnsavedListener_redirects { }
178183

184+
@IntraOwnerContainer(owner = @Ref(ChunkHolder.class))
185+
abstract class ChunkHolder_redirects {
186+
// TODO dasm inheritance
187+
@FieldRedirect(@FieldSig(name = "pos", type = @Ref(ChunkPos.class)))
188+
protected CubePos cc_cubePos;
189+
}
190+
179191
// Forge stuff
180192
// TODO move to a forge-specific sourceset
181193
@TypeRedirect(from = @Ref(ChunkEvent.Load.class), to = @Ref(Event.class))
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.github.opencubicchunks.cubicchunks.server.level;
2+
3+
public interface CCServerPlayer {
4+
CloTrackingView cc_getCloTrackingView();
5+
}

src/main/java/io/github/opencubicchunks/cubicchunks/server/level/CubeHolder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ interface PlayerProvider {
1818
/**
1919
* Returns the players tracking the given cube.
2020
*/
21-
List<ServerPlayer> getPlayers(CubePos pos, boolean boundaryOnly);
21+
List<ServerPlayer> cc_getPlayers(CubePos pos, boolean boundaryOnly);
2222
}
2323
}

0 commit comments

Comments
 (0)