Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73ab029e4c | ||
|
|
47b4ce394c | ||
|
|
6275320901 | ||
|
|
a113654b36 | ||
|
|
671522acdc | ||
|
|
2779390c6b | ||
|
|
4fc704f16a | ||
|
|
423f48684a | ||
|
|
c027a2e37f | ||
|
|
3ec9267550 | ||
|
|
57bd665a5e | ||
|
|
5faba7039e | ||
|
|
3d7011f7d7 |
22
README.md
22
README.md
@@ -24,31 +24,33 @@
|
||||
|
||||
```yaml
|
||||
verbose: false
|
||||
gameplay:
|
||||
server-mod-name: Kaiiju
|
||||
region-format:
|
||||
debug: false
|
||||
network:
|
||||
send-null-entity-packets: true
|
||||
alternate-keepalive: false
|
||||
region-format:
|
||||
debug: false
|
||||
gameplay:
|
||||
server-mod-name: Kaiiju
|
||||
shared-random-for-players: true
|
||||
world-settings:
|
||||
default:
|
||||
region-format:
|
||||
format: ANVIL
|
||||
linear:
|
||||
compression-level: 1
|
||||
crash-on-broken-symlink: true
|
||||
gameplay:
|
||||
shulker-box-drop-contents-when-destroyed: true
|
||||
fix-void-trading: true
|
||||
optimize-hoppers: true
|
||||
region-format:
|
||||
format: LINEAR
|
||||
linear:
|
||||
compression-level: 1
|
||||
crash-on-broken-symlink: true
|
||||
tick-when-empty: true
|
||||
break-redstone-on-top-of-trap-doors-early: true
|
||||
config-version: 1
|
||||
```
|
||||
Documentation: [Kaiiju Wiki](https://github.com/KaiijuMC/Kaiiju/wiki/Configuration)
|
||||
|
||||
### Roadmap
|
||||
- **Static view distance**: Reduce RAM usage / Region size with a "static" view distance.
|
||||
- **Linear timestamps**: Add chunk timestamps to linear region files.
|
||||
- **Native world conversion**: Convert region file format at startup.
|
||||
- **Stash deduplication**: Make giant dupe stashes possible and lagless.
|
||||
|
||||
|
||||
@@ -112,10 +112,10 @@ index 0000000000000000000000000000000000000000..dcfbabf54b19a4c29d5c95830242c5c2
|
||||
+}
|
||||
diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8fcfd6a1d4
|
||||
index 0000000000000000000000000000000000000000..b7ce89429675bde7f037793305275f4bf89d0727
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java
|
||||
@@ -0,0 +1,328 @@
|
||||
@@ -0,0 +1,337 @@
|
||||
+package dev.kaiijumc.kaiiju.region;
|
||||
+
|
||||
+import com.github.luben.zstd.ZstdInputStream;
|
||||
@@ -137,19 +137,22 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+import java.nio.file.StandardCopyOption;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Arrays;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.locks.ReentrantLock;
|
||||
+
|
||||
+public class LinearRegionFile extends Thread implements AbstractRegionFile {
|
||||
+ private static long SUPERBLOCK = -4323716122432332390L;
|
||||
+ private static byte VERSION = 1;
|
||||
+ private static int HEADER_SIZE = 32;
|
||||
+ private static int FOOTER_SIZE = 8;
|
||||
+ private static final long SUPERBLOCK = -4323716122432332390L;
|
||||
+ private static final byte VERSION = 2;
|
||||
+ private static final int HEADER_SIZE = 32;
|
||||
+ private static final int FOOTER_SIZE = 8;
|
||||
+ private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+ private static final List<Byte> SUPPORTED_VERSIONS = Arrays.asList((byte) 1, (byte) 2);
|
||||
+
|
||||
+
|
||||
+ private final byte[][] buffer = new byte[1024][];
|
||||
+ private final int[] bufferUncompressedSize = new int[1024];
|
||||
+
|
||||
+ private final int[] chunkTimestamps = new int[1024];
|
||||
+ private final Object markedToSaveLock = new Object();
|
||||
+ private final ChunkStatus[] statuses = new ChunkStatus[1024];
|
||||
+
|
||||
@@ -189,11 +192,11 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+
|
||||
+ long superBlock = rawDataStream.readLong();
|
||||
+ if (superBlock != SUPERBLOCK)
|
||||
+ throw new RuntimeException("Superblock invalid: " + superBlock + " file " + file);
|
||||
+ throw new RuntimeException("Invalid superblock: " + superBlock + " file " + file);
|
||||
+
|
||||
+ byte version = rawDataStream.readByte();
|
||||
+ if (version != VERSION)
|
||||
+ throw new RuntimeException("Version invalid: " + version + " file " + file);
|
||||
+ if (!SUPPORTED_VERSIONS.contains(version))
|
||||
+ throw new RuntimeException("Invalid version: " + version + " file " + file);
|
||||
+
|
||||
+ // Skip newestTimestamp (Long) + Compression level (Byte) + Chunk count (Short): Unused.
|
||||
+ rawDataStream.skipBytes(11);
|
||||
@@ -201,7 +204,7 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+ int dataCount = rawDataStream.readInt();
|
||||
+ long fileLength = file.toFile().length();
|
||||
+ if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE)
|
||||
+ throw new IOException("File length invalid " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
|
||||
+ throw new IOException("Invalid file length: " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
|
||||
+
|
||||
+ rawDataStream.skipBytes(8); // Skip data hash (Long): Unused.
|
||||
+
|
||||
@@ -217,7 +220,7 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+ int[] starts = new int[1024];
|
||||
+ for(int i = 0; i < 1024; i++) {
|
||||
+ starts[i] = dataStream.readInt();
|
||||
+ dataStream.skipBytes(4); // Skip timestamps (Int): Unimplemented TODO: Implement per-chunk timestamps
|
||||
+ dataStream.skipBytes(4); // Skip timestamps (Int): Unused.
|
||||
+ }
|
||||
+
|
||||
+ for(int i = 0; i < 1024; i++) {
|
||||
@@ -281,7 +284,7 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+ public synchronized void flush() throws IOException {
|
||||
+ if(!isMarkedToSave()) return;
|
||||
+
|
||||
+ long timestamp = System.currentTimeMillis() / 1000L;
|
||||
+ long timestamp = getTimestamp();
|
||||
+ short chunkCount = 0;
|
||||
+
|
||||
+ File tempFile = new File(regionFile.toString() + ".tmp");
|
||||
@@ -309,8 +312,8 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+ } else byteBuffers.add(null);
|
||||
+ }
|
||||
+ for(int i = 0; i < 1024; i++) {
|
||||
+ zstdDataStream.writeInt(this.bufferUncompressedSize[i]);
|
||||
+ zstdDataStream.writeInt(0); // TODO: IMPLEMENT PER CHUNK TIMESTAMPS
|
||||
+ zstdDataStream.writeInt(this.bufferUncompressedSize[i]); // Write uncompressed size
|
||||
+ zstdDataStream.writeInt(this.chunkTimestamps[i]); // Write timestamp
|
||||
+ }
|
||||
+ for(int i = 0; i < 1024; i++) {
|
||||
+ if(byteBuffers.get(i) != null)
|
||||
@@ -352,12 +355,13 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+ b = new byte[compressedLength];
|
||||
+ System.arraycopy(compressed, 0, b, 0, compressedLength);
|
||||
+
|
||||
+ this.buffer[getChunkIndex(pos.x, pos.z)] = b;
|
||||
+ int index = getChunkIndex(pos.x, pos.z);
|
||||
+ this.buffer[index] = b;
|
||||
+ this.chunkTimestamps[index] = getTimestamp();
|
||||
+ this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] = uncompressedSize;
|
||||
+ } catch (IOException e) {
|
||||
+ LOGGER.error("Chunk write IOException " + e + " " + this.regionFile);
|
||||
+ }
|
||||
+
|
||||
+ markToSave();
|
||||
+ }
|
||||
+
|
||||
@@ -410,6 +414,7 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+ int i = getChunkIndex(pos.x, pos.z);
|
||||
+ this.buffer[i] = null;
|
||||
+ this.bufferUncompressedSize[i] = 0;
|
||||
+ this.chunkTimestamps[i] = getTimestamp();
|
||||
+ markToSave();
|
||||
+ }
|
||||
+
|
||||
@@ -430,6 +435,10 @@ index 0000000000000000000000000000000000000000..245e3b1801c5f92054d9c0d0d8fc2a8f
|
||||
+ return (x & 31) + ((z & 31) << 5);
|
||||
+ }
|
||||
+
|
||||
+ private static int getTimestamp() {
|
||||
+ return (int) (System.currentTimeMillis() / 1000L);
|
||||
+ }
|
||||
+
|
||||
+ public boolean recalculateHeader() {
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Sofiane H. Djerbi" <46628754+kugge@users.noreply.github.com>
|
||||
Date: Sun, 7 May 2023 20:04:06 +0300
|
||||
Subject: [PATCH] Toggle break redstone on top of trap doors early
|
||||
|
||||
That patch break vanilla mechanics such as portal slicing.
|
||||
|
||||
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
|
||||
index b674bad0ace0aba53f1f3e76e6c891421aaac2a5..43c8e95454cfe831f69858eb3b520f9958280b54 100644
|
||||
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuWorldConfig.java
|
||||
@@ -150,11 +150,13 @@ public class KaiijuWorldConfig {
|
||||
public boolean fixVoidTrading = true;
|
||||
public boolean optimizeHoppers = true;
|
||||
public boolean tickWhenEmpty = true;
|
||||
+ public boolean breakRedstoneOnTopOfTrapDoorsEarly = true;
|
||||
|
||||
private void gameplaySettings() {
|
||||
shulkerBoxDropContentsWhenDestroyed = getBoolean("gameplay.shulker-box-drop-contents-when-destroyed", shulkerBoxDropContentsWhenDestroyed);
|
||||
fixVoidTrading = getBoolean("gameplay.fix-void-trading", fixVoidTrading);
|
||||
optimizeHoppers = getBoolean("gameplay.optimize-hoppers", optimizeHoppers);
|
||||
tickWhenEmpty = getBoolean("gameplay.tick-when-empty", tickWhenEmpty);
|
||||
+ breakRedstoneOnTopOfTrapDoorsEarly = getBoolean("gameplay.break-redstone-on-top-of-trap-doors-early", breakRedstoneOnTopOfTrapDoorsEarly);
|
||||
}
|
||||
}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
index 4bddb91e289bbfbc75d532e63f935d585e41fc43..f8dba24931bcfa28bde9cdec0201b591f29f9e09 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
@@ -126,6 +126,7 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW
|
||||
}
|
||||
// CraftBukkit end
|
||||
boolean open = (Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1; // Folia - break redstone on trapdoors early
|
||||
+ if (world.kaiijuConfig.breakRedstoneOnTopOfTrapDoorsEarly) { // Kaiiju - trigger break redstone on trapdoors early
|
||||
// Folia start - break redstone on trapdoors early
|
||||
// note: this must run before any state for this block/its neighborus are written to the world
|
||||
// we allow the redstone event to fire so that plugins can block
|
||||
@@ -144,6 +145,7 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW
|
||||
}
|
||||
}
|
||||
// Folia end - break redstone on trapdoors early
|
||||
+ } // Kaiiju - trigger break redstone on trapdoors early
|
||||
if (open) { // Folia - break redstone on trapdoors early
|
||||
state = (BlockState) state.setValue(TrapDoorBlock.OPEN, flag1);
|
||||
this.playSound((Player) null, world, pos, flag1);
|
||||
18
patches/server/0016-Fix-off-thread-raid-winners.patch
Normal file
18
patches/server/0016-Fix-off-thread-raid-winners.patch
Normal file
@@ -0,0 +1,18 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Sofiane H. Djerbi" <46628754+kugge@users.noreply.github.com>
|
||||
Date: Tue, 9 May 2023 15:11:56 +0300
|
||||
Subject: [PATCH] Fix off thread raid winners
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java
|
||||
index 359f1690497eac00899eb26c17308e0a6fe943ad..3cc320e854cbb9e70b6c63f1f950091c5195edae 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java
|
||||
@@ -404,6 +404,7 @@ public class Raid {
|
||||
UUID uuid = (UUID) iterator.next();
|
||||
Entity entity = this.level.getEntity(uuid);
|
||||
|
||||
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(entity)) continue; // Kaiiju - Prevent give effect to player off thread
|
||||
if (entity instanceof LivingEntity && !entity.isSpectator()) {
|
||||
LivingEntity entityliving = (LivingEntity) entity;
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Sofiane H. Djerbi" <46628754+kugge@users.noreply.github.com>
|
||||
Date: Wed, 10 May 2023 16:30:38 +0300
|
||||
Subject: [PATCH] Strip raytracing for EntityLiving#hasLineOfSight
|
||||
|
||||
This has been benchmarked on a huge gold farm.
|
||||
Resulting in significative performance improvements.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 49716190b784339b80c8a3ac8e5b13bc450284ee..440735caab3be903546638a3d01903720225c553 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3612,7 +3612,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
|
||||
|
||||
// Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
|
||||
- return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr
|
||||
+ return !(vec3d1.distanceToSqr(vec3d) > 128D * 128D) && this.level.rayTraceDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == net.minecraft.world.phys.BlockHitResult.Type.MISS; // Paper - use distanceToSqr // Kaiiju - Pufferfish - Strip raytracing
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
index 2ee9e8e3c1a28c1823de8e1fe421cc1f3e72f384..d99d77536e4d49b53575ae30614c0ab5fdbd3f73 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
@@ -73,6 +73,17 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
});
|
||||
}
|
||||
|
||||
+ // Kaiiju start - Pufferfish - broken down variant of below rayTraceBlock, used by World#rayTraceDirect
|
||||
+ @Nullable
|
||||
+ default net.minecraft.world.phys.BlockHitResult.Type rayTraceBlockDirect(Vec3 vec3d, Vec3 vec3d1, BlockPos blockposition, BlockState iblockdata, net.minecraft.world.phys.shapes.CollisionContext voxelshapecoll) {
|
||||
+ if (iblockdata.isAir()) return null;
|
||||
+ VoxelShape voxelshape = ClipContext.Block.COLLIDER.get(iblockdata, this, blockposition, voxelshapecoll);
|
||||
+ net.minecraft.world.phys.BlockHitResult movingobjectpositionblock = this.clipWithInteractionOverride(vec3d, vec3d1, blockposition, voxelshape, iblockdata);
|
||||
+
|
||||
+ return movingobjectpositionblock == null ? null : movingobjectpositionblock.getType();
|
||||
+ }
|
||||
+ // Kaiiju end
|
||||
+
|
||||
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
||||
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
|
||||
// Paper start - Prevent raytrace from loading chunks
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index a3b4b49ca8612a61bc2e7a1e2d2e942e7ebe1883..933373aaa7b1fa07862e2146e079abe91d126263 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -433,6 +433,91 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
return null;
|
||||
}
|
||||
|
||||
+ // Kaiiju start - Pufferfish - broken down method of raytracing for EntityLiving#hasLineOfSight, replaces IBlockAccess#rayTrace(RayTrace)
|
||||
+ public net.minecraft.world.phys.BlockHitResult.Type rayTraceDirect(net.minecraft.world.phys.Vec3 vec3d, net.minecraft.world.phys.Vec3 vec3d1, net.minecraft.world.phys.shapes.CollisionContext voxelshapecoll) {
|
||||
+ // most of this code comes from IBlockAccess#a(RayTrace, BiFunction, Function), but removes the needless functions
|
||||
+ if (vec3d.equals(vec3d1)) {
|
||||
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
||||
+ }
|
||||
+
|
||||
+ double endX = Mth.lerp(-1.0E-7D, vec3d1.x, vec3d.x);
|
||||
+ double endY = Mth.lerp(-1.0E-7D, vec3d1.y, vec3d.y);
|
||||
+ double endZ = Mth.lerp(-1.0E-7D, vec3d1.z, vec3d.z);
|
||||
+
|
||||
+ double startX = Mth.lerp(-1.0E-7D, vec3d.x, vec3d1.x);
|
||||
+ double startY = Mth.lerp(-1.0E-7D, vec3d.y, vec3d1.y);
|
||||
+ double startZ = Mth.lerp(-1.0E-7D, vec3d.z, vec3d1.z);
|
||||
+
|
||||
+ int currentX = Mth.floor(startX);
|
||||
+ int currentY = Mth.floor(startY);
|
||||
+ int currentZ = Mth.floor(startZ);
|
||||
+
|
||||
+ BlockPos.MutableBlockPos currentBlock = new BlockPos.MutableBlockPos(currentX, currentY, currentZ);
|
||||
+
|
||||
+ LevelChunk chunk = this.getChunkIfLoaded(currentBlock);
|
||||
+ if (chunk == null) {
|
||||
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
||||
+ }
|
||||
+
|
||||
+ net.minecraft.world.phys.BlockHitResult.Type initialCheck = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getBlockState(currentBlock), voxelshapecoll);
|
||||
+
|
||||
+ if (initialCheck != null) {
|
||||
+ return initialCheck;
|
||||
+ }
|
||||
+
|
||||
+ double diffX = endX - startX;
|
||||
+ double diffY = endY - startY;
|
||||
+ double diffZ = endZ - startZ;
|
||||
+
|
||||
+ int xDirection = Mth.sign(diffX);
|
||||
+ int yDirection = Mth.sign(diffY);
|
||||
+ int zDirection = Mth.sign(diffZ);
|
||||
+
|
||||
+ double normalizedX = xDirection == 0 ? Double.MAX_VALUE : (double) xDirection / diffX;
|
||||
+ double normalizedY = yDirection == 0 ? Double.MAX_VALUE : (double) yDirection / diffY;
|
||||
+ double normalizedZ = zDirection == 0 ? Double.MAX_VALUE : (double) zDirection / diffZ;
|
||||
+
|
||||
+ double normalizedXDirection = normalizedX * (xDirection > 0 ? 1.0D - Mth.frac(startX) : Mth.frac(startX));
|
||||
+ double normalizedYDirection = normalizedY * (yDirection > 0 ? 1.0D - Mth.frac(startY) : Mth.frac(startY));
|
||||
+ double normalizedZDirection = normalizedZ * (zDirection > 0 ? 1.0D - Mth.frac(startZ) : Mth.frac(startZ));
|
||||
+
|
||||
+ net.minecraft.world.phys.BlockHitResult.Type result;
|
||||
+
|
||||
+ do {
|
||||
+ if (normalizedXDirection > 1.0D && normalizedYDirection > 1.0D && normalizedZDirection > 1.0D) {
|
||||
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
||||
+ }
|
||||
+
|
||||
+ if (normalizedXDirection < normalizedYDirection) {
|
||||
+ if (normalizedXDirection < normalizedZDirection) {
|
||||
+ currentX += xDirection;
|
||||
+ normalizedXDirection += normalizedX;
|
||||
+ } else {
|
||||
+ currentZ += zDirection;
|
||||
+ normalizedZDirection += normalizedZ;
|
||||
+ }
|
||||
+ } else if (normalizedYDirection < normalizedZDirection) {
|
||||
+ currentY += yDirection;
|
||||
+ normalizedYDirection += normalizedY;
|
||||
+ } else {
|
||||
+ currentZ += zDirection;
|
||||
+ normalizedZDirection += normalizedZ;
|
||||
+ }
|
||||
+
|
||||
+ currentBlock.set(currentX, currentY, currentZ);
|
||||
+ if (chunk.getPos().x != currentBlock.getX() >> 4 || chunk.getPos().z != currentBlock.getZ() >> 4) {
|
||||
+ chunk = this.getChunkIfLoaded(currentBlock);
|
||||
+ if (chunk == null) {
|
||||
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
||||
+ }
|
||||
+ }
|
||||
+ result = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getBlockState(currentBlock), voxelshapecoll);
|
||||
+ } while (result == null);
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Kaiiju end
|
||||
+
|
||||
public boolean isInWorldBounds(BlockPos pos) {
|
||||
return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - use better/optimized check
|
||||
}
|
||||
18
patches/server/0018-Fix-off-thread-spider-addEffect.patch
Normal file
18
patches/server/0018-Fix-off-thread-spider-addEffect.patch
Normal file
@@ -0,0 +1,18 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Sofiane H. Djerbi" <46628754+kugge@users.noreply.github.com>
|
||||
Date: Wed, 10 May 2023 17:58:37 +0300
|
||||
Subject: [PATCH] Fix off thread spider addEffect
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
index 0c36bb47bd7040f1544817810e1c87157cdaff96..29935d7cab5a61f48ed540c60152ad06f5e90d08 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -180,6 +180,7 @@ public class Spider extends Monster {
|
||||
MobEffect mobeffectlist = entityspider_groupdataspider.effect;
|
||||
|
||||
if (mobeffectlist != null) {
|
||||
+ if (io.papermc.paper.util.TickThread.isTickThreadFor(this)) // Kaiiju - Prevent give effect to spider off thread
|
||||
this.addEffect(new MobEffectInstance(mobeffectlist, -1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN); // CraftBukkit
|
||||
}
|
||||
}
|
||||
163
patches/server/0019-Add-SIMD-utilities.patch
Normal file
163
patches/server/0019-Add-SIMD-utilities.patch
Normal file
@@ -0,0 +1,163 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Sofiane H. Djerbi" <46628754+kugge@users.noreply.github.com>
|
||||
Date: Thu, 11 May 2023 05:02:40 +0300
|
||||
Subject: [PATCH] Add SIMD utilities
|
||||
|
||||
Patch from Pufferfish
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 4686019a152114e63e997ee103fc8424b24b4581..0851203a4bed670242afc5ac86562075f32693ab 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -58,6 +58,14 @@ dependencies {
|
||||
}
|
||||
|
||||
val craftbukkitPackageVersion = "1_19_R3" // Paper
|
||||
+
|
||||
+// Kaiiju start - Pufferfish - SIMD utilities
|
||||
+tasks.withType<JavaCompile> {
|
||||
+ val compilerArgs = options.compilerArgs
|
||||
+ compilerArgs.add("--add-modules=jdk.incubator.vector")
|
||||
+}
|
||||
+// Kaiiju end
|
||||
+
|
||||
tasks.jar {
|
||||
archiveClassifier.set("dev")
|
||||
|
||||
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
|
||||
index 9fb33b35b4d6842ca8597f77a4116e3983ebfbcb..f1fe094c4b4c5932ba656165bb1671020c1277a5 100644
|
||||
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
|
||||
@@ -3,6 +3,7 @@ package dev.kaiijumc.kaiiju;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import dev.kaiijumc.kaiiju.command.KaiijuCommand;
|
||||
+import gg.pufferfish.pufferfish.simd.SIMDDetection;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -15,7 +16,6 @@ import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
-import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..586b4cd007b3b106966524e2697edddf88e3ac9d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+package gg.pufferfish.pufferfish.simd;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import java.util.logging.Level;
|
||||
+import java.util.logging.Logger;
|
||||
+import jdk.incubator.vector.FloatVector;
|
||||
+import jdk.incubator.vector.IntVector;
|
||||
+import jdk.incubator.vector.VectorSpecies;
|
||||
+
|
||||
+/**
|
||||
+ * Basically, java is annoying and we have to push this out to its own class.
|
||||
+ */
|
||||
+public class SIMDChecker {
|
||||
+
|
||||
+ public static boolean canEnable(Logger logger) {
|
||||
+ try {
|
||||
+ if (SIMDDetection.getJavaVersion() != 17 && SIMDDetection.getJavaVersion() != 18 && SIMDDetection.getJavaVersion() != 19) {
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ SIMDDetection.testRun = true;
|
||||
+
|
||||
+ VectorSpecies<Integer> ISPEC = IntVector.SPECIES_PREFERRED;
|
||||
+ VectorSpecies<Float> FSPEC = FloatVector.SPECIES_PREFERRED;
|
||||
+
|
||||
+ logger.log(Level.INFO, "Max SIMD vector size on this system is " + ISPEC.vectorBitSize() + " bits (int)");
|
||||
+ logger.log(Level.INFO, "Max SIMD vector size on this system is " + FSPEC.vectorBitSize() + " bits (float)");
|
||||
+
|
||||
+ if (ISPEC.elementSize() < 2 || FSPEC.elementSize() < 2) {
|
||||
+ logger.log(Level.WARNING, "SIMD is not properly supported on this system!");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+ } catch (NoClassDefFoundError | Exception ignored) {} // Basically, we don't do anything. This lets us detect if it's not functional and disable it.
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public static void simdWarning() {
|
||||
+ // Attempt to detect vectorization
|
||||
+ try {
|
||||
+ SIMDDetection.isEnabled = SIMDDetection.canEnable(Bukkit.getLogger());
|
||||
+ SIMDDetection.versionLimited = SIMDDetection.getJavaVersion() != 17 && SIMDDetection.getJavaVersion() != 18 && SIMDDetection.getJavaVersion() != 19;
|
||||
+ } catch (NoClassDefFoundError | Exception ignored) {
|
||||
+ ignored.printStackTrace();
|
||||
+ }
|
||||
+
|
||||
+ if (SIMDDetection.isEnabled) {
|
||||
+ Bukkit.getLogger().info("SIMD operations detected as functional. Will replace some operations with faster versions.");
|
||||
+ } else if (SIMDDetection.versionLimited) {
|
||||
+ Bukkit.getLogger().warning("Will not enable SIMD! These optimizations are only safely supported on Java 17, Java 18, and Java 19.");
|
||||
+ } else {
|
||||
+ Bukkit.getLogger().warning("SIMD operations are available for your server, but are not configured!");
|
||||
+ Bukkit.getLogger().warning("To enable additional optimizations, add \"--add-modules=jdk.incubator.vector\" to your startup flags, BEFORE the \"-jar\".");
|
||||
+ Bukkit.getLogger().warning("If you have already added this flag, then SIMD operations are not supported on your JVM or CPU.");
|
||||
+ Bukkit.getLogger().warning("Debug: Java: " + System.getProperty("java.version") + ", test run: " + SIMDDetection.testRun);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..758fa97304a32bf17935c86dc03cbf50606935d8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java
|
||||
@@ -0,0 +1,32 @@
|
||||
+package gg.pufferfish.pufferfish.simd;
|
||||
+
|
||||
+import java.util.logging.Logger;
|
||||
+
|
||||
+public class SIMDDetection {
|
||||
+
|
||||
+ public static boolean isEnabled = false;
|
||||
+ public static boolean versionLimited = false;
|
||||
+ public static boolean testRun = false;
|
||||
+
|
||||
+ public static boolean canEnable(Logger logger) {
|
||||
+ try {
|
||||
+ return SIMDChecker.canEnable(logger);
|
||||
+ } catch (NoClassDefFoundError | Exception ignored) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static int getJavaVersion() {
|
||||
+ // https://stackoverflow.com/a/2591122
|
||||
+ String version = System.getProperty("java.version");
|
||||
+ if(version.startsWith("1.")) {
|
||||
+ version = version.substring(2, 3);
|
||||
+ } else {
|
||||
+ int dot = version.indexOf(".");
|
||||
+ if(dot != -1) { version = version.substring(0, dot); }
|
||||
+ }
|
||||
+ version = version.split("-")[0]; // Azul is stupid
|
||||
+ return Integer.parseInt(version);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 426777730f77664c69bd0a084a9323d767ebc0ad..5272164b18c2ca999c4744aede32f4a4c72525ed 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -225,6 +225,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
DedicatedServer.LOGGER.error("Unable to load server configuration", e);
|
||||
return false;
|
||||
}
|
||||
+ gg.pufferfish.pufferfish.simd.SIMDChecker.simdWarning();
|
||||
dev.kaiijumc.kaiiju.KaiijuConfig.registerCommands();
|
||||
// Kaiiju end
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
|
||||
37
patches/server/0020-Toggle-shared-random-for-players.patch
Normal file
37
patches/server/0020-Toggle-shared-random-for-players.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Sofiane H. Djerbi" <46628754+kugge@users.noreply.github.com>
|
||||
Date: Thu, 11 May 2023 17:12:34 +0300
|
||||
Subject: [PATCH] Toggle shared random for players
|
||||
|
||||
|
||||
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
|
||||
index f1fe094c4b4c5932ba656165bb1671020c1277a5..d3f6e5c873255d00160cf792898204a82a0ec5e8 100644
|
||||
--- a/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuConfig.java
|
||||
@@ -208,8 +208,10 @@ public class KaiijuConfig {
|
||||
}
|
||||
|
||||
public static String serverModName = "Kaiiju";
|
||||
+ public static boolean sharedRandomForPlayers = true;
|
||||
|
||||
private static void gameplaySettings() {
|
||||
serverModName = getString("gameplay.server-mod-name", serverModName);
|
||||
+ sharedRandomForPlayers = getBoolean("gameplay.shared-random-for-players", sharedRandomForPlayers);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 08e61a8940c142c68ed93359084ea46c7fd52310..f22b4ad629845462656834abb3e28d2c2588ace6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -560,6 +560,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
this.bb = Entity.INITIAL_AABB;
|
||||
this.stuckSpeedMultiplier = Vec3.ZERO;
|
||||
this.nextStep = 1.0F;
|
||||
+ // Kaiiju start - Toggle shared random for players
|
||||
+ if (!dev.kaiijumc.kaiiju.KaiijuConfig.sharedRandomForPlayers && this instanceof Player)
|
||||
+ this.random = RandomSource.create();
|
||||
+ else
|
||||
+ // Kaiiju end
|
||||
this.random = SHARED_RANDOM; // Paper
|
||||
this.remainingFireTicks = -this.getFireImmuneTicks();
|
||||
this.fluidHeight = new Object2DoubleArrayMap(2);
|
||||
Reference in New Issue
Block a user