🔵Your own statistics system

The library supports a custom stats system.

You can create your stats system in 5 steps.

Setup with database.

If you want to use file storage, see

Tips to setup with file storage
  1. Create UserStats model (Choose the saving method - file or database)

  2. Create a loader to load data from a file or database

  3. Create UserStatsManager (It is important to manage users)

  4. Create migration to create a database table (optional when you want to use file storage)

  5. Setup all in your main class

First step - create UserStats model
public class MyUserStats extends AbstractDbModel implements UserStats {

    @Id
    private final UUID uuid;
    private final String name;
    private final String arenaName;
    private int wins;
    private int defeats;
    private int kills;

    public UserStats(UUID uuid, String name, String arenaName) {
        this.uuid = uuid;
        this.name = name;
        this.arenaName = arenaName;
        init(); //don't forget
    }

    public UserStats(UUID uuid, String name, String arenaName, int wins, int defeats,int kills) {
        this.uuid = uuid;
        this.name = name;
        this.arenaName = arenaName;
        this.wins = wins;
        this.defeats = defeats;
        this.kills = kills;
        init(); //don't forget
    }

    //or use @Table annotation
    @Override
    public String getTableName() {
        return "users_stats"; //it is important
    }
    
    //Methods to add stats
    public void addWin() {
        wins++;
        update();
    }

    public void addDefeat() {
        defeats++;
        update();
    }

    public void addKill() {
        kills++;
        update();
    }
}
Second step - create a loader
public class MyStatisticsLoader extends AbstractSqlDataBaseLoader<MyUserStats> {

    private final ISQLDataBase sqlDataBase = DatabasesApiPlugin.getApi()
         .getCurrentSqlDataBase();

    @Override
    public void load() {
        load("myminigame_users_stats");
    }

    @Override
    public void load(String tableName) {
        QueryBuilder queryBuilder = new QueryBuilder();

        String query = queryBuilder.selectAll(tableName).build();

        try (ResultSet resultSet = sqlDataBase.getAsyncQuery().query(query)) {

            while (resultSet.next()) {
                MyUserStats userStats = new MyUserStats(
                        UUID.fromString(resultSet.getString("uuid")),
                        resultSet.getString("name"),
                        resultSet.getString("arenaName"),
                        resultSet.getInt("wins"),
                        resultSet.getInt("defeats"),
                        resultSet.getInt("kills"),
                );

                getData().add(userStats);
            }

        } catch (ExecutionException | InterruptedException | SQLException e) {
            throw new RuntimeException(e);
        }

    }
}
Third step - create UserStatsManager
public class UserStatsManager extends AbstractStatistics<MyUserStats> {

    private final MyStatisticsLoader statisticsLoader; //inject your loader

    //this method is deprecated, 
    //it's recommended to override save, delete and update methods in model 
    public void addNewUser(MyUserStats userStats) {
        QueryBuilder queryBuilder = new QueryBuilder();

        String sql = queryBuilder.insert(userStats.getTableName(), null, userStats.getUuid().toString(), userStats.getName(),
                        userStats.getArenaName(), userStats.getWins(), userStats.getDefeats(), userStats.getKills())
                .build();

        try {
            DatabasesApiPlugin.getApi().getCurrentSqlDataBase().getAsyncQuery().update(sql);
        } catch (ExecutionException | InterruptedException e) {
            throw new RuntimeException(e);
        }

        statisticsLoader.addObject(userStats);
    }

    @Override
    public Optional<MyUserStats> getUser(UUID uuid, String arenaName) {
        return statisticsLoader.getData()
                .stream()
                .filter(userStats -> userStats.getUuid().equals(uuid))
                .filter(userStats -> userStats.getArenaName().equalsIgnoreCase(arenaName))
                .findAny();
    }

    @Override
    public List<MyUserStats> getAllStatsByUuid(UUID uuid) {
        return statisticsLoader.getData().stream()
                .filter(userStats -> userStats.getUuid().equals(uuid))
                .collect(Collectors.toList());
    }

    //calculates total of stats
    public int getTotalWins(UUID uuid) {
        return getTotal(uuid, MyUserStats::getWins);
    }

    public int getTotalDefeats(UUID uuid) {
        return getTotal(uuid, MyUserStats::getDefeats);
    }

    public int getTotalKills(UUID uuid) {
        return getTotal(uuid, MyUserStats::getKills);
    }
}
Fourth step - create migration (Create thanks to T-DataBasesAPI)
public class CreateMyStatsTable extends CreateUserStatsTable {

    private final ISQLDataBase currentSqlDataBase = 
       DatabasesApiPlugin.getApi().getCurrentSqlDataBase();

    @Override
    protected ITable createTableUserStats() {
        return currentSqlDataBase.getTableCreator()
                .id()
                .createColumn("uuid", new VarcharDataType(36), false)
                .createColumn("name", new VarcharDataType(30), false)
                .createColumn("arenaName", new VarcharDataType(50), false)
                .createColumn("wins", DataTypes.INT, false)
                .defaultValue("wins", 0)
                .createColumn("defeats", DataTypes.INT, false)
                .defaultValue("defeats", 0)
                .createColumn("kills", DataTypes.INT, false)
                .defaultValue("kills", 0);
    }
}
Fifth step - setup all in your main class

private UserStatsManager userStatisticsManager;

@Override
public onEnable() {
  MyStatisticsLoader statsLoader = new MyStatisticsLoader();
  
  userStatisticsManager = new UserStatsManager(statsLoader);
  
   Migrations migrations = DatabasesApiPlugin.getApi().getMigrations();
   migrations.addMigration(new CreateMyStatsTable());
   migrations.migrateAll();

   getLoaders().registerLoaders(statsLoader);

   getLoaders().loadAll();
}

How to add stats?

Create method getUserStatsOrCreate(player, arena) in your UserStatsManager.

public MyUserStats getUserStatsOrCreate(Player player, Arena arena) {
  Optional<MyUserStats> userStatsOptional = getUser(player.getUniqueId(), arena.getName());

  MyUserStats userStats;
  if (!userStatsOptional.isPresent()) {
    userStats = new MyUserStats(player.getUniqueId(), player.getName(), 
        arena.getName());

    addNewUser(userStats);
    } else {
       userStats = userStatsOptional.get();
    }

    return userStats;
 }

Add stats

MyUserStats userStats = statisticsManager.getUserStatsOrCreate(player, arena);
userStats.addWin();

Last updated