Base impl. Feature Limits

This commit is contained in:
Jascha Starke 2013-02-01 22:25:43 +01:00
parent dbce96a5ac
commit 0d0a9bfaba
16 changed files with 955 additions and 25 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@
/.classpath
/.settings
/.buildpath
/.checkstyle
# maven
/target

View file

@ -56,12 +56,12 @@
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.4.6-R0.1</version>
<version>1.4.7-R0.1</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.4.6-R0.1</version>
<version>1.4.7-R0.1</version>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>

View file

@ -28,8 +28,27 @@ public class Config extends PluginConfiguration {
super.save();
}
/**
* Metrics
*
* This settings allows the Addon-Author to track the Servers using this plugin. It will not track any player
* related data like names, ips, online time or such. Please do not disable the option! As more servers are using
* the plugin and the author knows, as more he is willing to support the plugin! Its a win-win for both.
*
* default: true
* @TODO Move to a sub-class modular configuration
*/
@IsConfigurationNode(order = 1000)
public boolean getMetrics() {
return config.getBoolean("metrics", true);
}
/**
* Debug
*
* The debug modus spams much details about the plugin to the server-log (console) which can help to solve issues.
*
* default: false
*/
@IsConfigurationNode(order = 9999)
public boolean getDebug() {

View file

@ -0,0 +1,41 @@
package de.jaschastarke.minecraft.limitedcreative;
import org.bukkit.event.Listener;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.bukkit.tools.stats.IStatistics;
import de.jaschastarke.bukkit.tools.stats.PiwikStatistics;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
public class FeatureMetrics extends CoreModule<LimitedCreative> implements Listener {
public FeatureMetrics(LimitedCreative plugin) {
super(plugin);
}
private IStatistics metric;
@Override
public void initialize(ModuleEntry<IModule> pEntry) {
super.initialize(pEntry);
if (!plugin.getPluginConfig().getMetrics()) {
pEntry.initialState = ModuleState.DISABLED;
}
}
@Override
public void onEnable() {
metric = new PiwikStatistics(plugin);
}
@Override
public void onDisable() {
metric.unregister();
}
public void track(String event) {
if (metric == null)
throw new IllegalAccessError("The feature hasn't been enabled");
metric.trackEvent(event);
}
}

View file

@ -16,7 +16,7 @@ import de.jaschastarke.bukkit.lib.commands.ICommand;
import de.jaschastarke.bukkit.lib.commands.MethodCommand;
import de.jaschastarke.bukkit.lib.commands.IMethodCommandContainer;
import de.jaschastarke.bukkit.lib.commands.MissingPermissionCommandException;
import de.jaschastarke.bukkit.lib.commands.NeedsPlayerCommandException;
import de.jaschastarke.bukkit.lib.commands.NeedsPlayerArgumentCommandException;
import de.jaschastarke.bukkit.lib.commands.annotations.Alias;
import de.jaschastarke.bukkit.lib.commands.annotations.Description;
import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand;
@ -37,14 +37,14 @@ public class FeatureSwitchGameMode extends CoreModule<LimitedCreative> {
}
@Override
public void OnEnable() {
public void onEnable() {
if (commands == null)
commands = new Commands();
plugin.getMainCommand().getHandler().registerCommands(commands.getCommandList());
}
@Override
public void OnDisable() {
public void onDisable() {
if (commands != null)
plugin.getMainCommand().getHandler().removeCommands(commands.getCommandList());
}
@ -66,20 +66,23 @@ public class FeatureSwitchGameMode extends CoreModule<LimitedCreative> {
protected boolean changeGameMode(CommandContext context, String player, GameMode tgm, IAbstractPermission permission) throws MissingPermissionCommandException, CommandException {
Player target = null;
if (player != null && !player.isEmpty())
if (player != null && !player.isEmpty()) {
target = Bukkit.getPlayer(player);
else if (context.isPlayer())
if (target == null)
throw new CommandException("Player " + player + " not found");
} else if (context.isPlayer()) {
target = context.getPlayer();
}
if (target == null)
throw new NeedsPlayerCommandException();
throw new NeedsPlayerArgumentCommandException();
if (!target.equals(context.getSender()) && !context.checkPermission(SwitchGameModePermissions.OTHER))
throw new MissingPermissionCommandException(SwitchGameModePermissions.OTHER);
GameMode wgm = Hooks.DefaultWorldGameMode.get(target.getWorld());
if (context.checkPermission(permission) || (wgm == tgm && context.checkPermission(SwitchGameModePermissions.BACKONLY)))
if (!context.checkPermission(permission) && !(wgm != tgm || !context.checkPermission(SwitchGameModePermissions.BACKONLY)))
throw new MissingPermissionCommandException(permission);
target.setGameMode(tgm);

View file

@ -1,22 +1,25 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.i18n;
import de.jaschastarke.I18n;
import de.jaschastarke.bukkit.lib.Core;
import de.jaschastarke.bukkit.lib.PluginLang;
import de.jaschastarke.bukkit.lib.configuration.ConfigCommand;
public class LimitedCreative extends Core {
protected Config config = null;
protected MainCommand command = null;
@Override
public void OnInitialize() {
super.OnInitialize();
public void onInitialize() {
super.onInitialize();
config = new Config(this);
this.debug = config.getDebug();
setLang(new PluginLang("lang/messages", this));
command = new MainCommand(this);
ConfigCommand cc = new ConfigCommand(config, Permissions.CONFIG);
cc.setPackageName(this.getName() + " - " + this.getLocale().trans(cc.getPackageName()));
command.registerCommand(cc);
commands.registerCommand(command);
Hooks.inizializeHooks(this);
@ -26,15 +29,21 @@ public class LimitedCreative extends Core {
addModule(new ModCreativeLimits(this));
addModule(new ModRegions(this));
addModule(new ModCmdBlocker(this));
addModule(new FeatureMetrics(this));
config.saveDefault();
}
@Override
public boolean isDebug() {
return config.getDebug();
}
public Config getPluginConfig() {
return config;
}
public i18n getLocale() {
public I18n getLocale() {
return getLang();
}

View file

@ -1,19 +1,26 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.minecraft.limitedcreative.limits.LimitConfig;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
public class ModCreativeLimits extends CoreModule<LimitedCreative> {
protected LimitConfig config;
public ModCreativeLimits(LimitedCreative plugin) {
super(plugin);
}
public LimitConfig getConfig() {
return config;
}
protected FeatureBlockItemSpawn blockDrops = null;
@Override
public void Initialize(ModuleEntry<IModule> entry) {
super.Initialize(entry);
public void initialize(ModuleEntry<IModule> entry) {
super.initialize(entry);
blockDrops = plugin.getModule(FeatureBlockItemSpawn.class);
if (blockDrops == null)
blockDrops = plugin.addModule(new FeatureBlockItemSpawn(plugin)).getModule();

View file

@ -18,6 +18,7 @@ import de.jaschastarke.minecraft.limitedcreative.inventories.store.InvYamlStorag
import de.jaschastarke.minecraft.limitedcreative.inventories.store.PlayerInventoryStorage;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
public class ModInventories extends CoreModule<LimitedCreative> {
protected PlayerInventoryStorage storage;
@ -34,20 +35,30 @@ public class ModInventories extends CoreModule<LimitedCreative> {
}
@Override
public void Initialize(ModuleEntry<IModule> entry) {
super.Initialize(entry);
public void initialize(ModuleEntry<IModule> entry) {
super.initialize(entry);
listeners.addListener(new PlayerListener(this));
config = plugin.getPluginConfig().registerSection(new InventoryConfig(this));
config = plugin.getPluginConfig().registerSection(new InventoryConfig(this, entry));
armor_config = config.registerSection(new ArmoryConfig(this));
if (!config.getEnabled()) {
entry.initialState = ModuleState.DISABLED;
return;
}
String incomp = Hooks.InventoryIncompatible.test();
if (incomp != null) {
getLog().warn(plugin.getLocale().trans("basic.conflict", incomp, this.getName()));
entry.initialState = ModuleState.NOT_INITIALIZED;
}
}
@Override
public void OnEnable() {
super.OnEnable();
public void onEnable() {
String incomp = Hooks.InventoryIncompatible.test();
if (incomp != null) {
throw new IllegalAccessError(plugin.getLocale().trans("basic.conflict", incomp, this.getName()));
}
super.onEnable();
storage = new InvYamlStorage(this, new File(plugin.getDataFolder(), config.getFolder()));
inventories = new WeakHashMap<Player, Inventory>();
getLog().info(plugin.getLocale().trans("basic.loaded.module"));

View file

@ -11,7 +11,7 @@ import de.jaschastarke.bukkit.lib.ModuleLogger;
import de.jaschastarke.bukkit.lib.configuration.Configuration;
import de.jaschastarke.bukkit.lib.items.MaterialDataNotRecognizedException;
import de.jaschastarke.bukkit.lib.items.MaterialNotRecognizedException;
import de.jaschastarke.bukkit.lib.items.Utils;
import de.jaschastarke.bukkit.lib.items.ItemUtils;
import de.jaschastarke.configuration.IConfigurationSubGroup;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
@ -28,6 +28,12 @@ public class ArmoryConfig extends Configuration implements IConfigurationSubGrou
public ArmoryConfig(ModInventories modInventories) {
mod = modInventories;
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public void setValues(ConfigurationSection sect) {
if (sect == null || sect.getValues(false).size() == 0) {
@ -68,7 +74,7 @@ public class ArmoryConfig extends Configuration implements IConfigurationSubGrou
} else {
MaterialData md = null;
try {
md = Utils.parseMaterial((String) entry.getValue());
md = ItemUtils.parseMaterial((String) entry.getValue());
} catch (MaterialNotRecognizedException e) {
getLog().warn(L("exception.config.material_not_found", entry.getValue()));
} catch (MaterialDataNotRecognizedException e) {

View file

@ -3,10 +3,14 @@ package de.jaschastarke.minecraft.limitedcreative.inventories;
import org.bukkit.configuration.ConfigurationSection;
import de.jaschastarke.bukkit.lib.configuration.Configuration;
import de.jaschastarke.configuration.IConfigurationNode;
import de.jaschastarke.configuration.IConfigurationSubGroup;
import de.jaschastarke.configuration.InvalidValueException;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.minecraft.limitedcreative.ModInventories;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
/**
* Inventory-Feature
@ -15,10 +19,32 @@ import de.jaschastarke.minecraft.limitedcreative.ModInventories;
*/
@ArchiveDocComments
public class InventoryConfig extends Configuration implements IConfigurationSubGroup {
protected ModInventories mod;
public InventoryConfig(ModInventories modInventories) {
protected ModuleEntry<IModule> entry;
public InventoryConfig(ModInventories modInventories, ModuleEntry<IModule> modEntry) {
mod = modInventories;
entry = modEntry;
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public void setValue(IConfigurationNode node, Object pValue) throws InvalidValueException {
super.setValue(node, pValue);
if (node.getName().equals("enabled")) {
if ((Boolean) pValue) {
entry.activate();
} else {
entry.disable();
}
}
}
@Override
public void setValues(ConfigurationSection sect) {
if (sect == null || sect.getValues(false).size() == 0) {
@ -91,7 +117,7 @@ public class InventoryConfig extends Configuration implements IConfigurationSubG
*
* default: "inventories"
*/
@IsConfigurationNode(order = 400)
@IsConfigurationNode(order = 400, readonly = true)
public String getFolder() {
return config.getString("folder", "inventories");
}

View file

@ -0,0 +1,120 @@
package de.jaschastarke.minecraft.limitedcreative.limits;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import de.jaschastarke.bukkit.lib.configuration.ConfigurableList;
import de.jaschastarke.bukkit.lib.items.ItemUtils;
import de.jaschastarke.bukkit.lib.items.MaterialDataNotRecognizedException;
import de.jaschastarke.bukkit.lib.items.MaterialNotRecognizedException;
public class BlackList extends ArrayList<BlackList.Blacklisted> implements ConfigurableList {
private static final long serialVersionUID = -3701659163474405152L;
public static class Blacklisted {
private String stringRep;
private MaterialData md;
private boolean hasData = false;
public Blacklisted(String rep) {
stringRep = rep;
try {
md = ItemUtils.parseMaterial(rep);
hasData = rep.contains(ItemUtils.MATERIAL_DATA_SEP);
} catch (MaterialNotRecognizedException e) {
throw new IllegalArgumentException(e);
} catch (MaterialDataNotRecognizedException e) {
throw new IllegalArgumentException(e);
}
}
public Blacklisted(Material m) {
md = new MaterialData(m);
stringRep = m.toString();
}
public Blacklisted(MaterialData md) {
this.md = md;
stringRep = md.getItemType().toString() + ItemUtils.MATERIAL_DATA_SEP + Integer.toString(md.getData());
}
public boolean matches(ItemStack item) {
if (hasData) {
return md.equals(item.getData());
} else {
return item.getType().equals(md.getItemType());
}
}
public boolean matches(Block block) {
if (hasData) {
return md.equals(block.getData());
} else {
return block.getType().equals(md.getItemType());
}
}
public String toString() {
return stringRep;
}
}
public BlackList() {
}
public BlackList(List<?> list) {
if (list != null) {
for (Object el : list) {
if (el instanceof Blacklisted)
add((Blacklisted) el);
else
add(el.toString());
}
}
}
public boolean contains(String e) {
for (Blacklisted bl : this) {
if (bl.toString().equals(e))
return true;
}
return false;
}
public boolean isListed(ItemStack item) {
for (Blacklisted bl : this) {
if (bl.matches(item))
return true;
}
return false;
}
public boolean isListed(Block block) {
for (Blacklisted bl : this) {
if (bl.matches(block))
return true;
}
return false;
}
@Override // ConfigurableList, not List<E>
public void add(String e) {
if (!contains(e)) {
add(new Blacklisted(e));
}
}
@Override // ConfigurableList, not List<E>
public boolean remove(String e) {
Iterator<Blacklisted> it = iterator();
while (it.hasNext()) {
if (it.next().toString().equals(e)) {
it.remove();
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,62 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.limits;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import de.jaschastarke.minecraft.lib.permissions.IDynamicPermission;
import de.jaschastarke.minecraft.limitedcreative.ModCreativeLimits;
public class BlockListener implements Listener {
private ModCreativeLimits mod;
public BlockListener(ModCreativeLimits mod) {
this.mod = mod;
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
if (!event.isCancelled() && event.getPlayer().getGameMode() == GameMode.CREATIVE) {
if (mod.getConfig().getBlockBreak().isListed(event.getBlock())) {
if (!checkPermission(event.getPlayer(), NoLimitPermissions.BREAK(event.getBlock()))) {
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.break"));
}
}
}
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (!event.isCancelled() && event.getPlayer().getGameMode() == GameMode.CREATIVE) {
if (mod.getConfig().getBlockUse().isListed(event.getBlock())) {
if (!checkPermission(event.getPlayer(), NoLimitPermissions.USE(event.getBlock()))) {
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.place"));
}
}
}
}
private boolean checkPermission(Player player, IDynamicPermission perm) {
return mod.getPlugin().getPermManager().hasPermission(player, perm);
}
}

View file

@ -0,0 +1,55 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.limits;
import org.bukkit.GameMode;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityTargetEvent;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.limitedcreative.ModCreativeLimits;
public class EntityListener implements Listener {
private ModCreativeLimits mod;
public EntityListener(ModCreativeLimits mod) {
this.mod = mod;
}
/**
* don't let the player be target by creatures he can't kill
*/
@EventHandler
public void onEntityTargetPlayer(EntityTargetEvent event) {
if (event.getTarget() instanceof Player && !event.isCancelled()) {
if (event.getEntity() instanceof Creature) {
if (((Player) event.getTarget()).getGameMode() == GameMode.CREATIVE && mod.getConfig().getBlockDamageMob()) {
if (!checkPermission((Player) event.getTarget(), NoLimitPermissions.MOB_DAMAGE)) {
event.setCancelled(true);
}
}
}
}
}
private boolean checkPermission(Player player, IAbstractPermission perm) {
return mod.getPlugin().getPermManager().hasPermission(player, perm);
}
}

View file

@ -0,0 +1,243 @@
package de.jaschastarke.minecraft.limitedcreative.limits;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import de.jaschastarke.bukkit.lib.configuration.Configuration;
import de.jaschastarke.configuration.IConfigurationNode;
import de.jaschastarke.configuration.IConfigurationSubGroup;
import de.jaschastarke.configuration.InvalidValueException;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.minecraft.limitedcreative.ModCreativeLimits;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
/**
* Creative Limits-Feature
*
* http://dev.bukkit.org/server-mods/limited-creative/pages/features/limit/
*/
@ArchiveDocComments
public class LimitConfig extends Configuration implements IConfigurationSubGroup {
protected ModCreativeLimits mod;
protected ModuleEntry<IModule> entry;
public LimitConfig(ModCreativeLimits modInventories, ModuleEntry<IModule> modEntry) {
mod = modInventories;
entry = modEntry;
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public void setValue(IConfigurationNode node, Object pValue) throws InvalidValueException {
super.setValue(node, pValue);
if (node.getName().equals("enabled")) {
if ((Boolean) pValue) {
entry.activate();
} else {
entry.disable();
}
}
}
@Override
public void setValues(ConfigurationSection sect) {
super.setValues(sect);
// Config Upgrade
if (!sect.contains("interact") && sect.contains("sign")) {
interactList = new BlackList();
if (config.getBoolean("sign", true)) {
interactList.add(new BlackList.Blacklisted(Material.SIGN));
interactList.add(new BlackList.Blacklisted(Material.SIGN_POST));
}
if (config.getBoolean("button", false)) {
interactList.add(new BlackList.Blacklisted(Material.LEVER));
interactList.add(new BlackList.Blacklisted(Material.STONE_BUTTON));
interactList.add(new BlackList.Blacklisted(Material.WOOD_BUTTON));
}
if (config.getBoolean("workbench", false)) {
interactList.add(new BlackList.Blacklisted(Material.WORKBENCH));
interactList.add(new BlackList.Blacklisted(Material.ANVIL));
interactList.add(new BlackList.Blacklisted(Material.ENCHANTMENT_TABLE));
}
}
if (!sect.contains("removeDrops") && sect.contains("remove_drops"))
sect.set("removeDrops", sect.getBoolean("remove_drops"));
if (!sect.contains("damageToMobs") && sect.contains("damagemob"))
sect.set("damageToMobs", sect.getBoolean("damagemob"));
}
@Override
public String getName() {
return "limit";
}
@Override
public int getOrder() {
return 200;
}
/**
* LimitEnabled
*
* Prevents all players in creative-mode from:
* - accessing chests
* - dropping items from "inventory" to the ground
* - doing PvP (wouldn't be fair, would it?)
*
* Also if this option is disabled all other Limit-Options below are disabled too. To just disable some of these
* limitations, use the "nolimit"-permissions.
*
* default: true
*/
@IsConfigurationNode(order = 100)
public boolean getEnabled() {
return config.getBoolean("enabled", true);
}
/**
* LimitDropsInsteadPrevent
*
* When enabled items that are dropped by creative players are removed (burning in the hellfire or so, they just
* disappear). When disabled the items stay in the inventory of the player.
*
* default: false
*/
@IsConfigurationNode(order = 200)
public boolean getRemoveDrops() {
return config.getBoolean("removeDrops", false);
}
public static enum BlockPickup {
PREVENT,
REMOVE;
}
/**
* LimitDamageToMobs
*
* Prevents dealing damage to all creatures when the player is in creative (friendly sheeps as well as hostile
* creepers).
*
* default: false
*/
@IsConfigurationNode(name = "damageToMobs", order = 300)
public boolean getBlockDamageMob() {
return config.getBoolean("damageToMobs", false);
}
/**
* LimitPickup
*
* Prevents the pickup of items while in creative mode. Either the items are just stay on ground and ignore that a
* creative player walks over it ("prevent"), or the are "remove"d when a creative player walks over it. This is
* helpful e.g. when the creative player destroys a long line of rails.
*
* valid options: remove / prevent / false
* default: remove
*/
@IsConfigurationNode(name = "pickup", order = 300)
public BlockPickup getBlockPickup() {
return getEnum(BlockPickup.class, "pickup", BlockPickup.PREVENT);
}
private BlackList interactList;
/**
* LimitInteraction
*
* Prevents players of using interacting with specific blocks as addition to chests in creative mode (and only in
* creative).
*
* You can use the technical name (see http://jd.bukkit.org/doxygen/d6/d0e/enumorg_1_1bukkit_1_1Material.html) or
* the id of the block/item (better use the id, if you're not sure). You may add the data separated with a colon
* e.g.: "WOOL:11" blocks blue wool. But be sure to put it in quotes, to not break yml-configuration! Named data
* values aren't supported yet. If you don't add a data-value, all blocks of this material are blocked.
*
* default:
* - SIGN
* - SIGN_POST
* - LEVER
* - STONE_BUTTON
* - WOOD_BUTTON
* - WORKBENCH
* - ANVIL
* - ENCHANTMENT_TABLE
*/
@IsConfigurationNode(name = "interact", order = 600)
public BlackList getBlockInteraction() {
if (interactList == null) {
interactList = new BlackList(config.getList("interact"));
if (!config.contains("interact")) {
interactList.add(new BlackList.Blacklisted(Material.SIGN));
interactList.add(new BlackList.Blacklisted(Material.SIGN_POST));
interactList.add(new BlackList.Blacklisted(Material.LEVER));
interactList.add(new BlackList.Blacklisted(Material.STONE_BUTTON));
interactList.add(new BlackList.Blacklisted(Material.WOOD_BUTTON));
interactList.add(new BlackList.Blacklisted(Material.WORKBENCH));
interactList.add(new BlackList.Blacklisted(Material.ANVIL));
interactList.add(new BlackList.Blacklisted(Material.ENCHANTMENT_TABLE));
}
}
return interactList;
}
private BlackList useList;
/**
* LimitUse
*
* Prevents players of using or placing specific items/blocks in creative mode (and only in creative).
*
* You can use the technical name (see http://jd.bukkit.org/doxygen/d6/d0e/enumorg_1_1bukkit_1_1Material.html) or
* the id of the block/item (better use the id, if you're not sure). You may add the data separated with a colon
* e.g.: "WOOL:11" blocks blue wool. But be sure to put it in quotes, to not break yml-configuration! Named data
* values aren't supported yet. If you don't add a data-value, all blocks of this material are blocked.
*
* default:
* - EXP_BOTTLE
* - BEDROCK
*/
@IsConfigurationNode(name = "use", order = 700)
public BlackList getBlockUse() {
if (useList == null) {
useList = new BlackList(config.getList("use"));
if (!config.contains("use")) {
useList.add(new BlackList.Blacklisted(Material.EXP_BOTTLE));
useList.add(new BlackList.Blacklisted(Material.BEDROCK));
}
}
return useList;
}
private BlackList breakList;
/**
* LimitBreak
*
* Prevents players of destroying specific blocks in creative mode (and only in creative).
*
* You can use the technical name (see http://jd.bukkit.org/doxygen/d6/d0e/enumorg_1_1bukkit_1_1Material.html) or
* the id of the block/item (better use the id, if you're not sure). You may add the data separated with a colon
* e.g.: "WOOL:11" blocks blue wool. But be sure to put it in quotes, to not break yml-configuration! Named data
* values aren't supported yet. If you don't add a data-value, all blocks of this material are blocked.
*
* default:
* - BEDROCK
*/
@IsConfigurationNode(name = "break", order = 800)
public BlackList getBlockBreak() {
if (breakList == null) {
breakList = new BlackList(config.getList("use"));
if (!config.contains("break")) {
breakList.add(new BlackList.Blacklisted(Material.BEDROCK));
}
}
return breakList;
}
}

View file

@ -0,0 +1,118 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.limits;
import java.util.Collection;
import org.bukkit.block.Block;
import org.bukkit.material.MaterialData;
import org.bukkit.permissions.PermissionDefault;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.minecraft.lib.permissions.BasicPermission;
import de.jaschastarke.minecraft.lib.permissions.DynamicPermission;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.lib.permissions.IDynamicPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermissionContainer;
import de.jaschastarke.minecraft.lib.permissions.IsChildPermission;
import de.jaschastarke.minecraft.lib.permissions.SimplePermissionContainerNode;
import de.jaschastarke.minecraft.limitedcreative.Permissions;
@ArchiveDocComments
public class NoLimitPermissions extends BasicPermission {
public NoLimitPermissions(IAbstractPermission parent, String name, PermissionDefault defaultValue) {
super(parent, name, defaultValue);
}
public static final IPermissionContainer PARENT = new SimplePermissionContainerNode(Permissions.CONTAINER, "nolimit");
/**
* Grants bypassing of all nolimit-permissions.
*/
public static final IPermission ALL = new NoLimitPermissions(PARENT, "*", PermissionDefault.OP);
/**
* Allows bypassing the "do not open a chest"-limitation
*/
@IsChildPermission
public static final IPermission CHEST = new BasicPermission(PARENT, "chest", PermissionDefault.FALSE);
/**
* Allows bypassing the "do not drop anything"-limitation
*/
@IsChildPermission
public static final IPermission DROP = new BasicPermission(PARENT, "drop", PermissionDefault.FALSE);
/**
* Allows bypassing the "do not pickup anything"-limitation
*/
@IsChildPermission
public static final IPermission PICKUP = new BasicPermission(PARENT, "pickup", PermissionDefault.FALSE);
/**
* Allows bypassing the "no pvp"-limitation
*/
@IsChildPermission
public static final IPermission PVP = new BasicPermission(PARENT, "pvp", PermissionDefault.FALSE);
/**
* Allows bypassing the "no dealing damage to creatures"-limitation
*/
@IsChildPermission
public static final IPermission MOB_DAMAGE = new BasicPermission(PARENT, "mob_damage", PermissionDefault.FALSE);
/**
* Allows bypassing the "do not interact with specific blocks"-limitation
*/
@IsChildPermission
public static final IPermission BASE_INTERACT = new BasicPermission(PARENT, "interact", PermissionDefault.FALSE);
/**
* Allows bypassing the "block place/item use"-limitation
*/
@IsChildPermission
public static final IPermission BASE_USE = new BasicPermission(PARENT, "use", PermissionDefault.FALSE);
/**
* Allows bypassing the "block break"-limitation
*/
@IsChildPermission
public static final IPermission BASE_BREAK = new BasicPermission(PARENT, "break", PermissionDefault.FALSE);
public static IDynamicPermission INTERACT(Block block) {
return new MaterialPermission(BASE_INTERACT, new MaterialData(block.getType(), block.getData()));
}
public static IDynamicPermission USE(Block block) {
return new MaterialPermission(BASE_USE, new MaterialData(block.getType(), block.getData()));
}
public static IDynamicPermission USE(MaterialData m) {
return new MaterialPermission(BASE_USE, m);
}
public static IDynamicPermission BREAK(Block block) {
return new MaterialPermission(BASE_BREAK, new MaterialData(block.getType(), block.getData()));
}
public static class MaterialPermission extends DynamicPermission {
private MaterialData md;
public MaterialPermission(IAbstractPermission parent, MaterialData m) {
super(parent);
md = m;
}
@Override
protected void buildPermissionsToCheck(Collection<IAbstractPermission> perms) {
perms.add(new BasicPermission(parent, md.getItemType().toString()));
perms.add(new BasicPermission(parent, md.getItemType().toString() + IAbstractPermission.SEP + md.getData()));
}
}
}

View file

@ -0,0 +1,209 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.limits;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.StorageMinecart;
import org.bukkit.entity.Villager;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.InventoryHolder;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.lib.permissions.IDynamicPermission;
import de.jaschastarke.minecraft.limitedcreative.ModCreativeLimits;
import de.jaschastarke.minecraft.limitedcreative.limits.LimitConfig.BlockPickup;
public class PlayerListener implements Listener {
private ModCreativeLimits mod;
public PlayerListener(ModCreativeLimits mod) {
this.mod = mod;
}
/**
* The isCancelled in PlayerInteractEvent doesn't check useItemInHand, even this decides (when clicking on
* entity with e.g. a bucket)
* @param event
* @return The relevant "isCancelled"
*/
public static boolean isCancelled(PlayerInteractEvent event) {
return event.useInteractedBlock() == Event.Result.DENY && event.useItemInHand() == Event.Result.DENY;
}
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
if (!event.isCancelled() && event.getPlayer().getGameMode() == GameMode.CREATIVE) {
if (checkPermission(event, NoLimitPermissions.DROP))
return;
event.getItemDrop().remove();
//event.setCancelled(true); // doesn't make much sense
}
}
@EventHandler
public void onEntityDeath(EntityDeathEvent event) {
if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
if (player.getGameMode() == GameMode.CREATIVE) {
if (checkPermission(player, NoLimitPermissions.DROP))
return;
event.getDrops().clear();
}
}
}
@EventHandler
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
if (!event.isCancelled() && event.getPlayer().getGameMode() == GameMode.CREATIVE) {
LimitConfig.BlockPickup pickup = mod.getConfig().getBlockPickup();
if (pickup != null) {
if (checkPermission(event, NoLimitPermissions.DROP))
return;
if (pickup == BlockPickup.REMOVE) {
event.getItem().remove();
}
event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!isCancelled(event) && event.getPlayer().getGameMode() == GameMode.CREATIVE) {
if (mod.getConfig().getBlockUse().isListed(event.getItem())) {
if (!checkPermission(event, NoLimitPermissions.USE(event.getItem().getData()))) {
event.setCancelled(true);
event.setUseItemInHand(Event.Result.DENY);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.use"));
return;
}
}
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Block block = event.getClickedBlock();
if (isChest(block)) {
if (!checkPermission(event, NoLimitPermissions.CHEST)) {
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.chest"));
return;
}
} else if (mod.getConfig().getBlockInteraction().isListed(block)) {
if (!checkPermission(event, NoLimitPermissions.INTERACT(block))) {
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.interact"));
return;
}
}
}
}
}
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (!event.isCancelled() && event.getPlayer().getGameMode() == GameMode.CREATIVE) {
if (mod.getConfig().getBlockUse().isListed(event.getPlayer().getItemInHand())) {
if (!checkPermission(event, NoLimitPermissions.USE(event.getPlayer().getItemInHand().getData()))) {
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.use"));
return;
}
}
Entity entity = event.getRightClicked();
if (isChest(entity)) {
if (!checkPermission(event, NoLimitPermissions.CHEST)) {
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.chest"));
return;
}
} else if (entity instanceof Villager && mod.getConfig().getBlockInteraction().size() > 0) {
if (!checkPermission(event, NoLimitPermissions.BASE_INTERACT)) {
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("blocked.entity"));
return;
}
}
}
}
@EventHandler
public void onEntityDamageByEntity(EntityDamageEvent rawevent) {
if (rawevent instanceof EntityDamageByEntityEvent && !rawevent.isCancelled()) {
EntityDamageByEntityEvent event = (EntityDamageByEntityEvent) rawevent;
Entity source = event.getDamager();
if (source instanceof Projectile)
source = ((Projectile) source).getShooter();
if (source instanceof Player) {
Player player = (Player) source;
if (player.getGameMode() == GameMode.CREATIVE) {
if (event.getEntity() instanceof Player) {
if (!checkPermission(player, NoLimitPermissions.PVP)) {
event.setCancelled(true);
}
} else if (event.getEntity() instanceof LivingEntity && mod.getConfig().getBlockDamageMob()) {
if (!checkPermission(player, NoLimitPermissions.MOB_DAMAGE)) {
event.setCancelled(true);
}
}
}
}
}
}
/**
* Returns if the block is a chest or an other inventory-holder, that can hold items.
*/
private boolean isChest(Block block) {
return block.getState() instanceof InventoryHolder ||
block.getType() == Material.ENDER_CHEST || block.getType() == Material.BEACON; // Workaround, Bukkit not recognize a Enderchests/Beacons
}
/**
* Returns if the entity can hold items. Like storage minecarts or item-frames.
*/
private boolean isChest(Entity entity) {
return entity instanceof StorageMinecart || entity instanceof ItemFrame;
}
private boolean checkPermission(Player player, IAbstractPermission perm) {
return mod.getPlugin().getPermManager().hasPermission(player, perm);
}
private boolean checkPermission(PlayerEvent event, IAbstractPermission perm) {
return mod.getPlugin().getPermManager().hasPermission(event.getPlayer(), perm);
}
private boolean checkPermission(PlayerEvent event, IDynamicPermission perm) {
return mod.getPlugin().getPermManager().hasPermission(event.getPlayer(), perm);
}
}