package codechicken.nei; import codechicken.core.CommonUtils; import codechicken.core.ServerUtils; import codechicken.lib.inventory.InventoryRange; import codechicken.lib.inventory.InventoryUtils; import codechicken.lib.packet.PacketCustom; 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; import net.minecraft.nbt.CompressedStreamTools; 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; import java.io.*; import java.util.*; import java.util.zip.ZipException; public class NEIServerUtils { public static boolean isRaining(World world) { return world.getWorldInfo().isRaining(); } public static void toggleRaining(World world, boolean notify) { boolean raining = !world.isRaining(); if (!raining)//turn off ((WorldServer) world).provider.resetRainAndThunder(); else world.getWorldInfo().setRaining(!isRaining(world)); 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) { if (slot == -999) player.inventory.setItemStack(item); else if (containerInv) player.openContainer.putStackInSlot(slot, item); else player.inventory.setInventorySlotContents(slot, item); } public static ItemStack getSlotContents(EntityPlayer player, int slot, boolean containerInv) { if (slot == -999) return player.inventory.getItemStack(); else if (containerInv) return player.openContainer.getSlot(slot).getStack(); else return player.inventory.getStackInSlot(slot); } @SuppressWarnings("unchecked") public static void deleteAllItems(EntityPlayerMP player) { for (Slot slot : (List<Slot>) player.openContainer.inventorySlots) slot.putStack(null); player.updateCraftingInventory(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 = world.provider.getDimensionId(); int hour = (int) (getTime(world) % 24000) / 1000; int newhour = hour; while (NEIServerConfig.isActionDisabled(dim, NEIActions.timeZones[newhour / 6])) newhour = ((newhour / 6 + 1) % 4) * 6; if (newhour != hour) setHourForward(world, newhour, false); } public static boolean canItemFitInInventory(EntityPlayer player, ItemStack itemstack) { return InventoryUtils.insertItem(new InventoryRange(player.inventory, 0, 36), itemstack, true) == 0; } public static void sendNotice(ICommandSender sender, IChatComponent msg, String permission) { ChatComponentTranslation notice = new ChatComponentTranslation("chat.type.admin", sender.getCommandSenderName(), msg.createCopy()); notice.getChatStyle().setColor(EnumChatFormatting.GRAY).setItalic(true); if (NEIServerConfig.canPlayerPerformAction("CONSOLE", permission)) MinecraftServer.getServer().addChatMessage(notice); for (EntityPlayer p : ServerUtils.getPlayers()) if(p == sender) p.addChatComponentMessage(msg); 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) { return stack1 != null && stack2 != null && (stack1.getItem() == stack2.getItem() && (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage()) && ItemStack.areItemStackTagsEqual(stack2, stack1)); } /** * {@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) { 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()); } /** * 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) { 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()); 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) { player.addChatComponentMessage(setColour(new ChatComponentTranslation("nei.chat.give.noitem"), EnumChatFormatting.WHITE)); return; } int given = stack.stackSize; if(doGive) { if (infinite) player.inventory.addItemStackToInventory(stack); else given -= InventoryUtils.insertItem(player.inventory, stack, false); } sendNotice(player, new ChatComponentTranslation("commands.give.success", stack.getChatComponent(), infinite ? "\u221E" : Integer.toString(given), player.getCommandSenderName()), "notify-item"); player.openContainer.detectAndSendChanges(); } public static ItemStack copyStack(ItemStack itemstack, int i) { if (itemstack == null) return null; itemstack.stackSize += i; return itemstack.splitStack(i); } public static ItemStack copyStack(ItemStack itemstack) { if (itemstack == null) return null; 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) { 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; } 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) { if (mode < 0 || mode >= NEIActions.gameModes.length || NEIActions.nameActionMap.containsKey(NEIActions.gameModes[mode]) && !NEIServerConfig.canPlayerPerformAction(player.getCommandSenderName(), NEIActions.gameModes[mode])) return; //creative+ NEIServerConfig.forPlayer(player.getCommandSenderName()).enableAction("creative+", mode == 2); if(mode == 2 && !(player.openContainer instanceof ContainerCreativeInv))//open the container immediately for the client NEISPH.processCreativeInv(player, true); //change it on the server player.theItemInWorldManager.setGameType(getGameType(mode)); //tell the client to change it new PacketCustom(NEISPH.channel, 14).writeByte(mode).sendToPlayer(player); player.addChatMessage(new ChatComponentTranslation("nei.chat.gamemode." + mode)); } public static void cycleCreativeInv(EntityPlayerMP player, int steps) { InventoryPlayer inventory = player.inventory; //top down [row][col] ItemStack[][] slots = new ItemStack[10][9]; PlayerSave playerSave = NEIServerConfig.forPlayer(player.getCommandSenderName()); //get 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); for (int row = 0; row < 6; row++) System.arraycopy(playerSave.creativeInv, row * 9, slots[row], 0, 9); ItemStack[][] newslots = new ItemStack[10][]; //put back for (int row = 0; row < 10; row++) newslots[(row + steps + 10) % 10] = slots[row]; 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); for (int row = 0; row < 6; row++) System.arraycopy(newslots[row], 0, playerSave.creativeInv, row * 9, 9); playerSave.setDirty(); } public static List<int[]> getEnchantments(ItemStack itemstack) { ArrayList<int[]> arraylist = new ArrayList<int[]>(); if (itemstack != null) { NBTTagList nbttaglist = itemstack.getEnchantmentTagList(); if (nbttaglist != null) for (int i = 0; i < nbttaglist.tagCount(); i++) { NBTTagCompound tag = nbttaglist.getCompoundTagAt(i); arraylist.add(new int[]{tag.getShort("id"), tag.getShort("lvl")}); } } return arraylist; } public static boolean stackHasEnchantment(ItemStack itemstack, int e) { List<int[]> allenchantments = getEnchantments(itemstack); for (int[] ai : allenchantments) if (ai[0] == e) return true; return false; } public static int getEnchantmentLevel(ItemStack itemstack, int e) { List<int[]> allenchantments = getEnchantments(itemstack); for (int[] ai : allenchantments) if (ai[0] == e) return ai[1]; return -1; } public static boolean doesEnchantmentConflict(List<int[]> enchantments, Enchantment e) { for (int[] ai : enchantments) if (!e.canApplyTogether(Enchantment.enchantmentsList[ai[0]])) return true; return false; } public static RuntimeException throwCME(String msg) { if (CommonUtils.isClient()) return ClientHandler.throwCME(msg); throw new RuntimeException(msg); } @SuppressWarnings("unchecked") public static ItemStack[] extractRecipeItems(Object obj) { 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]); throw new ClassCastException("not an ItemStack, ItemStack[] or List<ItemStack?"); } public static List<Integer> getRange(final int start, final int end) { return new AbstractList<Integer>() { @Override public Integer get(int index) { return start+index; } @Override public int size() { return end-start; } }; } public static StringBuilder fixTrailingCommaList(StringBuilder sb) { if(sb.charAt(sb.length()-1) == ',') sb.deleteCharAt(sb.length()-1); return sb; } 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); } } public static NBTTagCompound readNBT(File file) throws IOException { if(!file.exists()) return null; FileInputStream in = new FileInputStream(file); NBTTagCompound tag; try { tag = CompressedStreamTools.readCompressed(in); } catch(ZipException e) { if(e.getMessage().equals("Not in GZIP format")) tag = CompressedStreamTools.read(file); else throw e; } 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(); } }