MYSQL Inventory Items

Discussion in 'Spigot Plugin Development' started by Daeshan, Jun 1, 2016.

  1. So I am trying to create a quests system so that each custom NPC that I have ,using CitizensAPI, will have a list of their own quests. I have a mysql database that has a Q_NPC_ID which looks for all the quest for a certain npc with that id and gives them an inventory full of quests that Have their id.

    Right now it is just giving me everyones quests no matter the NPC. Dont mind crappy and ugly code, im still very new. But if someone could help out with that :D
    Code (Text):
        @EventHandler
        public void npcclick(PlayerInteractEntityEvent event){
            if(event.getRightClicked() instanceof Villager){
                event.setCancelled(true);
                try{
                    Statement statement2 = Main.c.createStatement();
                    ResultSet rss = statement2
                            .executeQuery("SELECT * FROM NPCS WHERE Cate='Q'");
                   
                    String questinv = "ยง4"+ event.getRightClicked().getName() + "'s Quests";
                    Inventory inv = Bukkit.createInventory(null,27, questinv);
                   
                    while(rss.next()){
                   
                    Statement statement = Main.c.createStatement();
                    ResultSet rs = statement
                            .executeQuery("SELECT * FROM Quests WHERE NPC_ID='" + rss.getInt("ID") + "'");
                   
                    while (rs.next()) {
                        ItemStack quests = new ItemStack(Material.PAPER, 1);
                        ItemMeta questsmeta = quests.getItemMeta();
                        questsmeta.setDisplayName(ChatColor.AQUA + "" + ChatColor.BOLD + rs.getString("Name").toUpperCase());
                       
                        ArrayList<String> questlore = new ArrayList<String>();
                        questlore.add(ChatColor.GRAY + rs.getString("Q_Desc"));
                        questlore.add(ChatColor.WHITE + "Required Lvl: "+ ChatColor.RED + rs.getString("Req_LVL"));
                        questlore.add(ChatColor.WHITE + "Reward: "+ ChatColor.GOLD + rs.getInt("Reward_Amount")+ " " +rs.getString("Reward_Item") );
                       
                        questlore.add(ChatColor.WHITE + "Return to: "+ ChatColor.RED + rss.getString("Name"));

                        questsmeta.setLore(questlore);
                        quests.setItemMeta(questsmeta);
                            inv.addItem(quests);
                       
                    }
                   
                    Player player = event.getPlayer();
                    player.openInventory(inv);
                   
                    }
     
  2. You don't really seem to do entity based filtering in your query, you just always fetch all NPCs with Cate = Q.

    Also,
    • Don't query your database on the main thread.
    • Use PreparedStatements when parameters are involved (rather than simply concatenating Strings)
    • First collect all Strings, then query the DB once for all IDs (chain some ORs in the WHERE)
    • Close your resources after you're done with them (preferably with try-with-resources)
    • Don't depend on static where not necessary (static cling)
      • Main.c shouldn't be a thing
     
  3. Could you explain and provide small exmaples for some of this
     
    • This is basically wrapping all DB interaction in a BukkitScheduler#runTaskAsynchronously call
    • Code (Java):
      PreparedStatement stmt = conn.prepareStatement("SELECT foo FROM bar WHERE foo = ?");
      stmt.setString(1, "footastic"); // Starts at index 1
      ResultSet rs = stmt.executeQuery();
      http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
    • Assuming you have a ResultSet for IDs
      Code (Java):
      List ids = new List;
      queryAppend = new List
      while idSet has rows
          add id to ids
          add 'id = ?' to queryAppend
      join queryAppend with ' OR '
      stmt =conn.prepareStatement('SELECT foo FROM bar WHERE ' + queryAppend); // joinedIDs is 'id = ? OR id = ?' ... repeated <# of id> times
      index = 1
      for each id in ids
          stmt.setString(index, id);
          increment index
      result = stmt.executeQuery()
    • https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
    • Learn how to use constructors. This is basic Java, really :p.
     
  4. I get a null pointer here in my code. I have not yet put it in the async I will after I get it working.

    Code (Text):
    [17:28:58 ERROR]: Could not pass event PlayerJoinEvent to AtlasCraft v1.0
    org.bukkit.event.EventException
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:310) ~[latest.jar:git-Spigot-8a048fe-a022dd2]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[latest.jar:git-Spigot-8a048fe-a022dd2]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.PlayerList.onPlayerJoin(PlayerList.java:333) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.PlayerList.a(PlayerList.java:159) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.LoginListener.b(LoginListener.java:144) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.LoginListener.c(LoginListener.java:54) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.NetworkManager.a(NetworkManager.java:233) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.ServerConnection.c(ServerConnection.java:140) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.MinecraftServer.D(MinecraftServer.java:825) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.DedicatedServer.D(DedicatedServer.java:399) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.MinecraftServer.C(MinecraftServer.java:665) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at net.minecraft.server.v1_9_R2.MinecraftServer.run(MinecraftServer.java:564) [latest.jar:git-Spigot-8a048fe-a022dd2]
            at java.lang.Thread.run(Thread.java:745) [?:1.7.0_79]
    Caused by: java.lang.NullPointerException
            at me.dabuseck.atlas.MYSQL.MYSQL_InsertPlayerData.playerExists(MYSQL_InsertPlayerData.java:24) ~[?:?]
            at me.dabuseck.atlas.tools.checkers.OnJoin_Checker.onJoin(OnJoin_Checker.java:30) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_79]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_79]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_79]
            at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_79]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[latest.jar:git-Spigot-8a048fe-a022dd2]
            ... 14 more
    [EDIT]
    So I know where the error is occuring. It is happening at the m.c...This is a new problem now. I will worry about the other. I am trying to make it not depend on statics.

    [EDIT 2]
    FIXED
     
    #5 Daeshan, Jun 1, 2016
    Last edited: Jun 2, 2016