Skip to content

Commit

Permalink
memory leak fix
Browse files Browse the repository at this point in the history
  • Loading branch information
FalsePattern committed Jun 4, 2024
1 parent c01ea9e commit 619e571
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 50 deletions.
4 changes: 2 additions & 2 deletions dependencies.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies {
shadeCompile("com.github.GTNewHorizons:ZenScript:1.0.0-GTNH")
compileOnly("net.industrial-craft:industrialcraft-2:2.2.828-experimental:dev")
implementation("codechicken:codechickencore-mc1.7.10:1.3.2-mega:dev")
compileOnly("codechicken:notenoughitems-mc1.7.10:2.1.6-gtmega:dev")
implementation("codechicken:codechickencore-mc1.7.10:1.4.0-mega:dev")
compileOnly("codechicken:notenoughitems-mc1.7.10:2.3.0-mega:dev")
}
14 changes: 12 additions & 2 deletions src/main/java/minetweaker/api/logger/MTLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ public void logWarning(String message) {
if(players.isEmpty()) {
unprocessed.add(message2);
} else {
for(IPlayer player : players) {
for (int i = 0; i < players.size(); i++) {
IPlayer player = players.get(i);
if (player.brokenReference()) {
players.remove(i--);
continue;
}
player.sendChat(message2);
}
}
Expand All @@ -85,7 +90,12 @@ public void logError(String message, Throwable exception) {
if(players.isEmpty()) {
unprocessed.add(message2);
} else {
for(IPlayer player : players) {
for (int i = 0; i < players.size(); i++) {
IPlayer player = players.get(i);
if (player.brokenReference()) {
players.remove(i--);
continue;
}
player.sendChat(message2);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/minetweaker/api/player/IPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,8 @@ public interface IPlayer {

// not an exposed method, so far. would it be useful?
void copyToClipboard(String value);

default boolean brokenReference() {
return false;
}
}
142 changes: 96 additions & 46 deletions src/main/java/minetweaker/mc1710/player/MCPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,38 @@
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.IChatComponent;

import java.lang.ref.WeakReference;
import java.util.function.Consumer;
import java.util.function.Function;

/**
*
* @author Stan
*/
public class MCPlayer implements IPlayer {
private final EntityPlayer player;
private final WeakReference<EntityPlayer> player;

public MCPlayer(EntityPlayer player) {
this.player = player;
this.player = new WeakReference<>(player);
}

public EntityPlayer getInternal() {
return player;
return player.get();
}

private <T> T ifPresent(Function<EntityPlayer, T> fn, T defaultValue) {
EntityPlayer plr = player.get();
if (plr != null) {
return fn.apply(plr);
}
return defaultValue;
}

private void ifPresent(Consumer<EntityPlayer> fn) {
EntityPlayer plr = player.get();
if (plr != null) {
fn.accept(plr);
}
}

@Override
Expand All @@ -44,126 +63,157 @@ public String getId() {

@Override
public String getName() {
return player.getCommandSenderName();
return ifPresent(EntityPlayer::getCommandSenderName, "MISSING");
}

@Override
public IData getData() {
return NBTConverter.from(player.getEntityData(), true);
return ifPresent(player -> NBTConverter.from(player.getEntityData(), true), null);
}

@Override
public int getXP() {
return player.experienceLevel;
return ifPresent(player -> player.experienceLevel, 0);
}

@Override
public void setXP(int xp) {
player.experienceLevel = 0;
player.addExperienceLevel(xp);
ifPresent(player -> {
player.experienceLevel = 0;
player.addExperienceLevel(xp);
});
}

@Override
public void removeXP(int xp) {
final int newLvl = Math.max(0, player.experienceLevel - xp);
player.experienceLevel = 0;
player.addExperienceLevel(newLvl);
ifPresent(player -> {
final int newLvl = Math.max(0, player.experienceLevel - xp);
player.experienceLevel = 0;
player.addExperienceLevel(newLvl);
});
}

@Override
public void update(IData data) {
NBTConverter.updateMap(player.getEntityData(), data);
ifPresent(player -> {
NBTConverter.updateMap(player.getEntityData(), data);
});
}

@Override
public void sendChat(IChatMessage message) {
Object internal = message.getInternal();
if (!(internal instanceof IChatComponent)) {
MineTweakerAPI.logError("not a valid chat message");
return;
}
player.addChatMessage((IChatComponent) internal);
ifPresent(player -> {
Object internal = message.getInternal();
if (!(internal instanceof IChatComponent)) {
MineTweakerAPI.logError("not a valid chat message");
return;
}
player.addChatMessage((IChatComponent) internal);
});
}

@Override
public void sendChat(String message) {
if (message.length() > MAX_CHAT_MESSAGE_LENGTH)
{
message = message.substring(0, MAX_CHAT_MESSAGE_LENGTH);
}
player.addChatMessage(new ChatComponentText(message));
public void sendChat(String msg) {
ifPresent(player -> {
String message = msg;
if (message.length() > MAX_CHAT_MESSAGE_LENGTH)
{
message = message.substring(0, MAX_CHAT_MESSAGE_LENGTH);
}
player.addChatMessage(new ChatComponentText(message));
});
}

@Override
public int getHotbarSize() {
return 9;
return ifPresent(p -> 9, 0);
}

@Override
public IItemStack getHotbarStack(int i) {
return i < 0 || i >= 9 ? null : MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i));
return ifPresent(player -> i < 0 || i >= 9 ? null : MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)), null);
}

@Override
public int getInventorySize() {
return player.inventory.getSizeInventory();
return ifPresent(player -> player.inventory.getSizeInventory(), 0);
}

@Override
public IItemStack getInventoryStack(int i) {
return MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i));
return ifPresent(player -> MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)), null);
}

@Override
public IItemStack getCurrentItem() {
return MineTweakerMC.getIItemStack(player.getCurrentEquippedItem());
return ifPresent(player -> MineTweakerMC.getIItemStack(player.getCurrentEquippedItem()), null);
}

@Override
public boolean isCreative() {
return player.capabilities.isCreativeMode;
return ifPresent(player -> player.capabilities.isCreativeMode, false);
}

@Override
public boolean isAdventure() {
return !player.capabilities.allowEdit;
return ifPresent(player -> !player.capabilities.allowEdit, false);
}

@Override
public void openBrowser(String url) {
if (player instanceof EntityPlayerMP && MineTweakerConfig.handleDesktopPackets) {
MineTweakerMod.NETWORK.sendTo(
new MineTweakerOpenBrowserPacket(url),
(EntityPlayerMP) player);
}
ifPresent(player -> {
if (player instanceof EntityPlayerMP && MineTweakerConfig.handleDesktopPackets) {
MineTweakerMod.NETWORK.sendTo(
new MineTweakerOpenBrowserPacket(url),
(EntityPlayerMP) player);
}
});
}

@Override
public void copyToClipboard(String value) {
if (player instanceof EntityPlayerMP && MineTweakerConfig.handleDesktopPackets) {
MineTweakerMod.NETWORK.sendTo(
new MineTweakerCopyClipboardPacket(value),
(EntityPlayerMP) player);
}
ifPresent(player -> {
if (player instanceof EntityPlayerMP && MineTweakerConfig.handleDesktopPackets) {
MineTweakerMod.NETWORK.sendTo(
new MineTweakerCopyClipboardPacket(value),
(EntityPlayerMP) player);
}
});
}

@Override
public boolean equals(Object other) {
if (other.getClass() != this.getClass())
return false;

return ((MCPlayer) other).player == player;
MCPlayer o = (MCPlayer) other;
return ifPresent(p1 -> o.ifPresent(p2 -> p1 == p2, false), false);
}

private volatile Integer hash;

@Override
public int hashCode() {
int hash = 5;
hash = 23 * hash + (this.player != null ? this.player.hashCode() : 0);
if (hash == null) {
synchronized (this) {
if (hash == null) {
hash = ifPresent(player -> {
int h = 5;
h = 23 * h + player.hashCode();
return h;
}, 0);
}
}
}
return hash;
}

@Override
public void give(IItemStack stack) {
player.inventory.addItemStackToInventory(MineTweakerMC.getItemStack(stack).copy());
ifPresent(player -> player.inventory.addItemStackToInventory(MineTweakerMC.getItemStack(stack).copy()));
}

@Override
public boolean brokenReference() {
return ifPresent(p -> false, true);
}
}

0 comments on commit 619e571

Please sign in to comment.