Fully cleanup

This commit is contained in:
Sotr
2018-06-11 03:13:41 +08:00
parent 7856043ed6
commit a17a194c6a
14 changed files with 114 additions and 115 deletions

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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
}
}
}

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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);
}
/**

View File

@@ -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();
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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;

View File

@@ -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()) {