2012-01-15 00:51:37 +01:00
|
|
|
package net.citizensnpcs;
|
|
|
|
|
2012-01-19 11:52:58 +01:00
|
|
|
import java.io.File;
|
2012-01-23 15:30:15 +01:00
|
|
|
import java.util.HashMap;
|
2012-02-04 07:48:23 +01:00
|
|
|
import java.util.List;
|
2012-01-23 15:30:15 +01:00
|
|
|
import java.util.Map;
|
2012-01-29 21:58:19 +01:00
|
|
|
import java.util.logging.Level;
|
2012-01-19 11:52:58 +01:00
|
|
|
|
2012-01-23 15:30:15 +01:00
|
|
|
import net.citizensnpcs.Settings.Setting;
|
2012-01-15 00:51:37 +01:00
|
|
|
import net.citizensnpcs.api.CitizensAPI;
|
2012-01-19 11:52:58 +01:00
|
|
|
import net.citizensnpcs.api.DataKey;
|
2012-02-04 00:35:24 +01:00
|
|
|
import net.citizensnpcs.api.exception.NPCException;
|
2012-01-19 11:52:58 +01:00
|
|
|
import net.citizensnpcs.api.exception.NPCLoadException;
|
2012-01-18 05:04:08 +01:00
|
|
|
import net.citizensnpcs.api.npc.NPC;
|
2012-01-19 11:52:58 +01:00
|
|
|
import net.citizensnpcs.api.npc.trait.Character;
|
2012-01-23 07:12:45 +01:00
|
|
|
import net.citizensnpcs.api.npc.trait.DefaultInstanceFactory;
|
2012-01-19 11:52:58 +01:00
|
|
|
import net.citizensnpcs.api.npc.trait.Trait;
|
2012-01-26 22:08:32 +01:00
|
|
|
import net.citizensnpcs.api.npc.trait.trait.Owner;
|
2012-01-21 17:21:21 +01:00
|
|
|
import net.citizensnpcs.api.npc.trait.trait.SpawnLocation;
|
2012-01-29 19:23:42 +01:00
|
|
|
import net.citizensnpcs.api.npc.trait.trait.Spawned;
|
2012-01-25 16:29:54 +01:00
|
|
|
import net.citizensnpcs.command.CommandManager;
|
2012-01-25 21:07:49 +01:00
|
|
|
import net.citizensnpcs.command.Injector;
|
2012-02-08 09:26:14 +01:00
|
|
|
import net.citizensnpcs.command.command.HelpCommands;
|
2012-01-25 16:29:54 +01:00
|
|
|
import net.citizensnpcs.command.command.NPCCommands;
|
|
|
|
import net.citizensnpcs.command.exception.CommandUsageException;
|
|
|
|
import net.citizensnpcs.command.exception.MissingNestedCommandException;
|
|
|
|
import net.citizensnpcs.command.exception.NoPermissionsException;
|
|
|
|
import net.citizensnpcs.command.exception.RequirementMissingException;
|
|
|
|
import net.citizensnpcs.command.exception.ServerCommandException;
|
|
|
|
import net.citizensnpcs.command.exception.UnhandledCommandException;
|
|
|
|
import net.citizensnpcs.command.exception.WrappedCommandException;
|
2012-01-15 00:51:37 +01:00
|
|
|
import net.citizensnpcs.npc.CitizensNPCManager;
|
2012-01-30 12:58:59 +01:00
|
|
|
import net.citizensnpcs.storage.DatabaseStorage;
|
2012-01-19 11:52:58 +01:00
|
|
|
import net.citizensnpcs.storage.Storage;
|
2012-01-30 12:58:59 +01:00
|
|
|
import net.citizensnpcs.storage.YamlStorage;
|
2012-02-05 08:18:40 +01:00
|
|
|
import net.citizensnpcs.trait.Inventory;
|
2012-02-03 10:20:48 +01:00
|
|
|
import net.citizensnpcs.trait.LookClose;
|
2012-01-16 04:15:32 +01:00
|
|
|
import net.citizensnpcs.util.Messaging;
|
2012-01-25 16:29:54 +01:00
|
|
|
import net.citizensnpcs.util.StringHelper;
|
2012-01-15 00:51:37 +01:00
|
|
|
|
2012-01-18 05:04:08 +01:00
|
|
|
import org.bukkit.Bukkit;
|
2012-01-22 18:43:58 +01:00
|
|
|
import org.bukkit.ChatColor;
|
2012-01-19 11:52:58 +01:00
|
|
|
import org.bukkit.command.Command;
|
|
|
|
import org.bukkit.command.CommandSender;
|
2012-01-29 21:58:19 +01:00
|
|
|
import org.bukkit.craftbukkit.CraftServer;
|
2012-02-03 10:20:48 +01:00
|
|
|
import org.bukkit.entity.CreatureType;
|
2012-01-19 11:52:58 +01:00
|
|
|
import org.bukkit.entity.Player;
|
2012-01-23 15:30:15 +01:00
|
|
|
import org.bukkit.permissions.Permission;
|
|
|
|
import org.bukkit.permissions.PermissionDefault;
|
2012-01-15 00:51:37 +01:00
|
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
|
|
|
2012-02-04 07:48:23 +01:00
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
2012-01-15 06:09:31 +01:00
|
|
|
public class Citizens extends JavaPlugin {
|
2012-01-29 21:58:19 +01:00
|
|
|
private static final String COMPATIBLE_MC_VERSION = "1.1";
|
2012-01-25 16:29:54 +01:00
|
|
|
|
2012-02-04 07:48:23 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
2012-02-04 09:13:20 +01:00
|
|
|
private static final List<Class<? extends Trait>> defaultTraits = Lists.newArrayList(Owner.class, Spawned.class,
|
2012-02-05 08:18:40 +01:00
|
|
|
LookClose.class, SpawnLocation.class, Inventory.class);
|
2012-02-04 07:48:23 +01:00
|
|
|
|
2012-01-28 05:11:23 +01:00
|
|
|
private volatile CitizensNPCManager npcManager;
|
2012-02-08 09:26:14 +01:00
|
|
|
private final DefaultInstanceFactory<Character> characterManager = new DefaultInstanceFactory<Character>();
|
|
|
|
private final DefaultInstanceFactory<Trait> traitManager = new DefaultInstanceFactory<Trait>();
|
|
|
|
private final CommandManager cmdManager = new CommandManager();
|
2012-01-21 14:56:50 +01:00
|
|
|
private Settings config;
|
2012-01-29 21:58:19 +01:00
|
|
|
private Storage saves;
|
2012-01-30 19:55:16 +01:00
|
|
|
private boolean compatible;
|
2012-01-21 14:56:50 +01:00
|
|
|
|
2012-02-04 07:48:23 +01:00
|
|
|
private boolean handleMistake(CommandSender sender, String command, String modifier) {
|
|
|
|
int minDist = Integer.MAX_VALUE;
|
|
|
|
String closest = "";
|
|
|
|
for (String string : cmdManager.getAllCommandModifiers(command)) {
|
|
|
|
int distance = StringHelper.getLevenshteinDistance(modifier, string);
|
|
|
|
if (minDist > distance) {
|
|
|
|
minDist = distance;
|
|
|
|
closest = string;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!closest.isEmpty()) {
|
|
|
|
sender.sendMessage(ChatColor.GRAY + "Unknown command. Did you mean:");
|
|
|
|
sender.sendMessage(StringHelper.wrap(" /") + command + " " + StringHelper.wrap(closest));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-01-23 09:45:34 +01:00
|
|
|
@Override
|
|
|
|
public boolean onCommand(CommandSender sender, Command cmd, String cmdName, String[] args) {
|
2012-01-25 16:29:54 +01:00
|
|
|
Player player = null;
|
|
|
|
if (sender instanceof Player)
|
|
|
|
player = (Player) sender;
|
|
|
|
|
|
|
|
try {
|
|
|
|
// must put command into split.
|
|
|
|
String[] split = new String[args.length + 1];
|
|
|
|
System.arraycopy(args, 0, split, 1, args.length);
|
|
|
|
split[0] = cmd.getName().toLowerCase();
|
|
|
|
|
|
|
|
String modifier = "";
|
|
|
|
if (args.length > 0)
|
|
|
|
modifier = args[0];
|
|
|
|
|
|
|
|
// No command found!
|
|
|
|
if (!cmdManager.hasCommand(split[0], modifier)) {
|
|
|
|
if (!modifier.isEmpty()) {
|
|
|
|
boolean value = handleMistake(sender, split[0], modifier);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NPC npc = null;
|
2012-01-28 23:40:00 +01:00
|
|
|
if (player != null)
|
2012-01-25 16:29:54 +01:00
|
|
|
npc = npcManager.getSelectedNPC(player);
|
|
|
|
|
|
|
|
try {
|
|
|
|
cmdManager.execute(split, player, player == null ? sender : player, npc);
|
|
|
|
} catch (ServerCommandException ex) {
|
|
|
|
sender.sendMessage("You must be in-game to execute that command.");
|
|
|
|
} catch (NoPermissionsException ex) {
|
|
|
|
Messaging.sendError(player, "You don't have permission to execute that command.");
|
|
|
|
} catch (MissingNestedCommandException ex) {
|
|
|
|
Messaging.sendError(player, ex.getUsage());
|
|
|
|
} catch (CommandUsageException ex) {
|
|
|
|
Messaging.sendError(player, ex.getMessage());
|
|
|
|
Messaging.sendError(player, ex.getUsage());
|
|
|
|
} catch (RequirementMissingException ex) {
|
|
|
|
Messaging.sendError(player, ex.getMessage());
|
|
|
|
} catch (WrappedCommandException e) {
|
|
|
|
throw e.getCause();
|
|
|
|
} catch (UnhandledCommandException e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
Messaging.sendError(player, "That is not a valid number.");
|
|
|
|
} catch (Throwable excp) {
|
|
|
|
excp.printStackTrace();
|
|
|
|
Messaging.sendError(player, "Please report this error: [See console]");
|
|
|
|
Messaging.sendError(player, excp.getClass().getName() + ": " + excp.getMessage());
|
2012-01-23 09:45:34 +01:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-01-19 12:43:21 +01:00
|
|
|
@Override
|
|
|
|
public void onDisable() {
|
2012-01-29 21:58:19 +01:00
|
|
|
// Don't bother with this part if MC versions are not compatible
|
2012-01-30 12:58:59 +01:00
|
|
|
if (compatible) {
|
2012-01-29 21:58:19 +01:00
|
|
|
config.save();
|
|
|
|
saveNPCs();
|
|
|
|
for (NPC npc : npcManager)
|
|
|
|
npc.despawn();
|
|
|
|
Bukkit.getScheduler().cancelTasks(this);
|
|
|
|
}
|
2012-01-21 13:53:58 +01:00
|
|
|
|
2012-01-19 12:43:21 +01:00
|
|
|
Messaging.log("v" + getDescription().getVersion() + " disabled.");
|
|
|
|
}
|
2012-01-15 00:51:37 +01:00
|
|
|
|
2012-01-19 12:43:21 +01:00
|
|
|
@Override
|
|
|
|
public void onEnable() {
|
2012-01-29 21:58:19 +01:00
|
|
|
// Disable if the server is not using the compatible Minecraft version
|
2012-01-30 19:55:16 +01:00
|
|
|
compatible = ((CraftServer) getServer()).getServer().getVersion().startsWith(COMPATIBLE_MC_VERSION);
|
2012-01-30 12:58:59 +01:00
|
|
|
String mcVersion = ((CraftServer) getServer()).getServer().getVersion();
|
|
|
|
if (!compatible) {
|
2012-01-29 21:58:19 +01:00
|
|
|
Messaging.log(Level.SEVERE, "v" + getDescription().getVersion() + " is not compatible with Minecraft v"
|
|
|
|
+ mcVersion + ". Disabling.");
|
|
|
|
getServer().getPluginManager().disablePlugin(this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-21 14:56:50 +01:00
|
|
|
// Configuration file
|
|
|
|
config = new Settings(this);
|
|
|
|
config.load();
|
2012-01-19 11:52:58 +01:00
|
|
|
|
2012-01-23 15:30:15 +01:00
|
|
|
// NPC storage
|
2012-02-07 09:31:28 +01:00
|
|
|
if (Setting.USE_DATABASE.asBoolean())
|
2012-01-23 15:30:15 +01:00
|
|
|
saves = new DatabaseStorage();
|
2012-02-07 09:31:28 +01:00
|
|
|
else
|
2012-01-23 15:30:15 +01:00
|
|
|
saves = new YamlStorage(getDataFolder() + File.separator + "saves.yml");
|
2012-01-18 05:04:08 +01:00
|
|
|
|
2012-01-23 17:05:22 +01:00
|
|
|
// Register API managers
|
|
|
|
npcManager = new CitizensNPCManager(saves);
|
|
|
|
CitizensAPI.setNPCManager(npcManager);
|
|
|
|
CitizensAPI.setCharacterManager(characterManager);
|
|
|
|
CitizensAPI.setTraitManager(traitManager);
|
|
|
|
|
2012-01-19 12:43:21 +01:00
|
|
|
// Register events
|
2012-01-22 08:10:25 +01:00
|
|
|
getServer().getPluginManager().registerEvents(new EventListen(npcManager), this);
|
2012-01-16 04:15:32 +01:00
|
|
|
|
2012-01-25 16:29:54 +01:00
|
|
|
// Register commands and permissions
|
|
|
|
registerCommands();
|
2012-01-23 15:30:15 +01:00
|
|
|
registerPermissions();
|
|
|
|
|
2012-02-04 09:13:20 +01:00
|
|
|
// Register default traits
|
|
|
|
traitManager.registerAll(defaultTraits);
|
2012-02-03 10:20:48 +01:00
|
|
|
|
|
|
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new NPCUpdater(npcManager), 0, 1);
|
|
|
|
|
2012-01-19 12:43:21 +01:00
|
|
|
Messaging.log("v" + getDescription().getVersion() + " enabled.");
|
2012-01-18 05:04:08 +01:00
|
|
|
|
2012-01-19 12:43:21 +01:00
|
|
|
// Setup NPCs after all plugins have been enabled (allows for multiworld
|
|
|
|
// support and for NPCs to properly register external settings)
|
|
|
|
if (Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
try {
|
|
|
|
setupNPCs();
|
|
|
|
} catch (NPCLoadException ex) {
|
2012-01-29 21:58:19 +01:00
|
|
|
Messaging.log(Level.SEVERE, "Issue when loading NPCs: " + ex.getMessage());
|
2012-01-19 12:43:21 +01:00
|
|
|
}
|
|
|
|
}
|
2012-01-20 08:27:14 +01:00
|
|
|
}) == -1) {
|
2012-01-29 21:58:19 +01:00
|
|
|
Messaging.log(Level.SEVERE, "Issue enabling plugin. Disabling.");
|
2012-01-19 12:43:21 +01:00
|
|
|
getServer().getPluginManager().disablePlugin(this);
|
|
|
|
}
|
|
|
|
}
|
2012-01-18 05:04:08 +01:00
|
|
|
|
2012-02-08 09:26:14 +01:00
|
|
|
public CitizensNPCManager getNPCManager() {
|
|
|
|
return npcManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
public DefaultInstanceFactory<Character> getCharacterManager() {
|
|
|
|
return characterManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
public CommandManager getCommandManager() {
|
|
|
|
return cmdManager;
|
|
|
|
}
|
|
|
|
|
2012-02-04 07:48:23 +01:00
|
|
|
private void registerCommands() {
|
2012-02-08 09:26:14 +01:00
|
|
|
cmdManager.setInjector(new Injector(this));
|
2012-02-04 07:48:23 +01:00
|
|
|
|
2012-02-08 09:26:14 +01:00
|
|
|
// Register command classes
|
2012-02-04 07:48:23 +01:00
|
|
|
cmdManager.register(NPCCommands.class);
|
2012-02-08 09:26:14 +01:00
|
|
|
cmdManager.register(HelpCommands.class);
|
2012-02-04 07:48:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private void registerPermissions() {
|
|
|
|
// TODO There has to be a better way than this (maybe use Permission
|
|
|
|
// annotation to register permissions?)
|
|
|
|
Map<String, Boolean> children = new HashMap<String, Boolean>();
|
|
|
|
children.put("citizens.npc.create", true);
|
|
|
|
children.put("citizens.npc.spawn", true);
|
|
|
|
children.put("citizens.npc.despawn", true);
|
|
|
|
children.put("citizens.npc.select", true);
|
|
|
|
children.put("citizens.npc.tp", true);
|
|
|
|
children.put("citizens.npc.tphere", true);
|
2012-02-04 09:13:20 +01:00
|
|
|
children.put("citizens.npc.look-close", true);
|
2012-02-04 07:48:23 +01:00
|
|
|
|
|
|
|
Permission perm = new Permission("citizens.*", PermissionDefault.OP, children);
|
|
|
|
getServer().getPluginManager().addPermission(perm);
|
|
|
|
}
|
|
|
|
|
2012-01-23 09:45:34 +01:00
|
|
|
private void saveNPCs() {
|
2012-01-28 05:11:23 +01:00
|
|
|
for (NPC npc : npcManager)
|
2012-01-29 12:43:27 +01:00
|
|
|
npc.save(saves.getKey("npc." + npc.getId()));
|
|
|
|
saves.save();
|
2012-01-19 12:43:21 +01:00
|
|
|
}
|
2012-01-19 11:52:58 +01:00
|
|
|
|
2012-01-19 12:43:21 +01:00
|
|
|
private void setupNPCs() throws NPCLoadException {
|
2012-01-29 12:43:27 +01:00
|
|
|
int created = 0, spawned = 0;
|
|
|
|
for (DataKey key : saves.getKey("npc").getIntegerSubKeys()) {
|
2012-01-19 12:43:21 +01:00
|
|
|
int id = Integer.parseInt(key.name());
|
|
|
|
if (!key.keyExists("name"))
|
|
|
|
throw new NPCLoadException("Could not find a name for the NPC with ID '" + id + "'.");
|
2012-02-03 10:20:48 +01:00
|
|
|
|
|
|
|
String type = key.getString("traits.type");
|
|
|
|
NPC npc = npcManager.createNPC(
|
|
|
|
type.equalsIgnoreCase("DEFAULT") ? CreatureType.MONSTER : CreatureType.valueOf(key.getString(
|
|
|
|
"traits.type").toUpperCase()), id, key.getString("name"), null);
|
2012-02-04 00:35:24 +01:00
|
|
|
try {
|
|
|
|
npc.load(key);
|
|
|
|
} catch (NPCException ex) {
|
|
|
|
Messaging.log(ex.getMessage());
|
|
|
|
}
|
2012-01-29 12:43:27 +01:00
|
|
|
++created;
|
|
|
|
if (npc.isSpawned())
|
|
|
|
++spawned;
|
2012-01-19 12:43:21 +01:00
|
|
|
}
|
2012-01-30 19:55:16 +01:00
|
|
|
Messaging.log("Loaded " + created + " NPCs (" + spawned + " spawned).");
|
2012-01-19 12:43:21 +01:00
|
|
|
}
|
2012-01-15 00:51:37 +01:00
|
|
|
}
|