How to save data in a config similar to spigot?


#1

I’m new to Sponge and am having trouble understanding some things. I’m looking to save simple data, an int and a UUID, and I want to be able to edit the data depending on different things, and read from it. I am pretty familiar with doing config data in Spigot, but I can’t find anything similar to it in Sponge. Please help!


#2

The offical sponge docs explains it very well.
https://docs.spongepowered.org/stable/en/plugin/configuration/index.html


#3

I’ve gone through it a few times this morning but it’s still a bit confusing to me, any tips on getting started? @MoseMister


#4

Tips:

  • Try something, try to solve it, then ask concrete questions.
  • Look at other plugins, most of them use config files. Mind that not everyone does it “the right way”. Try simpler plugins first.

#5

this is probably “Not the right way” as RandomByte would say as its not created on start and is hard coded. But this code is a simple way to get the config stuff as close to bukkit as possible.

Note that was created when I was new to Sponge so some of it isn’t really right but focus on the set and gets. The has doesn’t work


#6

Ok so I got saving data to work, but loading is having issues. Anyone got any ideas why?

My join event for loading (with some things not included as they arent part of the problem) - https://pastebin.com/CkSHRwi1

And my config class - https://pastebin.com/yMe6NHD0

(Also for saving data for some reason only for me my uuid is contained in quotes like “591jg8gdsj258j” but the other ones are not, it doesn’t matter the order it’s always mine for some reason, not sure if connected or not)


#7

Why are you reloading the root node on save? Also your passing a node that your using as root for the load, is this the root node or another node?


#8

Honestly I have no clue what to do with this sponge config stuff. I kind of have an idea of what I’m doing with some other stuff in Sponge but config is really confusing me, I’ve just been following the docs and some example code i found online to see if anything works. Ill just send the full code I have now because I’m completely lost. For some reason when I get the node now it just says 0 as level instead of whats actually in there @MoseMister

Main class - https://pastebin.com/7sYbY1kC (has some stuff from my level system but that works fine)

Config Class - https://pastebin.com/zXsfgwUd

Could you help point me to where I should go with this? Because the saving works fine I just dont know whats wrong with the loading. No errors at this point it just makes my level (the int im retrieving from the path) to 0. here is what the path looks like

Players {
    Level {
        "3ed066b4-0579-47b8-a937-399bdafad5d1"=1
    }
    XP {
        "3ed066b4-0579-47b8-a937-399bdafad5d1"=0
    }
}

#9

sure, probably not the best idea giving you a really outdated bit of code I wrote when I didnt understand Sponge like I do now, but its commented so much.

main class:

private Config config;

@Listener
public void onEnable(GameStartingServerEvent event){
    //this is setting your config in the destination you wish and leaving it in a field you are able to access at any time
    this.config = new Config.JsonConfig(new File("Configuration/<your plugin name>/Config.conf"));
}

@Listener
public void onLeave(ClientConnectionEvent.Disconnect event) {
    //gets the player who disconnected
    Player player = event.getTargetEntity();
    //gets the xp of the player (use your own code)
    int xp = 0;
    //gets the level of the player (use your own code)
    int level = 0;
    //sets the xp of the player in the node of 'Players.XP.<player uuid>'
    this.config.set(xp, "Players", "XP", player.getUniqueId().toString());
    //sets the xp of the player in the node of 'Players.Level.<player uuid>'
    this.config.set(level, "Players", "Level", player.getUniqueId().toString());
    //saves the changes of the config
    this.config.save();
}

@Listener
public void onPlayerJoin(ClientConnectionEvent.Join event){
    //gets the player who just connected
    Player player = event.getTargetEntity();
    //gets the xp value in the config at the node of 'Players.XP.<player uuid>'
    int xp = this.config.getInt("Players", "XP", player.getUniqueId().toString());
    //gets the level value in the config at the node of 'Players.Level.<player uuid>'
    int level = this.config.getInt("Players", "Level", player.getUniqueId().toString());
}

public Config getConfig(){
    //gets the config
    return this.config;
}

config class

package org.myexampleproject.test;

import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
import ninja.leaping.configurate.loader.ConfigurationLoader;
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

 public class Config {

//this is the configutation loader, as in the rules that the configuration uses on the destination
private ConfigurationLoader loader;
//this is the root node, it has all the data of the config
private ConfigurationNode rootNode;

//Sponge has support for Gson, Json and Yaml, this activates the config in Json mode (Sponge prefers Json)
public static class JsonConfig extends Config {

    public JsonConfig(File file) {
        this(HoconConfigurationLoader.builder().setFile(file).build());
    }

    public JsonConfig(HoconConfigurationLoader loader) {
        super(loader);
    }
}

//this activates the config in Yaml mode
public static class YamlConfig extends Config {

    public YamlConfig(File file){
        this(YAMLConfigurationLoader.builder().setFile(file).build());
    }

    public YamlConfig(YAMLConfigurationLoader loader) {
        super(loader);
    }
}


public Config(ConfigurationLoader<? extends ConfigurationNode>  loader){
    //sets the loader
    this.loader = loader;
    try {
        //sets the root node with all the values found in the config
        rootNode = loader.load();
    } catch (IOException e) {
        //if failed to read the set the root node with no previous knowledge
        rootNode = loader.createEmptyNode();
    }
}

//sets a value in the config at the node
public void set(Object value, Object... node){
    this.rootNode.getNode(node).setValue(value);
}

//gets a string at the node
public String getString(Object... node){
    return getNode(node).getString();
}

//gets a int at the node
public int getInt(Object... node){
    return getNode(node).getInt();
}

//gets a double at the node
public double getDouble(Object... node){
    return getNode(node).getDouble();
}

//gets a list at the node, do the following to get a String list
//config.getList(ConfigurationLoader::getString, node)
//for a Integer list
//config.getList(ConfigurationLoader::getInt, node)
//you get it, i hope
public <R extends Object> List<R> getList(Function<? super ConfigurationNode, ? extends R> type, Object... node) {
    return getNode(node).getChildrenList().stream().map(type).collect(Collectors.toList());
}

//saves all the current changes to the config
public void save(){
    try {
        this.loader.save(this.rootNode);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private ConfigurationNode getNode(Object... node){
    return this.rootNode.getNode(node);
}
}

#10

Thank you man! I will try this out now


#11

@MoseMister I put it in and im getting errors in the console at here line 170 - http://prntscr.com/ls8792 and at here line 218 - http://prntscr.com/ls87e6
Not sure what’s wrong


#12

Also I took out the config related stuff that wasn’t in that block, cause I wasn’t sure if it was needed, anything I should uncomment (thats what i mean by took out)

EDIT - Omg im sorry I forgot the @Listener on Onenable, silly me! Thank you so much man it looks like it works!!! @MoseMister