Configuration List of Objects

Discussion in 'Plugin Development' started by MineStein, Jul 5, 2016.

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

    MineStein

    I can never figure out how to do this. I'm sure this is rather simple but how would I get a list with other values attached than the base one in the config.yml.

    For example:

    Code:
    reports:
      player:
        - reportedBy: MineStein_
          playerReported: MineStein_
          reportReason: 'This is a reason'
    I have absolutely no idea how I would access each individual item under a list item (playerReported and reportReason in this case).
     
  2. Offline

    Zombie_Striker

    @MineStein
    Simple:
    Code:
    String reportedBy = Config#getString(reports.player.reportedBy);
    ]String playerReported = Config#getString(reports.player.playerReported);
    ]String reason = Config#getString(reports.player.reportReason);
     
  3. Offline

    MineStein

    @Zombie_Striker That doesn't make any sense though for what I'm trying to do. Perhaps I was unclear. I want to be able to take out each individual item after a list element and construct an object out of it.

    Example:
    Code:
    reports:
      player:
        - reportedBy: MineStein_
          playerReported: MineStein_
          reportReason: 'This is a reason.'
        - reportedBy: AnotherPlayer
          playerReported: AnotherPlayer
          reportReason: 'This is  another reason.'
    Say I had a report object and I wanted to construct a list of those report objects. I would want to go through each individual list element and get the elements that follow to construct the object without jumping to the next list element.
     
  4. Offline

    ArsenArsen

    Code:
    reports:
      player:
        reporter1: 
          reportedBy: MineStein_
          playerReported: MineStein_
          reportReason: 'This is a reason.'
        reporter2: 
          reportedBy: AnotherPlayer
          playerReported: AnotherPlayer
          reportReason: 'This is  another reason.'
    Is the valid way to do this. To get all off them use ConfigurationSection#getKeys(boolean deep);
    So like getConfig().getConfigurationSection("reports.player").getKeys(false)
     
  5. Offline

    Tecno_Wizard

    ArsenArsen likes this.
  6. Offline

    MineStein

    @ArsenArsen I don't think so. If you look at how plugins like Magic handle configuration they clearly use this method.
     
  7. Offline

    ArsenArsen

    I never said its the absolute best top of the line method, I just said it's a valid one. And I have never heard of that plugin, found it.

    ++ EDIT 1 ++
    @Tecno_Wizard is right. Thats another method. Better then mine. I just didn't think of it.
    -- EDIT 1 --
     
    Last edited: Jul 6, 2016
  8. Offline

    MineStein

    Alright. I decided to try setting and getting the object in the configuration. It works for the most part. The problem now is that I'm getting an error.

    Config:
    Code:
    test:
    - !!me.tylergrissom.exampleplugin.manager.ReportData
      playerBeingReported: MineStein_
      problem: This is the problem.
      reportType: PLAYER
      step: 0
    
    Error:
    http://hastebin.com/voxomexiri.pas

    ReportData:
    Code:
    public class ReportData {
    
        public enum ReportType {
    
            PLAYER,
    
            BUG,
    
            OTHER
        }
    
        private int step;
        private ReportType reportType;
        private String playerBeingReported, problem;
    
        public int getStep() {
            return step;
        }
    
        public ReportType getReportType() {
            return reportType;
        }
    
        public String getPlayerBeingReported() {
            return playerBeingReported;
        }
    
        public String getProblem() {
            return problem;
        }
    
        public void setStep(int step) {
            this.step = step;
        }
    
        public void setReportType(ReportType reportType) {
            this.reportType = reportType;
        }
    
        public void setPlayerBeingReported(String playerBeingReported) {
            this.playerBeingReported = playerBeingReported;
        }
    
        public void setProblem(String problem) {
            this.problem = problem;
        }
    
        public ReportData() {
            this.step = 0;
        }
    }
    
    Main Code:
    Code:
    ReportData reportData = new ReportData();
    
            reportData.setProblem("This is the problem.");
            reportData.setPlayerBeingReported("MineStein_");
            reportData.setReportType(ReportData.ReportType.PLAYER);
    
            List<ReportData> reportDataList = new ArrayList<ReportData>();
    
            reportDataList.add(reportData);
    
            getConfig().set("test", reportDataList);
            saveConfig();
    
            reportDataList = (List<ReportData>) getConfig().getList("test");
    
            Bukkit.getLogger().severe(reportDataList.get(0).getPlayerBeingReported());
     
  9. Offline

    ArsenArsen


    No configuration serializable?
     
  10. Offline

    MineStein

    @ArsenArsen I have no idea how to apply that code to my existing plugin.
     
  11. Offline

    ArsenArsen

    In your serialize() method make a Map<String, Object>, then map.put("variable1", variable1); map.put("variable2", variable2); ... then return it. And a constructor which takes the map, gets stuff from it and set the variables. Like
    Code:
    YourObject(Map< String, Object> m){
        variable1 = m.get("variable1");
            .
            .
            .
    }
    But first in your onEnable do ConfigurationSerialization.registerClass(YourObject.class).
    Optionally add @SerializableAs("MyCoolObject"). Theres no real function but beautification I think.

    More info on this jibberish I wrote here.
     
  12. Offline

    Tecno_Wizard

    If you change the path of the Class or the name of the Class itself, it won't break the serialization.
     
  13. Offline

    ArsenArsen

    Ohhh! Thanks! Ill make sure to take a note of that.
     
  14. Offline

    Tecno_Wizard

    @ArsenArsen I'm pretty sure at least. I've tried figuring out how the whole thing works and it is utterly confusing. A lot of the backend of Bukkit is more complicated than it really needs to be.
     
    bwfcwalshy and ArsenArsen like this.
  15. Offline

    MineStein

    @ArsenArsen What would I pass in for the Map value in the constructor upon instantiation?
     
  16. Offline

    ArsenArsen

    @MineStein you make 2 constructors. One with the map which the YamlConfiguration will use and one which you use to create your type.
     
  17. Offline

    MineStein

    @ArsenArsen Alright. Now how would I set and access the values in the configuration?
     
  18. Any object using the ConfigurationSerializable implementation can just use
    Code:
    FileConfiguration.set(String, Object implementing ConfigurationSerializable
    And the same get method. Yaml will handle everything else for you.
     
  19. Offline

    MineStein

    Alright. It works getting the single objects but the problem is that I don't seem to able to get lists of the object.

    Would I also need to register my enum inside of that class?
     
  20. Offline

    ArsenArsen

    No, just set the List<YourObject> into the config and then retrieve it using ( (List<YourObject>) config.get("PaTh"))
     
  21. Offline

    MCKrypto14

    This might work.
    Code:
    public final class Report {
         private static final Hashtable<String, Report> reports;
    
         private final String player, reporter, reason;
    
         static {
              reports = new Hashtable<String, Report>();
         }
    
         private Report(final String player, final String reporter, final String reason) {
             this.player = player;
             this.reporter = reporter;
             this.reason = reason;
         }
    
         private final void save(final FileConfiguration config) {
              final ConfigurationSection reportSection =
         }
    
         public static final void saveReports(final FileConfiguration config) {
              reports.entrySet().forEach(report -> {
                   final ConfigurationSection section = config.getConfigurationSection("reports").createSection(report.player);
                   section.set("playerReported", report.player);
                   section.set("reportedBy", report.reporter);
                   section.set("reportReason", report.reason);
              }
         }
    
         public static final void readReports(final FileConfiguration config) {
              config.getConfigurationSection("reports").getKeys(false).forEach(key -> {
                   final ConfigurationSection section = config.get("reports." + key);
                   report(key, section.getString("reportedBy"), section.getString("reportReason");
              }
         }
    
         public static final void create(final String player, final String reporter, final String reason) {
              reports.put(player, new Report(player, reporter, reason));
         }
    }
    And to report a player, you would do this:
    Code:
    Report.create("MineStein_", "MineStein_", "This is a reason");
    And in your main plugin, you would save/read like this:
    Code:
    public final class Main extends JavaPlugin {
        @Override
        public final void onEnable() {
             this.saveDefaultConfig();
             Report.read(this.getConfig());
         }
    
         @Override
         public final void onDisable() {
              Report.save(this.getConfig());
              this.saveConfig();
         }
    }
     
    Last edited: Jul 9, 2016
  22. Offline

    ArsenArsen

    @MCKrypto14 I do not think he is trying to do that. I suggested that at first but he said its not what hes doing.
     
Thread Status:
Not open for further replies.

Share This Page