Solved MySQL - Player Join Event

Discussion in 'Plugin Development' started by thomasjcf21, Oct 28, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    thomasjcf21

    Hello All,

    I have a plugin so that when a player joins the server it posts there display name to the server. However the first player gets inserted once into the MySQL which is what I want. The second person gets inserted twice. And the third person gets inserted 4 times. Why is that?? Here is my code:
    Code:java
    1. package me.thomasjcf21.PEWI;
    2.  
    3. import java.sql.*;
    4.  
    5. import org.bukkit.Bukkit;
    6. import org.bukkit.entity.Player;
    7. import org.bukkit.event.EventHandler;
    8. import org.bukkit.event.Listener;
    9. import org.bukkit.event.player.PlayerJoinEvent;
    10. import org.bukkit.event.player.PlayerQuitEvent;
    11. import org.bukkit.plugin.java.JavaPlugin;
    12.  
    13. public class PEWI extends JavaPlugin implements Listener{
    14.  
    15. public void onEnable(){
    16. System.out.println("PEWI Enabled!");
    17. Bukkit.getPluginManager().registerEvents(this, this);
    18. String url = "jdbc:mysql://localhost:3307/";
    19. String dbName = "PEWI";
    20. String driver = "com.mysql.jdbc.Driver";
    21. String userName = "root";
    22. String password = "";
    23. try {
    24. Class.forName(driver).newInstance();
    25. Connection conn = DriverManager.getConnection(url+dbName,userName,password);
    26. Statement st = conn.createStatement();
    27. int val = st.executeUpdate("INSERT into online VALUE(online)");
    28. if(val==1)
    29. conn.close();
    30. } catch (Exception e) {
    31. e.printStackTrace();
    32. }
    33. }
    34.  
    35. public void onDisable(){
    36. System.out.println("PEWI Disabled!");
    37. String url = "jdbc:mysql://localhost:3307/";
    38. String dbName = "PEWI";
    39. String driver = "com.mysql.jdbc.Driver";
    40. String userName = "root";
    41. String password = "";
    42. try {
    43. Class.forName(driver).newInstance();
    44. Connection conn = DriverManager.getConnection(url+dbName,userName,password);
    45. Statement st = conn.createStatement();
    46. int val = st.executeUpdate("TRUNCATE online");
    47. int val1 = st.executeUpdate("TRUNCATE players");
    48. if(val==1 && val1==1){
    49. conn.close();
    50. }
    51. } catch (Exception e) {
    52. e.printStackTrace();
    53. }
    54. }
    55.  
    56. @EventHandler
    57. public void onPlayerJoin(PlayerJoinEvent event){
    58. String player = event.getPlayer().getDisplayName();
    59. Bukkit.getPluginManager().registerEvents(this, this);
    60. String url = "jdbc:mysql://localhost:3307/";
    61. String dbName = "PEWI";
    62. String driver = "com.mysql.jdbc.Driver";
    63. String userName = "root";
    64. String password = "";
    65. try {
    66. Class.forName(driver).newInstance();
    67. Connection conn = DriverManager.getConnection(url+dbName,userName,password);
    68. Statement st = conn.createStatement();
    69. int val = st.executeUpdate("INSERT into players (player) VALUE('"+player+"')");
    70. if(val==1)
    71. conn.close();
    72. } catch (Exception e) {
    73. e.printStackTrace();
    74. }
    75. }
    76. }
    77.  
     
  2. Offline

    Jordymt

    Maybe you should add a line like; if the user is already in the database --> cancel or update

    Something like this
    Code:
    IF EXISTS (SELECT * FROM Table WHERE Column='Value')
        UPDATE Table SET (...) WHERE Column='Value'
     
  3. Offline

    thomasjcf21

    Thanks :)

    Jordymt

    Can you put into the code so I can see it context please :) :D

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
  4. Offline

    Jordymt

  5. Offline

    tenowg

    I could be completely wrong, but calling registerEvents everytime the event if fired is not needed, and very well could be causing the event to be called/fired more than once per event. So in this case:

    fired on first player: 1 entry (re-registeres event)
    fired on second player: 2 entries (re-registeres event)
    fired on thrid player: 3 entries (etc, etc...)

    Remove the Bukkit.getPluginManager().registerEvents(this, this); from the event code, and test it then.
     
  6. Offline

    Jordymt


    Woops, missed that part, you only need to call it in the onEnable :$
     
  7. Offline

    thomasjcf21

    What do you mean?? Jordymt

    tenowg Ok thanks I will try it now

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
  8. Offline

    Jordymt


    You only need to put the register events in de onEnable, the others can be removed!

    Code:java
    1. Bukkit.getPluginManager().registerEvents(this, this);
     
  9. Offline

    thomasjcf21

    Jordymt likes this.
  10. Offline

    tenowg

    just as a side note, you might want to look into using ON DUPLICATE UPDATE clause in mysql

    I believe off the top of my head, that it would look like this:

    INSERT INTO table VALUE (values) ON DUPLICATE UPDATE value = somevalue;

    if you make the playername a primary key, and try to add the same player twice it will instead update the record.

    thomasjcf21

    You should also look into what columns you make unique indexs, as well as what columns you make primary... in your case (if the error wasn't about running the event more than once) if you had made the playername unique (or primary) it would have refused to insert the record altogether a second time.
     
  11. Offline

    1Rogue


    I'm assuming that you read from the post I made previously about this (about 10 minutes before this: http://forums.bukkit.org/threads/mysql-update-exisiting-row.188441/#post-1947950), so I'll clarify.

    ON DUPLICATE KEY is called when you attempt to insert a specified value into a column when there is already a key index in place (whether that be the PRIMARY, UNIQUE, KEY, SPATIAL etc...). It is similar to a "catch" in java where you simply attempt a statement and resolve if something goes wrong.

    Also, MySQL uses VALUES not VALUE. Overall, a statement might look like so:

    Code:sql
    1. INSERT INTO `table` (`column_key`)
    2. VALUES ('example value')
    3. ON DUPLICATE KEY UPDATE `variable` = /* some value */;


    Keep in mind that when you do this method (with only inserting the `key_value` or something similar), you should really keep a notice on what values you allow null, and the defaults used when inserting. If you do not specify defaults / not nulls for the columns you'll simply insert a row of null values.
     
  12. Offline

    tenowg

    Nope, didn't see any post by you... and I was just giving a point of reference to be researched, not a full example. Thanks for expanding on this alittle more for these guys.
     
Thread Status:
Not open for further replies.

Share This Page