Shared random to world w/ thread safety fixes
This commit is contained in:
@@ -70,7 +70,7 @@ public abstract class Akari {
|
|||||||
|
|
||||||
public static boolean isPrimaryThread(boolean assign) {
|
public static boolean isPrimaryThread(boolean assign) {
|
||||||
Thread current = Thread.currentThread();
|
Thread current = Thread.currentThread();
|
||||||
return current == MinecraftServer.getServer().primaryThread || (assign ? current instanceof AssignableThread : false);
|
return current == MinecraftServer.getServer().primaryThread || (assign ? (current.getClass() == AssignableThread.class) : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String EMPTY_STRING = "";
|
public static final String EMPTY_STRING = "";
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.akarin.api.internal.mixin;
|
package io.akarin.api.internal.mixin;
|
||||||
|
|
||||||
public interface IMixinLockProvider {
|
public interface IMixinWorldServer {
|
||||||
public Object lock();
|
public Object lock();
|
||||||
|
public Object rand();
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ import co.aikar.timings.MinecraftTimings;
|
|||||||
import co.aikar.timings.TimingHandler;
|
import co.aikar.timings.TimingHandler;
|
||||||
import io.akarin.api.internal.Akari;
|
import io.akarin.api.internal.Akari;
|
||||||
import io.akarin.api.internal.Akari.AssignableFactory;
|
import io.akarin.api.internal.Akari.AssignableFactory;
|
||||||
import io.akarin.api.internal.mixin.IMixinLockProvider;
|
import io.akarin.api.internal.mixin.IMixinWorldServer;
|
||||||
import io.akarin.server.core.AkarinGlobalConfig;
|
import io.akarin.server.core.AkarinGlobalConfig;
|
||||||
import io.akarin.server.core.AkarinSlackScheduler;
|
import io.akarin.server.core.AkarinSlackScheduler;
|
||||||
import net.minecraft.server.BlockPosition;
|
import net.minecraft.server.BlockPosition;
|
||||||
@@ -241,7 +241,7 @@ public abstract class MixinMinecraftServer {
|
|||||||
entityWorld.timings.tickEntities.startTiming();
|
entityWorld.timings.tickEntities.startTiming();
|
||||||
WorldServer fEntityWorld = entityWorld;
|
WorldServer fEntityWorld = entityWorld;
|
||||||
Akari.STAGE_ENTITY_TICK.submit(() -> {
|
Akari.STAGE_ENTITY_TICK.submit(() -> {
|
||||||
synchronized (((IMixinLockProvider) fEntityWorld).lock()) {
|
synchronized (((IMixinWorldServer) fEntityWorld).lock()) {
|
||||||
tickEntities(fEntityWorld);
|
tickEntities(fEntityWorld);
|
||||||
fEntityWorld.getTracker().updatePlayers();
|
fEntityWorld.getTracker().updatePlayers();
|
||||||
fEntityWorld.explosionDensityCache.clear(); // Paper - Optimize explosions
|
fEntityWorld.explosionDensityCache.clear(); // Paper - Optimize explosions
|
||||||
@@ -253,7 +253,7 @@ public abstract class MixinMinecraftServer {
|
|||||||
WorldServer world = worlds.get(interlaceWorld);
|
WorldServer world = worlds.get(interlaceWorld);
|
||||||
world.timings.doTick.startTiming();
|
world.timings.doTick.startTiming();
|
||||||
Akari.STAGE_WORLD_TICK.submit(() -> {
|
Akari.STAGE_WORLD_TICK.submit(() -> {
|
||||||
synchronized (((IMixinLockProvider) world).lock()) {
|
synchronized (((IMixinWorldServer) world).lock()) {
|
||||||
tickWorld(world);
|
tickWorld(world);
|
||||||
}
|
}
|
||||||
}, world);
|
}, world);
|
||||||
@@ -262,7 +262,7 @@ public abstract class MixinMinecraftServer {
|
|||||||
|
|
||||||
WorldServer primaryWorld = worlds.get(0);
|
WorldServer primaryWorld = worlds.get(0);
|
||||||
primaryWorld.timings.doTick.startTiming();
|
primaryWorld.timings.doTick.startTiming();
|
||||||
synchronized (((IMixinLockProvider) primaryWorld).lock()) {
|
synchronized (((IMixinWorldServer) primaryWorld).lock()) {
|
||||||
tickWorld(primaryWorld);
|
tickWorld(primaryWorld);
|
||||||
}
|
}
|
||||||
primaryWorld.timings.doTick.stopTiming();
|
primaryWorld.timings.doTick.stopTiming();
|
||||||
|
|||||||
@@ -1,15 +1,37 @@
|
|||||||
package io.akarin.server.mixin.core;
|
package io.akarin.server.mixin.core;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import io.akarin.api.internal.mixin.IMixinLockProvider;
|
import io.akarin.api.internal.mixin.IMixinWorldServer;
|
||||||
import net.minecraft.server.WorldServer;
|
import net.minecraft.server.WorldServer;
|
||||||
|
|
||||||
@Mixin(value = WorldServer.class, remap = false)
|
@Mixin(value = WorldServer.class, remap = false)
|
||||||
public abstract class MixinWorldServer implements IMixinLockProvider {
|
public abstract class MixinWorldServer implements IMixinWorldServer {
|
||||||
private final Object tickLock = new Object();
|
private final Object tickLock = new Object();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object lock() {
|
public Object lock() {
|
||||||
return tickLock;
|
return tickLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Random sharedRandom = new io.akarin.api.internal.utils.random.LightRandom() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private boolean locked = false;
|
||||||
|
@Override
|
||||||
|
public synchronized void setSeed(long seed) {
|
||||||
|
if (locked) {
|
||||||
|
LogManager.getLogger().error("Ignoring setSeed on Entity.SHARED_RANDOM", new Throwable());
|
||||||
|
} else {
|
||||||
|
super.setSeed(seed);
|
||||||
|
locked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Random rand() {
|
||||||
|
return sharedRandom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import org.bukkit.entity.LivingEntity;
|
|||||||
import org.bukkit.entity.Vehicle;
|
import org.bukkit.entity.Vehicle;
|
||||||
import co.aikar.timings.MinecraftTimings; // Paper
|
import co.aikar.timings.MinecraftTimings; // Paper
|
||||||
import co.aikar.timings.Timing; // Paper
|
import co.aikar.timings.Timing; // Paper
|
||||||
|
import io.akarin.api.internal.mixin.IMixinWorldServer;
|
||||||
|
|
||||||
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||||
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||||
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
|
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
|
||||||
@@ -51,7 +53,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
|
|||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
private static final int CURRENT_LEVEL = 2;
|
private static final int CURRENT_LEVEL = 2;
|
||||||
// Paper start
|
// Paper start
|
||||||
public static Random SHARED_RANDOM = new io.akarin.api.internal.utils.random.LightRandom() { // Akarin - LightRNG
|
public static Random SHARED_RANDOM = new java.util.Random() {
|
||||||
private boolean locked = false;
|
private boolean locked = false;
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setSeed(long seed) {
|
public synchronized void setSeed(long seed) {
|
||||||
@@ -208,7 +210,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper
|
|||||||
this.length = 1.8F;
|
this.length = 1.8F;
|
||||||
this.ax = 1;
|
this.ax = 1;
|
||||||
this.ay = 1.0F;
|
this.ay = 1.0F;
|
||||||
this.random = SHARED_RANDOM; // Paper
|
this.random = ((IMixinWorldServer) world).rand(); // Paper // Akarin
|
||||||
this.fireTicks = -this.getMaxFireTicks();
|
this.fireTicks = -this.getMaxFireTicks();
|
||||||
this.justCreated = true;
|
this.justCreated = true;
|
||||||
this.uniqueID = MathHelper.a(this.random);
|
this.uniqueID = MathHelper.a(this.random);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Akarin Changes Note
|
* Akarin Changes Note
|
||||||
* 1) FastBitSet for faster access (performance)
|
* 1) BitSet for faster access (performance)
|
||||||
*/
|
*/
|
||||||
public class RegistryID<K> implements Registry {
|
public class RegistryID<K> implements Registry {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user