Compare commits
4 Commits
v0.2.0-bet
...
v0.2.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac0c7deb43 | ||
|
|
16c8398d8a | ||
|
|
661ef813bb | ||
|
|
cf1d26a73c |
@@ -21,6 +21,6 @@ junit_version=5.11.3
|
|||||||
fabric_lithium_version=t1FlWYl9
|
fabric_lithium_version=t1FlWYl9
|
||||||
neo_lithium_version=iDqQi66g
|
neo_lithium_version=iDqQi66g
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=0.2.0-beta.8
|
mod_version=0.2.0-beta.9
|
||||||
maven_group=ca.spottedleaf.moonrise
|
maven_group=ca.spottedleaf.moonrise
|
||||||
archives_base_name=moonrise
|
archives_base_name=moonrise
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package ca.spottedleaf.moonrise.common.util;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class EntityUtil {
|
||||||
|
|
||||||
|
private static final ThreadLocal<DecimalFormat> THREE_DECIMAL_PLACES = ThreadLocal.withInitial(() -> {
|
||||||
|
return new DecimalFormat("#,##0.000");
|
||||||
|
});
|
||||||
|
|
||||||
|
private static String formatVec(final Vec3 vec) {
|
||||||
|
final DecimalFormat format = THREE_DECIMAL_PLACES.get();
|
||||||
|
|
||||||
|
return "(" + format.format(vec.x) + "," + format.format(vec.y) + "," + format.format(vec.z) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String dumpEntityWithoutReferences(final Entity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return "{null}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{type=" + entity.getClass().getSimpleName() + ",id=" + entity.getId() + ",uuid=" + entity.getUUID() + ",pos=" + formatVec(entity.position())
|
||||||
|
+ ",mot=" + formatVec(entity.getDeltaMovement()) + ",aabb=" + entity.getBoundingBox() + ",removed=" + entity.getRemovalReason() + ",has_vehicle=" + (entity.getVehicle() != null)
|
||||||
|
+ ",passenger_count=" + entity.getPassengers().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String dumpEntity(final Entity entity) {
|
||||||
|
final List<Entity> passengers = entity.getPassengers();
|
||||||
|
final List<String> passengerStrings = new ArrayList<>(passengers.size());
|
||||||
|
|
||||||
|
for (final Entity passenger : passengers) {
|
||||||
|
passengerStrings.add("(" + dumpEntityWithoutReferences(passenger) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{root=[" + dumpEntityWithoutReferences(entity) + "], vehicle=[" + dumpEntityWithoutReferences(entity.getVehicle())
|
||||||
|
+ "], passengers=[" + String.join(",", passengerStrings) + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityUtil() {}
|
||||||
|
}
|
||||||
@@ -15,21 +15,25 @@ public class TickThread extends Thread {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class);
|
||||||
|
|
||||||
|
private static String getThreadContext() {
|
||||||
|
return "thread=" + Thread.currentThread().getName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void ensureTickThread(final String reason) {
|
public static void ensureTickThread(final String reason) {
|
||||||
if (!isTickThread()) {
|
if (!isTickThread()) {
|
||||||
LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
|
LOGGER.error("Thread failed main thread check: " + reason + ", context=" + getThreadContext(), new Throwable());
|
||||||
throw new IllegalStateException(reason);
|
throw new IllegalStateException(reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ensureTickThread(final Level world, final BlockPos pos, final String reason) {
|
public static void ensureTickThread(final Level world, final BlockPos pos, final String reason) {
|
||||||
if (!isTickThreadFor(world, pos)) {
|
if (!isTickThreadFor(world, pos)) {
|
||||||
final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " +
|
final String ex = "Thread failed main thread check: " +
|
||||||
reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos;
|
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos;
|
||||||
LOGGER.error(ex, new Throwable());
|
LOGGER.error(ex, new Throwable());
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
@@ -37,8 +41,8 @@ public class TickThread extends Thread {
|
|||||||
|
|
||||||
public static void ensureTickThread(final Level world, final BlockPos pos, final int blockRadius, final String reason) {
|
public static void ensureTickThread(final Level world, final BlockPos pos, final int blockRadius, final String reason) {
|
||||||
if (!isTickThreadFor(world, pos, blockRadius)) {
|
if (!isTickThreadFor(world, pos, blockRadius)) {
|
||||||
final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " +
|
final String ex = "Thread failed main thread check: " +
|
||||||
reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius;
|
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius;
|
||||||
LOGGER.error(ex, new Throwable());
|
LOGGER.error(ex, new Throwable());
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
@@ -46,8 +50,8 @@ public class TickThread extends Thread {
|
|||||||
|
|
||||||
public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) {
|
public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) {
|
||||||
if (!isTickThreadFor(world, pos)) {
|
if (!isTickThreadFor(world, pos)) {
|
||||||
final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " +
|
final String ex = "Thread failed main thread check: " +
|
||||||
reason + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos;
|
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos;
|
||||||
LOGGER.error(ex, new Throwable());
|
LOGGER.error(ex, new Throwable());
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
@@ -55,8 +59,8 @@ public class TickThread extends Thread {
|
|||||||
|
|
||||||
public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) {
|
public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) {
|
||||||
if (!isTickThreadFor(world, chunkX, chunkZ)) {
|
if (!isTickThreadFor(world, chunkX, chunkZ)) {
|
||||||
final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " +
|
final String ex = "Thread failed main thread check: " +
|
||||||
reason + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ);
|
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ);
|
||||||
LOGGER.error(ex, new Throwable());
|
LOGGER.error(ex, new Throwable());
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
@@ -64,8 +68,8 @@ public class TickThread extends Thread {
|
|||||||
|
|
||||||
public static void ensureTickThread(final Entity entity, final String reason) {
|
public static void ensureTickThread(final Entity entity, final String reason) {
|
||||||
if (!isTickThreadFor(entity)) {
|
if (!isTickThreadFor(entity)) {
|
||||||
final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " +
|
final String ex = "Thread failed main thread check: " +
|
||||||
reason + ", entity=" + entity;
|
reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity);
|
||||||
LOGGER.error(ex, new Throwable());
|
LOGGER.error(ex, new Throwable());
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
@@ -73,8 +77,8 @@ public class TickThread extends Thread {
|
|||||||
|
|
||||||
public static void ensureTickThread(final Level world, final AABB aabb, final String reason) {
|
public static void ensureTickThread(final Level world, final AABB aabb, final String reason) {
|
||||||
if (!isTickThreadFor(world, aabb)) {
|
if (!isTickThreadFor(world, aabb)) {
|
||||||
final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " +
|
final String ex = "Thread failed main thread check: " +
|
||||||
reason + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb;
|
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb;
|
||||||
LOGGER.error(ex, new Throwable());
|
LOGGER.error(ex, new Throwable());
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
@@ -82,8 +86,8 @@ public class TickThread extends Thread {
|
|||||||
|
|
||||||
public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) {
|
public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) {
|
||||||
if (!isTickThreadFor(world, blockX, blockZ)) {
|
if (!isTickThreadFor(world, blockX, blockZ)) {
|
||||||
final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " +
|
final String ex = "Thread failed main thread check: " +
|
||||||
reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ);
|
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ);
|
||||||
LOGGER.error(ex, new Throwable());
|
LOGGER.error(ex, new Throwable());
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package ca.spottedleaf.moonrise.mixin.chunk_system;
|
||||||
|
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
|
import net.minecraft.world.level.gameevent.DynamicGameEventListener;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(DynamicGameEventListener.class)
|
||||||
|
abstract class DynamicGameEventListenerMixin {
|
||||||
|
@Shadow @Nullable private SectionPos lastSection;
|
||||||
|
|
||||||
|
@Inject(method = "remove", at = @At("RETURN"))
|
||||||
|
private void onRemove(final CallbackInfo ci) {
|
||||||
|
// We need to unset the last section when removed, otherwise if the same instance is re-added at the same position it
|
||||||
|
// will assume there was no change and fail to re-register.
|
||||||
|
// In vanilla, chunks rarely unload and re-load quickly enough to trigger this issue. However, our chunk system has a
|
||||||
|
// quirk where fast chunk reload cycles will often occur on player login (see PR #22).
|
||||||
|
// So we fix this vanilla oversight as our changes cause it to manifest in bugs much more often (see issue #87).
|
||||||
|
this.lastSection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
"chunk_system.ChunkStepMixin",
|
"chunk_system.ChunkStepMixin",
|
||||||
"chunk_system.ChunkStorageMixin",
|
"chunk_system.ChunkStorageMixin",
|
||||||
"chunk_system.DistanceManagerMixin",
|
"chunk_system.DistanceManagerMixin",
|
||||||
|
"chunk_system.DynamicGameEventListenerMixin",
|
||||||
"chunk_system.EntityGetterMixin",
|
"chunk_system.EntityGetterMixin",
|
||||||
"chunk_system.EntityMixin",
|
"chunk_system.EntityMixin",
|
||||||
"chunk_system.EntityTickListMixin",
|
"chunk_system.EntityTickListMixin",
|
||||||
|
|||||||
Reference in New Issue
Block a user