Merge pull request #242 from FatSaw/ver/1.12.2

Some features from other cores
This commit is contained in:
josephworks
2023-03-06 22:38:11 -07:00
committed by GitHub
9 changed files with 266 additions and 315 deletions

View File

@@ -262,4 +262,9 @@ public class AkarinGlobalConfig {
private static void parallelMode() { private static void parallelMode() {
parallelMode = getInt("core.parallel-mode", 1); parallelMode = getInt("core.parallel-mode", 1);
} }
public static boolean noChunksPastWorldBorder = true;
private static void noChunksPastWorldBorder() {
noChunksPastWorldBorder = getBoolean("core.no-chunks-past-world-border", noChunksPastWorldBorder);
}
} }

View File

@@ -0,0 +1,19 @@
package io.akarin.server.mixin.core;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.server.BlockMinecartDetector;
import net.minecraft.server.BlockPosition;
import net.minecraft.server.IBlockData;
import net.minecraft.server.World;
@Mixin(value = BlockMinecartDetector.class, remap = false)
public abstract class MixinBlockMinecartDetector {
@Inject(at = @At("HEAD"), method = "e", cancellable = true)
private void e(World world, BlockPosition blockposition, IBlockData iblockdata, CallbackInfo ci) {
if (iblockdata.getBlock() != (Object)this) ci.cancel();
}
}

View File

@@ -0,0 +1,50 @@
package io.akarin.server.mixin.core;
import javax.annotation.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.server.EntityLiving;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.MathHelper;
import net.minecraft.server.MobEffect;
import net.minecraft.server.MobEffectList;
import net.minecraft.server.MobEffects;
@Mixin(value = EntityLiving.class, remap = false)
public abstract class MixinEntityLiving {
@Shadow public abstract boolean hasEffect(MobEffectList mobeffectlist);
@Shadow @Nullable public abstract MobEffect getEffect(MobEffectList mobeffectlist);
@Shadow protected abstract float ct();
protected long lastJumpTime = 0L; // Dionysus - Backport ArrowDMG fix
@Overwrite
protected void cu() {
// Dionysus start - Backport ArrowDMG fix
long time = System.nanoTime();
boolean canCrit = true;
if ((Object)this instanceof EntityPlayer) {
canCrit = false;
if (time - lastJumpTime > (long)(0.250e9)) {
lastJumpTime = time;
canCrit = true;
}
}
// Dionysus end - Backport ArrowDMG fix
((EntityLiving)(Object)this).motY = (double) ct();
if (hasEffect(MobEffects.JUMP)) {
((EntityLiving)(Object)this).motY += (double) ((float) (getEffect(MobEffects.JUMP).getAmplifier() + 1) * 0.1F);
}
if (canCrit&&((EntityLiving)(Object)this).isSprinting()) {
float f = ((EntityLiving)(Object)this).yaw * 0.017453292F;
((EntityLiving)(Object)this).motX -= (double) (MathHelper.sin(f) * 0.2F);
((EntityLiving)(Object)this).motZ += (double) (MathHelper.cos(f) * 0.2F);
}
((EntityLiving)(Object)this).impulse = true;
}
}

View File

@@ -0,0 +1,92 @@
package io.akarin.server.mixin.core;
import java.util.Iterator;
import java.util.List;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import io.akarin.server.core.AkarinGlobalConfig;
import net.minecraft.server.Chunk;
import net.minecraft.server.ChunkCoordIntPair;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.PacketPlayOutMapChunk;
import net.minecraft.server.PlayerChunk;
import net.minecraft.server.PlayerChunkMap;
import net.minecraft.server.WorldBorder;
@Mixin(value = PlayerChunk.class, remap = false)
public abstract class MixinPlayerChunk {
@Shadow @Final private static Logger a;
@Shadow @Final private ChunkCoordIntPair location;
@Shadow @Final private PlayerChunkMap playerChunkMap;
@Shadow @Final public List<EntityPlayer> c;
@Shadow public Chunk chunk;
@Shadow private int dirtyCount;
@Shadow private int h;
@Shadow private long i;
@Shadow private boolean done;
@Shadow public abstract void sendChunk(EntityPlayer entityplayer);
@Overwrite
public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument
if (this.c.contains(entityplayer)) {
a.debug("Failed to add player. {} already is in chunk {}, {}", entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z));
return;
}
if (AkarinGlobalConfig.noChunksPastWorldBorder) {
WorldBorder worldborder = playerChunkMap.getWorld().getWorldBorder();
int centerchunkx = ((int)worldborder.getCenterX()) >> 4;
int centerchunkz = ((int)worldborder.getCenterZ()) >> 4;
int sizechunks = ((int)worldborder.getSize()) >> 5;
++sizechunks;
if(location.x<centerchunkx - sizechunks||location.x>=centerchunkx + sizechunks||location.z<centerchunkz - sizechunks||location.z>=centerchunkz + sizechunks) {
return;
}
}
if (this.c.isEmpty()) {
this.i = this.playerChunkMap.getWorld().getTime();
}
this.c.add(entityplayer);
if (this.done) {
this.sendChunk(entityplayer);
}
}
@Overwrite
public boolean b() {
if (this.done) {
return true;
}
if (this.chunk == null) {
return false;
}
if (!this.chunk.isReady()) {
return false;
}
if (!this.chunk.world.chunkPacketBlockController.onChunkPacketCreate(this.chunk, '\uffff', false)) { // Paper - Anti-Xray - Load nearby chunks if necessary
return false;
}
this.dirtyCount = 0;
this.h = 0;
this.done = true;
if (c.isEmpty()) return true; // Akarin - Fixes MC-120780
PacketPlayOutMapChunk packetplayoutmapchunk = new PacketPlayOutMapChunk(this.chunk, '\uffff');
Iterator<EntityPlayer> iterator = this.c.iterator();
while (iterator.hasNext()) {
EntityPlayer entityplayer = iterator.next();
entityplayer.playerConnection.sendPacket(packetplayoutmapchunk);
this.playerChunkMap.getWorld().getTracker().a(entityplayer, this.chunk);
}
return true;
}
}

View File

@@ -0,0 +1,17 @@
package io.akarin.server.mixin.core;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.TileEntityLootable;
@Mixin(value = TileEntityLootable.class, remap = false)
public abstract class MixinTileEntityLootable {
@Inject(at = @At("HEAD"), method = "b(Lnet/minecraft/server/EntityHuman;Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfo;)V", cancellable = true)
private void b(EntityHuman entityhuman, CallbackInfo ci) {
if (entityhuman == null) ci.cancel();
}
}

View File

@@ -0,0 +1,29 @@
package io.akarin.server.mixin.core;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.server.BlockPosition;
import net.minecraft.server.WorldBorder;
@Mixin(value = WorldBorder.class, remap = false)
public abstract class MixinWorldBorder {
@Shadow
public abstract boolean isInBounds(BlockPosition blockposition);
@Overwrite
public boolean isBlockInBounds(int chunkX, int chunkZ) {
BlockPosition.MutableBlockPosition mutPos = new BlockPosition.MutableBlockPosition(); // Dionysus - avoid collisions with other threads
mutPos.setValues(chunkX, 64, chunkZ);
return isInBounds(mutPos);
}
@Overwrite
public boolean isChunkInBounds(int chunkX, int chunkZ) {
BlockPosition.MutableBlockPosition mutPos = new BlockPosition.MutableBlockPosition(); // Dionysus - avoid collisions with other threads // threads
mutPos.setValues(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15);
return isInBounds(mutPos);
}
}

View File

@@ -0,0 +1,47 @@
package io.akarin.server.mixin.optimization;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.server.DataBits;
@Mixin(value = DataBits.class, remap = false)
public abstract class MixinDataBits {
@Shadow @Final private long[] a;
@Shadow @Final private int b;
@Shadow @Final private long c;
@Overwrite
public void a(int i, int j) {
int k = i * this.b;
int l = k >> 6;
int i1 = (i + 1) * this.b - 1 >> 6;
int j1 = k ^ l << 6;
this.a[l] = this.a[l] & ~(this.c << j1) | ((long) j & this.c) << j1;
if (l != i1) {
int k1 = 64 - j1;
int l1 = this.b - k1;
this.a[i1] = this.a[i1] >>> l1 << l1 | ((long) j & this.c) >> k1;
}
}
@Overwrite
public int a(int i) {
int j = i * this.b;
int k = j >> 6;
int l = (i + 1) * this.b - 1 >> 6;
int i1 = j ^ k << 6;
if (k == l) {
return (int) (this.a[k] >>> i1 & this.c);
} else {
int j1 = 64 - i1;
return (int) ((this.a[k] >>> i1 | this.a[l] << j1) & this.c);
}
}
}

View File

@@ -1,314 +0,0 @@
package net.minecraft.server;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
// CraftBukkit Start
import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor;
// CraftBukkit end
/**
* Akarin Changes Note
* 1) Check whether players empty (performance, MC-120780)
*/
public class PlayerChunk {
private static final Logger a = LogManager.getLogger();
private final PlayerChunkMap playerChunkMap;
public final List<EntityPlayer> c = Lists.newArrayList(); // CraftBukkit - public
private final ChunkCoordIntPair location;
private final short[] dirtyBlocks = new short[64];
@Nullable
public Chunk chunk; // CraftBukkit - public
private int dirtyCount;
private int h;
private long i;
private boolean done;
// CraftBukkit start - add fields
boolean chunkExists; // Paper
private boolean loadInProgress = false;
private Runnable loadedRunnable = new Runnable() {
@Override
public void run() {
loadInProgress = false;
PlayerChunk.this.chunk = PlayerChunk.this.playerChunkMap.getWorld().getChunkProviderServer().getOrLoadChunkAt(location.x, location.z);
markChunkUsed(); // Paper - delay chunk unloads
}
};
// Paper start - delay chunk unloads
public final void markChunkUsed() {
if (chunk != null && chunk.scheduledForUnload != null) {
chunk.scheduledForUnload = null;
}
}
// Paper end
// CraftBukkit end
public PlayerChunk(PlayerChunkMap playerchunkmap, int i, int j) {
this.playerChunkMap = playerchunkmap;
this.location = new ChunkCoordIntPair(i, j);
// CraftBukkit start
loadInProgress = true;
this.chunk = playerchunkmap.getWorld().getChunkProviderServer().getChunkAt(i, j, loadedRunnable, false);
this.chunkExists = this.chunk != null || ChunkIOExecutor.hasQueuedChunkLoad(playerChunkMap.getWorld(), i, j); // Paper
markChunkUsed(); // Paper - delay chunk unloads
// CraftBukkit end
}
public ChunkCoordIntPair a() {
return this.location;
}
public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument
if (this.c.contains(entityplayer)) {
PlayerChunk.a.debug("Failed to add player. {} already is in chunk {}, {}", entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z));
} else {
if (this.c.isEmpty()) {
this.i = this.playerChunkMap.getWorld().getTime();
}
this.c.add(entityplayer);
// CraftBukkit start - use async chunk io
// if (this.done) {
// this.sendChunk(entityplayer);
// }
if (this.done) {
this.sendChunk(entityplayer);
}
// CraftBukkit end
}
}
public void b(EntityPlayer entityplayer) {
if (this.c.contains(entityplayer)) {
// CraftBukkit start - If we haven't loaded yet don't load the chunk just so we can clean it up
if (!this.done) {
this.c.remove(entityplayer);
if (this.c.isEmpty()) {
ChunkIOExecutor.dropQueuedChunkLoad(this.playerChunkMap.getWorld(), this.location.x, this.location.z, this.loadedRunnable);
this.playerChunkMap.b(this);
}
return;
}
// CraftBukkit end
if (this.done) {
entityplayer.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(this.location.x, this.location.z));
}
this.c.remove(entityplayer);
if (this.c.isEmpty()) {
this.playerChunkMap.b(this);
}
}
}
public boolean a(boolean flag) {
if (this.chunk != null) {
return true;
} else {
/* CraftBukkit start
if (flag) {
this.chunk = this.playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(this.location.x, this.location.z);
} else {
this.chunk = this.playerChunkMap.getWorld().getChunkProviderServer().getOrLoadChunkAt(this.location.x, this.location.z);
}
*/
if (!loadInProgress) {
loadInProgress = true;
this.chunk = playerChunkMap.getWorld().getChunkProviderServer().getChunkAt(this.location.x, this.location.z, loadedRunnable, flag);
markChunkUsed(); // Paper - delay chunk unloads
}
// CraftBukkit end
return this.chunk != null;
}
}
public boolean b() {
if (this.done) {
return true;
} else if (this.chunk == null) {
return false;
} else if (!this.chunk.isReady()) {
return false;
} else if (!this.chunk.world.chunkPacketBlockController.onChunkPacketCreate(this.chunk, '\uffff', false)) { // Paper - Anti-Xray - Load nearby chunks if necessary
return false; // Paper - Anti-Xray - Wait and try again later
} else {
this.dirtyCount = 0;
this.h = 0;
this.done = true;
if (c.isEmpty()) return true; // Akarin - Fixes MC-120780
PacketPlayOutMapChunk packetplayoutmapchunk = new PacketPlayOutMapChunk(this.chunk, '\uffff');
Iterator iterator = this.c.iterator();
while (iterator.hasNext()) {
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
entityplayer.playerConnection.sendPacket(packetplayoutmapchunk);
this.playerChunkMap.getWorld().getTracker().a(entityplayer, this.chunk);
}
return true;
}
}
public void sendChunk(EntityPlayer entityplayer) {
if (this.done) {
this.chunk.world.chunkPacketBlockController.onChunkPacketCreate(this.chunk, '\uffff', true); // Paper - Anti-Xray - Load nearby chunks if necessary
entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(this.chunk, '\uffff'));
this.playerChunkMap.getWorld().getTracker().a(entityplayer, this.chunk);
}
}
public void c() {
long i = this.playerChunkMap.getWorld().getTime();
if (this.chunk != null) {
this.chunk.c(this.chunk.x() + i - this.i);
}
this.i = i;
}
public void a(int i, int j, int k) {
if (this.done) {
if (this.dirtyCount == 0) {
this.playerChunkMap.a(this);
}
this.h |= 1 << (j >> 4);
if (this.dirtyCount < 64) {
short short0 = (short) (i << 12 | k << 8 | j);
for (int l = 0; l < this.dirtyCount; ++l) {
if (this.dirtyBlocks[l] == short0) {
return;
}
}
this.dirtyBlocks[this.dirtyCount++] = short0;
}
}
}
public void a(Packet<?> packet) {
if (this.done) {
for (int i = 0; i < this.c.size(); ++i) {
this.c.get(i).playerConnection.sendPacket(packet);
}
}
}
public void d() {
if (this.done && this.chunk != null) {
if (this.dirtyCount != 0) {
int i;
int j;
int k;
if (this.dirtyCount == 1) {
i = (this.dirtyBlocks[0] >> 12 & 15) + this.location.x * 16;
j = this.dirtyBlocks[0] & 255;
k = (this.dirtyBlocks[0] >> 8 & 15) + this.location.z * 16;
BlockPosition blockposition = new BlockPosition(i, j, k);
this.a((new PacketPlayOutBlockChange(this.playerChunkMap.getWorld(), blockposition)));
if (this.playerChunkMap.getWorld().getType(blockposition).getBlock().isTileEntity()) {
this.a(this.playerChunkMap.getWorld().getTileEntity(blockposition));
}
} else if (this.dirtyCount == 64) {
// Paper - Anti-Xray - Loading chunks here could cause a ConcurrentModificationException #1104
//this.chunk.world.chunkPacketBlockController.onChunkPacketCreate(this.chunk, this.h, true); // Paper - Anti-Xray - Load nearby chunks if necessary
this.a((new PacketPlayOutMapChunk(this.chunk, this.h)));
} else {
this.a((new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, this.chunk)));
for (i = 0; i < this.dirtyCount; ++i) {
j = (this.dirtyBlocks[i] >> 12 & 15) + this.location.x * 16;
k = this.dirtyBlocks[i] & 255;
int l = (this.dirtyBlocks[i] >> 8 & 15) + this.location.z * 16;
BlockPosition blockposition1 = new BlockPosition(j, k, l);
if (this.playerChunkMap.getWorld().getType(blockposition1).getBlock().isTileEntity()) {
this.a(this.playerChunkMap.getWorld().getTileEntity(blockposition1));
}
}
}
this.dirtyCount = 0;
this.h = 0;
}
}
}
private void a(@Nullable TileEntity tileentity) {
if (tileentity != null) {
PacketPlayOutTileEntityData packetplayouttileentitydata = tileentity.getUpdatePacket();
if (packetplayouttileentitydata != null) {
this.a(packetplayouttileentitydata);
}
}
}
public boolean d(EntityPlayer entityplayer) {
return this.c.contains(entityplayer);
}
public boolean a(Predicate<EntityPlayer> predicate) {
return Iterables.tryFind(this.c, predicate).isPresent();
}
public boolean a(double d0, Predicate<EntityPlayer> predicate) {
int i = 0;
for (int j = this.c.size(); i < j; ++i) {
EntityPlayer entityplayer = this.c.get(i);
if (predicate.apply(entityplayer) && this.location.a(entityplayer) < d0 * d0) {
return true;
}
}
return false;
}
public boolean e() {
return this.done;
}
@Nullable
public Chunk f() {
return this.chunk;
}
public double g() {
double d0 = Double.MAX_VALUE;
Iterator iterator = this.c.iterator();
while (iterator.hasNext()) {
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
double d1 = this.location.a(entityplayer);
if (d1 < d0) {
d0 = d1;
}
}
return d0;
}
}

View File

@@ -28,6 +28,11 @@
"core.MixinMinecraftServer", "core.MixinMinecraftServer",
"core.MixinChunkIOExecutor", "core.MixinChunkIOExecutor",
"core.MixinPlayerConnectionUtils", "core.MixinPlayerConnectionUtils",
"core.MixinPlayerChunk",
"core.MixinWorldBorder",
"core.MixinEntityLiving",
"core.MixinTileEntityLootable",
"core.MixinBlockMinecartDetector",
"nsc.OptimisticNetworkManager", "nsc.OptimisticNetworkManager",
"nsc.NonblockingServerConnection", "nsc.NonblockingServerConnection",
@@ -44,6 +49,7 @@
"optimization.MixinContainerHorse", "optimization.MixinContainerHorse",
"optimization.MixinExplosion", "optimization.MixinExplosion",
"optimization.MixinMathHelper", "optimization.MixinMathHelper",
"optimization.MixinBlockStationary" "optimization.MixinBlockStationary",
"optimization.MixinDataBits"
] ]
} }