Solved Save block breaking in SQLite database

Discussion in 'Plugin Development' started by jimbo8, Jan 2, 2014.

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

    jimbo8

    Hi!

    I finally managed to learn SQL, yay!

    So now, I'm going to start LOGGING EVERONE AND EVERYTHING! Mwuahahah! > : )
    Nah, just kidding. But I'm going to start logging every block broken by who, and the coordinates.

    But how do i load the coordinates and blocks properly?

    This doesn't work for me;

    Code:java
    1. package me.Thomas.MySQLTestPlugin.KommandoerOgSlikt;
    2.  
    3. import java.sql.ResultSet;
    4. import java.sql.SQLException;
    5.  
    6. import me.Thomas.MySQLTestPlugin.Main;
    7.  
    8. import org.bukkit.ChatColor;
    9. import org.bukkit.Location;
    10. import org.bukkit.Material;
    11. import org.bukkit.World;
    12. import org.bukkit.entity.Player;
    13. import org.bukkit.event.EventHandler;
    14. import org.bukkit.event.Listener;
    15. import org.bukkit.event.block.Action;
    16. import org.bukkit.event.player.PlayerInteractEvent;
    17.  
    18. public class SjekkBlokkLogg implements Listener{
    19. Main plugin;
    20.  
    21. public SjekkBlokkLogg(Main instance){
    22. plugin = instance;
    23. }
    24.  
    25. @EventHandler
    26. public void sjekkLogg(PlayerInteractEvent event){
    27. Player player = event.getPlayer();
    28. if(event.getAction() == Action.RIGHT_CLICK_BLOCK){
    29. if (player.getItemInHand().getType() == Material.WATCH) {
    30. int x = event.getClickedBlock().getLocation().getBlockX();
    31. int y = event.getClickedBlock().getLocation().getBlockY();
    32. int z = event.getClickedBlock().getLocation().getBlockZ();
    33. World world = player.getWorld();
    34. Location loc = new Location(world, x, y, z);
    35. try {
    36. plugin.sql.initialise();
    37. ResultSet coordset = plugin.sql.sqlQuery("SELECT verden,x,y,z FROM blockbreak");
    38. ResultSet set = plugin.sql.sqlQuery("SELECT blokk FROM blockbreak ");
    39. ResultSet playerset = plugin.sql.sqlQuery("SELECT brukernavn FROM blockbreak");
    40. if(coordset.equals(loc)){
    41. while(coordset.next() || set.next() || playerset.next()){
    42. player.sendMessage(ChatColor.RED + "Denne blokken ble fjernet av " + playerset.getString("brukernavn") + ". Koordinater: " + "\nX: " + coordset.getString("x") + "\nY: " + coordset.getString("y") + "\nZ: " + coordset.getString("z") + "\nVerden: " + coordset.getString("verden"));
    43. }
    44. }else{
    45. player.sendMessage("Denne blokken har ingen blokklogg.");
    46. }
    47. set.close();
    48. }
    49. catch (SQLException e) {
    50. e.printStackTrace();
    51. }
    52.  
    53. }
    54. }
    55. }
    56. }
    57.  


    The way i save it:

    Code:java
    1. package me.Thomas.MySQLTestPlugin.KommandoerOgSlikt;
    2.  
    3. import java.sql.SQLException;
    4.  
    5. import me.Thomas.MySQLTestPlugin.Main;
    6.  
    7. import org.bukkit.World;
    8. import org.bukkit.entity.Player;
    9. import org.bukkit.event.EventHandler;
    10. import org.bukkit.event.Listener;
    11. import org.bukkit.event.block.BlockBreakEvent;
    12.  
    13. public class Blocklog implements Listener{
    14. Main plugin;
    15.  
    16. public Blocklog(Main instance){
    17. plugin = instance;
    18. }
    19. @EventHandler
    20. public void onPlayerBreak(BlockBreakEvent event){
    21. int x = event.getBlock().getX();
    22. int y = event.getBlock().getY();
    23. int z = event.getBlock().getZ();
    24. Player player = event.getPlayer();
    25. World world = player.getWorld();
    26. plugin.sql.initialise();
    27. try {
    28. plugin.sql.standardQuery("INSERT INTO blockbreak(brukernavn,x,y,z,verden) VALUES ('" + event.getPlayer().getName() + "', '" + x +"', '" + y + "', '" + z + "', '"+ world + "') ;");
    29. player.sendMessage("Lagret!"); //Debug message to make sure it get's saved
    30. } catch (SQLException e) {
    31. e.printStackTrace();
    32. }
    33. }
    34.  
    35.  
    36.  
    37. }
    38.  


    Btw, it is on norwegian :p
    I'm also using the Sync API to make my life a whole lot easier.

    http://dev.bukkit.org/bukkit-plugins/sync/

    I have no problems with changing API and/or use a library/anything else.

    Thanks!
     
  2. Offline

    CubieX

    Code:
    if(coordset.equals(loc)){
    This will not work. You need to create a new Location object from the data read from database and then you can compare the coordinates of those locations.
    Also, you can use a program like "SQLiteSpy" or similar to have a look at your database.
    This way you can find errors faster.

    But keep in mind that logging frequent actions like block breaking, placing and more is better done with MySQL (best with InnoDB engine) than SQLite.
    Because SQLite has only table-level-locking. Means, the whole table will be locked for every INSERT or UPDATE or DELETE query you issue until the query has been fully executed.
    This may lead to a performance problem at some point.
    MySQL with InnoDB engine has row-level-locking. Means, only the currently accessed row will be locked, while other rows can still be accessed simultaneously.
    Just as a thought.
    Make also sure to connect, write and read data asynchronously to/from DB within a separate thread, to avoid stalling the main thread. (=lag)
    What LogBlock for example also does, is using a queue to write data asynchronously and bulk-wise for better performance.

    If your plugin stays small, the used database engine is not that much of a concern.
    But if it eventually does nearly all of that stuff LogBlock for example does, then you will have to worry about this.
     
  3. Offline

    jimbo8

    CubieX
    I'm using Navicat SQLite to check and edit the file.

    I will stick with SQLite for now, until i need a better way to store the data.

    How would i do that?
     
  4. Offline

    CubieX

    I don't speak norwegian. So I don't know exactly what this output is used for:
    Code:
    ResultSet coordset = plugin.sql.sqlQuery("SELECT verden,x,y,z FROM blockbreak");
    ResultSet set = plugin.sql.sqlQuery("SELECT blokk FROM blockbreak ");
    ResultSet playerset = plugin.sql.sqlQuery("SELECT brukernavn FROM blockbreak");
    But if you want to output who broke the clicked block and when,
    then you need to extend your SELECT queries with a WHERE statement to only get the block at the clicked location.
    You do not need to compare the locations then. because your ResultSet will now only hold the history of this clicked block.
     
  5. Offline

    jimbo8

    CubieX

    Okay, i guess i will translate my code before sending it :p

    Yeah, something like this then?
    Code:
    ResultSet coordset = plugin.sql.sqlQuery("SELECT * FROM blockbreak WHERE x,y,z='something inside here';");

    Code translated:

    Code:
    ResultSet coordset = plugin.sql.sqlQuery("SELECT world,x,y,z FROM blockbreak");
    ResultSet set = plugin.sql.sqlQuery("SELECT block FROM blockbreak ");
    ResultSet playerset = plugin.sql.sqlQuery("SELECT username FROM blockbreak");
    Yeah.. you'll just have to be patient with me :p I'm still a beginner, got a lot of notes written down.

    SQL is so much easier when not working with Java.
     
  6. Offline

    CubieX

    SQL is SQL. I can't see why it should be more complicated when using it with Java. :confused:

    Your WHERE statement should look something like this:
    Code:
    WHERE world='" + world.getName() + "' AND x=" + x + " AND y=" + y + " AND z=" + z + ";";
    And you will surely add a timestamp later?
    If you have one, add an "ORDER BY timestamp DESC" statement to your queries to get your result set ordered with the newest entry at first position.
    It's easier to get a nice output list this way.
     
  7. Offline

    jimbo8

    CubieX

    Thanks for your help, i really appreciate it!
    It works perfectly fine now.
    Once again, thank you.

    [EDIT]
    Didn't see your edit before now.

    A time stamp would be great, i guess the MySQL docs says something about how to set it up?

    Misunderstood. Yeah, that would be great too ;)

    Do you know how i should log the time the block was broken?

    Like
    Code:
    Calendar time = Calendar.getInstance();
                SimpleDateFormat formatter = new SimpleDateFormat(
                        "dd/MMM HH:mm:ss");
                String tid = formatter.format(dato.getTime()).toString();
     
Thread Status:
Not open for further replies.

Share This Page