Giter Club home page Giter Club logo

configlib's People

Contributors

dhugo0022 avatar exlll avatar insprill avatar robothanzo avatar wiiiiam278 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

configlib's Issues

Enums as Keys in Maps

I need a Map<Material, Double> in my configuration.
Maybe you can add Enums as Map keys, thanks :)

I tried the following:

public class ChairsConfig extends BukkitYamlConfiguration {
    public ChairsConfig(Path path) {
        super(path);
        this.loadAndSave();
        if(validChairs.isEmpty()) {
            validChairs.put(Material.SPRUCE_STAIRS, 0.7);
            validChairs.put(Material.JUNGLE_STAIRS, 0.7);
            validChairs.put(Material.OAK_STAIRS, 0.7);
            validChairs.put(Material.BIRCH_STAIRS, 0.7);
            validChairs.put(Material.SANDSTONE_STAIRS, 0.7);
            validChairs.put(Material.COBBLESTONE_STAIRS, 0.7);
            validChairs.put(Material.BRICK_STAIRS, 0.7);
            validChairs.put(Material.NETHER_BRICK_STAIRS, 0.7);
            validChairs.put(Material.QUARTZ_STAIRS, 0.7);
            validChairs.put(Material.ACACIA_STAIRS, 0.7);
            validChairs.put(Material.DARK_OAK_STAIRS, 0.7);
            validChairs.put(Material.RED_SANDSTONE_STAIRS, 0.7);
            validChairs.put(Material.PURPUR_STAIRS, 0.7);
            this.save();
        }
    }

    @Comment("Set the blocks you want to be able to sit down on and sitting height. Use material_name:sitting_height")
    @ElementType(Material.class)
    public Map<Material, Double> validChairs = new HashMap<>();
}

The error after server start:

[16:32:13] [Server thread/ERROR]: Error occurred while enabling Chairs v4.2 (Is it up to date?)
de.exlll.configlib.ConfigurationException: The keys of map 'validChairs' must be simple types.
	at de.exlll.configlib.Validator.checkMapKeysSimple(Validator.java:90) ~[?:?]
	at de.exlll.configlib.Validator.checkMapKeysAndValues(Validator.java:82) ~[?:?]
	at de.exlll.configlib.Converters$MapConverter.preConvertTo(Converters.java:323) ~[?:?]
	at de.exlll.configlib.Converters.convertTo(Converters.java:41) ~[?:?]
	at de.exlll.configlib.FieldMapper.toConvertibleObject(FieldMapper.java:36) ~[?:?]
	at de.exlll.configlib.FieldMapper.instanceToMap(FieldMapper.java:22) ~[?:?]
	at de.exlll.configlib.Configuration.save(Configuration.java:51) ~[?:?]
	at com.cnaude.chairs.config.ChairsConfig.<init>(ChairsConfig.java:42) ~[?:?]
	at com.cnaude.chairs.core.Chairs.onEnable(Chairs.java:55) ~[?:?]
	at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) ~[spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:339) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:403) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at org.bukkit.craftbukkit.v1_13_R2.CraftServer.enablePlugin(CraftServer.java:427) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at org.bukkit.craftbukkit.v1_13_R2.CraftServer.enablePlugins(CraftServer.java:341) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at net.minecraft.server.v1_13_R2.MinecraftServer.l(MinecraftServer.java:582) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at net.minecraft.server.v1_13_R2.MinecraftServer.a(MinecraftServer.java:545) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at net.minecraft.server.v1_13_R2.MinecraftServer.a(MinecraftServer.java:423) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at net.minecraft.server.v1_13_R2.DedicatedServer.init(DedicatedServer.java:288) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at net.minecraft.server.v1_13_R2.MinecraftServer.run(MinecraftServer.java:698) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
	at java.lang.Thread.run(Unknown Source) [?:?]

[Help] Unknown class deserialization

i have several classes like Command and Item

public class Command implements Test {
    private String command;

    @Override
    public void run(Player player) {
        Bukkit.dispatchCommand(player, command);
    }
}
public class Item implements Test {
    private Material material;
    private int amount;

    @Override
    public void run(Player player) {
        player.getInventory().addItem(new ItemStack(material, amount));
    }
}

i want my config to look like this and get a List<Test> from it

myList:
  - type: Item
    material: STONE
    amount: 25
  - type: Command
    command: /say Hello World

How can I do this or something similar with this library?

Shade ConfigLib using Java 8

I was trying to use this library on Java 8, but it looks like the latest version was compiled on a more recent version. I tried v2.2.0, but when I run the server it gives me Error captured: org.yaml.snakeyaml.constructor.Constructor: method 'void <init>()' not found (<shaded path>.configlib.configs.yaml.YamlConfiguration$YamlProperties$Builder:116), even after including snakeyaml 1.20 (as requested by v2.2.0 dependencies) in the .jar.
Do you have any guide on how to use the library in Java 8?

Charset string problem

I put this string (&7➥ &7Complete the previus task) inside a List in a record and when I save in the yaml file I get (&7➥ &7Complete the previus task)
I tried with the default one and also with bukkit.

image
image

[BUG] Unable to Initialize "Configuration class 'ConfigYAML' does not contain any (de-)serializable fields."

Describe the Bug
Unable to initialize a simple YAML Configuration without a more complex type.

To Reproduce

@Configuration
public class ConfigYAML {
    @Comment("Test Config Value")
    private final String test = "HELLO WORLD";

    @Comment("Test Color Code")
    private final int prefixHexCode = 0x189EA9;
}
de.exlll.configlib.ConfigurationException: Configuration class 'ConfigYAML' does not contain any (de-)serializable fields.
        at de.exlll.configlib.ConfigurationSerializer.requireSerializableElements(ConfigurationSerializer.java:44) ~[Vouching-1.0-SNAPSHOT-shaded.jar:?]
        at de.exlll.configlib.TypeSerializer.<init>(TypeSerializer.java:23) ~[Vouching-1.0-SNAPSHOT-shaded.jar:?]
        at de.exlll.configlib.ConfigurationSerializer.<init>(ConfigurationSerializer.java:11) ~[Vouching-1.0-SNAPSHOT-shaded.jar:?]
        at de.exlll.configlib.TypeSerializer.newSerializerFor(TypeSerializer.java:32) ~[Vouching-1.0-SNAPSHOT-shaded.jar:?]
        at de.exlll.configlib.YamlConfigurationStore.<init>(YamlConfigurationStore.java:46) ~[Vouching-1.0-SNAPSHOT-shaded.jar:?]
        at de.exlll.configlib.YamlConfigurations.update(YamlConfigurations.java:149) ~[Vouching-1.0-SNAPSHOT-shaded.jar:?]

Expected behavior
The configuration should initialize successfully even if no complex or custom serializers are present.

Additional context
I know this is mainly designed for complex configurations, however, I was unable to get a simple string only, such as a messages.yml, to generate without an error.

Add support for java 16+

Many servers use 1.16.X and if you downgrade your jdk to java 16
would allow many devs to have ConfigLib (which is the best config lib on spigot)
on their plugins without impacting performance so much

Maven repo not working

Maven repo not working, Tried to include the code myself but code is missing...

Hope you can fix this assap

How does the library handle breaking changes(examples provided)?

Hello, the library looks awesome and I want to start using it, but I do have an important question...
Imagine a plugin whose version is 1, and it created the following config:

Settings:
    # How much money is given to every player on the winner team
    Reward: 100

Everything is working well.
After some time I want to release version 2 which not only rewards the top 3 players, but also each one gets a different amount of money:

Settings:
    # The rewards in decreasing order(first place gets the first amount, second place the second, etc)
    Rewards:
        - 100
        - 70
        - 50

Notice that:

  • Reward was renamed to Rewards
  • Rewards is now a list instead of a field

My question is how does the library handle this breaking change?
What if the user doesn't specify a number to neither configs - does the library throw a descriptive error message, returns a default value, or ignores the setting(if it's within a list)?

I'm asking these questions because my plugin is exactly in this situation and without clear answers I can't use your library... Thank you!

Publish to maven central

Hi, would it be possible to upload this project also to maven central?

The only requirement is that you verify a namespace (essential a domain or use io.github.).

The benefit would be that spigot plugins can define this lib as library in their plugin.yml and it will be downloaded in runtime.
Paper supports different repositories but spigot don't

Allow loading configs from internal JAR resources via an InputStream

Is your feature request related to a problem? Please describe.
I'd like to include several user-provided language files as resources within the JAR files I distribute and load these, based on the user's entry in their main config file, into a Configurable, which I can then save to the user's config directory, update, etc.

Describe the solution you'd like
Expose methods in the various implementations that accept an InputStream for loading from internally bundled JAR resources. Perhaps even a utility update method that accepts "defaults" to be read from an internal resource.

Obviously, the typical (and nice) way of defining defaults for configuration is in-code - but in the case of large multi-language locale files where the defaults vary based on the user's language, a resource-based solution seems more appropriate.

Describe alternatives you've considered
Manually copying the resource from the plugin to the user's config folder, circumventing the use of your library, or delving into SnakeYAML internals to do this :-(

Additional context
None

Polymorphic problem

Describe the bug
If we have a mother class with fields and 2 subclasses, with fields, only the subclasses fields are serialized/deserialized

To Reproduce

@Getter
    @NoArgsConstructor
    @AllArgsConstructor
    @Accessors(fluent = true)
    @Polymorphic
    @PolymorphicTypes({
            @PolymorphicTypes.Type(type = IntegerBackground.class, alias = "integer"),
            @PolymorphicTypes.Type(type = HexBackground.class, alias = "hex")
    })
    public static class Background {

        protected boolean enabled;
        protected int opacity;
        protected boolean shadowed;
        protected boolean seeThrough;

        public Color getColor() {
            return Color.BLACK.setAlpha(0);
        }
    }

    @Getter
    @NoArgsConstructor
    @Configuration
    @Polymorphic
    public static class IntegerBackground extends Background {

        private int red;
        private int green;
        private int blue;

        public IntegerBackground(boolean enabled, int red, int green, int blue, int opacity, boolean shadowed, boolean seeThrough) {
            super(enabled, opacity, shadowed, seeThrough);
            this.red = red;
            this.green = green;
            this.blue = blue;
        }

        @Override
        public Color getColor() {
            return !enabled ? Color.BLACK.setAlpha(0) : Color.fromRGB(red, green, blue).setAlpha(opacity);
        }
    }

    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    @Configuration
    @Polymorphic
    public static class HexBackground extends Background {

        private String hex;

        public HexBackground(boolean enabled, String hex, int opacity, boolean shadowed, boolean seeThrough) {
            super(enabled, opacity, shadowed, seeThrough);
            this.hex = hex;
        }

        @Override
        public Color getColor() {
            int hex = Integer.parseInt(this.hex.substring(1), 16);
            return !enabled ? Color.BLACK.setAlpha(0) : Color.fromRGB(hex).setAlpha(opacity);
        }
    }

Expected behavior
Mother fields should also be serialized/deserialized

Screenshots
image

Native support for Adventure API Component

It would be beneficial for this library to include native support for commonly used Adventure API objects such as TextComponent, Sound, and Key.

In my experience, I've used this library in two different projects, and the first task I always undertake is copying the ComponentSerializer, SoundSerializer, and KeySerializer modules.

The Adventure API also provides support, some of which is even native on other platforms. It would be advantageous to integrate similar support into this library. You can find more information about Adventure API support on other platforms here: https://docs.advntr.dev/platform/native.html

Add option to ignore fields from serialization

Sometimes it is useful to ignore certain fields from serialization and loading. That would allow the reuse of business classes via the @ConfigurationElement annotation.

This also allows adding internal fields to configs that should not be stored or loaded.

I will send a PR for that shortly, implementing a @Ignore annotation that gets added to the default filter list.

Annotation for YML Key

when parsing yml, can the variable be a different name ?
for example
java:

@Key("test.1")
private String test = "hello";

@Key("test.2")
private Integer test2 = 5;

config:

test:
     1: 'hello'
     2: 5

Config value POST load handler support

In Minecraft configuration, there's always a field for "display message" or "display name", and most of the time, it supports colors.

Problem I met

class MyConfig {
     String testMessage;
}
testMessage: "&aHi, or even §cHi, maybe <red>Hi?</red>" # The last one is MiniMessage support by PaperMC btw

While every time I want to use it, I need to

MyUtilsClass.translateColor(MyConfig.testMessage);

Which is frustrating to do. Although you can manually or loop through all the fields and translate them once your plugin starts, it's still frustrating to do so when I'm using a config library that aims to make my code easier and simpler.

If a additional POST load handler is support using annotation

class MyConfig {
     @ImMessage
     String testMessage;
}

In somewhere else

class FieldPostLoadHandler extends XXXXXX<String> {
       public String postProcess(String value) {
              MyUtilsClass.translateColor(MyConfig.testMessage);
       }
}

And register the handler to ConfigLib
configLib.registerPostLoadHandler(FieldFilter.matchAnnotation(ImMessage.class), new FieldPostLoadHandler()); //Just demo, idk where to put this registration

I know that we can use custom deserializer make to job done, but why I need to @SerializeWith and create a class for String (in this case) when I just need to post process the value. If I need multiple post process at the same time,
Ex: @SerializeWith - StringWithColorSerializer or StringWithColorAndFormatSerializer or StringWithFormatSerializer
Instead of
Ex: @ColoredString, @FormattedString

What I state here is just an example, Im using Adventure API TextComponent as my colored string object, but you get my point about why POST load handler is needed.

Server is offline

exlll.de:8081 is offline or unreachable, so gradle isn't working.
Pretty sure it's a dead project, but hey, you never know I guess.

Not working jitpack.io

Describe the bug
A clear and concise description of what the bug is.

respositories {
mavenCentral()
google()

    maven {
        name = "exlll"
        url = "https://jitpack.io"
    }

}

dependencies {
implementation "com.github.Exlll.ConfigLib:configlib-yaml:v4.4.0"
}

Could not resolve all files for configuration ':paper-core:compileClasspath'.
Could not resolve com.github.Exlll.ConfigLib:configlib-yaml:v4.4.0.
Required by:
project :paper-core
> No matching variant of com.github.Exlll.ConfigLib:configlib-yaml:v4.4.0 was found. The consumer was configured to find an API of a library compatible with Java 16, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally but:
- Variant 'apiElements' capability com.github.Exlll.ConfigLib:configlib-yaml:v4.4.0 declares an API of a library, packaged as a jar, and its dependencies declared externally:
- Incompatible because this component declares a component compatible with Java 17 and the consumer needed a component compatible with Java 16
- Other compatible attribute:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
- Variant 'javadocElements' capability com.github.Exlll.ConfigLib:configlib-yaml:v4.4.0 declares a runtime of a component, and its dependencies declared externally:
- Incompatible because this component declares documentation and the consumer needed a library
- Other compatible attributes:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
- Doesn't say anything about its target Java version (required compatibility with Java 16)
- Doesn't say anything about its elements (required them preferably in the form of class files)
- Variant 'runtimeElements' capability com.github.Exlll.ConfigLib:configlib-yaml:v4.4.0 declares a runtime of a library, packaged as a jar, and its dependencies declared externally:
- Incompatible because this component declares a component compatible with Java 17 and the consumer needed a component compatible with Java 16
- Other compatible attribute:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
- Variant 'sourcesElements' capability com.github.Exlll.ConfigLib:configlib-yaml:v4.4.0 declares a runtime of a component, and its dependencies declared externally:
- Incompatible because this component declares documentation and the consumer needed a library
- Other compatible attributes:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
- Doesn't say anything about its target Java version (required compatibility with Java 16)
- Doesn't say anything about its elements (required them preferably in the form of class files)

image

Not working dependency

Add better support for updating configurations

Goal: Give users more control over how configurations are updated.

The load process currently has the following properties over which developers have little control:

  • If a configuration file contains a node that does not correspond to some configuration element, this node is simply discarded.
  • If a node that corresponds to some configuration element is missing in the configuration file, the default value of that configuration element is used.
  • If a node contains an invalid value or a value that is not supported any longer (e.g. some enum constant), there is no way to replace that value during the loading process.

In many cases, the current behavior is not a problem as users can manually update a configuration file to a newer version. However, it would be convenient for users if this library allowed developers to implement automatic updates for their configurations.

A simple example is the renaming of configuration elements: Currently, if a configuration element (e.g. a class field) of some configuration type is renamed without manually updating the configuration file prior to loading a configuration of that configuration type, the information that was stored in the configuration file for that element is simply lost, as there is no way for developers to access this information during loading.

Implementation-wise, the easiest way to change all three properties listed above is to give developers full access to the Map instance returned by the YAML parser and let them do whatever they want with it. While this solution is easy to implement, it has two major drawbacks: First, accessing (deeply) nested values involves quite a lot of casting. Second, map keys used by developers might not have a mapping even though they appear to have one, possibly causing errors at runtime or confusion at development. The second problem is mostly caused by number types: Because the map instance returned by the YAML parser would, once this feature is implemented, only contain valid target types as map keys (in the case of numbers Long, and Double), a call like, for example map.get(1) would always return null, as 1 is of type int and would, therefore, never have a mapping.

A proper solution would be to transform the Map instance returned by the YAML parser to some internal tree-like or node-based representation and to then give developers access to this representation only. While this might result a clean API that abstracts away the underlying map and remedies the problems mentioned above, implementing such an API requires a lot of effort as major parts of the current implementation of this library would have to be rewritten. Also, the transformation of map instances to such a node-based representation might add a lot of computation and memory overhead at runtime.

A middle way can be reached by providing a small wrapper around the map instance. That wrapper can provide an API for accessing nested values without the need for casting and also support common operations like put or rename for adding or moving values around, respectively.

For example, this new Update-API could introduce a MapView interface whose implementation serves as a wrapper for the Map instance returned by the YAML parser, and a MapViewActions class that contains factories for common operations. These factories could return Consumers which allows chaining them together via the andThen method of the Consumer interface (see second example).

public interface MapView {
    interface Key {}
    static Key key(String... parts) { /* return key */ }
    
    Map<?, ?> getDelegate();
    void put(Key key, Object value);
    Object remove(Key key);
    Object get(Key key);
    Boolean getBoolean(Key key);
    Long getLong(Key key);
    Double getDouble(Key key);
    String getString(Key key);
    List<?> getList(Key key);
    Map<?, ?> getMap(Key key);
}

public final class MapViewActions {
    public static Consumer<MapView> put(Key key, Object value) {
        return view -> { /* do stuff */ };
    }
    public static Consumer<MapView> remove(Key key) {
        return view -> { /* do stuff */ };
    }
    public static Consumer<MapView> move(Key fromKey, Key toKey) {
        return view -> { /* do stuff */ };
    }
    public static Consumer<MapView> copy(Key fromKey, Key toKey) {
        return view -> { /* do stuff */ };
    }
}

Using these two classes, developers could write a custom Consumer that serves as an update function for a given configuration. Once written, that Consumer could then be passed to this library via a ConfigurationProperties object. For example, for a configuration type that has a configuration element (i.e. a class field or a record component) with name version, the update function could use that field to bring some configuration file up-to-date to the newest version, as shown below.

public final class Example {
    private static final String CURRENT_VERSION = "1.2.0";
    
    public static void main(String[] args) {
        final Consumer<MapView> updater = view -> {
            final Key versionKey = key("version");

            String version = view.getString(versionKey);
            while (!CURRENT_VERSION.equals(version)) {
                if (version == null) throw new RuntimeException("Missing version");
                switch (version) {
                    case "1.0.0" -> update_v1_0_0_to_v1_1_0().accept(view);
                    case "1.1.0" -> update_v1_1_0_to_v1_2_0().accept(view);
                    default -> throw new RuntimeException("Invalid version: " + version);
                }
                version = view.getString(versionKey);
            }
        };

        final ConfigurationProperties properties = ConfigurationProperties.newBuilder()
                .setUpdater(updater)
                .build();

        // use this properties object when loading the configuration...
    }
    
    private static Consumer<MapView> update_v1_0_0_to_v1_1_0() {
        return MapViewActions.put(key("a", "b"), "SOME_VALUE")
                .andThen(copy(key("a", "b"), key("a", "c")))
                .andThen(move(key("a", "b"), key("a", "d")))
                .andThen(remove(key("a", "c")))
                .andThen(put(key("version"), "1.1.0"));
    }

    private static Consumer<MapView> update_v1_1_0_to_v1_2_0() {
        return MapViewActions.put(key("version"), "1.2.0");
    }
}

An API to make version updates easier could additionally be added as part of this new Update-API or in a future release.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.