diff --git a/src/main/java/org/ultramine/commands/basic/TechCommands.java b/src/main/java/org/ultramine/commands/basic/TechCommands.java index a82c8dc..a33ab23 100644 --- a/src/main/java/org/ultramine/commands/basic/TechCommands.java +++ b/src/main/java/org/ultramine/commands/basic/TechCommands.java @@ -742,5 +742,6 @@ server.getConfigurationManager().maxPlayers = cfg.settings.player.maxPlayers; server.getMultiWorld().reloadServerWorlds(); + UltramineServerModContainer.getInstance().reloadToolsCfg(); } } diff --git a/src/main/java/org/ultramine/server/UltramineServerModContainer.java b/src/main/java/org/ultramine/server/UltramineServerModContainer.java index a53495b..009b8af 100644 --- a/src/main/java/org/ultramine/server/UltramineServerModContainer.java +++ b/src/main/java/org/ultramine/server/UltramineServerModContainer.java @@ -44,6 +44,7 @@ import org.ultramine.server.data.ServerDataLoader; import org.ultramine.server.data.player.PlayerCoreData; import org.ultramine.server.tools.ButtonCommand; +import org.ultramine.server.tools.ItemBlocker; import org.ultramine.server.tools.WarpProtection; public class UltramineServerModContainer extends DummyModContainer @@ -52,6 +53,7 @@ @SideOnly(Side.SERVER) private ButtonCommand buttonCommand; + private ItemBlocker itemBlocker; private final RecipeCache recipeCache = new RecipeCache(); public UltramineServerModContainer() @@ -112,7 +114,10 @@ { e.getServer().getMultiWorld().register(); if(e.getSide().isServer()) + { buttonCommand = new ButtonCommand(e.getServer()); + itemBlocker = new ItemBlocker(); + } } @Subscribe @@ -148,6 +153,7 @@ if(e.getSide().isServer()) { buttonCommand.load(e); + itemBlocker.load(); MinecraftForge.EVENT_BUS.register(new WarpProtection()); } } @@ -212,4 +218,9 @@ { return recipeCache; } + + public void reloadToolsCfg() + { + itemBlocker.reload(); + } } diff --git a/src/main/java/org/ultramine/server/tools/ItemBlocker.java b/src/main/java/org/ultramine/server/tools/ItemBlocker.java new file mode 100644 index 0000000..a572661 --- /dev/null +++ b/src/main/java/org/ultramine/server/tools/ItemBlocker.java @@ -0,0 +1,213 @@ +package org.ultramine.server.tools; + +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.ultramine.server.ConfigurationHandler; +import org.ultramine.server.tools.ItemBlocker.ItemBlockerSettings.BlockingSettings; +import org.ultramine.server.tools.ItemBlocker.ItemBlockerSettings.BlockingWorldList; +import org.ultramine.server.util.BasicTypeParser; +import org.ultramine.server.util.YamlConfigProvider; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.functions.GenericIterableFactory; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.Slot; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.EntityItemPickupEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; + +@SideOnly(Side.SERVER) +public class ItemBlocker +{ + private final File storage; + private final TIntObjectMap map = new TIntObjectHashMap(); + private PerWorldBlocker global; + + public ItemBlocker() + { + this.storage = new File(ConfigurationHandler.getSettingDir(), "itemblocker.yml"); + } + + public void load() + { + MinecraftForge.EVENT_BUS.register(this); + FMLCommonHandler.instance().bus().register(this); + reload(); + } + + public void reload() + { + global = null; + map.clear(); + ItemBlockerSettings set = YamlConfigProvider.getOrCreateConfig(storage, ItemBlockerSettings.class); + if(set.global != null) + global = new PerWorldBlocker(set.global); + for(Map.Entry ent : set.worlds.entrySet()) + { + map.put(ent.getKey(), new PerWorldBlocker(ent.getValue().list)); + } + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onPlayerInteractEvent(PlayerInteractEvent e) + { + ItemStack is = e.entityPlayer.inventory.getCurrentItem(); + BlockingSettings set = getBlockingSettings(e.entityPlayer.dimension, is); + if(set != null && set.useItem) + { + e.setCanceled(true); + if(set.rmItem) + e.entityPlayer.inventory.setInventorySlotContents(e.entityPlayer.inventory.currentItem, null); + if(e.entityPlayer.isEntityPlayerMP() && ((EntityPlayerMP)e.entityPlayer).playerNetServerHandler != null) + e.entityPlayer.addChatMessage(new ChatComponentTranslation("ultramine.tools.itemblocker.useitem").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + return; + } + + set = getBlockingSettings(e.entityPlayer.dimension, Block.getIdFromBlock(e.world.getBlock(e.x, e.y, e.z)), e.world.getBlockMetadata(e.x, e.y, e.z)); + if(set != null && set.useBlock) + { + e.setCanceled(true); + if(set.rmBlock) + e.world.setBlock(e.x, e.y, e.z, Blocks.air, 0, 3); + if(e.entityPlayer.isEntityPlayerMP() && ((EntityPlayerMP)e.entityPlayer).playerNetServerHandler != null) + e.entityPlayer.addChatMessage(new ChatComponentTranslation("ultramine.tools.itemblocker.useblock").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onEntityItemPickup(EntityItemPickupEvent e) + { + BlockingSettings set = getBlockingSettings(e.entityPlayer.dimension, e.item.getEntityItem()); + if(set != null && set.rmItem) + { + e.setCanceled(true); + e.item.setDead(); + if(e.entityPlayer.isEntityPlayerMP() && ((EntityPlayerMP)e.entityPlayer).playerNetServerHandler != null) + e.entityPlayer.addChatMessage(new ChatComponentTranslation("ultramine.tools.itemblocker.rmblock").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + + @SubscribeEvent + public void onEntityItemPickup(TickEvent.ServerTickEvent e) + { + if(e.phase == TickEvent.Phase.END) + { + for(EntityPlayerMP player : GenericIterableFactory.newCastingIterable(MinecraftServer.getServer().getConfigurationManager().playerEntityList, EntityPlayerMP.class)) + { + if(player.openContainer != player.inventoryContainer) + { + for(Slot slot : GenericIterableFactory.newCastingIterable(player.openContainer.inventorySlots, Slot.class)) + { + ItemStack is = slot.getStack(); + BlockingSettings set = getBlockingSettings(player.dimension, is); + if(set != null && set.rmItem) + { + slot.putStack(null); + player.addChatMessage(new ChatComponentTranslation("ultramine.tools.itemblocker.rmblock").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } + } + } + } + } + + private BlockingSettings getBlockingSettings(int dim, int id, int data) + { + PerWorldBlocker ws = map.get(dim); + BlockingSettings ret = ws == null ? null : ws.getBlockingSettings(id, data); + if(ret == null && global != null) + ret = global.getBlockingSettings(id, data); + return ret; + } + + private BlockingSettings getBlockingSettings(int dim, ItemStack stack) + { + return stack == null ? null : getBlockingSettings(dim, Item.getIdFromItem(stack.getItem()), stack.getItemDamage()); + } + + public void remap() + { + for(PerWorldBlocker ws : map.valueCollection()) + { + ws.remap(); + } + } + + private class PerWorldBlocker + { + private final Map itemMap = new HashMap(); + private final TIntObjectMap fastMap = new TIntObjectHashMap(); + + public PerWorldBlocker(List list) + { + for(BlockingSettings ent : list) + { + addBlocking(BasicTypeParser.parseStackType(ent.item), ent); + } + } + + private void addBlocking(ItemStack type, BlockingSettings set) + { + itemMap.put(type, set); + fastMap.put((Item.getIdFromItem(type.getItem()) << 16) | (type.getItemDamage() & 0xFFFF), set); + } + + public void remap() + { + for(Entry ent : itemMap.entrySet()) + { + ItemStack input = ent.getKey(); + fastMap.put((Item.getIdFromItem(input.getItem()) << 16) | (input.getItemDamage() & 0xFFFF), ent.getValue()); + } + } + + public BlockingSettings getBlockingSettings(int id, int data) + { + int idPart = id << 16; + BlockingSettings ret = fastMap.get(idPart | (data & 0xFFFF)); + if(ret == null) + ret = fastMap.get(idPart | Short.MAX_VALUE); + return ret; + } + } + + public static class ItemBlockerSettings + { + public List global; + public Map worlds = new HashMap(); + + public static class BlockingSettings + { + public String item; + public boolean useItem; + public boolean rmItem; + public boolean useBlock; + public boolean rmBlock; + } + + public static class BlockingWorldList + { + public List list; + } + } +} diff --git a/src/main/java/org/ultramine/server/util/BasicTypeParser.java b/src/main/java/org/ultramine/server/util/BasicTypeParser.java index 71799bd..8bcbcbd 100644 --- a/src/main/java/org/ultramine/server/util/BasicTypeParser.java +++ b/src/main/java/org/ultramine/server/util/BasicTypeParser.java @@ -170,6 +170,40 @@ return is; } + public static ItemStack parseStackType(String str) + { + int ind = str.lastIndexOf(':'); + String itemS; + int data; + if(ind == -1) + { + itemS = str; + data = 0; + } + else + { + itemS = str.substring(0, ind); + String dataS = str.substring(ind+1, str.length()); + if(dataS.equals("*")) + { + data = Short.MAX_VALUE; + } + else + { + try + { + data = Integer.parseInt(dataS); + } + catch(NumberFormatException e) + { + throw new CommandException("commands.generic.itemstack.data", dataS); + } + } + } + + return new ItemStack(CommandBase.getItemByText(null, itemS), 1, data); + } + /** * Examples - 10, 5s, 24h, 10d7h5m3s
* s - second
diff --git a/src/main/resources/assets/ultramine/lang/en_US.lang b/src/main/resources/assets/ultramine/lang/en_US.lang index 848d3dd..bc42dcc 100644 --- a/src/main/resources/assets/ultramine/lang/en_US.lang +++ b/src/main/resources/assets/ultramine/lang/en_US.lang @@ -6,6 +6,10 @@ ultramine.autobroadcast.debugmsg=Server load: %s (Peak: %s), TPS: %s/20, Mobs: %s, Items: %s, Players: %s ultramine.autobackup.start=Autobackup started +ultramine.tools.itemblocker.useitem=Use of this item is forbidden by server +ultramine.tools.itemblocker.useblock=Use of this block is forbidden by server +ultramine.tools.itemblocker.rmitem=This item is forbidden by server + ultramine.ability.blockbreak=You don't have permissions to break blocks ultramine.ability.blockplace=You don't have permissions to place blocks ultramine.ability.useitem=You don't have permissions to use items diff --git a/src/main/resources/assets/ultramine/lang/ru_RU.lang b/src/main/resources/assets/ultramine/lang/ru_RU.lang index 9fe6360..72812ef 100644 --- a/src/main/resources/assets/ultramine/lang/ru_RU.lang +++ b/src/main/resources/assets/ultramine/lang/ru_RU.lang @@ -6,6 +6,10 @@ ultramine.autobroadcast.debugmsg=Сервер нагружен на %s (В пике - %s), Тиков в секунду: %s/20, Мобов: %s, Предметов: %s, Игроков: %s ultramine.autobackup.start=Выполняется автоматический бэкап мира +ultramine.tools.itemblocker.useitem=Использование данного предмета запрещено сервером +ultramine.tools.itemblocker.useblock=Использование данного блока запрещено сервером +ultramine.tools.itemblocker.rmitem=Данный предмет запрещен сервером + ultramine.ability.blockbreak=У вас нет прав на разрушение блоков ultramine.ability.blockplace=У вас нет прав на установку блоков ultramine.ability.useitem=У вас нет прав на использование предметов