diff --git a/Craftizen.java b/Craftizen.java index 199fc8a..e75fe63 100644 --- a/Craftizen.java +++ b/Craftizen.java @@ -1,5 +1,3 @@ -import net.minecraft.server.MinecraftServer; -import java.util.List; import java.util.ArrayList; import java.util.logging.*; import java.util.Random; @@ -154,7 +152,14 @@ public String getId() { public String getName() { return name; } - + + /** + * @return the speed + */ + public double getSpeed() { + return speed; + } + public enum RouteType { NONE, WANDER, PATROL } diff --git a/CraftizenFlatfileDataSource.java b/CraftizenFlatfileDataSource.java new file mode 100644 index 0000000..e01c42a --- /dev/null +++ b/CraftizenFlatfileDataSource.java @@ -0,0 +1,390 @@ +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.logging.Logger; + + +public class CraftizenFlatfileDataSource extends CraftizenDataSource +{ + static final Logger log = Logger.getLogger("Minecraft"); + + private static final String DATA_FOLDER = "craftizens/"; + + private HashMap> npcQuests; + + public CraftizenFlatfileDataSource() + { + (new File(DATA_FOLDER)).mkdir(); + } + + public HashSet loadCraftizens() + { + synchronized (craftizenLock) + { + HashSet npcs = new HashSet(); + npcQuests = new HashMap>(); + + // get file list + File[] files = (new File(DATA_FOLDER)).listFiles(); + + // load npc data + for (File file : files) + { + if (file.getName().startsWith("npc-")) + { + PropertiesFile data = new PropertiesFile(DATA_FOLDER + + file.getName()); + Craftizen npc = new Craftizen(data.getString("npc_id"), + data.getString("npc_name"), data.getDouble("posx"), + data.getDouble("posy"), data.getDouble("posz"), + (float) data.getDouble("rotation"), + (float) data.getDouble("pitch"), + data.getInt("item_in_hand")); + + int i = 0; + ArrayList dialog = new ArrayList(); + while (data.containsKey("dialog_" + i)) + { + dialog.add(data.getString("dialog_" + i)); + i++; + } + npc.setDialog(dialog); + npcs.add(npc); + npcQuests.put(npc.getId(), new ArrayList()); + } + } + + // load quest data + for (File file : files) + { + if (file.getName().startsWith("quest-")) + { + PropertiesFile data = new PropertiesFile(DATA_FOLDER + + file.getName()); + ArrayList quests = npcQuests.get(data + .getString("start_npc")); + quests.add(data.getString("id")); + npcQuests.put(data.getString("start_npc"), quests); + } + } + return npcs; + } + } + + public void saveCraftizen(Craftizen c) + { + synchronized (craftizenLock) + { + PropertiesFile data = new PropertiesFile(DATA_FOLDER + "npc-" + + c.getId() + ".txt"); + data.setString("npc_id", c.getId()); + data.setString("npc_name", c.getName()); + data.setDouble("posx", c.getX()); + data.setDouble("posy", c.getY()); + data.setDouble("posz", c.getZ()); + data.setDouble("rotation", c.getRotation()); + data.setDouble("pitch", c.getPitch()); + data.setInt("item_in_hand", c.getItemInHand()); + } + } + + public void addCraftizenDialog(String npcid, String dialogid, String dialog) + { + synchronized (craftizenLock) + { + PropertiesFile data = new PropertiesFile(DATA_FOLDER + "npc-" + + npcid + ".txt"); + int i = -1; + while (data.containsKey("dialog_" + ++i)) + { + } + data.setString("dialog_" + i, dialog); + } + } + + public void deleteCraftizen(String id) + { + synchronized (craftizenLock) + { + (new File(DATA_FOLDER + "npc-" + id + ".txt")).delete(); + } + } + + public ArrayList getQuestList() + { + synchronized (questLock) + { + ArrayList quests = null; + + // get file list + File[] files = (new File(DATA_FOLDER)).listFiles(); + + // load quest data + for (File file : files) + { + if (file.getName().startsWith("quest-")) + { + PropertiesFile data = new PropertiesFile(DATA_FOLDER + + file.getName()); + if (quests == null) quests = new ArrayList(); + quests.add(data.getString("id")); + } + } + + return quests; + } + } + + public QuestInfo loadQuestInfo(String id) + { + synchronized (questLock) + { + if ((new File(DATA_FOLDER + "quest-" + id + ".txt")).exists()) + { + PropertiesFile data = new PropertiesFile(DATA_FOLDER + "quest-" + + id + ".txt"); + QuestInfo quest = new QuestInfo(data.getString("id"), + data.getString("quest_type"), + data.getString("quest_name"), + data.getString("quest_desc"), + data.getString("start_npc"), data.getString("end_npc"), + data.getString("prereq"), + data.getString("items_provided"), + data.getString("rewards"), data.getString("location"), + data.getString("data"), + data.getString("completion_text"), + data.getString("rankreq"), + data.getString("rankreward"), data.getString("cost"), + data.getString("prize")); + return quest; + } + else + { + return null; + } + } + } + + public ArrayList getAvailableQuests(Craftizen c, Player p) + { + synchronized (questLock) + { + ArrayList quests = new ArrayList(); + // getting quests this NPC has + for (String q : npcQuests.get(c.id)) + { + // now we only add QuestInfo objects that the player can + // actually access + QuestInfo quest = loadQuestInfo(q); + + // logic for ranks + String[] groups = p.getGroups(); + if (groups.length > 0) + { + if (groups[0] == null || groups[0].equals("")) + { + if (!quest.rankReq.isEmpty()) + { + continue; + } + } + else + { + if ((!quest.rankReq.isEmpty()) + && (!quest.rankReq.equalsIgnoreCase(groups[0]))) + { + continue; + } + } + } + else + { + if (!quest.rankReq.isEmpty()) + { + continue; + } + } + + PropertiesFile player = loadPlayer(p); + // logic for active quests + String[] activeQuests = player.getString("active-quests") + .split(","); + boolean activeFound = false; + for (String aq : activeQuests) + { + if (aq.equalsIgnoreCase(q)) + { + activeFound = true; + break; + } + } + if (activeFound) + { + continue; + } + // logic for already completed quests + String[] completedQuests = player.getString("completed-quests") + .split(","); + boolean completedFound = false; + for (String cq : completedQuests) + { + if (cq.equalsIgnoreCase(q)) + { + completedFound = true; + break; + } + } + if (completedFound) + { + continue; + } + + // add the quest to the list + quests.add(quest); + } + return quests; + } + } + + private PropertiesFile loadPlayer(Player p) + { + return new PropertiesFile(DATA_FOLDER + "player-" + p.getName() + + ".txt"); + } + + public HashMap getActiveQuests(Player p) + { + synchronized (questLock) + { + HashMap quests = new HashMap(); + + PropertiesFile player = loadPlayer(p); + String[] q = player.getString("active-quests").split(","); + for (String aq : q) + { + QuestInfo quest = loadQuestInfo(aq); + if (quest == null) + { + continue; + } + String progress = player.getString("progress-" + aq); + quests.put(quest, progress); + } + return quests; + } + } + + public void saveActiveQuest(Player player, Quest quest) + { + synchronized (questLock) + { + PropertiesFile p = loadPlayer(player); + if (p.getString("active-quests").isEmpty()) + { + p.setString("active-quests", quest.getId()); + } + else + { + p.setString("active-quests", p.getString("active-quests") + "," + + quest.getId()); + } + } + } + + public void saveQuestProgress(Player player, Quest quest, String progress) + { + synchronized (questLock) + { + PropertiesFile p = loadPlayer(player); + p.setString("progress-" + quest.getId(), progress); + } + } + + public void dropActiveQuest(Player player, Quest quest) + { + synchronized (questLock) + { + PropertiesFile p = loadPlayer(player); + String[] q = p.getString("active-quests").split(","); + String activeQuests = ""; + for (String aq : q) + { + if (!quest.getId().equalsIgnoreCase(aq)) + { + if (activeQuests.isEmpty()) + { + activeQuests = aq; + } + else + { + activeQuests = activeQuests + "," + aq; + } + } + } + p.setString("active-quests", activeQuests); + } + } + + public void saveCompletedQuest(Player player, Quest quest) + { + dropActiveQuest(player, quest); + synchronized (questLock) + { + PropertiesFile p = loadPlayer(player); + if (p.getString("completed-quests").isEmpty()) + { + p.setString("completed-quests", quest.getId()); + } + else + { + p.setString("completed-quests", p.getString("completed-quests") + + "," + quest.getId()); + } + } + } + + public void saveQuest(QuestInfo quest) + { + synchronized (questLock) + { + PropertiesFile data = new PropertiesFile(DATA_FOLDER + "quest-" + + quest.getId() + ".txt"); + + data.setString("id", quest.id); + data.setString("quest_name", (quest.name == null) ? "" : quest.name); + data.setString("quest_type", (quest.type == null) ? "" : quest.type); + data.setString("quest_desc", (quest.desc == null) ? "" : quest.desc); + data.setString("start_npc", (quest.pickUp == null) ? "" + : quest.pickUp); + data.setString("end_npc", (quest.turnIn == null) ? "" + : quest.turnIn); + data.setString("prereq", (quest.prereq == null) ? "" : quest.prereq); + data.setString("items_provided", + (quest.itemsProvidedStr == null) ? "" + : quest.itemsProvidedStr); + data.setString("rewards", (quest.rewardsStr == null) ? "" + : quest.rewardsStr); + data.setString("location", (quest.location == null) ? "" + : quest.location); + data.setString("data", (quest.data == null) ? "" : quest.data); + data.setString("completion_text", + (quest.completionText == null) ? "" : quest.completionText); + data.setString("rankreq", (quest.rankReq == null) ? "" + : quest.rankReq); + data.setString("rankreward", (quest.rankReward == null) ? "" + : quest.rankReward); + data.setInt("cost", quest.cost); + data.setInt("prize", quest.prize); + } + } + + public void deleteQuest(String questid) + { + synchronized (questLock) + { + (new File(DATA_FOLDER + "quest-" + questid + ".txt")).delete(); + } + } + +} diff --git a/CraftizenSQLDataSource.java b/CraftizenSQLDataSource.java index 9339d77..5cc3989 100644 --- a/CraftizenSQLDataSource.java +++ b/CraftizenSQLDataSource.java @@ -246,7 +246,11 @@ public QuestInfo loadQuestInfo(String id) { results.getString("rewards"), results.getString("location"), results.getString("data"), - results.getString("completion_text") + results.getString("completion_text"), + results.getString("rankreq"), + results.getString("rankreward"), + results.getString("cost"), + results.getString("prize") ); } } catch (SQLException e) { @@ -281,12 +285,25 @@ public ArrayList getAvailableQuests(Craftizen c, Player p) { "LEFT JOIN quests_completed qc2 ON qc2.player_name = ? AND qc2.quest_id = q.id " + "LEFT JOIN quests_active qa ON qa.player_name = ? AND qa.quest_id = q.id " + "WHERE c.npc_id = ? AND (q.prereq IS NULL OR qc.date_completed IS NOT NULL) " + - "AND qc2.quest_id IS NULL and qa.quest_id IS NULL " + "AND qc2.quest_id IS NULL and qa.quest_id IS NULL " + + "AND (q.rankreq IS NULL OR q.rankreq = ?) " ); query.setString(1, p.getName().toLowerCase()); query.setString(2, p.getName().toLowerCase()); query.setString(3, p.getName().toLowerCase()); query.setString(4, c.getId()); + + String[] groups = p.getGroups(); + if (groups.length > 0) { + if(groups[0] == null || groups[0].equals("")) { + query.setString(5, ""); + } else { + query.setString(5, groups[0]); + } + } else { + query.setString(5, ""); + } + results = query.executeQuery(); while (results.next()) { QuestInfo q = new QuestInfo( @@ -301,7 +318,11 @@ public ArrayList getAvailableQuests(Craftizen c, Player p) { results.getString("rewards"), results.getString("location"), results.getString("data"), - results.getString("completion_text") + results.getString("completion_text"), + results.getString("rankreq"), + results.getString("rankreward"), + results.getString("cost"), + results.getString("prize") ); quests.add(q); } @@ -350,7 +371,11 @@ public HashMap getActiveQuests(Player p) { results.getString("rewards"), results.getString("location"), results.getString("data"), - results.getString("completion_text") + results.getString("completion_text"), + results.getString("rankreq"), + results.getString("rankreward"), + results.getString("cost"), + results.getString("prize") ); String s = results.getString("progress"); quests.put(q,s); @@ -497,7 +522,9 @@ public void saveQuest(QuestInfo quest) { "quest_name = ?, quest_type = ?, quest_desc = ?, " + "start_npc = ?, end_npc = ?, prereq = ?, " + "items_provided = ?, rewards = ?, " + - "location = ?, data = ?, completion_text = ? " + + "location = ?, data = ?, completion_text = ?, " + + "rankreq = ?, rankreward = ?, " + + "cost = ?, prize = ? " + "WHERE id = ?"); query.setString(1,quest.name); query.setString(2,quest.type); @@ -510,10 +537,14 @@ public void saveQuest(QuestInfo quest) { query.setString(9,quest.location); query.setString(10,quest.data); query.setString(11,quest.completionText); - query.setString(12,quest.id); + query.setString(12,quest.rankReq); + query.setString(13,quest.rankReward); + query.setString(14,(new Integer(quest.cost)).toString()); + query.setString(15,(new Integer(quest.prize)).toString()); + query.setString(16,quest.id); query.executeUpdate(); } else { - query = conn.prepareStatement("INSERT INTO quests (id, quest_name, quest_type, quest_desc, start_npc, end_npc, prereq, items_provided, rewards, location, data, completion_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + query = conn.prepareStatement("INSERT INTO quests (id, quest_name, quest_type, quest_desc, start_npc, end_npc, prereq, items_provided, rewards, location, data, completion_text, rankreq, rankreward, cost, prize) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); query.setString(1,quest.id); query.setString(2,quest.name); query.setString(3,quest.type); @@ -526,6 +557,10 @@ public void saveQuest(QuestInfo quest) { query.setString(10,quest.location); query.setString(11,quest.data); query.setString(12,quest.completionText); + query.setString(13,quest.rankReq); + query.setString(14,quest.rankReward); + query.setString(15,(new Integer(quest.cost)).toString()); + query.setString(16,(new Integer(quest.prize)).toString()); query.executeUpdate(); } } catch (SQLException e) { diff --git a/Craftizens.java b/Craftizens.java index 4967411..8a5a2da 100644 --- a/Craftizens.java +++ b/Craftizens.java @@ -1,19 +1,14 @@ import java.util.HashSet; import java.util.HashMap; import java.util.ArrayList; -import java.util.List; -import java.io.File; -import java.io.FileWriter; -import java.io.BufferedWriter; -import java.io.IOException; -import java.util.Scanner; import java.util.logging.*; public class Craftizens extends Plugin { static final Logger log = Logger.getLogger("Minecraft"); public static boolean DEBUG = true; - public static String NPC_PREFIX = "§e"; +// public static String NPC_PREFIX = "§e"; + public static String NPC_PREFIX = "§e"; public static String NPC_SUFFIX = " (NPC)"; public static String TEXT_COLOR = Colors.Yellow; public static int INTERACT_ITEM = 340; @@ -22,6 +17,8 @@ public class Craftizens extends Plugin { public static int INTERACT_ANGLE_VARIATION = 25; public static int QADMIN_BOUNDARY_MARKER = 340; public static boolean QUESTS_ENABLED = true; + public static boolean ICONOMY_DETECTED = false; + public static String VERSION = "v0.7.2"; public static CraftizenDataSource data; public static HashSet npcs; @@ -56,9 +53,11 @@ public void enable() { INTERACT_ANGLE_VARIATION = props.getInt("npc-interact-angle-variation",25); QADMIN_BOUNDARY_MARKER = props.getInt("qadmin-boundary-marker",340); QUESTS_ENABLED = props.getBoolean("quests-enabled",true); - + data = new CraftizenSQLDataSource(); + loadiConomy(); + Craftizen.getPlayerList(); npcs = data.loadCraftizens(); @@ -73,7 +72,7 @@ public void enable() { CraftizensListener.loadActiveQuests(p); } - log.info("Craftizens v0.6 loaded successfully!"); + log.info("[Craftizens] Craftizens " + VERSION + " loaded successfully!"); } public void disable() { @@ -101,4 +100,26 @@ public void disable() { data = null; } + public static boolean loadiConomy() { + if (etc.getLoader().getPlugin("iConomy") != null) { + PropertiesFile iConomySettings = new PropertiesFile(iData.mainDir + "settings.properties"); + boolean mysql = iConomySettings.getBoolean("use-mysql", false); + + // MySQL + String driver = iConomySettings.getString("driver", "com.mysql.jdbc.Driver"); + String user = iConomySettings.getString("user", "root"); + String pass = iConomySettings.getString("pass", "root"); + String db = iConomySettings.getString("db", "jdbc:mysql://localhost:3306/minecraft"); + + // Data + iData.setup(mysql, 0, driver, user, pass, db); + log.info("[Craftizens] iConomy loaded successfully."); + ICONOMY_DETECTED = true; + return true; + } else { + log.warning("[Craftizens] iConomy failed to load."); + ICONOMY_DETECTED = false; + return false; + } + } } diff --git a/CraftizensListener.java b/CraftizensListener.java index 2b36fad..6ef05f2 100644 --- a/CraftizensListener.java +++ b/CraftizensListener.java @@ -1,4 +1,3 @@ -import net.minecraft.server.MinecraftServer; import java.util.logging.*; import java.util.ArrayList; import java.util.HashMap; @@ -20,8 +19,7 @@ public boolean onCommand(Player player, String [] split) { return false; } - public void npcCommand(Player player, String [] command) { - MinecraftServer s = etc.getServer().getMCServer(); + public void npcCommand(Player player, String [] command) { if (command[1].equals("clear")) { for (Craftizen npc : Craftizens.npcs) { npc.delete(); @@ -68,14 +66,21 @@ public void npcCommand(Player player, String [] command) { } + @SuppressWarnings("unchecked") public void questCommand(Player player, String [] command) { if (command.length == 1) { questCommandUsage(player); } else if ("view".startsWith(command[1].toLowerCase()) && command.length == 3) { if (Craftizens.pendingQuests.containsKey(player.getName())) { Object o = Craftizens.pendingQuests.get(player.getName()); - if (o instanceof ArrayList) { - ArrayList quests = (ArrayList)o; + if (o instanceof ArrayList) { + ArrayList quests = null; + try { +// TODO: this is extremely poor programming practice. Need to refactor/fix later. + quests = (ArrayList) o; + } catch (ClassCastException e) { + Craftizen.log.warning("[Craftizen] Pending quests was not an ArrayList!"); + } int i = -1; try { i = Integer.parseInt(command[2]); @@ -100,14 +105,18 @@ public void questCommand(Player player, String [] command) { Object o = Craftizens.pendingQuests.get(player.getName()); if (o instanceof QuestInfo) { QuestInfo qi = (QuestInfo)o; - Quest q = qi.createQuest(player, true); - Craftizens.pendingQuests.remove(player.getName()); - if (!Craftizens.activeQuests.containsKey(player.getName())) { - Craftizens.activeQuests.put(player.getName(),new ArrayList()); + if (qi.checkBalance(player, true)) { + Quest q = qi.createQuest(player, true); + Craftizens.pendingQuests.remove(player.getName()); + if (!Craftizens.activeQuests.containsKey(player.getName())) { + Craftizens.activeQuests.put(player.getName(),new ArrayList()); + } + Craftizens.activeQuests.get(player.getName()).add(q); + Craftizens.data.saveActiveQuest(player, q); + player.sendMessage(Craftizens.TEXT_COLOR + "Quest accepted!"); + } else { + player.sendMessage(Craftizens.TEXT_COLOR + "You can't afford this quest! It costs " + qi.cost + "."); } - Craftizens.activeQuests.get(player.getName()).add(q); - Craftizens.data.saveActiveQuest(player, q); - player.sendMessage(Craftizens.TEXT_COLOR + "Quest accepted!"); } else { player.sendMessage(Craftizens.TEXT_COLOR + "No quest to accept."); } @@ -251,8 +260,12 @@ public void qadminCommand(Player player, String [] command) { player.sendMessage("End NPC: " + q.turnIn); player.sendMessage("Prereq quest: " + q.prereq); player.sendMessage("Items prov: " + q.itemsProvidedStr); - player.sendMessage("Rewards: " + q.rewardsStr); - player.sendMessage("Comp text: " + ((q.completionText.length()>50)?q.completionText.substring(0,50)+"...":q.completionText)); + player.sendMessage("Rewards: " + (q.rewardsStr == null ? "None" : q.rewardsStr)); + player.sendMessage("Rank requirement: " + q.rankReq); + player.sendMessage("Rank reward: " + q.rankReward); + player.sendMessage("Cost: " + q.cost + " (iConomy is currently " + (Craftizens.ICONOMY_DETECTED ? "enabled)" : "disabled)")); + player.sendMessage("Prize: " + q.prize + " (iConomy is currently " + (Craftizens.ICONOMY_DETECTED ? "enabled)" : "disabled)")); + player.sendMessage("Comp text: " + ((q.completionText != null && q.completionText.length()>50)?q.completionText.substring(0,50)+"...":q.completionText)); player.sendMessage("Data: " + q.data); q = null; } else { @@ -290,6 +303,19 @@ public void qadminCommand(Player player, String [] command) { player.sendMessage("No such quest."); } + // iConomy Hook + } else if (command[1].equalsIgnoreCase("iConomy")) { + if (command.length > 2 && command[2].equals("-disable")) { + Craftizens.ICONOMY_DETECTED = false; + player.sendMessage("iConomy disabled. Use /qadmin iConomy to turn it back on."); + } else if (Craftizens.loadiConomy()) { + player.sendMessage("iConomy loaded successfully."); + player.sendMessage("use /qadmin iConomy -disable to turn it off."); + } else { + player.sendMessage("iConomy failed to load."); + player.sendMessage("Perhaps you don't have the plugin running?"); + } + } else if (command.length >= 2 && Craftizens.newQuests != null && Craftizens.newQuests.containsKey(player.getName())) { QuestInfo quest = Craftizens.newQuests.get(player.getName()); @@ -412,6 +438,78 @@ public void qadminCommand(Player player, String [] command) { player.sendMessage("Use /qadmin prereq -delete to remove the prereq quest."); } + // rankreq + } else if (command[1].equalsIgnoreCase("rankreq")) { + if (command.length == 3) { + if (command[2].equals("-delete")) { + quest.rankReq = null; + player.sendMessage("Quest rank requirement removed."); + } else if (quest.setRankReq(command[2])){ + player.sendMessage("Quest rank requirmenet set to " + command[2] + "."); + } else { + player.sendMessage("Invalid rank requirement."); + } + } else if (command.length == 2 && quest.rankReq != null) { + player.sendMessage("Quest " + quest.id + " rank requirement: " + quest.rankReq); + } else { + player.sendMessage("Use /qadmin rankreq [rankname] to set the rank requirement."); + player.sendMessage("Use /qadmin rankreq -delete to remove the rank requirement."); + } + + // rankreward + } else if (command[1].equalsIgnoreCase("rankreward")) { + if (command.length == 3) { + if (command[2].equals("-delete")) { + quest.rankReward = null; + player.sendMessage("Quest rank reward removed."); + } else if (quest.setRankReward(command[2])){ + player.sendMessage("Quest rank reward set to " + command[2] + "."); + } else { + player.sendMessage("Invalid rank reward."); + } + } else if (command.length == 2 && quest.rankReward != null) { + player.sendMessage("Quest " + quest.id + " rank reward: " + quest.rankReward); + } else { + player.sendMessage("Use /qadmin rankreward [rankname] to set the rank reward."); + player.sendMessage("Use /qadmin rankreward -delete to remove the rank reward."); + } + + // cost + } else if (command[1].equalsIgnoreCase("cost")) { + if (command.length == 3) { + if (command[2].equals("-delete")) { + quest.cost = 0; + player.sendMessage("Quest cost removed."); + } else if (quest.setCost(command[2])){ + player.sendMessage("Quest cost set to " + command[2] + "."); + } else { + player.sendMessage("Invalid cost."); + } + } else if (command.length == 2) { + player.sendMessage("Quest " + quest.id + " cost: " + quest.cost); + } else { + player.sendMessage("Use /qadmin cost [rankname] to set the quest cost."); + player.sendMessage("Use /qadmin cost -delete to remove the quest cost."); + } + + // prize + } else if (command[1].equalsIgnoreCase("prize")) { + if (command.length == 3) { + if (command[2].equals("-delete")) { + quest.prize = 0; + player.sendMessage("Quest prize removed."); + } else if (quest.setPrize(command[2])){ + player.sendMessage("Quest prize set to " + command[2] + "."); + } else { + player.sendMessage("Invalid prize."); + } + } else if (command.length == 2) { + player.sendMessage("Quest " + quest.id + " prize: " + quest.prize); + } else { + player.sendMessage("Use /qadmin prize [rankname] to set the quest prize."); + player.sendMessage("Use /qadmin prize -delete to remove the quest prize."); + } + // items provided } else if (command[1].equalsIgnoreCase("itemsprovided")) { if (command.length > 2) { @@ -629,7 +727,7 @@ public static boolean lookingAt(Player player, double x, double y, double z) { if (x <= player.getX() && z <= player.getZ()) { angle = 180 - angle; } else if (x <= player.getX() && z >= player.getZ()) { - angle = angle; +// angle = angle; } else if (x >= player.getX() && z >= player.getZ()) { angle = 360 - angle; } else { diff --git a/FetchBlockQuest.java b/FetchBlockQuest.java index 2b489a6..3c96c0b 100644 --- a/FetchBlockQuest.java +++ b/FetchBlockQuest.java @@ -118,7 +118,7 @@ public void onPlayerMove(Player player, Location from, Location to) { } public void sendFakeBlockPacket(Player player, int x, int y, int z, int type) { - fm packet = new fm(); + fn packet = new fn(); packet.a = x; packet.b = y; packet.c = z; diff --git a/NonPlayerCharacter.java b/NonPlayerCharacter.java index 008cb29..bec0703 100644 --- a/NonPlayerCharacter.java +++ b/NonPlayerCharacter.java @@ -4,26 +4,26 @@ public abstract class NonPlayerCharacter { public static List players; - private es user; - private gv handler; + private et user; + private gw handler; public NonPlayerCharacter(String name, double x, double y, double z, float rotation, float pitch, int itemInHand) { if (players == null) getPlayerList(); MinecraftServer s = etc.getServer().getMCServer(); - user = new es(s, s.e, name, new ju(s.e)); + user = new et(s, s.e, name, new jv(s.e)); teleportTo(x,y,z,rotation,pitch); if (itemInHand > 0) { setItemInHand(itemInHand); } - handler = new gv(user, 512, 1 , true ); + handler = new gw(user, 512, 1 , true ); } public void delete() { for (Object player : players) { - ((es)player).a.b(new dh(handler.a.g)); + ((et)player).a.b(new di(handler.a.g)); } } @@ -94,7 +94,7 @@ public int getItemInHand() { } public void setItemInHand(int type) { - user.am.a[0] = new hm(type); + user.am.a[0] = new hn(type); } public void teleportTo(double x, double y, double z, float rotation, float pitch) { diff --git a/Quest.java b/Quest.java index 9414a33..ef3a99c 100644 --- a/Quest.java +++ b/Quest.java @@ -42,6 +42,42 @@ protected void giveRewards() { player.giveItem(i, info.rewards.get(i)); } } + if (info.rankReward != null) { + setRank(player, info.rankReward); + } + + if (Craftizens.ICONOMY_DETECTED) { + if (info.prize > 0) { + int money = iData.getBalance(player.getName()); + iData.setBalance(player.getName(), money + info.prize); + + player.sendMessage("Awarding cash prize of " + info.prize + "."); + } + } + } + + private void setRank(Player p, String rank) { + etc.getInstance(); + Group g = etc.getDataSource().getGroup(rank); + if (g != null) { + String[] arrayOfString = { g.Name }; + p.setGroups(arrayOfString); + p.setIgnoreRestrictions(g.IgnoreRestrictions); + p.setAdmin(g.Administrator); + + int i = 0; + + if (!etc.getDataSource().doesPlayerExist(p.getName())) { + i = 1; + } + + if (i != 0) + etc.getDataSource().addPlayer(p); + else + etc.getDataSource().modifyPlayer(p); + } else { + p.sendMessage("Error setting rank. Please contact your local admin."); + } } protected void complete() { diff --git a/QuestInfo.java b/QuestInfo.java index 4e03be2..2c6caf0 100644 --- a/QuestInfo.java +++ b/QuestInfo.java @@ -11,10 +11,16 @@ public class QuestInfo { public String turnIn; public String prereq; + public String rankReq; + public String rankReward; + + public int cost = 0; + public int prize = 0; + public String itemsProvidedStr; - public HashMap itemsProvided; + public HashMap itemsProvided = new HashMap(); public String rewardsStr; - public HashMap rewards; + public HashMap rewards = new HashMap(); public String location; public String data; @@ -27,7 +33,7 @@ public QuestInfo(String id) { this.desc = ""; } - public QuestInfo(String id, String type, String name, String desc, String pickUp, String turnIn, String prereq, String itemsProvided, String rewards, String location, String data, String completionText) { + public QuestInfo(String id, String type, String name, String desc, String pickUp, String turnIn, String prereq, String itemsProvided, String rewards, String location, String data, String completionText, String rankReq, String rankReward, String cost, String prize) { // get normal data this.id = id; this.type = type; @@ -74,6 +80,39 @@ public QuestInfo(String id, String type, String name, String desc, String pickUp this.location = location; this.data = data; this.completionText = completionText; + this.rankReq = rankReq; + this.rankReward = rankReward; + + try { + this.cost = Integer.parseInt(cost); + } catch (NumberFormatException e) { + this.cost = 0; + } + + try { + this.prize = Integer.parseInt(prize); + } catch (NumberFormatException e) { + this.prize = 0; + } + } + + // this function uses hardcoded € because iConomy is not a singleton + // so I can't get iConony.moneyName + public boolean checkBalance(Player player, boolean deduct) { + if (Craftizens.ICONOMY_DETECTED) { + int money = iData.getBalance(player.getName()); + if (money >= cost) { + if (deduct && cost > 0) { + iData.setBalance(player.getName(), money - cost); + player.sendMessage(Craftizens.TEXT_COLOR + "Taking cost of " + cost + "."); + } + return true; + } else { + return false; + } + } else { + return true; + } } public void show(Player player) { @@ -96,6 +135,18 @@ public void show(Player player) { if (!rewardsStr.equals("")) { player.sendMessage(Craftizens.TEXT_COLOR + " Reward: " + rewardsStr.split(":")[0]); } + if (rankReq != null && !rankReq.equals("")) { + player.sendMessage(Craftizens.TEXT_COLOR + " Rank Required: " + rankReq); + } + if (rankReward != null && !rankReward.equals("")) { + player.sendMessage(Craftizens.TEXT_COLOR + " Rank Reward: " + rankReward); + } + if (Craftizens.ICONOMY_DETECTED && cost > 0) { + player.sendMessage(Craftizens.TEXT_COLOR + " Cost: " + cost); + } + if (Craftizens.ICONOMY_DETECTED && prize > 0) { + player.sendMessage(Craftizens.TEXT_COLOR + " Prize: " + prize); + } player.sendMessage(Craftizens.TEXT_COLOR + "Type '/quest accept' to accept this quest."); } @@ -171,6 +222,67 @@ public boolean setPrereq(String q) { } } + /** + * @param rankReq the rankReq to set + */ + public boolean setRankReq(String rankReq) { + if (rankReq.matches("^[a-zA-Z0-9]+$")) { + this.rankReq = rankReq; + return true; + } else { + return false; + } + } + + /** + * @param rankReward the rankReward to set + */ + public boolean setRankReward(String rankReward) { + if (rankReward.matches("^[a-zA-Z0-9]+$")) { + etc.getInstance(); + Group g = etc.getDataSource().getGroup(rankReward); + if (g != null) { + this.rankReward = rankReward; + return true; + } + return false; + } else { + return false; + } + } + + /** + * @param cost the cost to set + */ + public boolean setCost(String cost) { + if (cost.matches("^[0-9]+$")) { + try { + this.cost = Integer.parseInt(cost); + return true; + } catch (NumberFormatException e) { + return false; + } + } else { + return false; + } + } + + /** + * @param prize the prize to set + */ + public boolean setPrize(String prize) { + if (prize.matches("^[0-9]+$")) { + try { + this.prize = Integer.parseInt(prize); + return true; + } catch (NumberFormatException e) { + return false; + } + } else { + return false; + } + } + public boolean setItemsProvided(String i) { if (i.matches("[a-zA-Z0-9\\- ]+:([0-9]+ [0-9]+,)*[0-9]+ [0-9]+")) { this.itemsProvidedStr = i; diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..1ffd7b6 --- /dev/null +++ b/README.txt @@ -0,0 +1,8 @@ +0.7 - Added rankreq and rankreward functionality + +0.7.1 - Added iConomy hook + +Also I added the .sql script to the commit + +Find latest compiled jar here: +http://mc.nexua.org/plugins/Craftizens/v071/ \ No newline at end of file diff --git a/craftizens.sql b/craftizens.sql new file mode 100644 index 0000000..3807033 --- /dev/null +++ b/craftizens.sql @@ -0,0 +1,67 @@ +CREATE TABLE `minecraft`.`craftizens` ( + `npc_id` varchar(12) NOT NULL, + `npc_name` varchar(30) CHARACTER SET utf8 NOT NULL, + `posx` double NOT NULL, + `posy` double NOT NULL, + `posz` double NOT NULL, + `rotation` float NOT NULL, + `pitch` float NOT NULL, + PRIMARY KEY (`npc_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +CREATE TABLE `minecraft`.`quests` ( + `id` varchar(12) NOT NULL, + `quest_name` text CHARACTER SET utf8 NOT NULL, + `start_npc` varchar(12) NOT NULL, + `end_npc` varchar(12) NOT NULL, + `items_provided` text CHARACTER SET utf8, + `rewards` text CHARACTER SET utf8, + `quest_desc` mediumtext CHARACTER SET utf8 NOT NULL, + `quest_type` varchar(10) NOT NULL, + `prereq` varchar(12) DEFAULT NULL, + `location` text, + `data` text, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +CREATE TABLE `minecraft`.`quests_active` ( + `player_name` varchar(25) NOT NULL, + `quest_id` varchar(12) NOT NULL, + `progress` varchar(50) DEFAULT NULL, + PRIMARY KEY (`player_name`,`quest_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +CREATE TABLE `minecraft`.`quests_completed` ( + `player_name` varchar(25) NOT NULL, + `quest_id` varchar(12) NOT NULL, + `date_completed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`player_name`,`quest_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- v0.2 update + +ALTER TABLE `minecraft`.`craftizens` ADD COLUMN `item_in_hand` INT NOT NULL DEFAULT 0 AFTER `pitch`; + +-- v0.5 update + +ALTER TABLE `minecraft`.`quests` ADD COLUMN `completion_text` TEXT DEFAULT NULL AFTER `data`; + +CREATE TABLE `minecraft`.`craftizens_dialog` ( + `npc_id` varchar(12) NOT NULL, + `dialog_id` varchar(12) NOT NULL, + `dialog_text` text NOT NULL, + PRIMARY KEY (`npc_id`,`dialog_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- v0.6 update + +ALTER TABLE `minecraft`.`craftizens` ADD COLUMN `route_type` VARCHAR(8) DEFAULT NULL AFTER `item_in_hand`, + ADD COLUMN `route` TEXT DEFAULT NULL AFTER `route_type`; + +-- v0.7 update +ALTER TABLE `minecraft`.`quests` ADD COLUMN `rankreq` VARCHAR(12) DEFAULT NULL AFTER `prereq`, + ADD COLUMN `rankreward` VARCHAR(12) DEFAULT NULL AFTER `rankreq`; + +-- v0.7.1 update +ALTER TABLE `minecraft`.`quests` ADD COLUMN `cost` VARCHAR(12) DEFAULT '0' AFTER `rankreward`, + ADD COLUMN `prize` VARCHAR(12) DEFAULT '0' AFTER `cost`; diff --git a/iData.java b/iData.java new file mode 100644 index 0000000..3da762b --- /dev/null +++ b/iData.java @@ -0,0 +1,211 @@ +import java.io.*; +import java.sql.*; +import java.util.Map; +import java.util.logging.Logger; + +public final class iData implements Serializable { + protected static final Logger log = Logger.getLogger("Minecraft"); + public static PropertiesFile accounts; + private static int startingBalance; + + // Serial + private static final long serialVersionUID = -5796481236376288855L; + + // Database + static boolean mysql = false; + static String driver = "com.mysql.jdbc.Driver"; + static String user = "root"; + static String pass = "root"; + static String db = "jdbc:mysql://localhost:3306/minecraft"; + + // Directories + static String mainDir = "iConomy/"; + static String logDir = "logs/"; + + public static void setup(boolean mysql, int balance, String driver, String user, String pass, String db) { + startingBalance = balance; + + // Database + iData.driver = driver; + iData.user = user; + iData.pass = pass; + iData.db = db; + + if (!mysql) { + accounts = new PropertiesFile(mainDir + "balances.properties"); + } else { + // MySQL + iData.mysql = true; + + try { + Class.forName(driver); + } catch (ClassNotFoundException ex) { + log.severe("[iConomy MySQL] Unable to find driver class " + driver); + } + } + } + + public static Connection MySQL() { + try { + return DriverManager.getConnection(db,user,pass); + } catch (SQLException ex) { + log.severe("[iConomy MySQL] Unable to retreive MySQL connection"); + } + + return null; + } + + public static int globalBalance() { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + int current = 0; + + if (mysql) { + try { + conn = MySQL(); + ps = conn.prepareStatement("SELECT balance FROM iBalances"); + rs = ps.executeQuery(); + + while(rs.next()) { + current += rs.getInt("balance"); + } + + return current; + } catch (SQLException ex) { + return 0; + } finally { + try { + if (ps != null) { ps.close(); } + if (rs != null) { rs.close(); } + if (conn != null) { conn.close(); } + } catch (SQLException ex) { } + } + } else { + Map balances; + + try { + balances = accounts.returnMap(); + } catch (Exception ex) { + log.info("[iConomy] Listing failed for accounts."); + return 0; + } + + for (Object key: balances.keySet()) { + int balance = Integer.parseInt((String)balances.get(key)); + current += balance; + } + + return current; + } + } + + public static boolean hasBalance(String playerName) { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + boolean has = false; + + if (mysql) { + try { + conn = MySQL(); + ps = conn.prepareStatement("SELECT balance FROM iBalances WHERE player = ? LIMIT 1"); + ps.setString(1, playerName); + rs = ps.executeQuery(); + + has = (rs.next()) ? true : false; + } catch (SQLException ex) { + log.severe("[iConomy] Unable to grab the balance for [" + playerName + "] from database!"); + } finally { + try { + if (ps != null) { ps.close(); } + if (rs != null) { rs.close(); } + if (conn != null) { conn.close(); } + } catch (SQLException ex) { } + } + } else { + return (accounts.getInt(playerName) != 0) ? true : false; + } + + return has; + } + + public static int getBalance(String playerName) { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + int balance = startingBalance; + + if (mysql) { + try { + conn = MySQL(); + ps = conn.prepareStatement("SELECT balance FROM iBalances WHERE player = ? LIMIT 1"); + ps.setString(1, playerName); + rs = ps.executeQuery(); + + if (rs.next()) { + balance = rs.getInt("balance"); + } else { + ps = conn.prepareStatement("INSERT INTO iBalances (player, balance) VALUES(?,?)"); + ps.setString(1, playerName); + ps.setInt(2, balance); + ps.executeUpdate(); + } + } catch (SQLException ex) { + log.severe("[iConomy] Unable to grab the balance for [" + playerName + "] from database!"); + } finally { + try { + if (ps != null) { ps.close(); } + if (rs != null) { rs.close(); } + if (conn != null) { conn.close(); } + } catch (SQLException ex) { } + } + } else { + // To work with plugins we must do this. + try { + accounts.load(); + } catch (IOException ex) { + log.severe("[iConomy] Unable to reload balances."); + } + + // Return the balance + return (hasBalance(playerName)) ? accounts.getInt(playerName) : accounts.getInt(playerName, startingBalance); + } + + return balance; + } + + public static void setBalance(String playerName, int balance) { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + + if (mysql) { + try { + conn = MySQL(); + + if (hasBalance(playerName)) { + ps = conn.prepareStatement("UPDATE iBalances SET balance = ? WHERE player = ? LIMIT 1", Statement.RETURN_GENERATED_KEYS); + ps.setInt(1, balance); + ps.setString(2, playerName); + ps.executeUpdate(); + } else { + ps = conn.prepareStatement("INSERT INTO iBalances (player, balance) VALUES(?,?)"); + ps.setString(1, playerName); + ps.setInt(2, balance); + ps.executeUpdate(); + } + } catch (SQLException ex) { + log.severe("[iConomy] Unable to update or create the balance for [" + playerName + "] from database!"); + } finally { + try { + if (ps != null) { ps.close(); } + if (rs != null) { rs.close(); } + if (conn != null) { conn.close(); } + } catch (SQLException ex) { } + } + } else { + accounts.setInt(playerName, balance); + } + } +}