- 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
unsafe: false
# InventoryFolder
# The folder inside the datadir-folder (plugin/LimitedCreative) where the inventories are saved to.
# By default the inventories are saved to "plugin/LimitedCreative/inventories".
@ -39,11 +38,24 @@ limit:
# default: 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
# Prevents the pickup of items while in creative mode
# default: 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
# Prevents interacting with signs (right-click), while in creative mode, so trading becomes more difficult.
# 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
creative: Changes the game mode of a player to creative
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:
changed: "{0}'s game mode has been changed"
no_change: Already in that game mode.

View file

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

View file

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

View file

@ -75,6 +75,13 @@ public class Configuration {
public boolean getSignBlock() {
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() {
return c.getBoolean("permissions.enabled", false);
}
@ -118,6 +125,16 @@ public class Configuration {
c.set("permissions.keepinventory", value);
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() {
_block_break = null;

View file

@ -37,18 +37,23 @@ public class Inventory {
public Inventory(Player p) {
player = p;
inv = p.getInventory();
}
private PlayerInventory inv() {
return player.getInventory();
}
public void save() {
LimitedCreativeCore.debug(player.getName() + " storing inventory "+player.getGameMode().toString());
File f = new File(LimitedCreativeCore.plugin.getDataFolder(), getFileName(player, player.getGameMode()));
storeInventory(inv, f);
storeInventory(inv(), f);
}
public void load(GameMode gm) {
LimitedCreativeCore.debug(player.getName() + " loading inventory "+gm.toString());
File f = new File(LimitedCreativeCore.plugin.getDataFolder(), getFileName(player, gm));
try {
restoreInventory(inv, f);
restoreInventory(inv(), f);
} catch (IllegalArgumentException e) {
if (LimitedCreativeCore.plugin.config.getUnsafeStorage()) {
throw e;
@ -62,13 +67,13 @@ public class Inventory {
}
public void clear() {
inv.setArmorContents(new ItemStack[]{
inv().setArmorContents(new ItemStack[]{
new ItemStack(0),
new ItemStack(0),
new ItemStack(0),
new ItemStack(0),
});
inv.clear();
inv().clear();
}
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.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.bukkit.ChatColor;
@ -46,38 +47,70 @@ import static de.jaschastarke.minecraft.utils.Locale.L;
public class LCPlayer {
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 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");
public static YamlConfiguration store = YamlConfiguration.loadConfiguration(_store_file);
private boolean _isPermanentCreative = false;
private boolean _isRegionCreative = false;
private LCPlayer(Player pplayer) {
player = pplayer;
private LCPlayer(Player player) {
this.player = player;
_isRegionCreative = store.getBoolean(player.getName()+".region_creative", false) && player.getGameMode() == GameMode.CREATIVE;
if (player.getGameMode() == GameMode.CREATIVE && !this.isRegionCreative()) {
LimitedCreativeCore.debug(player.getName() + " was already creative");
setPermanentCreative(true);
}
}
private void updatePlayer(Player player) {
this.player = player;
_inv = null;
}
public Player getRaw() {
return player;
}
public static LCPlayer get(Player pplayer) {
if (!players.containsKey(pplayer)) {
LCPlayer p = new LCPlayer(pplayer);
players.put(pplayer, p);
public void touch() {
_timestamp = System.currentTimeMillis();
}
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;
} 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() {
return _isRegionCreative;
@ -124,16 +157,21 @@ public class LCPlayer {
if (plugin.config.getStoreEnabled()) {
if (plugin.config.getPermissionToKeepInventory() && hasPermission("limitedcreative.keepinventory"))
return true;
Inventory inv = new Inventory(player);
inv.save();
if (plugin.config.getStoreCreative() && inv.isStored(GameMode.CREATIVE)) {
inv.load(GameMode.CREATIVE);
inv().save();
if (plugin.config.getStoreCreative() && inv().isStored(GameMode.CREATIVE)) {
inv().load(GameMode.CREATIVE);
} else {
inv.clear();
inv().clear();
}
}
return true;
}
private Inventory inv() {
if (_inv == null)
_inv = new Inventory(player);
return _inv;
}
public boolean onSetSurvival() {
LimitedCreativeCore.debug(player.getName() + " going into survival");
if (isRegionCreative()) {
@ -147,27 +185,36 @@ public class LCPlayer {
if (plugin.config.getStoreEnabled()) {
if (plugin.config.getPermissionToKeepInventory() && hasPermission("limitedcreative.keepinventory"))
return true;
Inventory inv = new Inventory(player);
if (plugin.config.getStoreCreative()) {
inv.save();
inv().save();
}
if (inv.isStored(GameMode.SURVIVAL))
inv.load(GameMode.SURVIVAL);
if (inv().isStored(GameMode.SURVIVAL))
inv().load(GameMode.SURVIVAL);
}
return true;
}
public void onDropItem(PlayerDropItemEvent event) {
LimitedCreativeCore.debug(player.getName() + " ("+player.getGameMode()+") drops items " + event.getItemDrop().getItemStack().getType());
if (player.getGameMode() == GameMode.CREATIVE) {
if (plugin.config.getPermissionsEnabled() && hasPermission("limitedcreative.nolimit.drop"))
return;
LimitedCreativeCore.debug("removed");
if (plugin.config.getRemoveDrop())
event.getItemDrop().remove();
else
event.setCancelled(true);
}
}
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"))
return;
if (plugin.config.getBlockPickupInCreative()) {
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
public void onDisable() {
plugin.getServer().getScheduler().cancelTasks(this);
plugin = null;
worldguard = null;
config = null;
@ -82,6 +83,13 @@ public class LimitedCreativeCore extends JavaPlugin {
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();
if (worldguard != null)
logger.info("["+df.getName() + " v" + df.getVersion() + "] "+L("basic.loaded.worldguard"));

View file

@ -47,6 +47,10 @@ public class MainListener implements Listener {
@EventHandler
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 (!LCPlayer.get(event.getPlayer()).onSetCreative())
event.setCancelled(true);

View file

@ -19,6 +19,7 @@ package de.jaschastarke.minecraft.utils;
import java.io.File;
import java.text.MessageFormat;
import java.util.List;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
@ -40,8 +41,16 @@ public class Locale {
return "lang/"+locale+".yml";
}
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 msg;
}

View file

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