Logging Certain Blocks

Discussion in 'Plugin Development' started by SilentThief, Aug 14, 2014.

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

    SilentThief

    Hello Bukkit Community! I am looking for a way to log certain blocks that have been broken.

    For instance, I break a diamond ore block, I want it to get saved into a .yml file, and then can be referenced later with a command, and each time a player breaks a diamond ore, it increases the number of diamond ore blocks broken in the config file, by one.

    How exactly would I go about doing that?

    Code:
    Code:java
    1. package net.marc.xray;
    2.  
    3. import org.bukkit.Material;
    4. import org.bukkit.block.Block;
    5. import org.bukkit.entity.Player;
    6. import org.bukkit.event.EventHandler;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.event.block.BlockBreakEvent;
    9.  
    10. public class LogBlocks implements Listener
    11. {
    12. @EventHandler
    13. public void logBlocks(BlockBreakEvent event)
    14. {
    15. Player player = event.getPlayer();
    16. Block block = event.getBlock();
    17.  
    18. if (block.getType().equals(Material.STONE))
    19. {
    20. player.sendMessage("You have broken stone! This is a test.");
    21. }
    22. }
    23. }
     
  2. Offline

    LordVakar

    onBlockBreakEvent, check if the block is diamond ore, then increase in config for each player or one global one.
     
  3. Offline

    SilentThief

    I have tried that, it just keeps resetting the value in the config file each time, only setting it to 1 each time a block is broken, I have added my current code to the main post.

    Think of the stone as the diamond_ore I am referencing.

    Still looking for a bit of help with this, if possible.

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

    stoneminer02

    As LordVakar said:
    Increase one global one
    Code:java
    1. String num = getConfig().getString("globalcount.diamond");
    2. num = (int)num + 1;

    or do the same just for players.
     
  5. Offline

    SilentThief

    Could you explain a little more?
    You are somehow converting a String into an int here...

    Code:java
    1.  
    2. package net.marc.xray;
    3.  
    4. import org.bukkit.Material;
    5. import org.bukkit.block.Block;
    6. import org.bukkit.event.EventHandler;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.event.block.BlockBreakEvent;
    9.  
    10. public class LogBlocks implements Listener
    11. {
    12. public static int stone = XRayChecker.getInstance().getConfig().getInt(".Stone");
    13. public static int diamond = XRayChecker.getInstance().getConfig().getInt(".Diamond");
    14. public static int emerald = XRayChecker.getInstance().getConfig().getInt(".Emerald");
    15.  
    16. public static void loadConfigs()
    17. {
    18. XRayChecker.getInstance().getConfig().set(".Stone", stone);
    19. XRayChecker.getInstance().getConfig().set(".Diamond", diamond);
    20. XRayChecker.getInstance().getConfig().set(".Emerald", emerald);
    21. }
    22.  
    23. @EventHandler
    24. public void logBlocks(BlockBreakEvent event)
    25. {
    26. Block block = event.getBlock();
    27. /*Player player = event.getPlayer();*/
    28.  
    29. if (block.getType().equals(Material.STONE))
    30. {
    31. //Player Breaking Stone
    32. stone = (int)stone + 1;
    33. XRayChecker.getInstance().saveConfig();
    34. }
    35. else if (block.getType().equals(Material.DIAMOND_ORE))
    36. {
    37. //Player Breaking Diamond Ore
    38. }
    39. else if (block.getType().equals(Material.EMERALD_ORE))
    40. {
    41. //Player Breaking Emerald Ore
    42. }
    43. }
    44. }
    45.  


    Still need some help with this, no idea why it isn't saving the values, it just returns it to 0, instead of counting upwards.

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

    Garris0n

    Well, first of all, you're attempting to access a JavaPlugin instance statically. Before it exists.
    Second, why the periods in front of the paths? I doubt YAML likes that very much.
    What...
     
    SilentThief likes this.
  7. Offline

    PandazNWafflez

    Code:
    package net.marc.xray;
     
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
     
    public class LogBlocks implements Listener {
    private XRayChecker plugin;
    private int stone;
    private int diamond;
    private int emerald;
     
    public LogBlocks() {
        // Store the plugin instance to avoid calling XRayChecker.getInstance() 226236 times
        // and generally making the code look awful. Really you should pass it in as a parameter but whatever.
        plugin = XRayChecker.getInstance();
        // Get the current values - if they don't exist they are assumed to be 0
        stone = plugin.getConfig().getInt("Stone", 0);
        diamond = plugin.getConfig().getInt("Diamond", 0);
        emerald = plugin.getConfig().getInt("Emerald", 0);
    }
     
    private void save() {
    // Set the values in the config
    plugin.getConfig().set("Stone", stone);
    plugin.getConfig().set("Diamond", diamond);
    plugin.getConfig().set("Emerald", emerald);
    // Use Bukkit's saveConfig() method to save the config
    plugin.saveConfig();
    }
     
    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
    Block block = event.getBlock();
     
    if (block.getType().equals(Material.STONE)) {
    // The player broke a stone block
    // Increment the stone value by one
    stone++;
    // Write the values to the configuration
    save();
    } else if (block.getType().equals(Material.DIAMOND_ORE)) {
    // The player broke a diamond ore block
    // Increment the diamond value by one
    diamond++;
    // Write the values to the configuration
    save();
    } else if (block.getType().equals(Material.EMERALD_ORE)) {
    // The player broke an emerald ore block
    // Increment the emerald value by one
    emerald++;
    // Write the values to the configuration
    save();
    }
    }
    }
    This will increase the value and write it every time a block of the type is broken by any player (I don't guarantee this compiles or works 100% - it's not hard to change). I'll leave you to figure out how to store a different value for each player.
     
  8. Offline

    SilentThief

    New to the configuration syntax. :/
    And I see what you're saying, I didn't think that one through, I will change it around. :)

    Edit:
    It works, woo, finally! :D
    Code:java
    1. package net.marc.xray;
    2.  
    3. import org.bukkit.Material;
    4. import org.bukkit.block.Block;
    5. import org.bukkit.event.EventHandler;
    6. import org.bukkit.event.Listener;
    7. import org.bukkit.event.block.BlockBreakEvent;
    8.  
    9. public class LogBlocks implements Listener
    10. {
    11. public static XRayChecker getInstance = XRayChecker.getInstance();
    12.  
    13. @EventHandler
    14. public void logBlocks(BlockBreakEvent event)
    15. {
    16. Block block = event.getBlock();
    17.  
    18. int stone = getInstance.getConfig().getInt("Stone");
    19. int diamond = getInstance.getConfig().getInt("Diamond");
    20. int emerald = getInstance.getConfig().getInt("Emerald");
    21.  
    22. if (block.getType().equals(Material.STONE))
    23. {
    24. //Player Breaking Stone
    25. stone = (int)stone + 1;
    26. getInstance.getConfig().set("Stone", stone);
    27. getInstance.saveConfig();
    28. }
    29. else if (block.getType().equals(Material.DIAMOND_ORE))
    30. {
    31. //Player Breaking Diamond Ore
    32. diamond = (int)diamond + 1;
    33. getInstance.getConfig().set("Diamond", diamond);
    34. getInstance.saveConfig();
    35. }
    36. else if (block.getType().equals(Material.EMERALD_ORE))
    37. {
    38. //Player Breaking Emerald Ore
    39. emerald = (int)emerald + 1;
    40. getInstance.getConfig().set("Emerald", emerald);
    41. getInstance.saveConfig();
    42. }
    43. }
    44. }


    Yea, that's what I'm trying to figure out now.
    I'm guessing I have to use hash maps, but that's just my guess.

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

    PandazNWafflez

    SilentThief Maps with a key of each player UUID is an option, but you would have to figure out a way to have a value for the Map which holds three different integers (hint, make an object).
     
  10. Offline

    SilentThief

    I came up with this (from what you said):
    Code:java
    1.  
    2. package net.marc.xray;
    3.  
    4. import java.util.HashMap;
    5. import java.util.Map;
    6. import java.util.UUID;
    7.  
    8. import org.bukkit.Material;
    9. import org.bukkit.block.Block;
    10. import org.bukkit.event.EventHandler;
    11. import org.bukkit.event.Listener;
    12. import org.bukkit.event.block.BlockBreakEvent;
    13.  
    14. public class LogBlocks implements Listener
    15. {
    16. public static Map<UUID, LogBlocks> playerMap = new HashMap<UUID, LogBlocks>();
    17.  
    18. private XRayChecker plugin;
    19. private int stone;
    20. private int diamond;
    21. private int emerald;
    22. LogBlocks blocks = new LogBlocks(stone, diamond, emerald);
    23.  
    24. public LogBlocks(int s, int d, int e)
    25. {
    26. plugin = XRayChecker.getInstance();
    27.  
    28. stone = plugin.getConfig().getInt("Player.Stone", 0);
    29. diamond = plugin.getConfig().getInt("Player.Diamond", 0);
    30. emerald = plugin.getConfig().getInt("Player.Emerald", 0);
    31.  
    32. stone = s;
    33. diamond = d;
    34. emerald = e;
    35. }
    36.  
    37. private void save()
    38. {
    39. plugin.getConfig().set("Player.Stone", stone);
    40. plugin.getConfig().set("Player.Diamond", diamond);
    41. plugin.getConfig().set("Player.Emerald", emerald);
    42.  
    43. plugin.saveConfig();
    44. }
    45.  
    46. @EventHandler
    47. public void onBlockBreak(BlockBreakEvent event)
    48. {
    49. Block block = event.getBlock();
    50.  
    51. if (block.getType().equals(Material.STONE))
    52. {
    53. stone++;
    54. save();
    55. }
    56. else if (block.getType().equals(Material.DIAMOND_ORE))
    57. {
    58. diamond++;
    59. save();
    60. }
    61. else if (block.getType().equals(Material.EMERALD_ORE))
    62. {
    63. emerald++;
    64. save();
    65. }
    66. }
    67. }
    68.  

    Hash maps are not my strong suit. As you can probably tell.
     
  11. Offline

    PandazNWafflez

    SilentThief That's not what I meant by make an object. Your object should be of a class looking something like this:

    Code:
    private class XRayData {
        UUID playerId;
        int stone, diamond, emerald;
     
        XRayData(UUID playerId) {
            this.playerId = playerId;
     
            stone = 0;
            diamond = 0;
            emerald = 0;
        }
     
        void load(ConfigurationSection sec) {
            playerId = UUID.fromString(sec.getString("uuid"));
            stone = sec.getInt("stone");
            diamond = sec.getInt("diamond");
            emerald = sec.getInt("emerald");
        }
     
        void save(ConfigurationSection sec) {
            sec.set("uuid", playerId.toString());
            sec.set("stone", stone);
            sec.set("diamond", diamond);
            sec.set("emerald", emerald);
        }
    }
    Define this class inside your LogBlocks class (inner classes).

    Create one of these objects whenever the player joins (PlayerJoinEvent). Call load(ConfigurationSection) only if the player has data already. To get a ConfigurationSection, call plugin.getConfig().getConfigurationSection("player-uuid"); If it doesn't exist, this will be null. Only call load if it isn't null. When a player quits, do likewise. Call getConfigurationSection(), but this time if it doesn't exist, create it with createSection("player-uuid");

    When a player breaks a block, look them up in your HashMap - defined as below:

    private final Map<UUID, XRayData> map = new HashMap<>();

    Because this is an inner class, don't worry about getters / setters - just do data.stone++; or whatever.

    This approach eliminates the need to save every time a block is broken. However, you should save all currently loaded players' data when the plugin disables (create a saveAll() in your listener, call it in onDisable(). saveAll() loops through map.values() and calls save() for all of them, in the same way I described before).
     
Thread Status:
Not open for further replies.

Share This Page