Rewrite Level Maintainer/Terminal Logic (#294)

Co-authored-by: boubou19 <miisterunknown@gmail.com>
This commit is contained in:
Kogepan229andboubou19 authored and GitHub committed 2025-06-09 20:12:08 +00:00
1 parent 1ffcea9dd9
commit 6ac5ea30f0
18 files changed
+1050 -1427

No files matched your search

@@ -16,11 +16,13 @@ public interface ILevelViewable extends IGridHost, ISide, ISegmentedInventory, I
TileEntity getTile();
@Deprecated
default long getSortValue() {
TileEntity te = getTile();
return ((long) te.zCoord << 24) ^ ((long) te.xCoord << 8) ^ te.yCoord;
}
@Deprecated
default boolean shouldDisplay() {
return true;
}
@@ -39,6 +41,7 @@ public interface ILevelViewable extends IGridHost, ISide, ISegmentedInventory, I
return 1;
};
@Deprecated
default ItemStack getSelfItemStack() {
return null;
}
@@ -46,8 +49,11 @@ public interface ILevelViewable extends IGridHost, ISide, ISegmentedInventory, I
/**
* "Target" Display representation
*/
@Deprecated
default ItemStack getDisplayItemStack() {
return null;
}
LevelItemInfo[] getLevelItemInfoList();
}
@@ -0,0 +1,20 @@
package com.glodblock.github.api.registries;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.NotNull;
public class LevelItemInfo {
public ItemStack stack;
public long quantity;
public long batchSize;
public LevelState state;
public LevelItemInfo(@NotNull ItemStack stack, long quantity, long batchSize, LevelState state) {
this.stack = stack;
this.quantity = quantity;
this.batchSize = batchSize;
this.state = state;
}
}
@@ -0,0 +1,9 @@
package com.glodblock.github.api.registries;
public enum LevelState {
None,
Idle,
Craft,
Export,
Error
}
@@ -1,7 +1,5 @@
package com.glodblock.github.client.gui;
import static com.glodblock.github.client.gui.container.ContainerLevelMaintainer.createLevelValues;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -13,7 +11,6 @@ import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.util.ForgeDirection;
@@ -23,12 +20,11 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.container.ContainerLevelMaintainer;
import com.glodblock.github.common.item.ItemWirelessUltraTerminal;
import com.glodblock.github.common.parts.PartLevelTerminal;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.inventory.gui.MouseRegionManager;
import com.glodblock.github.inventory.item.IWirelessTerminal;
@@ -49,9 +45,6 @@ import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.AEBaseContainer;
import appeng.container.slot.SlotFake;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.AEFeature;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketNEIDragClick;
import appeng.util.calculators.ArithHelper;
@@ -70,8 +63,6 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
private final Component[] component = new Component[TileLevelMaintainer.REQ_COUNT];
private final MouseRegionManager mouseRegions = new MouseRegionManager(this);
private Widget focusedWidget;
private int lastWorkingTick;
private int refreshTick;
private final CoFHFontRenderer render;
protected ItemStack icon = null;
@@ -89,7 +80,7 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
TEX_BG,
Minecraft.getMinecraft().getTextureManager(),
true);
this.refreshTick = 0;
if (ipl.player.openContainer instanceof AEBaseContainer container) {
var target = container.getTarget();
if (target instanceof PartLevelTerminal terminal) {
@@ -126,40 +117,11 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
}
}
}
public void postUpdate(List<IAEItemStack> list) {
for (Slot slot : this.cont.getRequestSlots()) {
if (!slot.getHasStack()) {
component[slot.getSlotIndex()].setState(State.None);
}
}
for (IAEItemStack is : list) {
NBTTagCompound data = is.getItemStack().getTagCompound();
if (data == null) {
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info("Received empty configuration: ", is);
}
continue;
}
long batch = data.getLong(TLMTags.Batch.tagName);
long quantity = data.getLong(TLMTags.Quantity.tagName);
int idx = data.getInteger(TLMTags.Index.tagName);
boolean isEnable = data.getBoolean(TLMTags.Enable.tagName);
State state = State.values()[data.getInteger(TLMTags.State.tagName)];
component[idx].getQty().textField.setText(String.valueOf(quantity));
component[idx].getBatch().textField.setText(String.valueOf(batch));
component[idx].getQty().validate();
component[idx].getBatch().validate();
component[idx].setEnable(isEnable);
component[idx].setState(state);
}
}
@Override
public void initGui() {
super.initGui();
this.lastWorkingTick = this.refreshTick;
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
component[i] = new Component(
new Widget(
@@ -176,7 +138,8 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
new GuiFCImgButton(guiLeft + 9, guiTop + 20 + 19 * i, "ENABLE", "ENABLE", false),
new GuiFCImgButton(guiLeft + 9, guiTop + 20 + 19 * i, "DISABLE", "DISABLE", false),
new FCGuiLineField(fontRendererObj, guiLeft + 47, guiTop + 33 + 19 * i, 125),
this.buttonList);
this.buttonList,
this.cont);
}
if (this.icon != null) {
this.originalGuiBtn = new GuiTabButton(
@@ -188,11 +151,10 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
this.originalGuiBtn.setHideEdge(13);
this.buttonList.add(originalGuiBtn);
}
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Refresh));
}
@Override
public void drawScreen(final int mouseX, final int mouseY, final float btn) {
this.refreshTick++;
super.drawScreen(mouseX, mouseY, btn);
for (Component com : this.component) {
com.getQty().textField.handleTooltip(mouseX, mouseY, this);
@@ -205,12 +167,7 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
mc.getTextureManager().bindTexture(TEX_BG);
drawTexturedModalRect(offsetX, offsetY, 0, 0, 176, ySize);
int tick = this.refreshTick;
int interval = 20;
if (tick > lastWorkingTick + interval && this.focusedWidget == null) {
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Refresh));
lastWorkingTick = this.refreshTick;
}
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
this.component[i].draw();
}
@@ -294,20 +251,6 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
}
}
@Override
protected void handleMouseClick(final Slot slot, final int slotIdx, final int ctrlDown, final int mouseButton) {
if (slot instanceof SlotFluidConvertingFake && this.cont.getPlayerInv().getItemStack() != null) {
this.component[slot.getSlotIndex()].getQty().textField
.setText(String.valueOf(this.cont.getPlayerInv().getItemStack().stackSize));
return;
}
super.handleMouseClick(slot, slotIdx, ctrlDown, mouseButton);
}
public void updateAmount(int idx, int stackSize) {
this.component[idx].getQty().textField.setText(String.valueOf(stackSize));
}
@Override
protected void actionPerformed(final GuiButton btn) {
if (btn == originalGuiBtn) {
@@ -351,6 +294,15 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
return null;
}
@Override
protected void handleMouseClick(Slot slot, int slotIdx, int ctrlDown, int mouseButton) {
if (slot instanceof SlotFluidConvertingFake && this.cont.getPlayerInv().getItemStack() == null) {
slot.putStack(null);
this.component[slot.getSlotIndex()].reset();
}
super.handleMouseClick(slot, slotIdx, ctrlDown, mouseButton);
}
@Override
public boolean handleDragNDrop(GuiContainer gui, int mouseX, int mouseY, ItemStack draggedStack, int button) {
if (draggedStack == null) {
@@ -366,11 +318,9 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
for (int i = 0; i < this.cont.getRequestSlots().length; i++) {
SlotFluidConvertingFake slot = this.cont.getRequestSlots()[i];
if (slotAtPosition.equals(slot)) {
ItemStack itemStack = createLevelValues(draggedStack.copy());
itemStack.getTagCompound().setInteger(TLMTags.Index.tagName, i);
slot.putStack(itemStack);
NetworkHandler.instance.sendToServer(new PacketNEIDragClick(itemStack, slot.getSlotIndex()));
this.updateAmount(slot.getSlotIndex(), itemStack.stackSize);
slot.putStack(draggedStack);
component[i].reset();
NetworkHandler.instance.sendToServer(new PacketNEIDragClick(draggedStack, slot.getSlotIndex()));
return true;
}
}
@@ -382,26 +332,44 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
return false;
}
public void updateComponent(int index, long quantity, long batchSize, boolean isEnabled, LevelState state) {
if (index < 0 || index >= TileLevelMaintainer.REQ_COUNT) return;
component[index].setEnable(isEnabled);
component[index].setState(state);
component[index].getQty().textField.setText(String.valueOf(quantity));
component[index].getBatch().textField.setText(String.valueOf(batchSize));
component[index].getQty().validate();
component[index].getBatch().validate();
}
public void updateComponent(int index, LevelState state) {
if (index < 0 || index >= TileLevelMaintainer.REQ_COUNT) return;
component[index].setState(state);
}
private class Component {
public boolean isEnable = true;
public boolean isEnable = false;
private final Widget qty;
private final Widget batch;
private final GuiFCImgButton disable;
private final GuiFCImgButton enable;
private final GuiFCImgButton submit;
private final FCGuiLineField line;
private State state;
private LevelState state;
private final ContainerLevelMaintainer container;
public Component(Widget qtyInput, Widget batchInput, GuiFCImgButton submitBtn, GuiFCImgButton enableBtn,
GuiFCImgButton disableBtn, FCGuiLineField line, List<GuiButton> buttonList) {
GuiFCImgButton disableBtn, FCGuiLineField line, List<GuiButton> buttonList,
ContainerLevelMaintainer container) {
this.qty = qtyInput;
this.batch = batchInput;
this.enable = enableBtn;
this.disable = disableBtn;
this.submit = submitBtn;
this.line = line;
this.state = State.None;
this.state = LevelState.None;
this.container = container;
buttonList.add(this.submit);
buttonList.add(this.enable);
buttonList.add(this.disable);
@@ -435,18 +403,25 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
batch.validate();
if (qty.getAmount() != null) {
this.send(qty);
qty.textField.setText(String.valueOf(qty.getAmount()));
}
if (batch.getAmount() != null) {
this.send(batch);
batch.textField.setText(String.valueOf(batch.getAmount()));
}
didSomething = true;
} else if (this.enable == btn) {
this.setEnable(false);
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Enable, this.getIndex()));
didSomething = true;
} else if (this.disable == btn) {
FluidCraft.proxy.netHandler.sendToServer(new CPacketLevelMaintainer(Action.Disable, this.getIndex()));
didSomething = true;
if (this.container.getInventory().get(this.getIndex()) != null) {
this.setEnable(true);
FluidCraft.proxy.netHandler
.sendToServer(new CPacketLevelMaintainer(Action.Disable, this.getIndex()));
didSomething = true;
}
}
return didSomething;
}
@@ -531,9 +506,18 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
}
}
public void setState(State state) {
public void setState(LevelState state) {
this.state = state;
}
public void reset() {
this.qty.textField.setText("0");
this.batch.textField.setText("0");
this.qty.validate();
this.batch.validate();
this.setEnable(false);
this.setState(LevelState.None);
}
}
private class Widget {
@@ -585,7 +569,7 @@ public class GuiLevelMaintainer extends AEBaseGui implements INEIGuiHandler {
public void validate() {
final double result = Calculator.conversion(this.textField.getText());
if (Double.isNaN(result)) {
if (Double.isNaN(result) || result < 0) {
this.amount = null;
this.textField.setTextColor(0xFF0000);
} else {
@@ -1,13 +1,6 @@
package com.glodblock.github.client.gui;
import static com.glodblock.github.common.item.ItemWirelessUltraTerminal.hasInfinityBoosterCard;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.CLEAR_ALL_BIT;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.DISCONNECT_BIT;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketAdd;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketEntry;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketOverwrite;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketRemove;
import static com.glodblock.github.network.SPacketLevelTerminalUpdate.PacketRename;
import java.text.NumberFormat;
import java.util.ArrayList;
@@ -17,7 +10,6 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -34,8 +26,6 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.util.ForgeDirection;
@@ -45,16 +35,17 @@ import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.base.FCBaseMEGui;
import com.glodblock.github.client.gui.container.ContainerLevelTerminal;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.network.CPacketInventoryAction;
import com.glodblock.github.network.CPacketLevelTerminalCommands;
import com.glodblock.github.network.CPacketLevelTerminalCommands.Action;
import com.glodblock.github.network.CPacketRenamer;
import com.glodblock.github.network.SPacketLevelTerminalUpdate;
import com.glodblock.github.util.FCGuiColors;
import com.glodblock.github.util.ModAndClassUtil;
import com.glodblock.github.util.NameConst;
@@ -65,7 +56,6 @@ import appeng.api.config.TerminalFontSize;
import appeng.api.config.TerminalStyle;
import appeng.api.config.YesNo;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.IGuiTooltipHandler;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiScrollbar;
@@ -83,7 +73,6 @@ import appeng.core.localization.PlayerMessages;
import appeng.helpers.InventoryAction;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
import appeng.util.ReadableNumberConverter;
import appeng.util.item.AEItemStack;
@@ -151,6 +140,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
};
searchFieldNames.setFocused(true);
extraOptionsText.add(ButtonToolTips.HighlightInterface.getLocal());
online = true;
}
public GuiLevelTerminal(final InventoryPlayer inventoryPlayer, final ITerminalHost te) {
@@ -184,8 +174,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
final int unusedSpace = height - ySize;
guiTop = (int) Math.floor(unusedSpace / (unusedSpace < 0 ? 3.8f : 2.0f));
// modeSwitchView = new GuiFCImgButton(guiLeft + xSize - 40, guiTop + 1, "SWITCH", "OFF", false);
// modeSwitchEdit = new GuiFCImgButton(guiLeft + xSize - 40, guiTop + 1, "SWITCH", "ON", false);
offsetY = guiTop + 8;
terminalStyleBox = new GuiImgButton(
guiLeft - 18,
@@ -290,7 +278,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
buttonList.add(terminalStyleBox);
buttonList.add(searchStringSave);
buttonList.add(craftingStatusBtn);
// buttonList.add(Objects.equals(currentMode, "OFF") ? modeSwitchView : modeSwitchEdit);
addSwitchGuiBtns();
super.drawScreen(mouseX, mouseY, btn);
@@ -322,11 +309,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
@Override
protected void actionPerformed(final GuiButton btn) {
// if (btn == modeSwitchView) {
// currentMode = "ON";
// } else if (btn == modeSwitchEdit) {
// currentMode = "OFF";
// } else
if (ModAndClassUtil.isSaveText && btn == searchStringSave) {
final boolean backwards = Mouse.isButtonDown(1);
@@ -566,26 +548,21 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
if (viewY + rowYBot <= titleBottom) {
continue;
}
AppEngInternalInventory inv = entry.getInventory();
for (int col = 0; col < entry.rowSize; ++col) {
final int colLeft = col * 18 + slotLeftMargin + 1;
final int colRight = colLeft + 18 + 1;
final int slotIdx = row * entry.rowSize + col;
ItemStack stack = inv.getStackInSlot(slotIdx);
LevelItemInfo info = entry.infoList[slotIdx];
boolean tooltip = relMouseX > colLeft - 1 && relMouseX < colRight - 1
&& relMouseY >= Math.max(viewY + rowYTop, LevelTerminalSection.TITLE_HEIGHT)
&& relMouseY < Math.min(viewY + rowYBot, viewHeight);
if (stack != null) {
NBTTagCompound data = stack.getTagCompound();
ItemStack itemStack = data.hasKey(TLMTags.Stack.tagName)
? ItemStack.loadItemStackFromNBT(data.getCompoundTag(TLMTags.Stack.tagName))
: stack.copy();
long quantity = data.getLong(TLMTags.Quantity.tagName);
long batch = data.getLong(TLMTags.Batch.tagName);
State state = State.values()[data.getInteger(TLMTags.State.tagName)];
if (info != null) {
ItemStack itemStack = info.stack;
long quantity = info.quantity;
long batch = info.batchSize;
LevelState state = info.state;
GL11.glPushMatrix();
GL11.glTranslatef(colLeft, viewY + rowYTop + 1, ITEM_STACK_Z);
@@ -608,7 +585,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
drawRect(offset, offset, offset + size, offset + size, color);
GL11.glTranslatef(0.0f, 0.0f, ITEM_STACK_OVERLAY_Z - ITEM_STACK_Z);
this.drawReadableAmount(fontRendererObj, quantity, true, 16777215);
if (batch > 0) {
if (batch >= 0) {
this.drawReadableAmount(fontRendererObj, batch, false, 16777215);
}
RenderHelper.disableStandardItemLighting();
@@ -622,7 +599,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
drawRect(0, 0, 16, 16, GuiColors.ItemSlotOverlayUnpowered.getColor());
}
} else {
tooltipStack = stack;
tooltipStack = itemStack;
}
GL11.glPopMatrix();
} else if (entry.filteredRecipes[slotIdx]) {
@@ -846,58 +823,50 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
&& mouseY < guiTop + HEADER_HEIGHT + viewHeight;
}
public void postUpdate(List<PacketEntry> updates, int statusFlags) {
if ((statusFlags & CLEAR_ALL_BIT) == CLEAR_ALL_BIT) {
/* Should clear all client entries. */
masterList.list.clear();
}
/* Should indicate disconnected, so the terminal turns dark. */
online = (statusFlags & DISCONNECT_BIT) != DISCONNECT_BIT;
for (PacketEntry cmd : updates) {
parsePacketCmd(cmd);
public void receivePackets(List<SPacketLevelTerminalUpdate.PacketEntry> packets) {
for (SPacketLevelTerminalUpdate.PacketEntry packet : packets) {
parsePacket(packet);
}
masterList.markDirty();
}
private void parsePacketCmd(PacketEntry cmd) {
long id = cmd.entryId;
if (cmd instanceof PacketAdd addCmd) {
private void parsePacket(SPacketLevelTerminalUpdate.PacketEntry packet) {
if (packet instanceof SPacketLevelTerminalUpdate.PacketAdd packetAdd) {
LevelTerminalEntry entry = new LevelTerminalEntry(
id,
addCmd.name,
addCmd.rows,
addCmd.rowSize,
addCmd.online).setLocation(addCmd.x, addCmd.y, addCmd.z, addCmd.dim, addCmd.side)
.setIcons(addCmd.selfItemStack, addCmd.displayItemStack).setItems(addCmd.items);
masterList.addEntry(entry);
} else if (cmd instanceof PacketRemove) {
masterList.removeEntry(id);
} else if (cmd instanceof PacketOverwrite owCmd) {
LevelTerminalEntry entry = masterList.list.get(id);
packetAdd.entryId,
packetAdd.name,
packetAdd.rows,
packetAdd.rowSize,
true).setLocation(packetAdd.x, packetAdd.y, packetAdd.z, packetAdd.dim, packetAdd.side)
.setInfoList(packetAdd.infolist);
this.masterList.addEntry(entry);
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketRemove packetRemove) {
this.masterList.removeEntry(packetRemove.entryId);
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketRename packetRename) {
LevelTerminalEntry entry = masterList.list.get(packetRename.entryId);
if (entry == null) return;
if (entry == null) {
return;
}
if (owCmd.itemsValid) {
if (owCmd.allItemUpdate) {
entry.fullItemUpdate(owCmd.items, owCmd.validIndices.length);
} else {
entry.partialItemUpdate(owCmd.items, owCmd.validIndices);
}
if (StatCollector.canTranslate(packetRename.newName)) {
entry.customName = StatCollector.translateToLocal(packetRename.newName);
} else {
entry.customName = StatCollector.translateToFallback(packetRename.newName);
}
masterList.isDirty = true;
} else if (cmd instanceof PacketRename renameCmd) {
LevelTerminalEntry entry = masterList.list.get(id);
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketDisconnect) {
online = false;
}
if (entry != null) {
if (StatCollector.canTranslate(renameCmd.newName)) {
entry.customName = StatCollector.translateToLocal(renameCmd.newName);
} else {
entry.customName = StatCollector.translateToFallback(renameCmd.newName);
}
}
else if (packet instanceof SPacketLevelTerminalUpdate.PacketOverwriteSlot packetOverwirteSlot) {
LevelTerminalEntry entry = masterList.list.get(packetOverwirteSlot.entryId);
if (entry == null) return;
entry.infoList[packetOverwirteSlot.index] = packetOverwirteSlot.info;
masterList.isDirty = true;
} else if (packet instanceof SPacketLevelTerminalUpdate.PacketOverwirteAllSlot packetOverwirteAllSlot) {
LevelTerminalEntry entry = masterList.list.get(packetOverwirteAllSlot.entryId);
if (entry == null) return;
entry.infoList = packetOverwirteAllSlot.infoList;
masterList.isDirty = true;
}
}
@@ -932,22 +901,23 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
@Override
public List<String> handleItemTooltip(ItemStack stack, int mouseX, int mouseY, List<String> currentToolTip) {
if (stack == null || !isShiftKeyDown()) return currentToolTip;
if (stack != null && isShiftKeyDown() && stack.hasTagCompound()) {
NBTTagCompound data = stack.getTagCompound();
for (LevelTerminalSection section : this.masterList.getVisibleSections()) {
for (LevelTerminalEntry entry : section.visibleEntries) {
for (LevelItemInfo info : entry.infoList) {
if (info != null && info.stack.equals(stack)) {
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_REQUEST_SIZE, "\n", false) + ": "
+ NumberFormat.getInstance().format(info.quantity));
if (data.hasKey(TLMTags.Quantity.tagName)) {
long quantity = data.getLong(TLMTags.Quantity.tagName);
long batch = data.getLong(TLMTags.Batch.tagName);
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_REQUEST_SIZE, "\n", false) + ": "
+ NumberFormat.getNumberInstance(Locale.US).format(quantity));
if (batch > 0) {
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_BATCH_SIZE, "\n", false) + ": "
+ NumberFormat.getNumberInstance(Locale.US).format(batch));
if (info.batchSize >= 0) {
currentToolTip.add(
I18n.format(NameConst.TT_LEVEL_MAINTAINER_BATCH_SIZE, "\n", false) + ": "
+ NumberFormat.getInstance().format(info.batchSize));
}
break;
}
}
}
}
@@ -1102,13 +1072,7 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
String name;
List<LevelTerminalEntry> entries = new ArrayList<>();
Set<LevelTerminalEntry> visibleEntries = new TreeSet<>(Comparator.comparing(e -> {
if (e.displayItemStack != null) {
return e.displayItemStack.getDisplayName() + e.id;
} else {
return String.valueOf(e.id);
}
}));
Set<LevelTerminalEntry> visibleEntries = new TreeSet<>(Comparator.comparing(e -> e.customName + e.id));
int height;
private boolean isDirty = true;
boolean visible = false;
@@ -1148,18 +1112,22 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
entry.dispY = -9999;
// Find search terms
if (!output.isEmpty()) {
AppEngInternalInventory inv = entry.inv;
boolean shouldAdd = false;
for (int i = 0; i < inv.getSizeInventory(); ++i) {
ItemStack stack = inv.getStackInSlot(i);
if (itemStackMatchesSearchTerm(stack, output)) {
for (int i = 0; i < entry.infoList.length; ++i) {
if (entry.infoList[i] == null) {
entry.filteredRecipes[i] = true;
continue;
}
if (itemStackMatchesSearchTerm(entry.infoList[i].stack, output)) {
shouldAdd = true;
entry.filteredRecipes[i] = false;
} else {
entry.filteredRecipes[i] = true;
}
}
if (!shouldAdd) {
continue;
}
@@ -1207,12 +1175,9 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
private class LevelTerminalEntry {
String customName;
AppEngInternalInventory inv;
GuiFCImgButton highlightButton;
GuiFCImgButton renameButton;
GuiFCImgButton configButton;
/** Nullable - icon that represents the interface's "target" */
ItemStack displayItemStack;
LevelTerminalSection section;
long id;
int x, y, z, dim, side;
@@ -1220,7 +1185,8 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
int guiHeight;
int dispY = -9999;
boolean[] filteredRecipes;
int numItems = 0;
LevelItemInfo[] infoList;
LevelTerminalEntry(long id, String name, int rows, int rowSize, boolean online) {
this.id = id;
@@ -1236,7 +1202,6 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
customName = StatCollector.translateToFallback(name);
}
}
inv = new AppEngInternalInventory(null, rows * rowSize, 1);
highlightButton = new GuiFCImgButton(1, 0, "HIGHLIGHT", "YES");
renameButton = new GuiFCImgButton(1, 0, "EDIT", "YES");
configButton = new GuiFCImgButton(1, 0, "CONFIG", "YES");
@@ -1254,53 +1219,11 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
return this;
}
LevelTerminalEntry setIcons(ItemStack selfItemStack, ItemStack displayItemStack) {
this.displayItemStack = displayItemStack;
LevelTerminalEntry setInfoList(LevelItemInfo[] infoList) {
this.infoList = infoList;
return this;
}
public void fullItemUpdate(NBTTagList items, int newSize) {
inv = new AppEngInternalInventory(null, newSize);
rows = newSize / rowSize;
numItems = 0;
for (int i = 0; i < inv.getSizeInventory(); ++i) {
setItemInSlot(ItemStack.loadItemStackFromNBT(items.getCompoundTagAt(i)), i);
}
guiHeight = 18 * rows + 4;
}
LevelTerminalEntry setItems(NBTTagList items) {
assert items.tagCount() == inv.getSizeInventory();
for (int i = 0; i < items.tagCount(); ++i) {
setItemInSlot(ItemStack.loadItemStackFromNBT(items.getCompoundTagAt(i)), i);
}
return this;
}
public void partialItemUpdate(NBTTagList items, int[] validIndices) {
for (int i = 0; i < validIndices.length; ++i) {
setItemInSlot(ItemStack.loadItemStackFromNBT(items.getCompoundTagAt(i)), validIndices[i]);
}
}
private void setItemInSlot(ItemStack stack, int idx) {
final int oldHasItem = inv.getStackInSlot(idx) != null ? 1 : 0;
final int newHasItem = stack != null ? 1 : 0;
inv.setInventorySlotContents(idx, stack);
// Update item count
numItems += newHasItem - oldHasItem;
assert numItems >= 0;
}
public AppEngInternalInventory getInventory() {
return inv;
}
public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) {
if (!section.visible || mouseButton < 0 || mouseButton > 2) {
return false;
@@ -1368,20 +1291,10 @@ public class GuiLevelTerminal extends FCBaseMEGui implements IDropToFillTextFiel
default -> null;// drop item:
};
if (action != null) {
ItemStack itemStack = getInventory().getStackInSlot(slotIdx);
if (itemStack != null && itemStack.hasTagCompound()
&& itemStack.getTagCompound().hasKey(TLMTags.Stack.tagName)) {
long batch = itemStack.getTagCompound().getLong(TLMTags.Batch.tagName);
NBTTagCompound stackData = itemStack.getTagCompound().getCompoundTag(TLMTags.Stack.tagName);
ItemStack is = ItemStack.loadItemStackFromNBT(stackData);
IAEItemStack stack = AEItemStack.create(is);
if (stack == null) return true;
stack.setStackSize(batch);
((AEBaseContainer) inventorySlots).setTargetStack(stack);
FluidCraft.proxy.netHandler.sendToServer(new CPacketInventoryAction(action, slotIdx, 0, stack));
}
if (action != null && this.infoList[slotIdx] != null) {
AEItemStack aeStack = AEItemStack.create(this.infoList[slotIdx].stack);
((AEBaseContainer) inventorySlots).setTargetStack(aeStack);
FluidCraft.proxy.netHandler.sendToServer(new CPacketInventoryAction(action, slotIdx, 0, aeStack));
}
return true;
@@ -1,20 +1,15 @@
package com.glodblock.github.client.gui.container;
import java.util.Objects;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.AeItemStackHandler;
import com.glodblock.github.inventory.slot.SlotFluidConvertingFake;
import com.glodblock.github.util.Util;
import com.glodblock.github.network.SPacketLevelMaintainerGuiUpdate;
import appeng.api.config.SecurityPermissions;
import appeng.container.AEBaseContainer;
@@ -26,6 +21,10 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
private final TileLevelMaintainer tile;
private final SlotFluidConvertingFake[] requestSlots = new SlotFluidConvertingFake[TileLevelMaintainer.REQ_COUNT];
private static final int UPDATE_INTERVAL = 20;
private boolean isFirstUpdate = true;
private int updateCount = UPDATE_INTERVAL;
public ContainerLevelMaintainer(InventoryPlayer ipl, TileLevelMaintainer tile) {
super(ipl, tile);
this.tile = tile;
@@ -48,49 +47,14 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
@Override
public void doAction(EntityPlayerMP player, InventoryAction action, int slotId, long id) {
Slot slot = getSlot(slotId);
if (slot instanceof SlotFluidConvertingFake) {
if (getSlot(slotId) instanceof SlotFluidConvertingFake slot) {
final ItemStack stack = player.inventory.getItemStack();
switch (action) {
case PICKUP_OR_SET_DOWN -> {
case PICKUP_OR_SET_DOWN, PLACE_SINGLE, SPLIT_OR_PLACE_SINGLE -> {
if (stack == null) {
slot.putStack(null);
} else {
((SlotFluidConvertingFake) slot).putConvertedStack(createLevelValues(stack.copy()));
}
}
case PLACE_SINGLE -> {
if (stack != null) {
((SlotFluidConvertingFake) slot).putConvertedStack(
createLevelValues(Objects.requireNonNull(Util.copyStackWithSize(stack, 1))));
}
}
case SPLIT_OR_PLACE_SINGLE -> {
ItemStack inSlot = slot.getStack();
if (inSlot != null) {
if (stack == null) {
slot.putStack(
createLevelValues(
Objects.requireNonNull(
Util.copyStackWithSize(
inSlot,
Math.max(1, inSlot.stackSize - 1)))));
} else if (stack.isItemEqual(inSlot)) {
slot.putStack(
createLevelValues(
Objects.requireNonNull(
Util.copyStackWithSize(
inSlot,
Math.min(
inSlot.getMaxStackSize(),
inSlot.stackSize + 1)))));
} else {
((SlotFluidConvertingFake) slot).putConvertedStack(
createLevelValues(Objects.requireNonNull(Util.copyStackWithSize(stack, 1))));
}
} else if (stack != null) {
((SlotFluidConvertingFake) slot).putConvertedStack(
createLevelValues(Objects.requireNonNull(Util.copyStackWithSize(stack, 1))));
slot.putConvertedStack(stack);
}
}
default -> {}
@@ -109,10 +73,8 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
for (int i = 0; i < this.getRequestSlots().length; i++) {
SlotFluidConvertingFake slot = this.getRequestSlots()[i];
if (!slot.getHasStack()) {
ItemStack itemStack = ((Slot) this.inventorySlots.get(idx)).getStack();
ItemStack configuration = createLevelValues(itemStack.copy());
configuration.getTagCompound().setInteger(TLMTags.Index.tagName, i);
slot.putConvertedStack(configuration);
ItemStack itemStack = this.inventorySlots.get(idx).getStack();
tile.updateStack(i, itemStack.copy());
break;
}
}
@@ -123,35 +85,23 @@ public class ContainerLevelMaintainer extends AEBaseContainer {
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
if (Platform.isClient()) {
return;
}
this.verifyPermissions(SecurityPermissions.BUILD, false);
super.detectAndSendChanges();
if (this.updateCount++ >= UPDATE_INTERVAL) {
this.updateGui();
}
}
public static ItemStack createLevelValues(ItemStack itemStack) {
var data = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
if (!data.hasKey(TLMTags.Stack.tagName)) {
var itemStackTag = new NBTTagCompound();
itemStack.copy().writeToNBT(itemStackTag);
data.setTag(TLMTags.Stack.tagName, itemStackTag);
}
if (!data.hasKey(TLMTags.Quantity.tagName)) {
data.setLong(TLMTags.Quantity.tagName, itemStack.stackSize > 0 ? itemStack.stackSize : 1);
}
if (!data.hasKey(TLMTags.Batch.tagName)) {
data.setLong(TLMTags.Batch.tagName, 1);
}
if (!data.hasKey(TLMTags.Enable.tagName)) {
data.setBoolean(TLMTags.Enable.tagName, false);
}
if (data.hasKey(TLMTags.Index.tagName)) {
data.removeTag(TLMTags.Index.tagName);
}
data.setInteger(TLMTags.State.tagName, State.None.ordinal());
itemStack.setTagCompound(data);
return itemStack;
public void updateGui() {
FluidCraft.proxy.netHandler.sendTo(
new SPacketLevelMaintainerGuiUpdate(this.tile.requests, !this.isFirstUpdate),
(EntityPlayerMP) this.getInventoryPlayer().player);
this.isFirstUpdate = false;
this.updateCount = 0;
}
}
@@ -1,30 +1,27 @@
package com.glodblock.github.client.gui.container;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.Nullable;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.client.gui.container.base.FCBaseContainer;
import com.glodblock.github.common.parts.PartLevelTerminal;
import com.glodblock.github.coremod.registries.LevelTerminalRegistry;
import com.glodblock.github.inventory.item.IWirelessTerminal;
import com.glodblock.github.network.SPacketLevelTerminalUpdate;
import com.google.common.primitives.Ints;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
@@ -32,12 +29,7 @@ import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.api.storage.ITerminalHost;
import appeng.api.util.DimensionalCoord;
import appeng.helpers.InventoryAction;
import appeng.items.misc.ItemEncodedPattern;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.AdaptorPlayerHand;
import appeng.util.inv.ItemSlot;
public class ContainerLevelTerminal extends FCBaseContainer {
@@ -50,8 +42,8 @@ public class ContainerLevelTerminal extends FCBaseContainer {
private final Map<Long, ContainerLevelTerminal.InvTracker> trackedById = new HashMap<>();
private IGrid grid;
private SPacketLevelTerminalUpdate dirty;
private boolean isDirty;
private SPacketLevelTerminalUpdate updatePacket;
private boolean isPacketDirty;
private boolean wasOff;
private int ticks = 0;
@@ -63,11 +55,13 @@ public class ContainerLevelTerminal extends FCBaseContainer {
} else if (monitorable instanceof IWirelessTerminal wirelessTerminal) {
grid = wirelessTerminal.getActionableNode().getGrid();
}
dirty = this.updateList();
if (dirty != null) {
this.isDirty = true;
updatePacket = this.updateList();
if (updatePacket != null) {
this.isPacketDirty = true;
} else {
dirty = new SPacketLevelTerminalUpdate();
updatePacket = new SPacketLevelTerminalUpdate();
this.isPacketDirty = false;
}
}
@@ -92,7 +86,7 @@ public class ContainerLevelTerminal extends FCBaseContainer {
if (!wasOff) {
SPacketLevelTerminalUpdate update = new SPacketLevelTerminalUpdate();
update.setDisconnect();
update.addDisconnectEntry();
wasOff = true;
FluidCraft.proxy.netHandler.sendTo(update, (EntityPlayerMP) this.getPlayerInv().player);
}
@@ -100,149 +94,20 @@ public class ContainerLevelTerminal extends FCBaseContainer {
}
wasOff = false;
if (isDirty) {
FluidCraft.proxy.netHandler.sendTo(dirty, (EntityPlayerMP) this.getPlayerInv().player);
dirty = new SPacketLevelTerminalUpdate();
isDirty = false;
if (isPacketDirty) {
FluidCraft.proxy.netHandler.sendTo(updatePacket, (EntityPlayerMP) this.getPlayerInv().player);
updatePacket = new SPacketLevelTerminalUpdate();
isPacketDirty = false;
} else if (++ticks % 20 == 0) {
ticks = 0;
SPacketLevelTerminalUpdate update = this.updateList();
if (update != null) {
FluidCraft.proxy.netHandler.sendTo(update, (EntityPlayerMP) this.getPlayerInv().player);
SPacketLevelTerminalUpdate updateNew = this.updateList();
if (updateNew != null) {
FluidCraft.proxy.netHandler.sendTo(updateNew, (EntityPlayerMP) this.getPlayerInv().player);
}
}
}
/**
* Merge from slot -> player inv. Returns the items not added.
*/
private ItemStack mergeToPlayerInventory(InventoryAdaptor playerInv, ItemStack stack) {
if (stack == null) return null;
for (ItemSlot slot : playerInv) {
if (Platform.isSameItemPrecise(slot.getItemStack(), stack)) {
if (slot.getItemStack().stackSize < slot.getItemStack().getMaxStackSize()) {
++slot.getItemStack().stackSize;
return null;
}
}
}
return playerInv.addItems(stack);
}
@Override
public void doAction(final EntityPlayerMP player, final InventoryAction action, final int slotIdx, final long id) {
final ContainerLevelTerminal.InvTracker invTracker = this.trackedById.get(id);
if (invTracker != null) {
final ItemStack handStack = player.inventory.getItemStack();
if (handStack != null && !(handStack.getItem() instanceof ItemEncodedPattern)) {
// Why even bother if we're not dealing with an encoded pattern in hand
return;
}
final ItemStack slotStack = invTracker.requests.getStackInSlot(slotIdx);
final InventoryAdaptor playerHand = new AdaptorPlayerHand(player);
switch (action) {
/* Set down/pickup. This is the same as SPLIT_OR_PLACE_SINGLE as our max stack sizes are 1 in slots. */
case PICKUP_OR_SET_DOWN -> {
if (handStack != null) {
for (int s = 0; s < invTracker.requests.getSizeInventory(); s++) {
/* Is there a duplicate pattern here? */
if (Platform.isSameItemPrecise(invTracker.requests.getStackInSlot(s), handStack)) {
/* We're done here - dupe found. */
return;
}
}
}
if (slotStack == null) {
/* Insert to container, if valid */
if (handStack == null) {
/* Nothing happens */
return;
}
invTracker.requests.setInventorySlotContents(slotIdx, playerHand.removeItems(1, null, null));
} else {
/* Exchange? */
if (handStack != null && handStack.stackSize > 1) {
/* Exchange is impossible, abort */
return;
}
invTracker.requests.setInventorySlotContents(slotIdx, playerHand.removeItems(1, null, null));
playerHand.addItems(slotStack.copy());
}
syncLevelTerminalSlot(invTracker, id, slotIdx, invTracker.requests.getStackInSlot(slotIdx));
}
/* Shift click from slotIdx -> player. Player -> slotIdx is not supported. */
case SHIFT_CLICK -> {
InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor(player.inventory, ForgeDirection.UNKNOWN);
ItemStack leftOver = mergeToPlayerInventory(playerInv, slotStack);
if (leftOver == null) {
invTracker.requests.setInventorySlotContents(slotIdx, null);
syncLevelTerminalSlot(invTracker, id, slotIdx, null);
}
}
/* Move all blank patterns -> player */
case MOVE_REGION -> {
final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor(player, ForgeDirection.UNKNOWN);
List<Integer> valid = new ArrayList<>();
for (int i = 0; i < invTracker.requests.getSizeInventory(); i++) {
ItemStack toExtract = invTracker.requests.getStackInSlot(i);
if (toExtract == null) {
continue;
}
ItemStack leftOver = mergeToPlayerInventory(playerInv, toExtract);
if (leftOver != null) {
break;
} else {
invTracker.requests.setInventorySlotContents(i, null);
}
valid.add(i);
}
if (!valid.isEmpty()) {
int[] validIndices = Ints.toArray(valid);
NBTTagList tag = new NBTTagList();
for (int i = 0; i < valid.size(); ++i) {
tag.appendTag(new NBTTagCompound());
}
dirty.addOverwriteEntry(id).setItems(validIndices, tag);
isDirty = true;
}
}
case CREATIVE_DUPLICATE -> {
if (player.capabilities.isCreativeMode) {
playerHand.addItems(handStack);
}
}
default -> {
return;
}
}
this.updateHeld(player);
}
}
private void syncLevelTerminalSlot(ContainerLevelTerminal.InvTracker inv, long id, int slot, ItemStack stack) {
int[] validIndices = { slot };
NBTTagList list = new NBTTagList();
NBTTagCompound item = new NBTTagCompound();
if (stack != null) {
stack.writeToNBT(item);
}
list.appendTag(item);
inv.updateNBT();
this.dirty.addOverwriteEntry(id).setItems(validIndices, list);
this.isDirty = true;
}
@Nullable
private SPacketLevelTerminalUpdate updateList() {
SPacketLevelTerminalUpdate update = null;
var supported = LevelTerminalRegistry.instance().getSupportedClasses();
@@ -257,64 +122,67 @@ public class ContainerLevelTerminal extends FCBaseContainer {
final ILevelViewable machine = isAdopted
? LevelTerminalRegistry.instance().getAdapter(clz).adapt(gridHost)
: (ILevelViewable) gridHost;
visited.add(gridHost);
/* First check if we are already tracking this node */
if (tracked.containsKey(gridHost)) {
/* Check for updates */
ContainerLevelTerminal.InvTracker knownTracker = tracked.get(gridHost);
/* Name changed? */
String name = machine.getCustomName();
if (!Objects.equals(knownTracker.name, name)) {
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addRenamedEntry(knownTracker.id, name);
knownTracker.name = name;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addRenameEntry(knownTracker.id, name);
}
/* Status changed? */
boolean isActive = gridNode.isActive() || machine.shouldDisplay();
LevelItemInfo[] prev = knownTracker.infoList;
LevelItemInfo[] curr = machine.getLevelItemInfoList();
if (prev.length == curr.length) {
for (int i = 0; i < prev.length; i++) {
if (prev[i] == null && curr[i] == null) continue;
if (!knownTracker.online && isActive) {
/* Node offline -> online */
knownTracker.online = true;
if (update == null) update = new SPacketLevelTerminalUpdate();
knownTracker.updateNBT();
update.addOverwriteEntry(knownTracker.id).setOnline(true)
.setItems(knownTracker.requests.getSizeInventory(), knownTracker.inventoryNbt);
} else if (knownTracker.online && !isActive) {
/* Node online -> offline */
knownTracker.online = false;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteEntry(knownTracker.id).setOnline(false);
}
for (int i = 0; i < knownTracker.requests.getSizeInventory(); i++) {
ItemStack knowmItemStack = ItemStack
.loadItemStackFromNBT(knownTracker.inventoryNbt.getCompoundTagAt(i));
ItemStack machineItemStack = machine.getInventoryByName("config").getStackInSlot(i);
if (isDifferent(knowmItemStack, machineItemStack)) {
if (update == null) update = new SPacketLevelTerminalUpdate();
knownTracker.updateNBT();
update.addOverwriteEntry(knownTracker.id)
.setItems(knownTracker.requests.getSizeInventory(), knownTracker.inventoryNbt);
if (prev[i] == null) {
knownTracker.infoList[i] = curr[i];
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteSlotEntry(knownTracker.id, i, curr[i]);
} else if (curr[i] == null) {
knownTracker.infoList[i] = null;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteSlotEntry(knownTracker.id, i, null);
} else if (!ItemStack.areItemStacksEqual(prev[i].stack, curr[i].stack)
|| prev[i].quantity == curr[i].quantity
|| prev[i].batchSize == curr[i].batchSize
|| prev[i].state == curr[i].state) {
knownTracker.infoList[i] = curr[i];
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteSlotEntry(knownTracker.id, i, curr[i]);
}
}
} else {
knownTracker.infoList = curr;
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addOverwriteAllSlotEntry(knownTracker.id, curr);
}
} else {
/* Add a new entry */
if (update == null) update = new SPacketLevelTerminalUpdate();
ContainerLevelTerminal.InvTracker entry = new ContainerLevelTerminal.InvTracker(
nextId++,
machine,
gridNode.isActive());
update.addNewEntry(entry.id, entry.name, entry.online)
.setLocation(entry.x, entry.y, entry.z, entry.dim, entry.side.ordinal())
.setItems(entry.rows, entry.rowSize, entry.inventoryNbt)
.setViewItemStack(machine.getSelfItemStack(), machine.getDisplayItemStack());
ContainerLevelTerminal.InvTracker entry = new ContainerLevelTerminal.InvTracker(nextId++, machine);
update.addNewEntry(
entry.id,
entry.x,
entry.y,
entry.z,
entry.dim,
entry.side.ordinal(),
entry.rows,
entry.rowSize,
entry.name,
entry.infoList);
tracked.put(gridHost, entry);
trackedById.put(entry.id, entry);
}
visited.add(gridHost);
}
}
@@ -327,10 +195,9 @@ public class ContainerLevelTerminal extends FCBaseContainer {
}
if (update == null) update = new SPacketLevelTerminalUpdate();
update.addRemoveEntry(entry.getValue().id);
trackedById.remove(entry.getValue().id);
it.remove();
update.addRemovalEntry(entry.getValue().id);
}
return update;
}
@@ -340,23 +207,10 @@ public class ContainerLevelTerminal extends FCBaseContainer {
return false;
}
private boolean isDifferent(final ItemStack a, final ItemStack b) {
if (a == null && b == null) {
return false;
}
if (a == null || b == null) {
return true;
}
return !ItemStack.areItemStacksEqual(a, b);
}
private static class InvTracker {
private final long id;
private String name;
private final IInventory requests;
private final int rowSize;
private final int rows;
private final int x;
@@ -364,16 +218,15 @@ public class ContainerLevelTerminal extends FCBaseContainer {
private final int z;
private final int dim;
private final ForgeDirection side;
private boolean online;
private NBTTagList inventoryNbt;
public InvTracker(long id, ILevelViewable machine, boolean online) {
private LevelItemInfo[] infoList;
public InvTracker(long id, ILevelViewable machine) {
DimensionalCoord location = machine.getLocation();
this.id = id;
this.name = machine.getCustomName();
this.requests = machine.getInventoryByName("config");
this.rowSize = machine.rowSize();
this.rows = machine.rows();
this.x = location.x;
@@ -381,26 +234,8 @@ public class ContainerLevelTerminal extends FCBaseContainer {
this.z = location.z;
this.dim = location.getDimension();
this.side = machine.getSide();
this.online = online;
this.inventoryNbt = new NBTTagList();
updateNBT();
this.infoList = machine.getLevelItemInfoList();
}
private void updateNBT() {
this.inventoryNbt = new NBTTagList();
for (int i = 0; i < this.rows; ++i) {
for (int j = 0; j < this.rowSize; ++j) {
final int offset = this.rowSize * i;
ItemStack stack = this.requests.getStackInSlot(offset + j);
if (stack != null) {
this.inventoryNbt.appendTag(stack.writeToNBT(new NBTTagCompound()));
} else {
this.inventoryNbt.appendTag(new NBTTagCompound());
}
}
}
}
}
}
@@ -18,6 +18,8 @@ import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
@@ -586,4 +588,15 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
return super.getInventoryByName(name);
}
@Override
public LevelItemInfo[] getLevelItemInfoList() {
ItemStack stack = this.config.getStackInSlot(0);
if (stack == null) return new LevelItemInfo[] { null };
return new LevelItemInfo[] { new LevelItemInfo(
stack,
this.getReportingValue(),
-1,
this.isProvidingStrongPower() > 0 ? LevelState.Craft : LevelState.Idle) };
}
}
@@ -1,23 +1,30 @@
package com.glodblock.github.common.tile;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
import java.util.concurrent.Future;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.common.Config;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.crossmod.thaumcraft.ThaumicEnergisticsCrafting;
import com.glodblock.github.inventory.AeItemStackHandler;
import com.glodblock.github.inventory.AeStackInventory;
import com.glodblock.github.inventory.AeStackInventoryImpl;
import com.glodblock.github.util.ModAndClassUtil;
import com.google.common.collect.ImmutableSet;
@@ -42,19 +49,16 @@ import appeng.api.networking.security.MachineSource;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.core.AELog;
import appeng.helpers.NonNullArrayIterator;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import io.netty.buffer.ByteBuf;
@@ -62,10 +66,19 @@ public class TileLevelMaintainer extends AENetworkTile
implements IAEAppEngInventory, IGridTickable, ICraftingRequester, IPowerChannelState, ILevelViewable {
public static final int REQ_COUNT = 5;
public final InventoryRequest requests = new InventoryRequest(this);
public static final String NBT_REQUESTS = "Requests";
public static final String NBT_STACK = "stack";
public static final String NBT_QUANTITY = "quantity";
public static final String NBT_BATCH = "batch";
public static final String NBT_ENABLE = "enable";
public static final String NBT_STATE = "state";
public static final String NBT_LINK = "link";
public final RequestInfo[] requests = new RequestInfo[REQ_COUNT];
private final LevelMaintainerInventory inventory = new LevelMaintainerInventory(requests, this);
private int firstRequest = 0;
private final BaseActionSource source;
private final IInventory inv = new AeItemStackHandler(requests.requestStacks);
private final IInventory inv = new AeItemStackHandler(inventory);
private boolean isPowered = false;
public TileLevelMaintainer() {
@@ -75,17 +88,23 @@ public class TileLevelMaintainer extends AENetworkTile
}
public AeStackInventory<IAEItemStack> getRequestSlots() {
return requests.requestStacks;
return inventory;
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return ImmutableSet.copyOf(new NonNullArrayIterator<>(requests.links));
return ImmutableSet.copyOf(
Arrays.stream(this.requests).filter(Objects::nonNull).map(info -> info.link).filter(Objects::nonNull)
.iterator());
}
@Override
public IAEItemStack injectCraftedItems(ICraftingLink link, IAEItemStack items, Actionable mode) {
int idx = requests.getIdxByLink(link);
int idx = this.getRequestIndexByLink(link);
if (idx == -1) {
AELog.warn("Invalid crafting link: " + link);
return items;
} ;
try {
if (getProxy().isActive()) {
final IEnergyGrid energy = getProxy().getEnergy();
@@ -97,7 +116,7 @@ public class TileLevelMaintainer extends AENetworkTile
.injectItems(ItemFluidDrop.getAeFluidStack(items), mode, source);
if (notInjectedItems != null) {
items.setStackSize(notInjectedItems.getStackSize());
requests.updateState(idx, State.Export);
this.updateState(idx, LevelState.Export);
return items;
} else {
@@ -117,10 +136,9 @@ public class TileLevelMaintainer extends AENetworkTile
@Override
public void jobStateChange(ICraftingLink link) {
for (int x = 0; x < REQ_COUNT; x++) {
if (requests.getLink(x) == link) {
requests.updateLink(x, link);
return;
for (int i = 0; i < REQ_COUNT; i++) {
if (requests[i] != null && requests[i].link == link) {
this.updateLink(i, null);
}
}
}
@@ -164,92 +182,107 @@ public class TileLevelMaintainer extends AENetworkTile
for (int j = 0; j < REQ_COUNT; ++j) {
int i = (firstRequest + j) % REQ_COUNT;
if (requests[i] == null) continue;
long quantity = requests.getQuantity(i);
long batchSize = requests.getBatchSize(i);
boolean isEnable = requests.isEnable(i);
if (!isEnable || batchSize == 0) requests.updateState(i, State.None);
if (batchSize > 0) {
IAEItemStack craftItem = requests.getCraftItem(i);
final long quantity = requests[i].quantity;
final long batchSize = requests[i].batchSize;
final boolean isEnable = requests[i].enable;
if (ModAndClassUtil.ThE) {
if (craftItem != null && ThaumicEnergisticsCrafting.isAspectStack(craftItem.getItemStack())) {
craftItem = ThaumicEnergisticsCrafting.convertAspectStack(craftItem);
}
}
if (!isEnable || quantity == 0 || batchSize == 0) {
this.updateState(i, LevelState.None);
continue;
}
IAEItemStack aeItem = inv.findPrecise(craftItem);
IAEItemStack craftItem = requests[i].itemStack.copy();
craftItem.setStackSize(batchSize);
long stackSize = aeItem == null ? 0 : aeItem.getStackSize();
if (ModAndClassUtil.ThE) {
if (aeItem != null && ThaumicEnergisticsCrafting.isAspectStack(aeItem.getItemStack())) {
stackSize = ThaumicEnergisticsCrafting.getEssentiaAmount(aeItem, grid);
}
}
boolean isDone = requests.isDone(i);
boolean isCraftable = aeItem != null && aeItem.isCraftable();
boolean shouldCraft = isCraftable && stackSize < quantity;
if (isDone) requests.updateState(i, State.Idle);
if (!isCraftable) requests.updateState(i, State.Error);
if (allBusy || !isDone || !shouldCraft) {
continue;
}
if (craftingGrid.canEmitFor(craftItem)) {
continue;
}
if (craftingGrid.isRequesting(craftItem)) {
continue;
}
// do crafting
Future<ICraftingJob> jobTask = requests.getJob(i);
if (jobTask == null) {
if (itemToBegin == null) {
itemToBegin = craftItem;
itemToBeginIdx = i;
}
} else if (jobTask.isDone()) {
requests.updateState(i, State.Craft);
try {
ICraftingJob job = jobTask.get();
if (job != null) {
if (jobToSubmit == null) {
jobToSubmit = job;
jobToSubmitIdx = i;
}
} else {
requests.updateState(i, State.Error);
}
} catch (Exception ignored) {
requests.updateState(i, State.Error);
}
if (ModAndClassUtil.ThE) {
if (ThaumicEnergisticsCrafting.isAspectStack(craftItem.getItemStack())) {
craftItem = ThaumicEnergisticsCrafting.convertAspectStack(craftItem);
}
}
IAEItemStack aeItem = inv.findPrecise(craftItem);
long stackSize = aeItem == null ? 0 : aeItem.getStackSize();
if (ModAndClassUtil.ThE) {
if (aeItem != null && ThaumicEnergisticsCrafting.isAspectStack(aeItem.getItemStack())) {
stackSize = ThaumicEnergisticsCrafting.getEssentiaAmount(aeItem, grid);
}
}
boolean isDone = this.isDone(i);
boolean isCraftable = aeItem != null && aeItem.isCraftable();
boolean shouldCraft = isCraftable && stackSize < quantity;
if (isDone) {
if (this.requests[i].state != LevelState.Idle) {
this.updateState(i, LevelState.Idle);
}
if (this.requests[i].link != null) {
this.updateLink(i, null);
}
if (!isCraftable) {
updateState(i, LevelState.Error);
}
}
if (allBusy || !isDone || !shouldCraft) {
continue;
}
if (craftingGrid.canEmitFor(craftItem)) {
continue;
}
if (craftingGrid.isRequesting(craftItem)) {
continue;
}
// do crafting
Future<ICraftingJob> jobTask = requests[i].job;
if (jobTask == null) {
if (itemToBegin == null) {
itemToBegin = craftItem;
itemToBeginIdx = i;
}
} else if (jobTask.isDone()) {
this.updateState(i, LevelState.Craft);
try {
ICraftingJob job = jobTask.get();
if (job != null) {
if (jobToSubmit == null) {
jobToSubmit = job;
jobToSubmitIdx = i;
}
} else {
this.updateState(i, LevelState.Error);
}
} catch (Exception ignored) {
this.updateState(i, LevelState.Error);
}
}
}
if (jobToSubmit != null) {
// Finished calculating a request, try to submit it.
ICraftingLink link = craftingGrid.submitJob(jobToSubmit, this, null, false, source);
requests.updateJob(jobToSubmitIdx, null);
requests[jobToSubmitIdx].job = null;
if (link != null) {
requests.updateState(jobToSubmitIdx, State.Craft);
requests.updateLink(jobToSubmitIdx, link);
this.updateState(jobToSubmitIdx, LevelState.Craft);
this.updateLink(jobToSubmitIdx, link);
} else {
requests.updateState(jobToSubmitIdx, State.Error);
this.updateState(jobToSubmitIdx, LevelState.Error);
}
} else if (itemToBegin != null) {
// No jobs to submit, start calculating some item.
requests.updateJob(
itemToBeginIdx,
craftingGrid.beginCraftingJob(getWorldObj(), grid, source, itemToBegin, null));
requests.updateState(itemToBeginIdx, State.Craft);
requests[itemToBeginIdx].job = craftingGrid
.beginCraftingJob(getWorldObj(), grid, source, itemToBegin, null);
this.updateState(itemToBeginIdx, LevelState.Craft);
// Try the next item next time.
firstRequest = (firstRequest + 1) % REQ_COUNT;
@@ -284,9 +317,6 @@ public class TileLevelMaintainer extends AENetworkTile
return getProxy().isActive();
}
@Override
public void gridChanged() {}
@Override
public boolean isPowered() {
return isPowered;
@@ -297,120 +327,205 @@ public class TileLevelMaintainer extends AENetworkTile
return isPowered;
}
public InventoryRequest getRequestInventory() {
return requests;
}
public IInventory getInventory() {
return inv;
}
public IInventory getInventoryByName(String name) {
if (name == "config") return new AeItemStackHandler(requests.requestStacks);
if (Objects.equals(name, "config")) return new AeItemStackHandler(this.inventory);
return null;
}
@Override
public LevelItemInfo[] getLevelItemInfoList() {
return Arrays.stream(this.requests).map(request -> {
if (request == null) return null;
return new LevelItemInfo(
request.itemStack.getItemStack(),
request.getQuantity(),
request.getBatchSize(),
request.getState());
}).toArray(LevelItemInfo[]::new);
}
public void updateQuantity(int idx, long size) {
requests.updateQuantity(idx, size);
if (requests[idx] == null) return;
requests[idx].quantity = size > 0 ? size : 0;
this.checkState(idx);
this.saveChanges();
}
public void updateBatchSize(int idx, long size) {
requests.updateBatchSize(idx, size);
if (requests[idx] == null) return;
requests[idx].batchSize = size > 0 ? size : 0;
this.checkState(idx);
this.saveChanges();
}
public void updateStatus(int idx, boolean enable) {
requests.updateStatus(idx, enable);
if (requests[idx] == null) return;
requests[idx].enable = enable;
this.checkState(idx);
this.saveChanges();
}
/**
* @deprecated
*/
@Deprecated
private void readLinkFromNBT__old(NBTTagCompound data) {
try {
for (int i = 0; i < REQ_COUNT; i++) {
final NBTTagCompound link = data.getCompoundTag("links-" + i);
if (link != null && link.hasNoTags()) {
requests.updateLink(i, null);
} else {
requests.updateLink(i, AEApi.instance().storage().loadCraftingLink(link, this));
if (!requests.isDone(i)) requests.updateState(i, State.Craft);
}
private void updateState(int idx, @NotNull LevelState state) {
if (requests[idx] == null) return;
requests[idx].state = state;
this.saveChanges();
}
public void updateStack(int idx, @Nullable ItemStack stack) {
if (stack == null) {
requests[idx] = null;
} else {
stack = this.removeRecursion(stack);
requests[idx] = new RequestInfo(stack, this);
}
this.saveChanges();
}
private void updateLink(int idx, @Nullable ICraftingLink link) {
if (requests[idx] == null) return;
requests[idx].link = link;
this.saveChanges();
}
private void checkState(int idx) {
if (!requests[idx].enable || requests[idx].quantity == 0 || requests[idx].batchSize == 0) {
this.updateState(idx, LevelState.None);
} else if (!this.isDone(idx)) {
this.updateState(idx, LevelState.Craft);
} else {
this.updateState(idx, LevelState.Idle);
}
}
public boolean isDone(int i) {
if (requests[i] == null) {
return true;
}
ICraftingLink link = requests[i].link;
return link == null || link.isDone() || link.isCanceled();
}
private int getRequestIndexByLink(ICraftingLink link) {
for (int i = 0; i < REQ_COUNT; i++) {
if (requests[i] != null && requests[i].link == link) {
return i;
}
} catch (Exception ignore) {}
}
return -1;
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public void writeToNBTEvent(NBTTagCompound data) {
requests.requestStacks.writeToNbt(data, TLMTags.RequestStacks.tagName);
NBTTagList tagList = new NBTTagList();
for (int i = 0; i < REQ_COUNT; i++) {
if (this.requests[i] != null) {
tagList.appendTag(this.requests[i].writeToNBT());
} else {
tagList.appendTag(new NBTTagCompound());
}
}
data.setTag(NBT_REQUESTS, tagList);
}
@TileEvent(TileEventType.WORLD_NBT_READ)
public void readFromNBTEvent(NBTTagCompound data) {
if (data.hasKey(TLMTags.RequestStacks.tagName)) {
requests.requestStacks.readFromNbt(data, TLMTags.RequestStacks.tagName);
if (Platform.isServer()) {
for (int i = 0; i < REQ_COUNT; i++) {
if (requests.requestStacks.getStack(i) != null) {
ItemStack storageStack = requests.requestStacks.getStack(i).getItemStack();
ItemStack itemStack = loadItemStackFromTag(storageStack);
ItemStack craftStack = removeRecursion(storageStack);
if (!ItemStack.areItemStacksEqual(itemStack, craftStack)) {
requests.updateStack(i, craftStack);
AELog.info(
"[TileLevelMaintainer] Replace craft stack from: " + itemStack.toString()
+ ":"
+ (itemStack.hasTagCompound() ? itemStack.getTagCompound() : "{no tags}")
+ "; with: "
+ craftStack
+ ":"
+ (craftStack.hasTagCompound() ? craftStack.getTagCompound()
: "{no tags}"));
}
if (data.hasKey(NBT_REQUESTS)) {
NBTTagList tagList = data.getTagList(NBT_REQUESTS, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.tagCount(); i++) {
NBTTagCompound tag = tagList.getCompoundTagAt(i);
if (tag == null || !tag.hasKey(NBT_STACK)) {
this.requests[i] = null;
} else if (this.requests[i] == null) {
try {
this.requests[i] = new RequestInfo(tag, this);
} catch (Exception ignored) {
this.requests[i] = null;
}
} else {
this.requests[i].loadFromNBT(tag);
}
}
} else if (data.hasKey("RequestStacks")) {
// Migration from old NBT
NBTTagList stacksTag = data.getCompoundTag("RequestStacks")
.getTagList("Contents", Constants.NBT.TAG_COMPOUND);
IAEItemStack[] stacks = new IAEItemStack[REQ_COUNT];
for (int i = 0; i < REQ_COUNT; i++) {
NBTTagCompound stackTag = stacksTag.getCompoundTagAt(i);
if (stackTag == null) continue;
stacks[i] = AEItemStack.loadItemStackFromNBT(stackTag);
if (stacks[i] == null) continue;
ItemStack itemstack = stacks[i].getItemStack();
if (!itemstack.hasTagCompound()) continue;
NBTTagCompound itemTag = itemstack.getTagCompound();
ItemStack craftStack = ItemStack.loadItemStackFromNBT(itemTag.getCompoundTag("Stack"));
craftStack = removeRecursion(craftStack);
if (craftStack == null) continue;
requests[i] = new RequestInfo(craftStack, this);
if (itemTag.hasKey("Enable")) {
requests[i].enable = itemTag.getBoolean("Enable");
}
if (itemTag.hasKey("Quantity")) {
requests[i].quantity = itemTag.getLong("Quantity");
}
if (itemTag.hasKey("Batch")) {
requests[i].batchSize = itemTag.getLong("Batch");
}
}
} else {
// Migration from old data storage
// Migration from old old data storage
long[] batches = new long[REQ_COUNT];
long[] quantyties = new long[REQ_COUNT];
requests.requestStacks.readFromNbt(data, "Batch");
ItemStack[] stacks = new ItemStack[REQ_COUNT];
NBTTagList batchTag = data.getCompoundTag("Batch").getTagList("Contents", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < REQ_COUNT; i++) {
IAEItemStack batchStack = requests.requestStacks.getStack(i);
batches[i] = batchStack != null ? batchStack.getStackSize() : 0;
NBTTagCompound stackTag = batchTag.getCompoundTagAt(i);
IAEItemStack stack = AEItemStack.loadItemStackFromNBT(stackTag);
batches[i] = stack != null ? stack.getStackSize() : 0;
}
requests.requestStacks.readFromNbt(data, "Count");
NBTTagList quantityTag = data.getCompoundTag("Count").getTagList("Contents", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < REQ_COUNT; i++) {
IAEItemStack quantityStack = requests.requestStacks.getStack(i);
quantyties[i] = quantityStack != null ? quantityStack.getStackSize() : 0;
NBTTagCompound stackTag = quantityTag.getCompoundTagAt(i);
IAEItemStack stack = AEItemStack.loadItemStackFromNBT(stackTag);
quantyties[i] = stack != null ? stack.getStackSize() : 0;
}
requests.requestStacks.readFromNbt(data, "Inventory");
NBTTagList inventoryTag = data.getCompoundTag("Count").getTagList("Contents", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < REQ_COUNT; i++) {
IAEItemStack requestsStack = requests.requestStacks.getStack(i);
if (requestsStack != null) {
requests.updateStack(i, requestsStack.getItemStack());
requests.updateBatchSize(i, batches[i]);
requests.updateQuantity(i, quantyties[i]);
}
NBTTagCompound stackTag = inventoryTag.getCompoundTagAt(i);
IAEItemStack stack = AEItemStack.loadItemStackFromNBT(stackTag);
stacks[i] = stack != null ? stack.getItemStack() : null;
}
for (int i = 0; i < REQ_COUNT; i++) {
if (stacks[i] == null) continue;
this.requests[i] = new RequestInfo(stacks[i], this);
this.requests[i].batchSize = batches[i];
this.requests[i].quantity = quantyties[i];
}
readLinkFromNBT__old(data);
}
}
// Remove old format NBT data from ItemStack
private ItemStack removeRecursion(ItemStack itemStack) {
if (itemStack != null && itemStack.hasTagCompound()
&& itemStack.getTagCompound().hasKey(TLMTags.Stack.tagName)) {
return removeRecursion(loadItemStackFromTag(itemStack));
if (itemStack == null || !itemStack.hasTagCompound()) return itemStack;
NBTTagCompound tag = itemStack.getTagCompound();
if (tag.hasKey("Stack") && tag.hasKey("Quantity")) {
return removeRecursion(ItemStack.loadItemStackFromNBT(itemStack.getTagCompound().getCompoundTag("Stack")));
}
return itemStack;
}
@Nullable
private static ItemStack loadItemStackFromTag(ItemStack itemStack) {
return ItemStack.loadItemStackFromNBT(itemStack.getTagCompound().getCompoundTag(TLMTags.Stack.tagName));
}
@TileEvent(TileEventType.NETWORK_READ)
public boolean readFromStream(final ByteBuf data) {
final boolean oldPower = isPowered;
@@ -449,7 +564,7 @@ public class TileLevelMaintainer extends AENetworkTile
}
@Override
public TileEntity getTile() {
public @NotNull TileEntity getTile() {
return this;
}
@@ -463,209 +578,140 @@ public class TileLevelMaintainer extends AENetworkTile
return REQ_COUNT;
}
@Override
public ItemStack getSelfItemStack() {
return getItemFromTile(this);
}
public static class RequestInfo {
public enum State {
None,
Idle,
Craft,
Export,
Error
}
private final TileLevelMaintainer tile;
private @NotNull IAEItemStack itemStack;
private long quantity;
private long batchSize;
private boolean enable;
private LevelState state;
@Nullable
private Future<ICraftingJob> job;
@Nullable
private ICraftingLink link;
public enum TLMTags {
RequestStacks("RequestStacks"),
Enable("Enable"),
Quantity("Quantity"),
Batch("Batch"),
Link("Link"),
State("State"),
Index("Index"),
Stack("Stack");
public final String tagName;
TLMTags(String tagName) {
this.tagName = tagName;
}
}
public static final class InventoryRequest {
private final AeStackInventoryImpl<IAEItemStack> requestStacks;
private final Future<ICraftingJob>[] jobs;
private final ICraftingLink[] links;
private final State[] state = new State[REQ_COUNT];
@SuppressWarnings("unchecked")
public InventoryRequest(TileLevelMaintainer tile) {
requestStacks = new AeStackInventoryImpl<>(StorageChannel.ITEMS, REQ_COUNT, tile);
jobs = new Future[REQ_COUNT];
links = new ICraftingLink[REQ_COUNT];
public RequestInfo(@NotNull ItemStack stack, TileLevelMaintainer tile) {
this.tile = tile;
itemStack = AEItemStack.create(stack);
quantity = 0;
batchSize = 0;
enable = false;
state = LevelState.None;
link = null;
job = null;
}
public State getState(int idx) {
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) {
return State.None;
} else {
return state[idx] == null ? State.Idle : state[idx];
public RequestInfo(NBTTagCompound tag, TileLevelMaintainer tile) throws IllegalArgumentException {
this.tile = tile;
itemStack = AEItemStack.loadItemStackFromNBT(tag.getCompoundTag(NBT_STACK));
if (itemStack == null) {
throw new IllegalArgumentException("ItemStack cannot be null!");
}
}
public int getIdxByLink(ICraftingLink link) {
for (int i = 0; i < REQ_COUNT; i++) {
if (links[i] == link) {
return i;
quantity = tag.getLong(NBT_QUANTITY);
batchSize = tag.getLong(NBT_BATCH);
enable = tag.getBoolean(NBT_ENABLE);
state = LevelState.values()[tag.getInteger(NBT_STATE)];
if (tag.hasKey(NBT_LINK)) {
try {
this.link = AEApi.instance().storage().loadCraftingLink(tag.getCompoundTag(NBT_LINK), this.tile);
} catch (Exception ignored) {
this.link = null;
}
}
return 0;
job = null;
}
public boolean isEnable(int idx) {
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) {
return true;
public void loadFromNBT(NBTTagCompound tag) {
itemStack = AEItemStack.loadItemStackFromNBT(tag.getCompoundTag(NBT_STACK));
quantity = tag.getLong(NBT_QUANTITY);
batchSize = tag.getLong(NBT_BATCH);
enable = tag.getBoolean(NBT_ENABLE);
state = LevelState.values()[tag.getInteger(NBT_STATE)];
if (tag.hasKey(NBT_LINK)) {
try {
this.link = AEApi.instance().storage().loadCraftingLink(tag.getCompoundTag(NBT_LINK), this.tile);
} catch (Exception ignored) {
this.link = null;
}
}
ItemStack is = ias.getItemStack();
return is.hasTagCompound() ? is.getTagCompound().getBoolean(TLMTags.Enable.tagName) : true;
}
public boolean isDone(int index) {
if (links[index] == null) {
return true;
public NBTTagCompound writeToNBT() {
NBTTagCompound tag = new NBTTagCompound();
NBTTagCompound stackTag = new NBTTagCompound();
itemStack.writeToNBT(stackTag);
tag.setTag(NBT_STACK, stackTag);
tag.setLong(NBT_QUANTITY, quantity);
tag.setLong(NBT_BATCH, batchSize);
tag.setBoolean(NBT_ENABLE, enable);
tag.setInteger(NBT_STATE, state.ordinal());
if (this.link != null) {
NBTTagCompound linkTag = new NBTTagCompound();
this.link.writeToNBT(linkTag);
tag.setTag(NBT_LINK, linkTag);
}
return links[index].isDone() || links[index].isCanceled();
return tag;
}
public Future<ICraftingJob> getJob(int idx) {
return jobs[idx];
public IAEItemStack getAEItemStack() {
return this.itemStack;
}
public ICraftingLink getLink(int idx) {
return links[idx];
public long getQuantity() {
return quantity;
}
public void updateJob(int idx, Future<ICraftingJob> job) {
jobs[idx] = job;
public long getBatchSize() {
return batchSize;
}
private void updateField(int idx, UnaryOperator<NBTTagCompound> updater) {
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) return;
ItemStack itemStack = ias.getItemStack();
NBTTagCompound data = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
data.setInteger(TLMTags.Index.tagName, idx);
itemStack.setTagCompound(updater.apply(data));
IAEItemStack newRequestStack = AEItemStack.create(itemStack);
newRequestStack.setStackSize(ias.getStackSize());
requestStacks.setStack(idx, newRequestStack);
public boolean isEnable() {
return enable;
}
public void updateLink(int idx, ICraftingLink link) {
links[idx] = link;
public LevelState getState() {
return state;
}
}
updateField(idx, data -> {
NBTTagCompound linkData = new NBTTagCompound();
if (link != null) link.writeToNBT(linkData);
data.setTag(TLMTags.Link.tagName, linkData);
private static class LevelMaintainerInventory implements AeStackInventory<IAEItemStack> {
return data;
});
private final RequestInfo[] requests;
private final TileLevelMaintainer tile;
private LevelMaintainerInventory(RequestInfo[] requests, TileLevelMaintainer tile) {
this.requests = requests;
this.tile = tile;
}
public void updateState(int idx, State nextState) {
state[idx] = nextState;
updateField(idx, data -> {
data.setInteger(TLMTags.State.tagName, nextState.ordinal());
return data;
});
@Override
public @NotNull Iterator<IAEItemStack> iterator() {
return Arrays.stream(requests).map(info -> info != null ? info.itemStack : null).iterator();
}
public void updateStatus(int idx, boolean enable) {
updateField(idx, data -> {
State nextState = enable ? State.Idle : State.None;
data.setBoolean(TLMTags.Enable.tagName, enable);
data.setInteger(TLMTags.State.tagName, nextState.ordinal());
return data;
});
@Override
public int getSlotCount() {
return requests.length;
}
public void updateQuantity(int idx, long quantity) {
updateField(idx, data -> {
data.setLong(TLMTags.Quantity.tagName, quantity);
return data;
});
@Override
public @Nullable IAEItemStack getStack(int slot) {
return requests[slot] != null ? requests[slot].itemStack : null;
}
public void updateBatchSize(int idx, long batch) {
updateField(idx, data -> {
data.setLong(TLMTags.Batch.tagName, batch);
data.setBoolean(TLMTags.Enable.tagName, true);
return data;
});
@Override
public void setStack(int slot, @Nullable IAEItemStack stack) {
if (stack == null) {
this.tile.updateStack(slot, null);
} else {
this.tile.updateStack(slot, stack.getItemStack());
}
}
public void updateStack(int idx, ItemStack itemStack) {
updateField(idx, data -> {
NBTTagCompound stackData = new NBTTagCompound();
if (itemStack != null) itemStack.writeToNBT(stackData);
data.setTag(TLMTags.Stack.tagName, stackData);
return data;
});
}
public IAEItemStack getAEItemStack(int idx) {
return requestStacks.getStack(idx);
}
public ItemStack getItemStack(int idx) {
return requestStacks.getStack(idx).getItemStack();
}
public long getQuantity(int idx) {
if (!isEnable(idx)) return 0;
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) return 0;
ItemStack itemStack = ias.getItemStack();
if (!itemStack.hasTagCompound()) return 0;
return itemStack.getTagCompound().getLong(TLMTags.Quantity.tagName);
}
public long getBatchSize(int idx) {
if (!isEnable(idx)) return 0;
IAEItemStack ias = requestStacks.getStack(idx);
if (ias == null) return 0;
ItemStack itemStack = ias.getItemStack();
if (!itemStack.hasTagCompound()) return 0;
return itemStack.getTagCompound().getLong(TLMTags.Batch.tagName);
}
public IAEItemStack getCraftItem(int idx) {
IAEItemStack is = requestStacks.getStack(idx);
if (is == null) return null;
if (is.getItemStack() == null) return null;
ItemStack qis = loadItemStackFromTag(is.getItemStack());
if (qis == null) return null;
IAEItemStack qais = AEItemStack.create(qis);
qais.setStackSize(getBatchSize(idx));
return qais;
@Override
public Stream<IAEItemStack> stream() {
return Arrays.stream(requests).map(info -> info != null ? info.itemStack : null);
}
}
}
@@ -1,7 +1,5 @@
package com.glodblock.github.coremod.registries.adapters;
import static com.glodblock.github.coremod.registries.adapters.PartLevelEmitterAdapter.getPatchedInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@@ -9,8 +7,9 @@ import net.minecraftforge.common.util.ForgeDirection;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.ILevelViewableAdapter;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.common.parts.PartFluidLevelEmitter;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
@@ -45,10 +44,7 @@ public class PartFluidLevelEmitterAdapter implements ILevelViewable, ILevelViewa
@Override
public IInventory getInventoryByName(String name) {
long value = delegate.getReportingValue();
State state = delegate.isProvidingStrongPower() > 0 ? State.Craft : State.Idle;
return getPatchedInventory(delegate.getInventoryByName(name), value, state);
return delegate.getInventoryByName(name);
}
@Override
@@ -82,7 +78,13 @@ public class PartFluidLevelEmitterAdapter implements ILevelViewable, ILevelViewa
}
@Override
public ItemStack getSelfItemStack() {
return delegate.getItemStack();
public LevelItemInfo[] getLevelItemInfoList() {
ItemStack stack = delegate.getInventoryByName("config").getStackInSlot(0);
if (stack == null) return new LevelItemInfo[] { null };
return new LevelItemInfo[] { new LevelItemInfo(
stack,
delegate.getReportingValue(),
-1,
delegate.isProvidingStrongPower() > 0 ? LevelState.Craft : LevelState.Idle) };
}
}
@@ -2,34 +2,24 @@ package com.glodblock.github.coremod.registries.adapters;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.NotNull;
import com.glodblock.github.api.registries.ILevelViewable;
import com.glodblock.github.api.registries.ILevelViewableAdapter;
import com.glodblock.github.common.tile.TileLevelMaintainer.State;
import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags;
import com.glodblock.github.inventory.AeItemStackHandler;
import com.glodblock.github.inventory.AeStackInventoryImpl;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.DimensionalCoord;
import appeng.parts.automation.PartLevelEmitter;
import appeng.util.item.AEItemStack;
public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAdapter {
private PartLevelEmitter delegate;
private static final int SLOT_IN = 0;
public PartLevelEmitterAdapter() {}
public ILevelViewable adapt(IGridHost gridHost) {
@@ -37,21 +27,6 @@ public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAd
return this;
}
@NotNull
static public IInventory getPatchedInventory(IInventory inventory, long quantity, State state) {
ItemStack itemStack = inventory.getStackInSlot(SLOT_IN);
if (itemStack == null) return inventory;
NBTTagCompound data = !itemStack.hasTagCompound() ? new NBTTagCompound() : itemStack.getTagCompound();
data.setLong(TLMTags.Quantity.tagName, quantity);
data.setInteger(TLMTags.State.tagName, state.ordinal());
itemStack.setTagCompound(data);
AeStackInventoryImpl<IAEItemStack> inv = new AeStackInventoryImpl<>(StorageChannel.ITEMS, 1);
inv.setStack(SLOT_IN, AEItemStack.create(itemStack));
return new AeItemStackHandler(inv);
}
@Override
public DimensionalCoord getLocation() {
return delegate.getLocation();
@@ -64,10 +39,7 @@ public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAd
@Override
public IInventory getInventoryByName(String name) {
long value = delegate.getReportingValue();
State state = delegate.isProvidingStrongPower() > 0 ? State.Craft : State.Idle;
return getPatchedInventory(delegate.getInventoryByName(name), value, state);
return delegate.getInventoryByName(name);
}
@Override
@@ -106,12 +78,13 @@ public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAd
}
@Override
public ItemStack getSelfItemStack() {
return delegate.getItemStack();
}
@Override
public ItemStack getDisplayItemStack() {
return delegate.getCrafterIcon();
public LevelItemInfo[] getLevelItemInfoList() {
ItemStack stack = delegate.getInventoryByName("config").getStackInSlot(0);
if (stack == null) return new LevelItemInfo[] { null };
return new LevelItemInfo[] { new LevelItemInfo(
stack,
delegate.getReportingValue(),
-1,
delegate.isProvidingStrongPower() > 0 ? LevelState.Craft : LevelState.Idle) };
}
}
@@ -61,7 +61,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
if (slot < 0 || slot >= TileLevelMaintainer.REQ_COUNT) {
throw new IllegalArgumentException("Invalid slot");
}
return tileEntity.requests.isDone(slot);
return tileEntity.isDone(slot);
}
private boolean isEnable(Arguments args) {
@@ -69,7 +69,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
if (slot < 0 || slot >= TileLevelMaintainer.REQ_COUNT) {
throw new IllegalArgumentException("Invalid slot");
}
return tileEntity.requests.isEnable(slot);
return tileEntity.requests[slot].isEnable();
}
private boolean setEnable(Arguments args) {
@@ -81,7 +81,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
throw new IllegalArgumentException("Invalid slot");
}
boolean enable = args.checkBoolean(1);
tileEntity.requests.updateStatus(slot, enable);
tileEntity.updateStatus(slot, enable);
return true;
}
}
@@ -103,12 +103,12 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
result.put("label", stack.getDisplayName());
result.put("maxDamage", stack.getMaxDamage());
result.put("name", GameRegistry.findUniqueIdentifierFor(stack.getItem()).toString());
result.put("quantity", tileEntity.requests.getQuantity(slot));
result.put("batch", tileEntity.requests.getBatchSize(slot));
result.put("quantity", tileEntity.requests[slot].getQuantity());
result.put("batch", tileEntity.requests[slot].getBatchSize());
result.put("isFluid", ItemFluidDrop.isFluidStack(stack));
if (ItemFluidDrop.isFluidStack(stack)) result.put("fluid", ItemFluidDrop.getFluidStack(stack));
result.put("isEnable", tileEntity.requests.isEnable(slot));
result.put("isDone", tileEntity.requests.isDone(slot));
result.put("isEnable", tileEntity.requests[slot].isEnable());
result.put("isDone", tileEntity.isDone(slot));
return new Object[] { result };
}
return new Object[] { null };
@@ -122,7 +122,7 @@ public class DriverLevelMaintainer extends DriverSidedTileEntity {
if (dbStack == null) {
throw new IllegalArgumentException("Invalid slot");
}
tileEntity.requests.updateStack(slot, dbStack);
tileEntity.updateStack(slot, dbStack);
} else {
throw new IllegalArgumentException("Not a database");
}
@@ -5,13 +5,14 @@ import java.util.List;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import com.glodblock.github.crossmod.waila.Tooltip;
import appeng.api.storage.data.IAEItemStack;
import appeng.integration.modules.waila.BaseWailaDataProvider;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
@@ -23,16 +24,24 @@ public class LevelMaintainerWailaDataProvider extends BaseWailaDataProvider {
final IWailaDataAccessor accessor, final IWailaConfigHandler config) {
final TileEntity te = accessor.getTileEntity();
if (te instanceof TileLevelMaintainer tileLevelMaintainer) {
te.readFromNBT(accessor.getNBTData());
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
IAEItemStack ias = tileLevelMaintainer.requests.getAEItemStack(i);
if (ias != null) {
currentToolTip.add(
Tooltip.tileLevelMaintainerFormat(
ias.getItemStack().getDisplayName(),
tileLevelMaintainer.requests.getQuantity(i),
tileLevelMaintainer.requests.getBatchSize(i),
tileLevelMaintainer.requests.isEnable(i)));
NBTTagCompound data = accessor.getNBTData();
if (data.hasKey(TileLevelMaintainer.NBT_REQUESTS)) {
NBTTagList tagList = data.getTagList(TileLevelMaintainer.NBT_REQUESTS, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.tagCount(); i++) {
NBTTagCompound tag = tagList.getCompoundTagAt(i);
if (tag == null || !tag.hasKey(TileLevelMaintainer.NBT_STACK)) continue;
try {
TileLevelMaintainer.RequestInfo request = new TileLevelMaintainer.RequestInfo(
tag,
tileLevelMaintainer);
currentToolTip.add(
Tooltip.tileLevelMaintainerFormat(
request.getAEItemStack().getItemStack().getDisplayName(),
request.getQuantity(),
request.getBatchSize(),
request.isEnable()));
} catch (Exception ignored) {}
}
}
}
@@ -20,6 +20,7 @@ import com.glodblock.github.network.CPacketSwitchGuis;
import com.glodblock.github.network.CPacketTransferRecipe;
import com.glodblock.github.network.CPacketValueConfig;
import com.glodblock.github.network.SPacketFluidUpdate;
import com.glodblock.github.network.SPacketLevelMaintainerGuiUpdate;
import com.glodblock.github.network.SPacketLevelTerminalUpdate;
import com.glodblock.github.network.SPacketMEFluidInvUpdate;
import com.glodblock.github.network.SPacketMEItemInvUpdate;
@@ -87,6 +88,11 @@ public class ChannelLoader implements Runnable {
SPacketPatternItemRenamer.class,
id++,
Side.SERVER);
netHandler.registerMessage(
new SPacketLevelMaintainerGuiUpdate.Handler(),
SPacketLevelMaintainerGuiUpdate.class,
id++,
Side.CLIENT);
}
public static void sendPacketToAllPlayers(Packet packet, World world) {
@@ -1,16 +1,9 @@
package com.glodblock.github.network;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayerMP;
import com.glodblock.github.client.gui.container.ContainerLevelMaintainer;
import com.glodblock.github.common.tile.TileLevelMaintainer;
import appeng.api.storage.data.IAEItemStack;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
@@ -19,28 +12,18 @@ import io.netty.buffer.ByteBuf;
public class CPacketLevelMaintainer implements IMessage {
public enum Action {
Refresh,
Quantity,
Batch,
Enable,
Disable
Disable,
}
private Action action;
private long size;
private int slotIndex;
public CPacketLevelMaintainer() {
this.action = Action.Refresh;
this.slotIndex = 0;
this.size = 0;
}
public CPacketLevelMaintainer(Action action) {
this.action = action;
this.slotIndex = 0;
this.size = 0;
}
@SuppressWarnings("unused")
public CPacketLevelMaintainer() {}
public CPacketLevelMaintainer(Action action, int slotIndex) {
this.action = action;
@@ -70,43 +53,17 @@ public class CPacketLevelMaintainer implements IMessage {
public static class Handler implements IMessageHandler<CPacketLevelMaintainer, IMessage> {
private List<IAEItemStack> refresh(ContainerLevelMaintainer cca) {
List<IAEItemStack> toSend = new ArrayList<>(TileLevelMaintainer.REQ_COUNT);
for (int i = 0; i < TileLevelMaintainer.REQ_COUNT; i++) {
IAEItemStack ias = cca.getTile().requests.getAEItemStack(i);
if (ias != null) {
toSend.add(ias);
}
}
return toSend;
}
@Nullable
@Override
public IMessage onMessage(CPacketLevelMaintainer message, MessageContext ctx) {
if (ctx.getServerHandler().playerEntity.openContainer instanceof final ContainerLevelMaintainer clm) {
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
List<IAEItemStack> toSend = switch (message.action) {
case Quantity -> {
clm.getTile().updateQuantity(message.slotIndex, message.size);
yield this.refresh(clm);
}
case Batch -> {
clm.getTile().updateBatchSize(message.slotIndex, message.size);
yield this.refresh(clm);
}
case Enable -> {
clm.getTile().updateStatus(message.slotIndex, false);
yield this.refresh(clm);
}
case Disable -> {
clm.getTile().updateStatus(message.slotIndex, true);
yield this.refresh(clm);
}
case Refresh -> this.refresh(clm);
};
SPacketMEUpdateBuffer.scheduleItemUpdate(player, toSend);
switch (message.action) {
case Quantity -> clm.getTile().updateQuantity(message.slotIndex, message.size);
case Batch -> clm.getTile().updateBatchSize(message.slotIndex, message.size);
case Enable -> clm.getTile().updateStatus(message.slotIndex, false);
case Disable -> clm.getTile().updateStatus(message.slotIndex, true);
}
clm.updateGui();
}
return null;
}
@@ -0,0 +1,122 @@
package com.glodblock.github.network;
import static com.glodblock.github.common.tile.TileLevelMaintainer.REQ_COUNT;
import static com.glodblock.github.common.tile.TileLevelMaintainer.RequestInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.GuiLevelMaintainer;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
public class SPacketLevelMaintainerGuiUpdate implements IMessage {
private Info[] infoList;
private boolean onlyState;
@SuppressWarnings("unused")
public SPacketLevelMaintainerGuiUpdate() {}
public SPacketLevelMaintainerGuiUpdate(RequestInfo[] requests, boolean onlyState) {
this.infoList = new Info[REQ_COUNT];
this.onlyState = onlyState;
for (int i = 0; i < REQ_COUNT; i++) {
if (requests[i] == null) {
this.infoList[i] = null;
} else {
this.infoList[i] = new Info(
requests[i].getQuantity(),
requests[i].getBatchSize(),
requests[i].isEnable(),
requests[i].getState());
}
}
}
@Override
public void fromBytes(ByteBuf buf) {
this.infoList = new Info[REQ_COUNT];
this.onlyState = buf.readBoolean();
for (int i = 0; i < REQ_COUNT; i++) {
if (buf.readBoolean()) {
if (this.onlyState) {
this.infoList[i] = new Info(LevelState.values()[buf.readInt()]);
} else {
this.infoList[i] = new Info(
buf.readLong(),
buf.readLong(),
buf.readBoolean(),
LevelState.values()[buf.readInt()]);
}
} else {
this.infoList[i] = null;
}
}
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeBoolean(this.onlyState);
for (Info info : this.infoList) {
buf.writeBoolean(info != null);
if (info == null) continue;
if (!this.onlyState) {
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeBoolean(info.enable);
}
buf.writeInt(info.state.ordinal());
}
}
private static class Info {
long quantity;
long batchSize;
boolean enable;
LevelState state;
Info(long quantity, long batchSize, boolean enable, LevelState state) {
this.quantity = quantity;
this.batchSize = batchSize;
this.enable = enable;
this.state = state;
}
Info(LevelState state) {
this.quantity = 0;
this.batchSize = 0;
this.enable = false;
this.state = state;
}
}
public static class Handler implements IMessageHandler<SPacketLevelMaintainerGuiUpdate, IMessage> {
@Override
public IMessage onMessage(SPacketLevelMaintainerGuiUpdate message, MessageContext ctx) {
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if (gs instanceof GuiLevelMaintainer gui) {
for (int i = 0; i < REQ_COUNT; i++) {
Info info = message.infoList[i];
if (info == null) continue;
if (message.onlyState) {
gui.updateComponent(i, info.state);
} else {
gui.updateComponent(i, info.quantity, info.batchSize, info.enable, info.state);
}
}
}
return null;
}
}
}
@@ -1,22 +1,17 @@
package com.glodblock.github.network;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.Nullable;
import com.glodblock.github.api.registries.LevelItemInfo;
import com.glodblock.github.api.registries.LevelState;
import com.glodblock.github.client.gui.GuiLevelTerminal;
import appeng.core.AEConfig;
@@ -27,58 +22,28 @@ import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
/**
* Packet used for level terminal updates. Packet allows the server to send an array of command packets, which are then
* processed in order. This allows for chaining commands to produce the desired update.
*/
public class SPacketLevelTerminalUpdate implements IMessage {
public static final int CLEAR_ALL_BIT = 1;
public static final int DISCONNECT_BIT = 2;
private final List<PacketEntry> commands = new ArrayList<>();
private int statusFlags;
public SPacketLevelTerminalUpdate() {}
@Override
public void fromBytes(ByteBuf buf) {
this.statusFlags = buf.readByte();
int numEntries = buf.readInt();
int entryNum = buf.readInt();
for (int i = 0; i < numEntries; ++i) {
try {
PacketType type = PacketType.values()[buf.readByte()];
for (int i = 0; i < entryNum; i++) {
PacketType type = PacketType.values()[buf.readByte()];
switch (type) {
case ADD -> this.commands.add(new PacketAdd(buf));
case REMOVE -> this.commands.add(new PacketRemove(buf));
case OVERWRITE -> this.commands.add(new PacketOverwrite(buf));
case RENAME -> this.commands.add(new PacketRename(buf));
default -> throw new IOException("Unknown packet type received of index " + type);
}
} catch (Exception e) {
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
"Corrupted packet commands: (" + i
+ ") of ("
+ numEntries
+ ") -> "
+ this.commands.size()
+ " : "
+ this.commands.stream().map(packetEntry -> packetEntry.getClass().getSimpleName())
.collect(Collectors.groupingBy(String::new, Collectors.counting())));
if (AEConfig.instance.isFeatureEnabled(AEFeature.DebugLogging)) {
AELog.info(" <- Parsed content: " + this.commands);
}
}
AELog.debug(e);
return;
switch (type) {
case ADD -> this.commands.add(new PacketAdd(buf));
case REMOVE -> this.commands.add(new PacketRemove(buf));
case RENAME -> this.commands.add(new PacketRename(buf));
case DISCONNECT -> this.commands.add(new PacketDisconnect(buf));
case OVERWRITE_SLOT -> this.commands.add(new PacketOverwriteSlot(buf));
case OVERWITE_ALL_SLOT -> this.commands.add(new PacketOverwirteAllSlot(buf));
}
}
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
" <- Received commands " + this.commands.size()
@@ -88,80 +53,49 @@ public class SPacketLevelTerminalUpdate implements IMessage {
}
}
@Override
public void toBytes(ByteBuf buf) {
try {
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
" <- Sent commands " + this.commands.size()
+ " : "
+ this.commands.stream().map(packetEntry -> packetEntry.getClass().getSimpleName())
.collect(Collectors.groupingBy(String::new, Collectors.counting())));
if (AEConfig.instance.isFeatureEnabled(AEFeature.DebugLogging)) {
AELog.info(" -> Sent commands: " + this.commands);
}
}
buf.writeInt(commands.size());
for (PacketEntry entry : this.commands) {
buf.writeByte(entry.getType().ordinal());
entry.write(buf);
}
buf.writeByte(statusFlags);
buf.writeInt(commands.size());
for (PacketEntry entry : commands) {
entry.write(buf);
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
" <- Sent commands " + this.commands.size()
+ " : "
+ this.commands.stream().map(packetEntry -> packetEntry.getClass().getSimpleName())
.collect(Collectors.groupingBy(String::new, Collectors.counting())));
if (AEConfig.instance.isFeatureEnabled(AEFeature.DebugLogging)) {
AELog.info(" -> Sent commands: " + this.commands);
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
/**
* Remove all entries on the terminal. This is done BEFORE any entries are processed, so you can set this to clear
* old entries, and add new ones after in one packet.
*/
public void setClear() {
statusFlags |= CLEAR_ALL_BIT;
public void addNewEntry(long id, int x, int y, int z, int dim, int side, int rows, int rowSize, String name,
LevelItemInfo[] infolist) {
this.commands.add(new PacketAdd(id, x, y, z, dim, side, rows, rowSize, name, infolist));
}
/**
* The terminal disconnected. Entries are still processed, but indicates for the GUI to darken/turn off the
* terminal. No further updates will arrive until the terminal reconnects.
*/
public void setDisconnect() {
this.statusFlags |= DISCONNECT_BIT;
public void addRemoveEntry(long id) {
this.commands.add(new PacketRemove(id));
}
/**
* Adds a new entry. Fill out the rest of the command using the {@link PacketAdd#setItems(int, int, NBTTagList)} and
* {@link PacketAdd#setLocation(int, int, int, int, int)}.
*
* @return the packet, which needs to have information filled out.
*/
public PacketAdd addNewEntry(long id, String name, boolean online) {
PacketAdd packet = new PacketAdd(id, name, online);
commands.add(packet);
return packet;
public void addRenameEntry(long id, String newName) {
this.commands.add(new PacketRename(id, newName));
}
/**
* Remove the entry with the id from the terminal.
*/
public void addRemovalEntry(long id) {
commands.add(new PacketRemove(id));
public void addDisconnectEntry() {
this.commands.add(new PacketDisconnect());
}
/**
* Rename the entry
*/
public void addRenamedEntry(long id, String newName) {
commands.add(new PacketRename(id, newName));
public void addOverwriteSlotEntry(long id, int index, LevelItemInfo info) {
this.commands.add(new PacketOverwriteSlot(id, index, info));
}
/**
* Overwrite the entry with new items or new status
*/
public PacketOverwrite addOverwriteEntry(long id) {
PacketOverwrite packet = new PacketOverwrite(id);
commands.add(packet);
return packet;
public void addOverwriteAllSlotEntry(long id, LevelItemInfo[] info) {
this.commands.add(new PacketOverwirteAllSlot(id, info));
}
public static class Handler implements IMessageHandler<SPacketLevelTerminalUpdate, IMessage> {
@@ -172,23 +106,22 @@ public class SPacketLevelTerminalUpdate implements IMessage {
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if (gs instanceof GuiLevelTerminal levelTerminal) {
levelTerminal.postUpdate(message.commands, message.statusFlags);
levelTerminal.receivePackets(message.commands);
}
return null;
}
}
enum PacketType {
protected enum PacketType {
ADD,
REMOVE,
OVERWRITE,
RENAME,
DISCONNECT,
OVERWRITE_SLOT,
OVERWITE_ALL_SLOT,
}
/**
* A packet for updating an entry.
*/
public abstract static class PacketEntry {
public final long entryId;
@@ -197,181 +130,87 @@ public class SPacketLevelTerminalUpdate implements IMessage {
this.entryId = entryId;
}
protected PacketEntry(ByteBuf buf) throws IOException {
public PacketEntry(ByteBuf buf) {
this.entryId = buf.readLong();
read(buf);
}
/**
* Needs to write the packet id.
*/
protected abstract void write(ByteBuf buf) throws IOException;
protected abstract PacketType getType();
/**
* Reading the entry id is not needed.
*/
protected abstract void read(ByteBuf buf) throws IOException;
protected void write(ByteBuf buf) {
buf.writeLong(this.entryId);
}
}
/**
* A command for sending a new entry.
*/
public static class PacketAdd extends PacketEntry {
public String name;
public int x, y, z, dim, side;
public int rows, rowSize;
public boolean online;
public ItemStack selfItemStack;
public ItemStack displayItemStack;
public NBTTagList items;
public String name;
public LevelItemInfo[] infolist;
PacketAdd(long id, String name, boolean online) {
PacketAdd(long id, int x, int y, int z, int dim, int side, int rows, int rowSize, String name,
LevelItemInfo[] infolist) {
super(id);
this.name = name;
this.online = online;
}
PacketAdd(ByteBuf buf) throws IOException {
super(buf);
}
public PacketAdd setLocation(int x, int y, int z, int dim, int side) {
this.x = x;
this.y = y;
this.z = z;
this.dim = dim;
this.side = side;
return this;
}
public PacketAdd setItems(int rows, int rowSize, NBTTagList items) {
this.rows = rows;
this.rowSize = rowSize;
this.items = items;
return this;
this.name = name;
this.infolist = infolist;
}
public PacketAdd setViewItemStack(ItemStack selfItemStack, ItemStack displayItemStack) {
this.selfItemStack = selfItemStack;
this.displayItemStack = displayItemStack;
return this;
}
@Override
protected void write(ByteBuf buf) throws IOException {
buf.writeByte(PacketType.ADD.ordinal());
buf.writeLong(entryId);
ByteBufUtils.writeUTF8String(buf, this.name);
buf.writeInt(x);
buf.writeInt(y);
buf.writeInt(z);
buf.writeInt(dim);
buf.writeByte(side);
buf.writeInt(rows);
buf.writeInt(rowSize);
ByteBuf tempBuf = Unpooled.directBuffer(256);
try {
try (ByteBufOutputStream stream = new ByteBufOutputStream(tempBuf)) {
NBTTagCompound wrapper = new NBTTagCompound();
if (selfItemStack != null) {
wrapper.setTag("self", selfItemStack.writeToNBT(new NBTTagCompound()));
}
if (displayItemStack != null) {
wrapper.setTag("display", displayItemStack.writeToNBT(new NBTTagCompound()));
}
wrapper.setTag("data", items);
CompressedStreamTools.writeCompressed(wrapper, stream);
}
buf.writeInt(tempBuf.readableBytes());
buf.writeBytes(tempBuf);
} finally {
tempBuf.release();
}
}
@Override
protected void read(ByteBuf buf) throws IOException {
this.name = ByteBufUtils.readUTF8String(buf);
public PacketAdd(ByteBuf buf) {
super(buf);
this.x = buf.readInt();
this.y = buf.readInt();
this.z = buf.readInt();
this.dim = buf.readInt();
this.side = buf.readByte();
this.side = buf.readInt();
this.rows = buf.readInt();
this.rowSize = buf.readInt();
int payloadSize = buf.readInt();
try (ByteBufInputStream stream = new ByteBufInputStream(buf, payloadSize)) {
NBTTagCompound payload = CompressedStreamTools.readCompressed(stream);
int available = stream.available();
if (available > 0) {
byte[] left = new byte[available];
int read = stream.read(left);
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info(
"Unread bytes detected (" + read
+ "): "
+ Arrays.toString(left)
+ " at "
+ dim
+ "#("
+ x
+ ":"
+ y
+ ":"
+ z
+ ")@"
+ ForgeDirection.getOrientation(side));
}
}
if (payload.hasKey("self", NBT.TAG_COMPOUND)) {
this.selfItemStack = ItemStack.loadItemStackFromNBT(payload.getCompoundTag("self"));
}
if (payload.hasKey("display", NBT.TAG_COMPOUND)) {
this.displayItemStack = ItemStack.loadItemStackFromNBT(payload.getCompoundTag("display"));
}
this.items = payload.getTagList("data", NBT.TAG_COMPOUND);
this.name = ByteBufUtils.readUTF8String(buf);
int infoSize = buf.readInt();
infolist = new LevelItemInfo[infoSize];
for (int i = 0; i < infoSize; i++) {
if (!buf.readBoolean()) continue;
ItemStack stack = ByteBufUtils.readItemStack(buf);
long quantity = buf.readLong();
long batchSize = buf.readLong();
LevelState state = LevelState.values()[buf.readInt()];
infolist[i] = new LevelItemInfo(stack, quantity, batchSize, state);
}
}
@Override
public String toString() {
return "PacketAdd{" + "name='"
+ name
+ '\''
+ ", x="
+ x
+ ", y="
+ y
+ ", z="
+ z
+ ", dim="
+ dim
+ ", side="
+ side
+ ", rows="
+ rows
+ ", rowSize="
+ rowSize
+ ", online="
+ online
+ ", selfItemStack="
+ selfItemStack
+ ", displayItemStack="
+ displayItemStack
+ ", items="
+ items
+ ", entryId="
+ entryId
+ '}';
protected PacketType getType() {
return PacketType.ADD;
}
@Override
protected void write(ByteBuf buf) {
super.write(buf);
buf.writeInt(this.x);
buf.writeInt(this.y);
buf.writeInt(this.z);
buf.writeInt(this.dim);
buf.writeInt(this.side);
buf.writeInt(this.rows);
buf.writeInt(this.rowSize);
ByteBufUtils.writeUTF8String(buf, this.name);
buf.writeInt(this.infolist.length);
for (int i = 0; i < this.infolist.length; i++) {
LevelItemInfo info = this.infolist[i];
buf.writeBoolean(info != null);
if (info == null) continue;
// System.out.println("Writing info: " + info.stack != null);
ByteBufUtils.writeItemStack(buf, info.stack);
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeInt(info.state.ordinal());
}
}
}
@@ -381,205 +220,147 @@ public class SPacketLevelTerminalUpdate implements IMessage {
super(id);
}
PacketRemove(ByteBuf buf) throws IOException {
PacketRemove(ByteBuf buf) {
super(buf);
}
@Override
protected PacketType getType() {
return PacketType.REMOVE;
}
@Override
protected void write(ByteBuf buf) {
buf.writeByte(PacketType.REMOVE.ordinal());
buf.writeLong(entryId);
}
@Override
protected void read(ByteBuf buf) {}
@Override
public String toString() {
return "PacketRemove{" + "entryId=" + entryId + '}';
super.write(buf);
}
}
/**
* Overwrite online status or inventory of the entry.
*/
public static class PacketOverwrite extends PacketEntry {
public static final int ONLINE_BIT = 1;
public static final int ONLINE_VALID = 1 << 1;
public static final int ITEMS_VALID = 1 << 2;
public static final int ALL_ITEM_UPDATE_BIT = 1 << 3;
public boolean onlineValid;
public boolean online;
public boolean itemsValid;
public boolean allItemUpdate;
public int[] validIndices;
public NBTTagList items;
protected PacketOverwrite(long id) {
super(id);
}
protected PacketOverwrite(ByteBuf buf) throws IOException {
super(buf);
}
public PacketOverwrite setOnline(boolean online) {
this.onlineValid = true;
this.online = online;
return this;
}
public PacketOverwrite setItems(int[] validIndices, NBTTagList items) {
this.itemsValid = true;
this.allItemUpdate = validIndices == null || validIndices.length == 0;
this.validIndices = validIndices;
this.items = items;
return this;
}
public PacketOverwrite setItems(int newSize, NBTTagList items) {
this.itemsValid = true;
this.allItemUpdate = true;
this.validIndices = new int[newSize];
this.items = items;
return this;
}
@Override
protected void write(ByteBuf buf) throws IOException {
buf.writeByte(PacketType.OVERWRITE.ordinal());
buf.writeLong(entryId);
int flags = 0;
if (onlineValid) {
flags |= ONLINE_VALID;
flags |= online ? ONLINE_BIT : 0;
}
if (itemsValid) {
flags |= ITEMS_VALID;
if (allItemUpdate) {
flags |= ALL_ITEM_UPDATE_BIT;
buf.writeByte(flags);
buf.writeInt(validIndices.length);
} else {
buf.writeByte(flags);
buf.writeInt(validIndices.length);
for (int validIndex : validIndices) {
buf.writeInt(validIndex);
}
}
ByteBuf tempBuf = Unpooled.directBuffer(256);
try {
try (ByteBufOutputStream stream = new ByteBufOutputStream(tempBuf)) {
NBTTagCompound wrapper = new NBTTagCompound();
wrapper.setTag("data", items);
CompressedStreamTools.writeCompressed(wrapper, stream);
}
buf.writeInt(tempBuf.readableBytes());
buf.writeBytes(tempBuf);
} finally {
tempBuf.release();
}
} else {
buf.writeByte(flags);
}
}
@Override
protected void read(ByteBuf buf) throws IOException {
int flags = buf.readByte();
/* Decide whether to use online flag or not */
if ((flags & ONLINE_VALID) == ONLINE_VALID) {
this.onlineValid = true;
this.online = (flags & ONLINE_BIT) == ONLINE_BIT;
}
/* Decide whether to read item list or not */
if ((flags & ITEMS_VALID) == ITEMS_VALID) {
this.itemsValid = true;
if ((flags & ALL_ITEM_UPDATE_BIT) == ALL_ITEM_UPDATE_BIT) {
this.allItemUpdate = true;
int numItems = buf.readInt();
this.validIndices = new int[numItems];
} else {
int numItems = buf.readInt();
this.validIndices = new int[numItems];
for (int i = 0; i < numItems; ++i) {
this.validIndices[i] = buf.readInt();
}
}
int payloadSize = buf.readInt();
try (ByteBufInputStream stream = new ByteBufInputStream(buf, payloadSize)) {
this.items = CompressedStreamTools.readCompressed(stream).getTagList("data", NBT.TAG_COMPOUND);
int available = stream.available();
if (available > 0) {
byte[] left = new byte[available];
int read = stream.read(left);
if (AEConfig.instance.isFeatureEnabled(AEFeature.PacketLogging)) {
AELog.info("Unread bytes detected (" + read + "): " + Arrays.toString(left));
}
}
}
}
}
@Override
public String toString() {
return "PacketOverwrite{" + "onlineValid="
+ onlineValid
+ ", online="
+ online
+ ", itemsValid="
+ itemsValid
+ ", allItemUpdate="
+ allItemUpdate
+ ", validIndices="
+ Arrays.toString(validIndices)
+ ", items="
+ items
+ ", entryId="
+ entryId
+ '}';
}
}
/**
* Rename the entry.
*/
public static class PacketRename extends PacketEntry {
public String newName;
protected PacketRename(long id, String newName) {
PacketRename(long id, String newName) {
super(id);
this.newName = newName;
}
protected PacketRename(ByteBuf buf) throws IOException {
PacketRename(ByteBuf buf) {
super(buf);
this.newName = ByteBufUtils.readUTF8String(buf);
}
@Override
protected PacketType getType() {
return PacketType.RENAME;
}
@Override
protected void write(ByteBuf buf) {
buf.writeByte(PacketType.RENAME.ordinal());
buf.writeLong(entryId);
ByteBufUtils.writeUTF8String(buf, newName);
super.write(buf);
ByteBufUtils.writeUTF8String(buf, this.newName);
}
}
public static class PacketDisconnect extends PacketEntry {
PacketDisconnect() {
super(0); // Ignored id
}
PacketDisconnect(ByteBuf buf) {
super(buf);
}
@Override
protected void read(ByteBuf buf) {
newName = ByteBufUtils.readUTF8String(buf);
protected PacketType getType() {
return PacketType.DISCONNECT;
}
}
public static class PacketOverwriteSlot extends PacketEntry {
public int index;
public LevelItemInfo info;
PacketOverwriteSlot(long id, int index, LevelItemInfo info) {
super(id);
this.index = index;
this.info = info;
}
PacketOverwriteSlot(ByteBuf buf) {
super(buf);
this.index = buf.readInt();
if (buf.readBoolean()) {
this.info = new LevelItemInfo(
ByteBufUtils.readItemStack(buf),
buf.readLong(),
buf.readLong(),
LevelState.values()[buf.readInt()]);
} else {
this.info = null;
}
}
@Override
public String toString() {
return "PacketRename{" + "newName='" + newName + '\'' + ", entryId=" + entryId + '}';
protected PacketType getType() {
return PacketType.OVERWRITE_SLOT;
}
@Override
protected void write(ByteBuf buf) {
super.write(buf);
buf.writeInt(index);
buf.writeBoolean(info != null);
ByteBufUtils.writeItemStack(buf, info.stack);
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeInt(info.state.ordinal());
}
}
public static class PacketOverwirteAllSlot extends PacketEntry {
public LevelItemInfo[] infoList;
PacketOverwirteAllSlot(long id, LevelItemInfo[] info) {
super(id);
this.infoList = info;
}
PacketOverwirteAllSlot(ByteBuf buf) {
super(buf);
int infoSize = buf.readInt();
this.infoList = new LevelItemInfo[infoSize];
for (int i = 0; i < infoSize; i++) {
if (!buf.readBoolean()) continue;
ItemStack stack = ByteBufUtils.readItemStack(buf);
long quantity = buf.readLong();
long batchSize = buf.readLong();
LevelState state = LevelState.values()[buf.readInt()];
this.infoList[i] = new LevelItemInfo(stack, quantity, batchSize, state);
}
}
@Override
protected PacketType getType() {
return PacketType.OVERWITE_ALL_SLOT;
}
@Override
protected void write(ByteBuf buf) {
super.write(buf);
buf.writeInt(this.infoList.length);
for (int i = 0; i < this.infoList.length; i++) {
LevelItemInfo info = this.infoList[i];
buf.writeBoolean(info != null);
if (info == null) continue;
buf.writeInt(i);
ByteBufUtils.writeItemStack(buf, info.stack);
buf.writeLong(info.quantity);
buf.writeLong(info.batchSize);
buf.writeInt(info.state.ordinal());
}
}
}
}
@@ -9,7 +9,6 @@ import net.minecraft.client.gui.GuiScreen;
import com.glodblock.github.client.gui.GuiFluidCraftConfirm;
import com.glodblock.github.client.gui.GuiItemMonitor;
import com.glodblock.github.client.gui.GuiLevelMaintainer;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEItemStack;
@@ -97,8 +96,6 @@ public class SPacketMEItemInvUpdate implements IMessage {
((GuiItemMonitor) gs).postUpdate(message.list, message.resort);
} else if (gs instanceof GuiFluidCraftConfirm) {
((GuiFluidCraftConfirm) gs).postUpdate(message.list, message.ref);
} else if (gs instanceof GuiLevelMaintainer) {
((GuiLevelMaintainer) gs).postUpdate(message.list);
}
return null;
}