- extended debug mode
 - major compatibility fix (hopefully fixes most issue tickets)
 - added remove pickups option
 - made remove drops optional
 - scheduled cleanup (to free a few bytes)
 - reload-command
This commit is contained in:
Jascha Starke 2012-02-01 22:25:34 +01:00
parent 4fc58c86aa
commit 700d8f54c1
11 changed files with 169 additions and 39 deletions

View file

@ -24,7 +24,6 @@ store:
# default: false # default: false
unsafe: false unsafe: false
# InventoryFolder # InventoryFolder
# The folder inside the datadir-folder (plugin/LimitedCreative) where the inventories are saved to. # The folder inside the datadir-folder (plugin/LimitedCreative) where the inventories are saved to.
# By default the inventories are saved to "plugin/LimitedCreative/inventories". # By default the inventories are saved to "plugin/LimitedCreative/inventories".
@ -39,11 +38,24 @@ limit:
# default: true # default: true
enabled: true enabled: true
# RemoveDrops
# When player not allowed to drop items, remove the item instead of putting it back to inventory/quickbar.
# You may disable this to get rid of the server.log-message: "Fetching addPacket for removed entity: CraftItem"
# default: true
remove_drops: true
# BlockPickup # BlockPickup
# Prevents the pickup of items while in creative mode # Prevents the pickup of items while in creative mode
# default: false # default: false
pickup: false pickup: false
# RemovePickup
# Instead of blocking the pickup, you may want to disappear the item from world (good when destroying walls with
# signs or playing with minecarts). Only works when BlockPickup: false.
# The permission nolimit.pickup bypasses the removing.
# default: false
remove_pickup: true
# BlockSign # BlockSign
# Prevents interacting with signs (right-click), while in creative mode, so trading becomes more difficult. # Prevents interacting with signs (right-click), while in creative mode, so trading becomes more difficult.
# Attention: this will also block useful signs, like Lifts. # Attention: this will also block useful signs, like Lifts.

View file

@ -16,7 +16,12 @@ command:
survival: Changes the game mode of a player to survival survival: Changes the game mode of a player to survival
creative: Changes the game mode of a player to creative creative: Changes the game mode of a player to creative
config: config:
overview: storecreative|blockpickup|blocksign|permissions|perm_keepinventory overview: "[setting] - empty for list of settings"
settings:
- "Available Settings: storecreative,"
- "removedrop, removepickup, blockpickup, blocksign,"
- "permissions, perm_keepinventory"
reload: Reloads plugin (doesn't work on update!)
gamemode: gamemode:
changed: "{0}'s game mode has been changed" changed: "{0}'s game mode has been changed"
no_change: Already in that game mode. no_change: Already in that game mode.

View file

@ -1,15 +1,15 @@
name: LimitedCreative name: LimitedCreative
main: de.jaschastarke.minecraft.limitedcreative.LimitedCreativeCore main: de.jaschastarke.minecraft.limitedcreative.LimitedCreativeCore
version: 0.8.1-beta version: 0.8.2-beta
softdepend: [WorldGuard, WorldEdit, MultiInv] softdepend: [WorldGuard, WorldEdit, MultiInv]
dev-url: http://dev.bukkit.org/server-mods/limited-creative/ dev-url: http://dev.bukkit.org/server-mods/limited-creative/
commands: commands:
limitedcreative: limitedcreative:
description: Main LimitedCreative-Controlling-Commands description: "LimitedCreative: GameMode-Switch, Creative-Regions, Config"
aliases: lc aliases: lc
usage: /<command> - displays LimitedCreative-Help usage: /<command> - displays LimitedCreative-Help
/region: /region:
description: Alternate region command, to use for WorldGuard-Integration description: "LimitedCreative-Region-Command: configure creative regions"
aliases: lcregion aliases: lcregion
usage: /<command> info|flag [<world>#]<region> - set/get region options usage: /<command> info|flag [<world>#]<region> - set/get region options
permissions: permissions:

View file

@ -40,6 +40,7 @@ public class Commands {
E, ENABLE, E, ENABLE,
D, DISABLE, D, DISABLE,
R, REGION, R, REGION,
RELOAD
}; };
@Override @Override
@ -74,6 +75,10 @@ public class Commands {
args = Arrays.copyOfRange(args, 1, args.length); args = Arrays.copyOfRange(args, 1, args.length);
plugin.getCommand("/region").execute(sender, "/region", args); plugin.getCommand("/region").execute(sender, "/region", args);
return true; return true;
case RELOAD:
plugin.getServer().getPluginManager().disablePlugin(plugin);
plugin.getServer().getPluginManager().enablePlugin(plugin);
return true;
} }
} catch (CommandException e) { } catch (CommandException e) {
LimitedCreativeCore.debug("CommandException: "+e.getMessage()); LimitedCreativeCore.debug("CommandException: "+e.getMessage());
@ -87,10 +92,11 @@ public class Commands {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
message.append("/"+c+" s[urvival] ["+L("command.player")+"] - "+L("command.switch.survival")+"\n"); message.append("/"+c+" s[urvival] ["+L("command.player")+"] - "+L("command.switch.survival")+"\n");
message.append("/"+c+" c[reative] ["+L("command.player")+"] - "+L("command.switch.creative")+"\n"); message.append("/"+c+" c[reative] ["+L("command.player")+"] - "+L("command.switch.creative")+"\n");
if (plugin.perm.hasPermission(sender, "limitedcreative.config")) if (plugin.perm.hasPermission(sender, "limitedcreative.config")) {
message.append("/"+c+" e[nable] "+L("command.config.overview")+"\n"); message.append("/"+c+" e[nable] "+L("command.config.overview")+"\n");
if (plugin.perm.hasPermission(sender, "limitedcreative.config"))
message.append("/"+c+" d[isable] "+L("command.config.overview")+"\n"); message.append("/"+c+" d[isable] "+L("command.config.overview")+"\n");
message.append("/"+c+" reload "+L("command.config.reload")+"\n");
}
if (plugin.perm.hasPermission(sender, "limitedcreative.regions")) if (plugin.perm.hasPermission(sender, "limitedcreative.regions"))
message.append("/"+c+" r[egion] "+L("command.worldguard.alias")+"\n"); message.append("/"+c+" r[egion] "+L("command.worldguard.alias")+"\n");
if (message.length() > 0) { if (message.length() > 0) {
@ -110,6 +116,8 @@ public class Commands {
BLOCKSIGN, BLOCKSIGN,
PERMISSIONS, PERMISSIONS,
PERM_KEEPINVENTORY, PERM_KEEPINVENTORY,
REMOVEDROP,
REMOVEPICKUP,
DEBUG, DEBUG,
}; };
@ -119,8 +127,11 @@ public class Commands {
} }
if (args.length > 2) if (args.length > 2)
throw new InvalidCommandException("exception.command.tomuchparameter"); throw new InvalidCommandException("exception.command.tomuchparameter");
if (args.length < 2) if (args.length < 2) {
throw new InvalidCommandException("exception.command.missingparameter"); for (String l : L("command.config.settings").split("\n"))
sender.sendMessage(l);
return;
}
Option opt = null; Option opt = null;
try { try {
@ -145,6 +156,15 @@ public class Commands {
case PERM_KEEPINVENTORY: case PERM_KEEPINVENTORY:
plugin.config.setPermissionToKeepInventory(b); plugin.config.setPermissionToKeepInventory(b);
break; break;
case REMOVEDROP:
plugin.config.setRemoveDrop(b);
break;
case REMOVEPICKUP:
plugin.config.setRemovePickup(b);
break;
case DEBUG:
plugin.config.setDebug(b);
break;
} }
sender.sendMessage(L("command.option.done")); sender.sendMessage(L("command.option.done"));
} }

View file

@ -75,6 +75,13 @@ public class Configuration {
public boolean getSignBlock() { public boolean getSignBlock() {
return c.getBoolean("limit.sign", true); return c.getBoolean("limit.sign", true);
} }
public boolean getRemoveDrop() {
return c.getBoolean("limit.remove_drops", true);
}
public boolean getRemovePickup() {
return c.getBoolean("limit.remove_pickup", false);
}
public boolean getPermissionsEnabled() { public boolean getPermissionsEnabled() {
return c.getBoolean("permissions.enabled", false); return c.getBoolean("permissions.enabled", false);
} }
@ -118,6 +125,16 @@ public class Configuration {
c.set("permissions.keepinventory", value); c.set("permissions.keepinventory", value);
this.save(); this.save();
} }
public void setRemoveDrop(boolean value) {
this.reload();
c.set("limit.remove_drops", value);
this.save();
}
public void setRemovePickup(boolean value) {
this.reload();
c.set("limit.remove_pickup", value);
this.save();
}
protected void reload() { protected void reload() {
_block_break = null; _block_break = null;

View file

@ -37,18 +37,23 @@ public class Inventory {
public Inventory(Player p) { public Inventory(Player p) {
player = p; player = p;
inv = p.getInventory(); }
private PlayerInventory inv() {
return player.getInventory();
} }
public void save() { public void save() {
LimitedCreativeCore.debug(player.getName() + " storing inventory "+player.getGameMode().toString());
File f = new File(LimitedCreativeCore.plugin.getDataFolder(), getFileName(player, player.getGameMode())); File f = new File(LimitedCreativeCore.plugin.getDataFolder(), getFileName(player, player.getGameMode()));
storeInventory(inv, f); storeInventory(inv(), f);
} }
public void load(GameMode gm) { public void load(GameMode gm) {
LimitedCreativeCore.debug(player.getName() + " loading inventory "+gm.toString());
File f = new File(LimitedCreativeCore.plugin.getDataFolder(), getFileName(player, gm)); File f = new File(LimitedCreativeCore.plugin.getDataFolder(), getFileName(player, gm));
try { try {
restoreInventory(inv, f); restoreInventory(inv(), f);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
if (LimitedCreativeCore.plugin.config.getUnsafeStorage()) { if (LimitedCreativeCore.plugin.config.getUnsafeStorage()) {
throw e; throw e;
@ -62,13 +67,13 @@ public class Inventory {
} }
public void clear() { public void clear() {
inv.setArmorContents(new ItemStack[]{ inv().setArmorContents(new ItemStack[]{
new ItemStack(0), new ItemStack(0),
new ItemStack(0), new ItemStack(0),
new ItemStack(0), new ItemStack(0),
new ItemStack(0), new ItemStack(0),
}); });
inv.clear(); inv().clear();
} }
private String getFileName(Player player, GameMode gm) { private String getFileName(Player player, GameMode gm) {

View file

@ -20,6 +20,7 @@ package de.jaschastarke.minecraft.limitedcreative;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -46,38 +47,70 @@ import static de.jaschastarke.minecraft.utils.Locale.L;
public class LCPlayer { public class LCPlayer {
private static LimitedCreativeCore plugin = LimitedCreativeCore.plugin; private static LimitedCreativeCore plugin = LimitedCreativeCore.plugin;
private static Map<Player, LCPlayer> players = new HashMap<Player, LCPlayer>(); private static Map<String, LCPlayer> players = new HashMap<String, LCPlayer>();
private Player player; private Player player;
private Map<Integer, ItemStack> tempinv = null; private Map<Integer, ItemStack> tempinv = null;
private Inventory _inv;
private boolean _isPermanentCreative = false;
private boolean _isRegionCreative = false;
private long _timestamp;
public static final long CLEANUP_TIMEOUT = 90000; // 90s * 20ticks
private static File _store_file = new File(plugin.getDataFolder(), "players.yml"); private static File _store_file = new File(plugin.getDataFolder(), "players.yml");
public static YamlConfiguration store = YamlConfiguration.loadConfiguration(_store_file); public static YamlConfiguration store = YamlConfiguration.loadConfiguration(_store_file);
private boolean _isPermanentCreative = false; private LCPlayer(Player player) {
private boolean _isRegionCreative = false; this.player = player;
private LCPlayer(Player pplayer) {
player = pplayer;
_isRegionCreative = store.getBoolean(player.getName()+".region_creative", false) && player.getGameMode() == GameMode.CREATIVE; _isRegionCreative = store.getBoolean(player.getName()+".region_creative", false) && player.getGameMode() == GameMode.CREATIVE;
if (player.getGameMode() == GameMode.CREATIVE && !this.isRegionCreative()) { if (player.getGameMode() == GameMode.CREATIVE && !this.isRegionCreative()) {
LimitedCreativeCore.debug(player.getName() + " was already creative"); LimitedCreativeCore.debug(player.getName() + " was already creative");
setPermanentCreative(true); setPermanentCreative(true);
} }
} }
private void updatePlayer(Player player) {
this.player = player;
_inv = null;
}
public Player getRaw() { public Player getRaw() {
return player; return player;
} }
public static LCPlayer get(Player pplayer) { public void touch() {
if (!players.containsKey(pplayer)) { _timestamp = System.currentTimeMillis();
LCPlayer p = new LCPlayer(pplayer); }
players.put(pplayer, p);
public boolean isOutdated() {
return !getRaw().isOnline() && _timestamp < (System.currentTimeMillis() - CLEANUP_TIMEOUT);
}
public static LCPlayer get(Player player) {
LimitedCreativeCore.debug("player: " + player.getName() + " - " + ((Object)player).hashCode() + " - " + player.getEntityId() + " - " + player.getUniqueId());
if (!players.containsKey(player.getName())) {
LCPlayer p = new LCPlayer(player);
players.put(player.getName(), p);
p.touch();
return p; return p;
} else { } else {
return players.get(pplayer); LCPlayer p = players.get(player.getName());
if (player != p.getRaw())
p.updatePlayer(player);
p.touch();
return p;
} }
} }
public static void cleanUp() {
int count = players.size();
Iterator<Map.Entry<String, LCPlayer>> i = players.entrySet().iterator();
while (i.hasNext()) {
Map.Entry<String, LCPlayer> entry = i.next();
if (entry.getValue().isOutdated()) {
LimitedCreativeCore.debug("removing "+entry.getValue().getRaw().getName());
i.remove();
}
}
LimitedCreativeCore.debug("cleanup done: player count: "+count+" / "+players.size());
}
public boolean isRegionCreative() { public boolean isRegionCreative() {
return _isRegionCreative; return _isRegionCreative;
@ -124,16 +157,21 @@ public class LCPlayer {
if (plugin.config.getStoreEnabled()) { if (plugin.config.getStoreEnabled()) {
if (plugin.config.getPermissionToKeepInventory() && hasPermission("limitedcreative.keepinventory")) if (plugin.config.getPermissionToKeepInventory() && hasPermission("limitedcreative.keepinventory"))
return true; return true;
Inventory inv = new Inventory(player); inv().save();
inv.save(); if (plugin.config.getStoreCreative() && inv().isStored(GameMode.CREATIVE)) {
if (plugin.config.getStoreCreative() && inv.isStored(GameMode.CREATIVE)) { inv().load(GameMode.CREATIVE);
inv.load(GameMode.CREATIVE);
} else { } else {
inv.clear(); inv().clear();
} }
} }
return true; return true;
} }
private Inventory inv() {
if (_inv == null)
_inv = new Inventory(player);
return _inv;
}
public boolean onSetSurvival() { public boolean onSetSurvival() {
LimitedCreativeCore.debug(player.getName() + " going into survival"); LimitedCreativeCore.debug(player.getName() + " going into survival");
if (isRegionCreative()) { if (isRegionCreative()) {
@ -147,27 +185,36 @@ public class LCPlayer {
if (plugin.config.getStoreEnabled()) { if (plugin.config.getStoreEnabled()) {
if (plugin.config.getPermissionToKeepInventory() && hasPermission("limitedcreative.keepinventory")) if (plugin.config.getPermissionToKeepInventory() && hasPermission("limitedcreative.keepinventory"))
return true; return true;
Inventory inv = new Inventory(player);
if (plugin.config.getStoreCreative()) { if (plugin.config.getStoreCreative()) {
inv.save(); inv().save();
} }
if (inv.isStored(GameMode.SURVIVAL)) if (inv().isStored(GameMode.SURVIVAL))
inv.load(GameMode.SURVIVAL); inv().load(GameMode.SURVIVAL);
} }
return true; return true;
} }
public void onDropItem(PlayerDropItemEvent event) { public void onDropItem(PlayerDropItemEvent event) {
LimitedCreativeCore.debug(player.getName() + " ("+player.getGameMode()+") drops items " + event.getItemDrop().getItemStack().getType());
if (player.getGameMode() == GameMode.CREATIVE) { if (player.getGameMode() == GameMode.CREATIVE) {
if (plugin.config.getPermissionsEnabled() && hasPermission("limitedcreative.nolimit.drop")) if (plugin.config.getPermissionsEnabled() && hasPermission("limitedcreative.nolimit.drop"))
return; return;
LimitedCreativeCore.debug("removed");
if (plugin.config.getRemoveDrop())
event.getItemDrop().remove(); event.getItemDrop().remove();
else
event.setCancelled(true);
} }
} }
public void onPickupItem(PlayerPickupItemEvent event) { public void onPickupItem(PlayerPickupItemEvent event) {
if (player.getGameMode() == GameMode.CREATIVE && plugin.config.getBlockPickupInCreative()) { if (player.getGameMode() == GameMode.CREATIVE) {
if (plugin.config.getPermissionsEnabled() && hasPermission("limitedcreative.nolimit.pickup")) if (plugin.config.getPermissionsEnabled() && hasPermission("limitedcreative.nolimit.pickup"))
return; return;
if (plugin.config.getBlockPickupInCreative()) {
event.setCancelled(true); event.setCancelled(true);
} else if(plugin.config.getRemovePickup()) {
event.getItem().remove();
event.setCancelled(true);
}
} }
} }

View file

@ -39,6 +39,7 @@ public class LimitedCreativeCore extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
plugin.getServer().getScheduler().cancelTasks(this);
plugin = null; plugin = null;
worldguard = null; worldguard = null;
config = null; config = null;
@ -82,6 +83,13 @@ public class LimitedCreativeCore extends JavaPlugin {
Commands.register(this); Commands.register(this);
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
LCPlayer.cleanUp();
}
}, LCPlayer.CLEANUP_TIMEOUT / 50L, LCPlayer.CLEANUP_TIMEOUT / 50L); // 50 = 1000ms / 20ticks
PluginDescriptionFile df = this.getDescription(); PluginDescriptionFile df = this.getDescription();
if (worldguard != null) if (worldguard != null)
logger.info("["+df.getName() + " v" + df.getVersion() + "] "+L("basic.loaded.worldguard")); logger.info("["+df.getName() + " v" + df.getVersion() + "] "+L("basic.loaded.worldguard"));

View file

@ -47,6 +47,10 @@ public class MainListener implements Listener {
@EventHandler @EventHandler
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) { public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
LimitedCreativeCore.debug("onPlayerGameModeChange: "+event.getPlayer().getName());
LimitedCreativeCore.debug("Current GameMode: "+event.getPlayer().getGameMode());
LimitedCreativeCore.debug("New GameMode: "+event.getNewGameMode());
LimitedCreativeCore.debug("isCancelled: "+event.isCancelled());
if (event.getNewGameMode() == GameMode.CREATIVE) { if (event.getNewGameMode() == GameMode.CREATIVE) {
if (!LCPlayer.get(event.getPlayer()).onSetCreative()) if (!LCPlayer.get(event.getPlayer()).onSetCreative())
event.setCancelled(true); event.setCancelled(true);

View file

@ -19,6 +19,7 @@ package de.jaschastarke.minecraft.utils;
import java.io.File; import java.io.File;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.List;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -40,8 +41,16 @@ public class Locale {
return "lang/"+locale+".yml"; return "lang/"+locale+".yml";
} }
public String get(String msg) { public String get(String msg) {
if (lang.contains(msg)) if (lang.contains(msg)) {
if (lang.isList(msg)) {
List<String> list = lang.getStringList(msg);
String[] lines = new String[list.size()];
list.toArray(lines);
return Util.join(lines, "\n");
} else {
return lang.getString(msg); return lang.getString(msg);
}
}
return msg; return msg;
} }

View file

@ -83,4 +83,7 @@ final public class Util {
public static String join(String[] list) { public static String join(String[] list) {
return join(list, " ", 0, list.length); return join(list, " ", 0, list.length);
} }
public static String join(String[] list, String sep) {
return join(list, sep, 0, list.length);
}
} }