Code Patterns

Copy-paste examples for common plugin tasks. Commands, events, ECS, GUI, and more.

← Back to Patterns
storage

File Storage

Persist data to JSON files using BlockingDiskFile. Thread-safe with built-in file locking.

Example Code

java
public class PlayerData extends BlockingDiskFile {

    private List<PlayerRecord> players = new ArrayList<>();

    public PlayerData() {
        super(Path.of("MyPlugin/players.json"));
    }

    @Override
    protected void read(BufferedReader reader) throws IOException {
        JsonParser.parseReader(reader).getAsJsonArray().forEach(entry -> {
            JsonObject obj = entry.getAsJsonObject();
            players.add(new PlayerRecord(
                obj.get("name").getAsString(),
                UUID.fromString(obj.get("uuid").getAsString())
            ));
        });
    }

    @Override
    protected void write(BufferedWriter writer) throws IOException {
        JsonArray array = new JsonArray();
        players.forEach(p -> {
            JsonObject obj = new JsonObject();
            obj.addProperty("name", p.name());
            obj.addProperty("uuid", p.uuid().toString());
            array.add(obj);
        });
        writer.write(array.toString());
    }

    @Override
    protected void create(BufferedWriter writer) throws IOException {
        writer.write("[]");
    }

    public void addPlayer(String name, UUID uuid) {
        this.fileLock.writeLock().lock();
        players.removeIf(p -> p.uuid().equals(uuid));
        players.add(new PlayerRecord(name, uuid));
        this.fileLock.writeLock().unlock();
        this.syncSave();
    }

    public record PlayerRecord(String name, UUID uuid) {}
}

// Usage:
PlayerData data = new PlayerData();
data.syncLoad();  // Load on startup
data.addPlayer("Steve", uuid);
data.syncSave();  // Save on shutdown

Thread Safety

Use fileLock.writeLock().lock/unlock() for thread-safe modifications.

Common Mistakes

Forgetting to call syncLoad() on startup. Not using file lock for modifications.