Skip to content

Commit ff3c9a9

Browse files
Fix WearBlackAllDay#72. Time ticking is not thread-safe and cause piston problems on worlds that does not tick the time
1 parent 66a519c commit ff3c9a9

5 files changed

Lines changed: 63 additions & 1 deletion

File tree

src/main/java/wearblackallday/dimthread/mixin/EntityMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public void onMoveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity
115115
this.uncompletedTeleportTargetForMoveToWorld = null;
116116
this.nbtCachedForMoveToWorld = null;
117117
this.world.spawnEntity((Entity) (Object) this);// if the teleporting failed, we need to add it back to the world
118-
LOGGER.debug("Failed to teleport {}, return it to it's previous world", this);
118+
LOGGER.debug("Failed to teleport {}, return it to its previous world", this);
119119
}
120120
}
121121
);

src/main/java/wearblackallday/dimthread/mixin/MinecraftServerMixin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1414
import wearblackallday.dimthread.DimThread;
1515
import wearblackallday.dimthread.util.CrashInfo;
16+
import wearblackallday.dimthread.util.ServerWorldAccessor;
1617
import wearblackallday.dimthread.util.ThreadPool;
1718

1819
import java.util.Collections;
@@ -72,6 +73,7 @@ public void tickWorlds(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
7273
});
7374

7475
pool.awaitCompletion();
76+
getWorlds().forEach(world -> ((ServerWorldAccessor) world).dimthread_tickTime()); // Time ticking is not thread-safe, fix https://github.com/WearBlackAllDay/DimensionalThreading/issues/72
7577

7678
if(crash.get() != null) {
7779
crash.get().crash("Exception ticking world");
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package wearblackallday.dimthread.mixin;
2+
3+
import net.minecraft.server.world.ServerWorld;
4+
import net.minecraft.util.profiler.Profiler;
5+
import net.minecraft.util.registry.RegistryEntry;
6+
import net.minecraft.util.registry.RegistryKey;
7+
import net.minecraft.world.MutableWorldProperties;
8+
import net.minecraft.world.World;
9+
import net.minecraft.world.dimension.DimensionType;
10+
import org.spongepowered.asm.mixin.Mixin;
11+
import org.spongepowered.asm.mixin.Shadow;
12+
import org.spongepowered.asm.mixin.injection.At;
13+
import org.spongepowered.asm.mixin.injection.Inject;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15+
import wearblackallday.dimthread.DimThread;
16+
import wearblackallday.dimthread.util.ServerWorldAccessor;
17+
18+
import java.util.function.Supplier;
19+
20+
@Mixin(ServerWorld.class)
21+
public abstract class ServerWorldMixin extends World implements ServerWorldAccessor {
22+
protected ServerWorldMixin(MutableWorldProperties properties, RegistryKey<World> registryRef, RegistryEntry<DimensionType> registryEntry, Supplier<Profiler> profiler, boolean isClient, boolean debugWorld, long seed) {
23+
super(properties, registryRef, registryEntry, profiler, isClient, debugWorld, seed);
24+
}
25+
26+
@Shadow protected abstract void tickTime();
27+
28+
boolean onMainThread = false;
29+
boolean timeTickedOnWorldThread = false;
30+
31+
/**
32+
* Time ticking is not thread-safe. We cancel time ticking from the world thread. However, DimThread will tick time on the main thread
33+
*/
34+
@Inject(method = "tickTime", at = @At("HEAD"), cancellable = true)
35+
private void preventTimeTicking(CallbackInfo ci) {
36+
if (DimThread.MANAGER.isActive(getServer()) && !onMainThread) {
37+
timeTickedOnWorldThread = true;
38+
ci.cancel();
39+
}
40+
}
41+
42+
@Override
43+
public void dimthread_tickTime() {
44+
if (timeTickedOnWorldThread) {
45+
onMainThread = true;
46+
tickTime();
47+
onMainThread = false;
48+
timeTickedOnWorldThread = false;
49+
}
50+
}
51+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package wearblackallday.dimthread.util;
2+
3+
/**
4+
* Create this calass wo that we can call tickTime from ServerWorldMixin
5+
*/
6+
public interface ServerWorldAccessor {
7+
void dimthread_tickTime();
8+
}

src/main/resources/dimthread.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"MinecraftServerMixin",
99
"RedstoneWireBlockMixin",
1010
"ServerChunkManagerMixin",
11+
"ServerWorldMixin",
1112
"WorldMixin"
1213
],
1314
"client": [

0 commit comments

Comments
 (0)