2014-04-29 10:54:20 +10:00
|
|
|
package codechicken.nei;
|
|
|
|
|
|
2023-09-25 00:35:24 +02:00
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.io.PrintWriter;
|
|
|
|
|
import java.io.StringWriter;
|
|
|
|
|
import java.util.AbstractList;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.zip.ZipException;
|
|
|
|
|
|
2014-04-29 10:54:20 +10:00
|
|
|
import net.minecraft.command.ICommandSender;
|
|
|
|
|
import net.minecraft.enchantment.Enchantment;
|
|
|
|
|
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.Item;
|
|
|
|
|
import net.minecraft.item.ItemStack;
|
2014-10-01 20:01:10 +10:00
|
|
|
import net.minecraft.nbt.CompressedStreamTools;
|
2022-01-31 01:01:12 +09:00
|
|
|
import net.minecraft.nbt.JsonToNBT;
|
|
|
|
|
import net.minecraft.nbt.NBTBase;
|
|
|
|
|
import net.minecraft.nbt.NBTException;
|
2014-04-29 10:54:20 +10:00
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
|
|
|
import net.minecraft.nbt.NBTTagList;
|
|
|
|
|
import net.minecraft.server.MinecraftServer;
|
|
|
|
|
import net.minecraft.util.ChatComponentTranslation;
|
|
|
|
|
import net.minecraft.util.EnumChatFormatting;
|
|
|
|
|
import net.minecraft.util.IChatComponent;
|
|
|
|
|
import net.minecraft.world.World;
|
|
|
|
|
import net.minecraft.world.WorldServer;
|
|
|
|
|
import net.minecraft.world.WorldSettings.GameType;
|
|
|
|
|
import net.minecraftforge.oredict.OreDictionary;
|
2023-09-25 00:35:24 +02:00
|
|
|
|
2022-01-31 01:01:12 +09:00
|
|
|
import org.apache.logging.log4j.Level;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
2023-09-25 00:35:24 +02:00
|
|
|
import codechicken.core.CommonUtils;
|
|
|
|
|
import codechicken.core.ServerUtils;
|
|
|
|
|
import codechicken.lib.inventory.InventoryRange;
|
|
|
|
|
import codechicken.lib.inventory.InventoryUtils;
|
|
|
|
|
import codechicken.lib.packet.PacketCustom;
|
|
|
|
|
import codechicken.nei.PacketIDs.S2C;
|
|
|
|
|
import codechicken.nei.util.NBTHelper;
|
|
|
|
|
import cpw.mods.fml.common.FMLLog;
|
|
|
|
|
import cpw.mods.fml.common.registry.GameRegistry;
|
2023-01-28 17:55:51 -08:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
public class NEIServerUtils {
|
2023-01-28 17:55:51 -08:00
|
|
|
|
2014-04-29 10:54:20 +10:00
|
|
|
public static boolean isRaining(World world) {
|
|
|
|
|
return world.getWorldInfo().isRaining();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void toggleRaining(World world, boolean notify) {
|
|
|
|
|
boolean raining = !world.isRaining();
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!raining) // turn off
|
|
|
|
|
((WorldServer) world).provider.resetRainAndThunder();
|
|
|
|
|
else world.getWorldInfo().setRaining(!isRaining(world));
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
if (notify)
|
|
|
|
|
ServerUtils.sendChatToAll(new ChatComponentTranslation("nei.chat.rain." + (raining ? "on" : "off")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void healPlayer(EntityPlayer player) {
|
|
|
|
|
player.heal(20);
|
|
|
|
|
player.getFoodStats().addStats(20, 1);
|
|
|
|
|
player.extinguish();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static long getTime(World world) {
|
|
|
|
|
return world.getWorldInfo().getWorldTime();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void setTime(long l, World world) {
|
|
|
|
|
world.getWorldInfo().setWorldTime(l);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void setSlotContents(EntityPlayer player, int slot, ItemStack item, boolean containerInv) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (slot == -999) player.inventory.setItemStack(item);
|
|
|
|
|
else if (containerInv) player.openContainer.putStackInSlot(slot, item);
|
|
|
|
|
else player.inventory.setInventorySlotContents(slot, item);
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static ItemStack getSlotContents(EntityPlayer player, int slot, boolean containerInv) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (slot == -999) return player.inventory.getItemStack();
|
|
|
|
|
else if (containerInv) return player.openContainer.getSlot(slot).getStack();
|
|
|
|
|
else return player.inventory.getStackInSlot(slot);
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void deleteAllItems(EntityPlayerMP player) {
|
2024-08-29 20:07:14 +02:00
|
|
|
for (Slot slot : player.openContainer.inventorySlots) slot.putStack(null);
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
player.sendContainerAndContentsToPlayer(player.openContainer, player.openContainer.getInventory());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void setHourForward(World world, int hour, boolean notify) {
|
|
|
|
|
long day = (getTime(world) / 24000L) * 24000L;
|
|
|
|
|
long newTime = day + 24000L + hour * 1000;
|
|
|
|
|
setTime(newTime, world);
|
|
|
|
|
if (notify)
|
|
|
|
|
ServerUtils.sendChatToAll(new ChatComponentTranslation("nei.chat.time", getTime(world) / 24000L, hour));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void advanceDisabledTimes(World world) {
|
|
|
|
|
int dim = CommonUtils.getDimension(world);
|
|
|
|
|
int hour = (int) (getTime(world) % 24000) / 1000;
|
|
|
|
|
int newhour = hour;
|
|
|
|
|
while (NEIServerConfig.isActionDisabled(dim, NEIActions.timeZones[newhour / 6]))
|
|
|
|
|
newhour = ((newhour / 6 + 1) % 4) * 6;
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (newhour != hour) setHourForward(world, newhour, false);
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean canItemFitInInventory(EntityPlayer player, ItemStack itemstack) {
|
2014-05-01 01:48:33 +10:00
|
|
|
return InventoryUtils.insertItem(new InventoryRange(player.inventory, 0, 36), itemstack, true) == 0;
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void sendNotice(ICommandSender sender, IChatComponent msg, String permission) {
|
2022-06-24 12:32:13 +01:00
|
|
|
ChatComponentTranslation notice = new ChatComponentTranslation(
|
|
|
|
|
"chat.type.admin",
|
|
|
|
|
sender.getCommandSenderName(),
|
|
|
|
|
msg.createCopy());
|
2014-04-29 10:54:20 +10:00
|
|
|
notice.getChatStyle().setColor(EnumChatFormatting.GRAY).setItalic(true);
|
|
|
|
|
|
|
|
|
|
if (NEIServerConfig.canPlayerPerformAction("CONSOLE", permission))
|
|
|
|
|
MinecraftServer.getServer().addChatMessage(notice);
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
for (EntityPlayer p : ServerUtils.getPlayers()) if (p == sender) p.addChatComponentMessage(msg);
|
2014-04-29 10:54:20 +10:00
|
|
|
else if (NEIServerConfig.canPlayerPerformAction(p.getCommandSenderName(), permission))
|
|
|
|
|
p.addChatComponentMessage(notice);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param stack1 The {@link ItemStack} being compared.
|
|
|
|
|
* @param stack2 The {@link ItemStack} to compare to.
|
|
|
|
|
* @return whether the two items are the same in terms of damage and itemID.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean areStacksSameType(ItemStack stack1, ItemStack stack2) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return stack1 != null && stack2 != null
|
|
|
|
|
&& (stack1.getItem() == stack2.getItem()
|
|
|
|
|
&& (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage())
|
|
|
|
|
&& ItemStack.areItemStackTagsEqual(stack2, stack1));
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
2022-02-08 05:12:26 +09:00
|
|
|
/**
|
|
|
|
|
* NBT-friendly version of {@link #areStacksSameType(ItemStack, ItemStack)}
|
2023-01-28 17:55:51 -08:00
|
|
|
*
|
2022-02-08 05:12:26 +09:00
|
|
|
* @param stack1 The {@link ItemStack} being compared.
|
|
|
|
|
* @param stack2 The {@link ItemStack} to compare to.
|
|
|
|
|
* @return whether the two items are the same in terms of itemID, damage and NBT.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean areStacksSameTypeWithNBT(ItemStack stack1, ItemStack stack2) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return stack1 != null && stack2 != null
|
|
|
|
|
&& stack1.getItem() == stack2.getItem()
|
|
|
|
|
&& (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage())
|
|
|
|
|
&& NBTHelper.matchTag(stack1.getTagCompound(), stack2.getTagCompound());
|
2022-02-08 05:12:26 +09:00
|
|
|
}
|
|
|
|
|
|
2014-04-29 10:54:20 +10:00
|
|
|
/**
|
|
|
|
|
* {@link ItemStack}s with damage -1 are wildcards allowing all damages. Eg all colours of wool are allowed to
|
|
|
|
|
* create Beds.
|
|
|
|
|
*
|
|
|
|
|
* @param stack1 The {@link ItemStack} being compared.
|
|
|
|
|
* @param stack2 The {@link ItemStack} to compare to.
|
|
|
|
|
* @return whether the two items are the same from the perspective of a crafting inventory.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean areStacksSameTypeCrafting(ItemStack stack1, ItemStack stack2) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return stack1 != null && stack2 != null
|
|
|
|
|
&& stack1.getItem() == stack2.getItem()
|
|
|
|
|
&& (stack1.getItemDamage() == stack2.getItemDamage()
|
|
|
|
|
|| stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE
|
|
|
|
|
|| stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE
|
|
|
|
|
|| stack1.getItem().isDamageable());
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-02-08 05:12:26 +09:00
|
|
|
* NBT-friendly version of {@link #areStacksSameTypeCrafting(ItemStack, ItemStack)}
|
2023-01-28 17:55:51 -08:00
|
|
|
*
|
2022-02-08 05:12:26 +09:00
|
|
|
* @param stack1 The {@link ItemStack} being compared.
|
|
|
|
|
* @param stack2 The {@link ItemStack} to compare to.
|
|
|
|
|
* @return whether the two items are the same from the perspective of a crafting inventory.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean areStacksSameTypeCraftingWithNBT(ItemStack stack1, ItemStack stack2) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return stack1 != null && stack2 != null
|
|
|
|
|
&& stack1.getItem() == stack2.getItem()
|
|
|
|
|
&& (stack1.getItemDamage() == stack2.getItemDamage()
|
|
|
|
|
|| stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE
|
|
|
|
|
|| stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE
|
|
|
|
|
|| stack1.getItem().isDamageable())
|
|
|
|
|
&& NBTHelper.matchTag(stack1.getTagCompound(), stack2.getTagCompound());
|
2022-02-08 05:12:26 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2014-04-29 10:54:20 +10:00
|
|
|
* A simple function for comparing ItemStacks in a compatible with comparators.
|
|
|
|
|
*
|
|
|
|
|
* @param stack1 The {@link ItemStack} being compared.
|
|
|
|
|
* @param stack2 The {@link ItemStack} to compare to.
|
|
|
|
|
* @return The ordering of stack1 relative to stack2.
|
|
|
|
|
*/
|
|
|
|
|
public static int compareStacks(ItemStack stack1, ItemStack stack2) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (stack1 == stack2) return 0; // catches both null
|
|
|
|
|
if (stack1 == null || stack2 == null) return stack1 == null ? -1 : 1; // null stack goes first
|
|
|
|
|
if (stack1.getItem() != stack2.getItem())
|
|
|
|
|
return Item.getIdFromItem(stack1.getItem()) - Item.getIdFromItem(stack2.getItem());
|
2014-04-29 10:54:20 +10:00
|
|
|
if (stack1.stackSize != stack2.stackSize) return stack1.stackSize - stack2.stackSize;
|
|
|
|
|
return stack1.getItemDamage() - stack2.getItemDamage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean areStacksIdentical(ItemStack stack1, ItemStack stack2) {
|
|
|
|
|
return compareStacks(stack1, stack2) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IChatComponent setColour(IChatComponent msg, EnumChatFormatting colour) {
|
|
|
|
|
msg.getChatStyle().setColor(colour);
|
|
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void givePlayerItem(EntityPlayerMP player, ItemStack stack, boolean infinite, boolean doGive) {
|
|
|
|
|
if (stack.getItem() == null) {
|
2022-06-24 12:32:13 +01:00
|
|
|
player.addChatComponentMessage(
|
|
|
|
|
setColour(new ChatComponentTranslation("nei.chat.give.noitem"), EnumChatFormatting.WHITE));
|
2014-04-29 10:54:20 +10:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int given = stack.stackSize;
|
2022-06-24 12:32:13 +01:00
|
|
|
if (doGive) {
|
|
|
|
|
if (infinite) player.inventory.addItemStackToInventory(stack);
|
|
|
|
|
else given -= InventoryUtils.insertItem(player.inventory, stack, false);
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
sendNotice(
|
|
|
|
|
player,
|
|
|
|
|
new ChatComponentTranslation(
|
|
|
|
|
"commands.give.success",
|
|
|
|
|
stack.func_151000_E(),
|
|
|
|
|
infinite ? "\u221E" : Integer.toString(given),
|
|
|
|
|
player.getCommandSenderName()),
|
|
|
|
|
"notify-item");
|
2014-04-29 10:54:20 +10:00
|
|
|
player.openContainer.detectAndSendChanges();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static ItemStack copyStack(ItemStack itemstack, int i) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (itemstack == null) return null;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
itemstack.stackSize += i;
|
|
|
|
|
return itemstack.splitStack(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static ItemStack copyStack(ItemStack itemstack) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (itemstack == null) return null;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
return copyStack(itemstack, itemstack.stackSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void toggleMagnetMode(EntityPlayerMP player) {
|
|
|
|
|
PlayerSave playerSave = NEIServerConfig.forPlayer(player.getCommandSenderName());
|
|
|
|
|
playerSave.enableAction("magnet", !playerSave.isActionEnabled("magnet"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int getCreativeMode(EntityPlayerMP player) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (NEIServerConfig.forPlayer(player.getCommandSenderName()).isActionEnabled("creative+")) return 2;
|
|
|
|
|
else if (player.theItemInWorldManager.isCreative()) return 1;
|
|
|
|
|
else if (player.theItemInWorldManager.getGameType().isAdventure()) return 3;
|
|
|
|
|
else return 0;
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static GameType getGameType(int mode) {
|
|
|
|
|
switch (mode) {
|
|
|
|
|
case 0:
|
|
|
|
|
return GameType.SURVIVAL;
|
|
|
|
|
case 1:
|
|
|
|
|
case 2:
|
|
|
|
|
return GameType.CREATIVE;
|
|
|
|
|
case 3:
|
|
|
|
|
return GameType.ADVENTURE;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void setGamemode(EntityPlayerMP player, int mode) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (mode < 0 || mode >= NEIActions.gameModes.length
|
|
|
|
|
|| NEIActions.nameActionMap.containsKey(NEIActions.gameModes[mode]) && !NEIServerConfig
|
|
|
|
|
.canPlayerPerformAction(player.getCommandSenderName(), NEIActions.gameModes[mode]))
|
|
|
|
|
return;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
// creative+
|
2014-07-03 15:26:48 +10:00
|
|
|
NEIServerConfig.forPlayer(player.getCommandSenderName()).enableAction("creative+", mode == 2);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (mode == 2 && !(player.openContainer instanceof ContainerCreativeInv)) // open the container immediately for
|
|
|
|
|
// the client
|
|
|
|
|
NEISPH.processCreativeInv(player, true);
|
2014-07-03 15:26:48 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
// change it on the server
|
2014-04-29 10:54:20 +10:00
|
|
|
player.theItemInWorldManager.setGameType(getGameType(mode));
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
// tell the client to change it
|
2023-09-06 18:05:15 +09:00
|
|
|
new PacketCustom(NEISPH.channel, S2C.SEND_GAME_MODE).writeByte(mode).sendToPlayer(player);
|
2014-04-29 10:54:20 +10:00
|
|
|
player.addChatMessage(new ChatComponentTranslation("nei.chat.gamemode." + mode));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void cycleCreativeInv(EntityPlayerMP player, int steps) {
|
|
|
|
|
InventoryPlayer inventory = player.inventory;
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
// top down [row][col]
|
2014-04-29 10:54:20 +10:00
|
|
|
ItemStack[][] slots = new ItemStack[10][9];
|
|
|
|
|
PlayerSave playerSave = NEIServerConfig.forPlayer(player.getCommandSenderName());
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
// get
|
2014-04-29 10:54:20 +10:00
|
|
|
System.arraycopy(inventory.mainInventory, 0, slots[9], 0, 9);
|
|
|
|
|
|
|
|
|
|
for (int row = 0; row < 3; row++)
|
|
|
|
|
System.arraycopy(inventory.mainInventory, (row + 1) * 9, slots[row + 6], 0, 9);
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
for (int row = 0; row < 6; row++) System.arraycopy(playerSave.creativeInv, row * 9, slots[row], 0, 9);
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
ItemStack[][] newslots = new ItemStack[10][];
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
// put back
|
|
|
|
|
for (int row = 0; row < 10; row++) newslots[(row + steps + 10) % 10] = slots[row];
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
System.arraycopy(newslots[9], 0, inventory.mainInventory, 0, 9);
|
|
|
|
|
|
|
|
|
|
for (int row = 0; row < 3; row++)
|
|
|
|
|
System.arraycopy(newslots[row + 6], 0, inventory.mainInventory, (row + 1) * 9, 9);
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
for (int row = 0; row < 6; row++) System.arraycopy(newslots[row], 0, playerSave.creativeInv, row * 9, 9);
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
playerSave.setDirty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<int[]> getEnchantments(ItemStack itemstack) {
|
2019-12-30 20:19:16 -08:00
|
|
|
ArrayList<int[]> arraylist = new ArrayList<>();
|
2014-04-29 10:54:20 +10:00
|
|
|
if (itemstack != null) {
|
|
|
|
|
NBTTagList nbttaglist = itemstack.getEnchantmentTagList();
|
|
|
|
|
if (nbttaglist != null) for (int i = 0; i < nbttaglist.tagCount(); i++) {
|
|
|
|
|
NBTTagCompound tag = nbttaglist.getCompoundTagAt(i);
|
2022-06-24 12:32:13 +01:00
|
|
|
arraylist.add(new int[] { tag.getShort("id"), tag.getShort("lvl") });
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return arraylist;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean stackHasEnchantment(ItemStack itemstack, int e) {
|
|
|
|
|
List<int[]> allenchantments = getEnchantments(itemstack);
|
2022-06-24 12:32:13 +01:00
|
|
|
for (int[] ai : allenchantments) if (ai[0] == e) return true;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int getEnchantmentLevel(ItemStack itemstack, int e) {
|
|
|
|
|
List<int[]> allenchantments = getEnchantments(itemstack);
|
2022-06-24 12:32:13 +01:00
|
|
|
for (int[] ai : allenchantments) if (ai[0] == e) return ai[1];
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean doesEnchantmentConflict(List<int[]> enchantments, Enchantment e) {
|
2022-06-24 12:32:13 +01:00
|
|
|
for (int[] ai : enchantments) if (!e.canApplyTogether(Enchantment.enchantmentsList[ai[0]])) return true;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static RuntimeException throwCME(String msg) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (CommonUtils.isClient()) return ClientHandler.throwCME(msg);
|
2014-04-29 10:54:20 +10:00
|
|
|
|
|
|
|
|
throw new RuntimeException(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
public static ItemStack[] extractRecipeItems(Object obj) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (obj instanceof ItemStack) return new ItemStack[] { (ItemStack) obj };
|
|
|
|
|
if (obj instanceof ItemStack[]) return (ItemStack[]) obj;
|
|
|
|
|
if (obj instanceof List) return ((List<ItemStack>) obj).toArray(new ItemStack[0]);
|
2014-04-29 10:54:20 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
throw new ClassCastException(obj + " not an ItemStack, ItemStack[] or List<ItemStack?");
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<Integer> getRange(final int start, final int end) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return new AbstractList<Integer>() {
|
2023-01-28 17:55:51 -08:00
|
|
|
|
2014-04-29 10:54:20 +10:00
|
|
|
@Override
|
|
|
|
|
public Integer get(int index) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return start + index;
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int size() {
|
2022-06-24 12:32:13 +01:00
|
|
|
return end - start;
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static StringBuilder fixTrailingCommaList(StringBuilder sb) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (sb.charAt(sb.length() - 1) == ',') sb.deleteCharAt(sb.length() - 1);
|
2014-04-29 10:54:20 +10:00
|
|
|
return sb;
|
|
|
|
|
}
|
2014-06-29 20:31:37 +10:00
|
|
|
|
|
|
|
|
public static void logOnce(Throwable t, Set<String> stackTraces, String message) {
|
|
|
|
|
logOnce(t, stackTraces, message, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void logOnce(Throwable t, Set<String> stackTraces, String message, String identifier) {
|
|
|
|
|
StringWriter sw = new StringWriter();
|
|
|
|
|
t.printStackTrace(new PrintWriter(sw));
|
|
|
|
|
String stackTrace = identifier + sw.toString();
|
|
|
|
|
if (!stackTraces.contains(stackTrace)) {
|
|
|
|
|
NEIServerConfig.logger.error(message, t);
|
|
|
|
|
stackTraces.add(stackTrace);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-10-01 20:01:10 +10:00
|
|
|
|
2022-01-31 01:01:12 +09:00
|
|
|
public static ItemStack getModdedItem(String itemId, String nbtString) {
|
|
|
|
|
int meta = -1;
|
|
|
|
|
ItemStack itemStack;
|
|
|
|
|
|
|
|
|
|
if (!itemId.contains(":")) {
|
|
|
|
|
NEIClientConfig.logger.info(String.format("Item ID %s is missing colon", itemId));
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
final String[] split = itemId.split(":");
|
|
|
|
|
// ModID:ItemID
|
|
|
|
|
String itemLookupId = split[0] + ":" + split[1];
|
|
|
|
|
|
|
|
|
|
if (split.length >= 3) {
|
|
|
|
|
int mIdx = -1;
|
|
|
|
|
if (split[2].matches("\\d+")) {
|
|
|
|
|
mIdx = 2;
|
|
|
|
|
} else {
|
|
|
|
|
itemLookupId += ":" + split[2];
|
|
|
|
|
if (split.length >= 4) mIdx = 3;
|
|
|
|
|
}
|
|
|
|
|
if (mIdx != -1) meta = Integer.parseInt(split[mIdx]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (meta != -1) {
|
|
|
|
|
itemStack = GameRegistry.makeItemStack(itemLookupId, meta, 1, nbtString == null ? "" : nbtString);
|
|
|
|
|
} else {
|
|
|
|
|
itemStack = GameRegistry.findItemStack(split[0], split[1], 1);
|
|
|
|
|
if (nbtString != null && !nbtString.isEmpty()) {
|
|
|
|
|
try {
|
|
|
|
|
final NBTBase nbttag = JsonToNBT.func_150315_a(nbtString);
|
|
|
|
|
if (!(nbttag instanceof NBTTagCompound)) {
|
|
|
|
|
NEIClientConfig.logger.info("Unexpected NBT string - multiple values {}", nbtString);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
itemStack.setTagCompound((NBTTagCompound) nbttag);
|
|
|
|
|
} catch (NBTException e) {
|
2022-06-24 12:32:13 +01:00
|
|
|
FMLLog.getLogger()
|
|
|
|
|
.log(Level.WARN, "Encountered an exception parsing ItemStack NBT string {}", nbtString, e);
|
2022-01-31 01:01:12 +09:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return itemStack;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-01 20:01:10 +10:00
|
|
|
public static NBTTagCompound readNBT(File file) throws IOException {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!file.exists()) return null;
|
2014-10-01 20:01:10 +10:00
|
|
|
FileInputStream in = new FileInputStream(file);
|
|
|
|
|
NBTTagCompound tag;
|
|
|
|
|
try {
|
|
|
|
|
tag = CompressedStreamTools.readCompressed(in);
|
2022-06-24 12:32:13 +01:00
|
|
|
} catch (ZipException e) {
|
|
|
|
|
if (e.getMessage().equals("Not in GZIP format")) tag = CompressedStreamTools.read(file);
|
|
|
|
|
else throw e;
|
2014-10-01 20:01:10 +10:00
|
|
|
}
|
|
|
|
|
in.close();
|
|
|
|
|
return tag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void writeNBT(NBTTagCompound tag, File file) throws IOException {
|
|
|
|
|
FileOutputStream out = new FileOutputStream(file);
|
|
|
|
|
CompressedStreamTools.writeCompressed(tag, out);
|
|
|
|
|
out.close();
|
|
|
|
|
}
|
2022-01-22 13:16:28 +09:00
|
|
|
|
|
|
|
|
public static int divideCeil(int numerator, int denominator) {
|
|
|
|
|
return (int) Math.ceil((float) numerator / denominator);
|
|
|
|
|
}
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|