Fully cleanup
This commit is contained in:
@@ -32,7 +32,7 @@ import net.minecraft.server.TileEntityHopper;
|
||||
import net.minecraft.server.WorldServer;
|
||||
|
||||
@Mixin(value = MinecraftServer.class, remap = false)
|
||||
public class MixinMinecraftServer {
|
||||
public abstract class MixinMinecraftServer {
|
||||
@Overwrite
|
||||
public String getServerModName() {
|
||||
return "Akarin";
|
||||
@@ -57,7 +57,6 @@ public class MixinMinecraftServer {
|
||||
WorldServer world = worlds.get(i);
|
||||
TileEntityHopper.skipHopperEvents = world.paperConfig.disableHopperMoveEvents || InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0;
|
||||
}
|
||||
|
||||
AkarinSlackScheduler.boot();
|
||||
}
|
||||
|
||||
@@ -69,9 +68,9 @@ public class MixinMinecraftServer {
|
||||
@Shadow private PlayerList v;
|
||||
@Shadow @Final private List<ITickable> o;
|
||||
|
||||
@Shadow public PlayerList getPlayerList() { return null; }
|
||||
@Shadow public ServerConnection an() { return null; }
|
||||
@Shadow public CustomFunctionData aL() { return null; }
|
||||
@Shadow public abstract PlayerList getPlayerList();
|
||||
@Shadow public abstract ServerConnection an();
|
||||
@Shadow public abstract CustomFunctionData aL();
|
||||
|
||||
private boolean tickEntities(WorldServer world) {
|
||||
try {
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
package io.akarin.server.mixin.cps;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
||||
@@ -15,7 +15,7 @@ import net.minecraft.server.IChunkLoader;
|
||||
import net.minecraft.server.WorldServer;
|
||||
|
||||
@Mixin(value = ChunkProviderServer.class, remap = false)
|
||||
public class MixinChunkProviderServer {
|
||||
public abstract class MixinChunkProviderServer {
|
||||
@Shadow @Final public WorldServer world;
|
||||
@Shadow public Long2ObjectOpenHashMap<Chunk> chunks;
|
||||
|
||||
@@ -26,11 +26,11 @@ public class MixinChunkProviderServer {
|
||||
// Akarin - avoid using the queue and simply check the unloaded flag during unloads
|
||||
// this.unloadQueue.add(Long.valueOf(ChunkCoordIntPair.a(chunk.locX, chunk.locZ)));
|
||||
pendingUnloadChunks++;
|
||||
chunk.setShouldUnload(true); // PAIL: shouldUnload
|
||||
chunk.setShouldUnload(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Shadow public boolean unloadChunk(Chunk chunk, boolean save) { return true; }
|
||||
@Shadow public abstract boolean unloadChunk(Chunk chunk, boolean save);
|
||||
@Shadow @Final private IChunkLoader chunkLoader;
|
||||
@Shadow @Final private static double UNLOAD_QUEUE_RESIZE_FACTOR;
|
||||
|
||||
|
||||
@@ -70,34 +70,34 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
private long lightUpdateTime;
|
||||
private ExecutorService lightExecutorService;
|
||||
|
||||
@Shadow private boolean m; // PAIL: isGapLightingUpdated
|
||||
@Shadow private boolean r; // PAIL: ticked
|
||||
@Shadow(aliases = "m") private boolean isGapLightingUpdated;
|
||||
@Shadow(aliases = "r") private boolean ticked;
|
||||
@Shadow @Final private ChunkSection[] sections;
|
||||
@Shadow @Final public int locX;
|
||||
@Shadow @Final public int locZ;
|
||||
@Shadow @Final public World world;
|
||||
@Shadow @Final public int[] heightMap;
|
||||
/** Which columns need their skylightMaps updated. */
|
||||
@Shadow @Final private boolean[] i; // PAIL: updateSkylightColumns
|
||||
@Shadow(aliases = "i") @Final private boolean[] updateSkylightColumns;
|
||||
/** Queue containing the BlockPosition of tile entities queued for creation */
|
||||
@Shadow @Final private ConcurrentLinkedQueue<BlockPosition> y; // PAIL: tileEntityPosQueue
|
||||
@Shadow(aliases = "y") @Final private ConcurrentLinkedQueue<BlockPosition> tileEntityPosQueue;
|
||||
/** Boolean value indicating if the terrain is populated. */
|
||||
@Shadow private boolean done; // isTerrainPopulated
|
||||
@Shadow(aliases = "done") private boolean isTerrainPopulated;
|
||||
@Shadow(aliases = "lit") private boolean isLightPopulated;
|
||||
/** Lowest value in the heightmap. */
|
||||
@Shadow private int v; // PAIL: heightMapMinimum
|
||||
@Shadow(aliases = "v") private int heightMapMinimum;
|
||||
|
||||
@Shadow public abstract int b(int x, int z); // PAIL: getHeightValue
|
||||
@Shadow @Nullable public abstract TileEntity g(BlockPosition pos); // PAIL: createNewTileEntity
|
||||
@Shadow @Nullable public abstract TileEntity a(BlockPosition pos, Chunk.EnumTileEntityState state); // PAIL: getTileEntity
|
||||
@Shadow(aliases = "b") public abstract int getHeightValue(int x, int z);
|
||||
@Shadow(aliases = "g") @Nullable public abstract TileEntity createNewTileEntity(BlockPosition pos);
|
||||
@Shadow(aliases = "a") @Nullable public abstract TileEntity getTileEntity(BlockPosition pos, Chunk.EnumTileEntityState state);
|
||||
@Shadow @Final public abstract IBlockData getBlockData(BlockPosition pos);
|
||||
@Shadow @Final public abstract IBlockData getBlockData(int x, int y, int z);
|
||||
@Shadow public abstract boolean isUnloading();
|
||||
/** Checks the height of a block next to a sky-visible block and schedules a lighting update as necessary */
|
||||
@Shadow public abstract void b(int x, int z, int maxValue); // PAIL: checkSkylightNeighborHeight
|
||||
@Shadow public abstract void a(int x, int z, int startY, int endY); // PAIL: updateSkylightNeighborHeight
|
||||
@Shadow public abstract void z(); // PAIL: setSkylightUpdated
|
||||
@Shadow public abstract int g(); // PAIL: getTopFilledSegment
|
||||
@Shadow(aliases = "b") public abstract void checkSkylightNeighborHeight(int x, int z, int maxValue);
|
||||
@Shadow(aliases = "a") public abstract void updateSkylightNeighborHeight(int x, int z, int startY, int endY);
|
||||
@Shadow(aliases = "z") public abstract void setSkylightUpdated();
|
||||
@Shadow(aliases = "g") public abstract int getTopFilledSegment();
|
||||
@Shadow public abstract void markDirty();
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
@@ -123,16 +123,16 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
@Inject(method = "b(Z)V", at = @At("HEAD"), cancellable = true)
|
||||
private void onTickHead(boolean skipRecheckGaps, CallbackInfo ci) {
|
||||
final List<Chunk> neighbors = this.getSurroundingChunks();
|
||||
if (this.m && this.world.worldProvider.m() && !skipRecheckGaps && !neighbors.isEmpty()) { // PAIL: isGapLightingUpdated - hasSkyLight
|
||||
if (this.isGapLightingUpdated && this.world.worldProvider.m() && !skipRecheckGaps && !neighbors.isEmpty()) { // PAIL: isGapLightingUpdated - hasSkyLight
|
||||
this.lightExecutorService.execute(() -> {
|
||||
this.recheckGapsAsync(neighbors);
|
||||
});
|
||||
this.m = false; // PAIL: isGapLightingUpdated
|
||||
this.isGapLightingUpdated = false;
|
||||
}
|
||||
|
||||
this.r = true; // PAIL: ticked
|
||||
this.ticked = true;
|
||||
|
||||
if (!this.isLightPopulated && this.done && !neighbors.isEmpty()) {
|
||||
if (!this.isLightPopulated && this.isTerrainPopulated && !neighbors.isEmpty()) {
|
||||
this.lightExecutorService.execute(() -> {
|
||||
this.checkLightAsync(neighbors);
|
||||
});
|
||||
@@ -140,11 +140,11 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
this.isLightPopulated = true;
|
||||
}
|
||||
|
||||
while (!this.y.isEmpty()) { // PAIL: tileEntityPosQueue
|
||||
BlockPosition blockpos = this.y.poll(); // PAIL: tileEntityPosQueue
|
||||
while (!this.tileEntityPosQueue.isEmpty()) {
|
||||
BlockPosition blockpos = this.tileEntityPosQueue.poll();
|
||||
|
||||
if (this.a(blockpos, Chunk.EnumTileEntityState.CHECK) == null && this.getBlockData(blockpos).getBlock().isTileEntity()) { // PAIL: getTileEntity
|
||||
TileEntity tileentity = this.g(blockpos); // PAIL: createNewTileEntity
|
||||
if (this.getTileEntity(blockpos, Chunk.EnumTileEntityState.CHECK) == null && this.getBlockData(blockpos).getBlock().isTileEntity()) { // PAIL: getTileEntity
|
||||
TileEntity tileentity = this.createNewTileEntity(blockpos);
|
||||
this.world.setTileEntity(blockpos, tileentity);
|
||||
this.world.b(blockpos, blockpos); // PAIL: markBlockRangeForRenderUpdate
|
||||
}
|
||||
@@ -180,9 +180,9 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
private void recheckGapsAsync(List<Chunk> neighbors) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
if (this.i[i + j * 16]) { // PAIL: updateSkylightColumns
|
||||
this.i[i + j * 16] = false; // PAIL: updateSkylightColumns
|
||||
int k = this.b(i, j); // PAIL: getHeightValue
|
||||
if (this.updateSkylightColumns[i + j * 16]) {
|
||||
this.updateSkylightColumns[i + j * 16] = false;
|
||||
int k = this.getHeightValue(i, j);
|
||||
int l = this.locX * 16 + i;
|
||||
int i1 = this.locZ * 16 + j;
|
||||
int j1 = Integer.MAX_VALUE;
|
||||
@@ -195,10 +195,10 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
j1 = Math.min(j1, chunk.w()); // PAIL: getLowestHeight
|
||||
}
|
||||
|
||||
this.b(l, i1, j1); // PAIL: checkSkylightNeighborHeight
|
||||
this.checkSkylightNeighborHeight(l, i1, j1);
|
||||
|
||||
for (EnumDirection enumfacing1 : EnumDirection.EnumDirectionLimit.HORIZONTAL) {
|
||||
this.b(l + enumfacing1.getAdjacentX(), i1 + enumfacing1.getAdjacentZ(), k); // PAIL: checkSkylightNeighborHeight
|
||||
this.checkSkylightNeighborHeight(l + enumfacing1.getAdjacentX(), i1 + enumfacing1.getAdjacentZ(), k);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,7 +269,7 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
* @param neighbors A thread-safe list of surrounding neighbor chunks
|
||||
*/
|
||||
private void checkLightAsync(List<Chunk> neighbors) {
|
||||
this.done = true;
|
||||
this.isTerrainPopulated = true;
|
||||
this.isLightPopulated = true;
|
||||
BlockPosition blockpos = new BlockPosition(this.locX << 4, 0, this.locZ << 4);
|
||||
|
||||
@@ -296,7 +296,7 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
chunk.a(enumfacing.opposite()); // PAIL: checkLightSide
|
||||
}
|
||||
|
||||
this.z(); // PAIL: setSkylightUpdated
|
||||
this.setSkylightUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,7 +310,7 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
* @return True if light update was successful, false if not
|
||||
*/
|
||||
private boolean checkLightAsync(int x, int z, List<Chunk> neighbors) {
|
||||
int i = this.g(); // PAIL: getTopFilledSegment
|
||||
int i = this.getTopFilledSegment();
|
||||
boolean flag = false;
|
||||
boolean flag1 = false;
|
||||
MutableBlockPosition blockpos$mutableblockpos = new MutableBlockPosition((this.locX << 4) + x, 0, (this.locZ << 4) + z);
|
||||
@@ -536,16 +536,16 @@ public abstract class MixinChunk implements IMixinChunk {
|
||||
k2 = i;
|
||||
}
|
||||
|
||||
if (l1 < this.v) { // PAIL: heightMapMinimum
|
||||
this.v = l1; // PAIL: heightMapMinimum
|
||||
if (l1 < this.heightMapMinimum) {
|
||||
this.heightMapMinimum = l1;
|
||||
}
|
||||
|
||||
if (this.world.worldProvider.m()) { // PAIL: hasSkyLight
|
||||
for (EnumDirection enumfacing : EnumDirection.EnumDirectionLimit.HORIZONTAL) {
|
||||
this.a(k + enumfacing.getAdjacentX(), l + enumfacing.getAdjacentZ(), j2, k2); // PAIL: updateSkylightNeighborHeight
|
||||
this.updateSkylightNeighborHeight(k + enumfacing.getAdjacentX(), l + enumfacing.getAdjacentZ(), j2, k2); // PAIL: updateSkylightNeighborHeight
|
||||
}
|
||||
|
||||
this.a(k, l, j2, k2); // PAIL: updateSkylightNeighborHeight
|
||||
this.updateSkylightNeighborHeight(k, l, j2, k2);
|
||||
}
|
||||
|
||||
this.markDirty();
|
||||
|
||||
@@ -38,8 +38,8 @@ public abstract class MixinWorld {
|
||||
@Shadow protected IChunkProvider chunkProvider;
|
||||
@Shadow int[] J; // PAIL: lightUpdateBlockList
|
||||
|
||||
@Shadow public abstract boolean c(EnumSkyBlock lightType, BlockPosition pos); // PAIL: checkLightFor
|
||||
@Shadow(aliases = "c") public abstract boolean checkLightFor(EnumSkyBlock lightType, BlockPosition pos);
|
||||
@Shadow public abstract MinecraftServer getMinecraftServer();
|
||||
@Shadow public abstract boolean areChunksLoaded(BlockPosition center, int radius, boolean allowEmpty);
|
||||
@Shadow public abstract void m(BlockPosition pos); // PAIL: notifyLightSet
|
||||
@Shadow(aliases = "m") public abstract void notifyLightSet(BlockPosition pos);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld
|
||||
private final ExecutorService lightExecutorService = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder().setNameFormat("Akarin Async Light Thread").build());
|
||||
|
||||
@Override
|
||||
public boolean c(EnumSkyBlock lightType, BlockPosition pos) { // PAIL: checkLightFor
|
||||
public boolean checkLightFor(EnumSkyBlock lightType, BlockPosition pos) { // PAIL: checkLightFor
|
||||
return updateLightAsync(lightType, pos, null);
|
||||
}
|
||||
|
||||
@@ -75,12 +75,12 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld
|
||||
int k1 = pos.getZ();
|
||||
|
||||
if (l > k) {
|
||||
this.J[j++] = 133152;
|
||||
this.J[j++] = 133152; // PAIL: lightUpdateBlockList
|
||||
} else if (l < k) {
|
||||
this.J[j++] = 133152 | k << 18;
|
||||
this.J[j++] = 133152 | k << 18; // PAIL: lightUpdateBlockList
|
||||
|
||||
while (i < j) {
|
||||
int l1 = this.J[i++];
|
||||
int l1 = this.J[i++]; // PAIL: lightUpdateBlockList
|
||||
int i2 = (l1 & 63) - 32 + i1;
|
||||
int j2 = (l1 >> 6 & 63) - 32 + j1;
|
||||
int k2 = (l1 >> 12 & 63) - 32 + k1;
|
||||
@@ -113,8 +113,8 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld
|
||||
i3 = this.getLightForAsync(lightType, blockpos$pooledmutableblockpos, currentChunk, neighbors);
|
||||
// Sponge end
|
||||
|
||||
if (i3 == l2 - l4 && j < this.J.length) {
|
||||
this.J[j++] = i4 - i1 + 32 | j4 - j1 + 32 << 6 | k4 - k1 + 32 << 12 | l2 - l4 << 18;
|
||||
if (i3 == l2 - l4 && j < this.J.length) { // PAIL: lightUpdateBlockList
|
||||
this.J[j++] = i4 - i1 + 32 | j4 - j1 + 32 << 6 | k4 - k1 + 32 << 12 | l2 - l4 << 18; // PAIL: lightUpdateBlockList
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld
|
||||
}
|
||||
|
||||
while (i < j) {
|
||||
int i5 = this.J[i++];
|
||||
int i5 = this.J[i++]; // PAIL: lightUpdateBlockList
|
||||
int j5 = (i5 & 63) - 32 + i1;
|
||||
int k5 = (i5 >> 6 & 63) - 32 + j1;
|
||||
int l5 = (i5 >> 12 & 63) - 32 + k1;
|
||||
@@ -143,32 +143,32 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld
|
||||
int k6 = Math.abs(j5 - i1);
|
||||
int l6 = Math.abs(k5 - j1);
|
||||
int i7 = Math.abs(l5 - k1);
|
||||
boolean flag = j < this.J.length - 6;
|
||||
boolean flag = j < this.J.length - 6; // PAIL: lightUpdateBlockList
|
||||
|
||||
if (k6 + l6 + i7 < 17 && flag) {
|
||||
// Sponge start - use thread safe method getLightForAsync
|
||||
if (this.getLightForAsync(lightType, blockpos1.west(), currentChunk, neighbors) < j6) {
|
||||
this.J[j++] = j5 - 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
|
||||
this.J[j++] = j5 - 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); // PAIL: lightUpdateBlockList
|
||||
}
|
||||
|
||||
if (this.getLightForAsync(lightType, blockpos1.east(), currentChunk, neighbors) < j6) {
|
||||
this.J[j++] = j5 + 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
|
||||
this.J[j++] = j5 + 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); // PAIL: lightUpdateBlockList
|
||||
}
|
||||
|
||||
if (this.getLightForAsync(lightType, blockpos1.down(), currentChunk, neighbors) < j6) {
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 - 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 - 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); // PAIL: lightUpdateBlockList
|
||||
}
|
||||
|
||||
if (this.getLightForAsync(lightType, blockpos1.up(), currentChunk, neighbors) < j6) {
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 + 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 + 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12); // PAIL: lightUpdateBlockList
|
||||
}
|
||||
|
||||
if (this.getLightForAsync(lightType, blockpos1.north(), currentChunk, neighbors) < j6) {
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - 1 - k1 + 32 << 12);
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - 1 - k1 + 32 << 12); // PAIL: lightUpdateBlockList
|
||||
}
|
||||
|
||||
if (this.getLightForAsync(lightType, blockpos1.south(), currentChunk, neighbors) < j6) {
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 + 1 - k1 + 32 << 12);
|
||||
this.J[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 + 1 - k1 + 32 << 12); // PAIL: lightUpdateBlockList
|
||||
}
|
||||
// Sponge end
|
||||
}
|
||||
@@ -251,6 +251,7 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutorService getLightingExecutor() {
|
||||
return this.lightExecutorService;
|
||||
}
|
||||
@@ -341,7 +342,7 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld
|
||||
final Chunk chunk = this.getLightChunk(pos, currentChunk, neighbors);
|
||||
if (chunk != null && !chunk.isUnloading()) {
|
||||
chunk.a(type, pos, lightValue); // PAIL: setBrightness
|
||||
this.m(pos); // PAIL: notifyLightSet
|
||||
this.notifyLightSet(pos); // PAIL: notifyLightSet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,16 +42,16 @@ public class NonblockingServerConnection {
|
||||
/**
|
||||
* Contains all endpoints added to this NetworkSystem
|
||||
*/
|
||||
@Shadow @Mutable @Final private List<ChannelFuture> g;
|
||||
@Shadow(aliases = "g") @Mutable @Final private List<ChannelFuture> endPoints;
|
||||
/**
|
||||
* A list containing all NetworkManager instances of all endpoints
|
||||
*/
|
||||
@Shadow @Mutable @Final private List<NetworkManager> h;
|
||||
@Shadow(aliases = "h") @Mutable @Final private List<NetworkManager> networkManagers;
|
||||
|
||||
@Overwrite
|
||||
private void addPending() {} // just keep compatibility
|
||||
|
||||
@Shadow @Final private MinecraftServer f;
|
||||
@Shadow(aliases = "f") @Final private MinecraftServer server;
|
||||
|
||||
/**
|
||||
* Adds channels (endpoint) that listens on publicly accessible network ports
|
||||
@@ -65,7 +65,7 @@ public class NonblockingServerConnection {
|
||||
Class<? extends ServerChannel> channelClass;
|
||||
EventLoopGroup loopGroup;
|
||||
|
||||
if (Epoll.isAvailable() && this.f.af()) { // PAIL: MinecraftServer::useNativeTransport
|
||||
if (Epoll.isAvailable() && this.server.af()) { // PAIL: MinecraftServer::useNativeTransport
|
||||
channelClass = EpollServerSocketChannel.class;
|
||||
loopGroup = ServerConnection.b.c();
|
||||
logger.info("Using epoll channel type");
|
||||
@@ -75,8 +75,8 @@ public class NonblockingServerConnection {
|
||||
logger.info("Using nio channel type");
|
||||
}
|
||||
|
||||
ServerBootstrap bootstrap = new ServerBootstrap().channel(channelClass).childHandler(ChannelAdapter.create(h)).group(loopGroup);
|
||||
synchronized (g) {
|
||||
ServerBootstrap bootstrap = new ServerBootstrap().channel(channelClass).childHandler(ChannelAdapter.create(networkManagers)).group(loopGroup);
|
||||
synchronized (endPoints) {
|
||||
data.addAll(Lists.transform(AkarinGlobalConfig.extraAddress, s -> {
|
||||
String[] info = s.split(":");
|
||||
try {
|
||||
@@ -87,7 +87,7 @@ public class NonblockingServerConnection {
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
data.forEach(address -> g.add(bootstrap.localAddress(address.host(), address.port()).bind().syncUninterruptibly())); // supports multi-port bind
|
||||
data.forEach(address -> endPoints.add(bootstrap.localAddress(address.host(), address.port()).bind().syncUninterruptibly())); // supports multi-port bind
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +98,8 @@ public class NonblockingServerConnection {
|
||||
public void b() {
|
||||
this.d = false;
|
||||
try {
|
||||
synchronized (g) { // safe fixes
|
||||
for (ChannelFuture channel : g) channel.channel().close().sync();
|
||||
synchronized (endPoints) { // safe fixes
|
||||
for (ChannelFuture channel : endPoints) channel.channel().close().sync();
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
logger.error("Interrupted whilst closing channel");
|
||||
@@ -128,13 +128,13 @@ public class NonblockingServerConnection {
|
||||
*/
|
||||
@Overwrite
|
||||
public void c() throws InterruptedException {
|
||||
synchronized (h) {
|
||||
synchronized (networkManagers) {
|
||||
// Spigot - This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order
|
||||
if (SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % SpigotConfig.playerShuffle == 0) {
|
||||
Collections.shuffle(h);
|
||||
Collections.shuffle(networkManagers);
|
||||
}
|
||||
|
||||
Iterator<NetworkManager> it = h.iterator();
|
||||
Iterator<NetworkManager> it = networkManagers.iterator();
|
||||
while (it.hasNext()) {
|
||||
NetworkManager manager = it.next();
|
||||
if (manager.h()) continue; // PAIL: NetworkManager::hasNoChannel
|
||||
|
||||
@@ -18,26 +18,26 @@ import net.minecraft.server.Packet;
|
||||
import net.minecraft.server.PacketPlayOutMapChunk;
|
||||
|
||||
@Mixin(value = NetworkManager.class, remap = false)
|
||||
public class OptimisticNetworkManager {
|
||||
public abstract class OptimisticNetworkManager {
|
||||
@Shadow public Channel channel;
|
||||
@Shadow @Final private Queue<NetworkManager.QueuedPacket> i;
|
||||
@Shadow @Final private ReentrantReadWriteLock j;
|
||||
@Shadow(aliases = "i") @Final private Queue<NetworkManager.QueuedPacket> packets;
|
||||
@Shadow(aliases = "j") @Final private ReentrantReadWriteLock queueLock;
|
||||
|
||||
@Shadow private Queue<NetworkManager.QueuedPacket> getPacketQueue() { return null; }
|
||||
@Shadow private void dispatchPacket(Packet<?> packet, GenericFutureListener<? extends Future<? super Void>>[] genericFutureListeners) {}
|
||||
@Shadow public abstract Queue<NetworkManager.QueuedPacket> getPacketQueue();
|
||||
@Shadow public abstract void dispatchPacket(Packet<?> packet, GenericFutureListener<? extends Future<? super Void>>[] genericFutureListeners);
|
||||
|
||||
private static final QueuedPacket SIGNAL_PACKET = new QueuedPacket(null, null);
|
||||
|
||||
@Overwrite
|
||||
private boolean m() {
|
||||
if (this.channel != null && this.channel.isOpen()) {
|
||||
if (this.i.isEmpty()) { // return if the packet queue is empty so that the write lock by Anti-Xray doesn't affect the vanilla performance at all
|
||||
if (this.packets.isEmpty()) { // return if the packet queue is empty so that the write lock by Anti-Xray doesn't affect the vanilla performance at all
|
||||
return true;
|
||||
}
|
||||
|
||||
this.j.readLock().lock();
|
||||
this.queueLock.readLock().lock();
|
||||
try {
|
||||
while (!this.i.isEmpty()) {
|
||||
while (!this.packets.isEmpty()) {
|
||||
NetworkManager.QueuedPacket packet = ((CheckedConcurrentLinkedQueue<QueuedPacket>) getPacketQueue()).poll(item -> {
|
||||
return item.getPacket() instanceof PacketPlayOutMapChunk && !((PacketPlayOutMapChunk) item.getPacket()).isReady();
|
||||
}, SIGNAL_PACKET);
|
||||
@@ -51,7 +51,7 @@ public class OptimisticNetworkManager {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.j.readLock().unlock();
|
||||
this.queueLock.readLock().unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,20 +42,21 @@ import net.minecraft.server.World;
|
||||
|
||||
@Mixin(value = EntityHorseAbstract.class, remap = false)
|
||||
public abstract class MixinEntityHorseAbstract extends Entity {
|
||||
@Shadow @Final private static DataWatcherObject<Optional<UUID>> bJ;
|
||||
@Shadow(aliases = "bJ") @Final private static DataWatcherObject<Optional<UUID>> OWNER_UNIQUE_ID;
|
||||
|
||||
@Nullable private Optional<UUID> cachedOwnerId;
|
||||
|
||||
@Nullable
|
||||
@Overwrite
|
||||
@Nullable public UUID getOwnerUUID() {
|
||||
if (cachedOwnerId == null) cachedOwnerId = datawatcher.get(bJ);
|
||||
public UUID getOwnerUUID() {
|
||||
if (cachedOwnerId == null) cachedOwnerId = datawatcher.get(OWNER_UNIQUE_ID);
|
||||
return cachedOwnerId.orNull();
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void setOwnerUUID(@Nullable UUID uuid) {
|
||||
cachedOwnerId = Optional.fromNullable(uuid);
|
||||
datawatcher.set(bJ, cachedOwnerId);
|
||||
datawatcher.set(OWNER_UNIQUE_ID, cachedOwnerId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,8 +46,9 @@ public abstract class MixinEntityTameableAnimal extends Entity {
|
||||
|
||||
@Nullable private Optional<UUID> cachedOwnerId;
|
||||
|
||||
@Nullable
|
||||
@Overwrite
|
||||
@Nullable public UUID getOwnerUUID() {
|
||||
public UUID getOwnerUUID() {
|
||||
if (cachedOwnerId == null) cachedOwnerId = datawatcher.get(by);
|
||||
return cachedOwnerId.orNull();
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ import net.minecraft.server.WorldGenBigTree;
|
||||
*/
|
||||
@Mixin(value = WorldGenBigTree.class, remap = false)
|
||||
public class WeakBigTree {
|
||||
@Shadow private World l;
|
||||
@Shadow(aliases = "l") private World worldReference;
|
||||
|
||||
@Inject(method = "generate", at = @At("RETURN"))
|
||||
private void clearWorldRef(World world, Random random, BlockPosition pos, CallbackInfoReturnable<?> info) {
|
||||
l = null; // Akarin - remove references to world objects to avoid memory leaks
|
||||
world = null; // Akarin - remove references to world objects to avoid memory leaks
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,55 +41,55 @@ import net.minecraft.server.ItemStack;
|
||||
*/
|
||||
@Mixin(value = EnchantmentManager.class, remap = false)
|
||||
public class WeakEnchantmentManager {
|
||||
@Shadow @Final private static EnchantmentManager.EnchantmentModifierProtection a;
|
||||
@Shadow @Final private static EnchantmentManager.EnchantmentModifierThorns c;
|
||||
@Shadow @Final private static EnchantmentManager.EnchantmentModifierArthropods d;
|
||||
@Shadow(aliases = "a") @Final private static EnchantmentManager.EnchantmentModifierProtection protection;
|
||||
@Shadow(aliases = "c") @Final private static EnchantmentManager.EnchantmentModifierThorns throns;
|
||||
@Shadow(aliases = "d") @Final private static EnchantmentManager.EnchantmentModifierArthropods arthropods;
|
||||
|
||||
@Shadow private static void a(EnchantmentManager.EnchantmentModifier modifier, Iterable<ItemStack> iterable) {}
|
||||
@Shadow private static void a(EnchantmentManager.EnchantmentModifier modifier, ItemStack itemstack) {}
|
||||
@Shadow(aliases = "a") private static void applyEnchantmentModifierArray(EnchantmentManager.EnchantmentModifier modifier, Iterable<ItemStack> iterable) {}
|
||||
@Shadow(aliases = "a") private static void applyEnchantmentModifier(EnchantmentManager.EnchantmentModifier modifier, ItemStack itemstack) {}
|
||||
|
||||
@Overwrite
|
||||
public static int a(Iterable<ItemStack> iterable, DamageSource damageSource) {
|
||||
EnchantmentManager.a.a = 0; // PAIL: damageModifier
|
||||
EnchantmentManager.a.b = damageSource;
|
||||
a(EnchantmentManager.a, iterable);
|
||||
a.b = null; // Akarin - Remove reference to Damagesource
|
||||
return EnchantmentManager.a.a;
|
||||
protection.a = 0; // PAIL: damageModifier
|
||||
protection.b = damageSource;
|
||||
applyEnchantmentModifierArray(protection, iterable);
|
||||
protection.b = null; // Akarin - Remove reference to Damagesource
|
||||
return protection.a;
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public static void a(EntityLiving user, Entity attacker) { // PAIL: applyThornEnchantments
|
||||
EnchantmentManager.c.b = attacker;
|
||||
EnchantmentManager.c.a = user;
|
||||
throns.b = attacker;
|
||||
throns.a = user;
|
||||
if (user != null) {
|
||||
a(EnchantmentManager.c, user.aQ()); // PAIL: applyEnchantmentModifierArray, getEquipmentAndArmor
|
||||
applyEnchantmentModifierArray(throns, user.aQ()); // PAIL: getEquipmentAndArmor
|
||||
}
|
||||
|
||||
if (attacker instanceof EntityHuman) {
|
||||
a(EnchantmentManager.c, user.getItemInMainHand()); // PAIL: applyEnchantmentModifier
|
||||
applyEnchantmentModifier(throns, user.getItemInMainHand());
|
||||
}
|
||||
|
||||
// Akarin Start - remove references to entity objects to avoid memory leaks
|
||||
c.b = null;
|
||||
c.a = null;
|
||||
// SAkarin end
|
||||
throns.b = null;
|
||||
throns.a = null;
|
||||
// Akarin end
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public static void b(EntityLiving user, Entity target) { // PAIL: applyArthropodEnchantments
|
||||
EnchantmentManager.d.a = user;
|
||||
EnchantmentManager.d.b = target;
|
||||
arthropods.a = user;
|
||||
arthropods.b = target;
|
||||
if (user != null) {
|
||||
a(EnchantmentManager.d, user.aQ()); // PAIL: applyEnchantmentModifierArray, getEquipmentAndArmor
|
||||
applyEnchantmentModifierArray(arthropods, user.aQ()); // PAIL: getEquipmentAndArmor
|
||||
}
|
||||
|
||||
if (user instanceof EntityHuman) {
|
||||
a(EnchantmentManager.d, user.getItemInMainHand()); // PAIL: applyEnchantmentModifier
|
||||
applyEnchantmentModifier(arthropods, user.getItemInMainHand());
|
||||
}
|
||||
|
||||
// Akarin Start - remove references to entity objects to avoid memory leaks
|
||||
d.a = null;
|
||||
d.b = null;
|
||||
arthropods.a = null;
|
||||
arthropods.b = null;
|
||||
// Akarin end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Queues;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -18,10 +18,10 @@ import java.util.Map.Entry;
|
||||
*/
|
||||
public class EnchantmentManager {
|
||||
|
||||
public static final EnchantmentManager.EnchantmentModifierProtection a = new EnchantmentManager.EnchantmentModifierProtection(null); // Akarin - private -> public
|
||||
private static final EnchantmentManager.EnchantmentModifierProtection a = new EnchantmentManager.EnchantmentModifierProtection(null);
|
||||
private static final EnchantmentManager.EnchantmentModifierDamage b = new EnchantmentManager.EnchantmentModifierDamage(null);
|
||||
public static final EnchantmentManager.EnchantmentModifierThorns c = new EnchantmentManager.EnchantmentModifierThorns(null); // Akarin - private -> public
|
||||
public static final EnchantmentManager.EnchantmentModifierArthropods d = new EnchantmentManager.EnchantmentModifierArthropods(null); // Akarin - private -> public
|
||||
private static final EnchantmentManager.EnchantmentModifierThorns c = new EnchantmentManager.EnchantmentModifierThorns(null);
|
||||
private static final EnchantmentManager.EnchantmentModifierArthropods d = new EnchantmentManager.EnchantmentModifierArthropods(null);
|
||||
|
||||
public static int getEnchantmentLevel(Enchantment enchantment, ItemStack itemstack) {
|
||||
if (itemstack.isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user