Add PlayerData DB table

This commit is contained in:
Alessandro Proto 2024-08-06 10:27:18 +02:00
parent f47e80d510
commit d40b2d1b3b
4 changed files with 227 additions and 6 deletions

View file

@ -9,7 +9,7 @@ yarn_mappings=1.21+build.9
loader_version=0.15.11
# Mod Properties
mod_version=1.3.1
mod_version=1.4.0
maven_group=ct
archives_base_name=ct-server

View file

@ -1,18 +1,26 @@
package ct.server;
import ct.server.database.DatabaseClient;
import ct.server.database.PlayerData;
import ct.server.database.PlayerTable;
import ct.server.http.ServiceServer;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.text.TextColor;
import net.minecraft.text.Texts;
import net.minecraft.util.Formatting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
public class CtServer implements ModInitializer {
@ -28,18 +36,27 @@ public class CtServer implements ModInitializer {
public static CtServer getInstance() {
return INSTANCE;
}
private static CtServer INSTANCE;
private ServiceServer serviceServer;
public ServiceServer serviceServer() {
return serviceServer;
}
private DatabaseClient database;
public DatabaseClient database() {
return database;
}
private PlayerTable playerTable;
public PlayerTable playerTable() {
return playerTable;
}
@Override
public void onInitialize() {
INSTANCE = this;
@ -48,8 +65,11 @@ public class CtServer implements ModInitializer {
try {
database = new DatabaseClient();
} catch(SQLException e) {
LOGGER.error("Could not connect to the database", e);
playerTable = new PlayerTable();
playerTable.ensureDatabaseCreated();
} catch (SQLException e) {
LOGGER.error("Database error", e);
}
try {
@ -65,17 +85,37 @@ public class CtServer implements ModInitializer {
}
});
ServerEntityEvents.ENTITY_LOAD.register((entity, world) -> {
if(entity instanceof ServerPlayerEntity) {
currentPlayerCount = world.getServer().getCurrentPlayerCount();
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
currentPlayerCount = server.getCurrentPlayerCount() + 1;
var player = handler.getPlayer();
var playerData = playerTable.getPlayerData(player.getUuid());
if(playerData == null) {
// new player!
playerData = new PlayerData(handler.getPlayer().getUuid());
playerData.firstJoinedDate(new Date());
playerData.name(player.getName().getString());
playerTable.updatePlayerData(playerData);
broadcastMessage(server, Text.literal("Welcome " + player.getName().getString() + " to the server!").formatted(Formatting.GREEN));
} else {
if (!playerData.name().equals(player.getName().getString())) {
playerData.name(player.getName().getString());
playerTable.updatePlayerData(playerData);
}
}
});
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
currentPlayerCount = server.getCurrentPlayerCount() - 1;
});
}
public void broadcastMessage(MinecraftServer server, Text message) {
for(ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) {
player.sendMessage(message, false);
}
}
public static float getTPS() {
return currentTps;
}

View file

@ -0,0 +1,65 @@
package ct.server.database;
import org.jetbrains.annotations.Nullable;
import java.util.Date;
import java.util.UUID;
public class PlayerData {
private final UUID uuid;
@Nullable
private String name;
private Date firstJoinedDate;
@Nullable
private String discordId;
private boolean isBot = false;
private boolean isAlt = false;
public PlayerData(UUID uuid) {
this.uuid = uuid;
}
public UUID uuid() {
return uuid;
}
public String name() {
if (name == null) {
return uuid.toString();
}
return name;
}
public void name(@Nullable String name) {
this.name = name;
}
public Date firstJoinedDate() {
return firstJoinedDate;
}
public void firstJoinedDate(Date firstJoinedDate) {
this.firstJoinedDate = firstJoinedDate;
}
public @Nullable String discordId() {
return discordId;
}
public void discordId(@Nullable String discordId) {
this.discordId = discordId;
}
public boolean isBot() {
return isBot;
}
public void isBot(boolean isBot) {
this.isBot = isBot;
}
public boolean isAlt() {
return isAlt;
}
public void isAlt(boolean isAlt) {
this.isAlt = isAlt;
}
}

View file

@ -0,0 +1,116 @@
package ct.server.database;
import ct.server.CtServer;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
public class PlayerTable {
private final DatabaseClient database = CtServer.getInstance().database();
private final HashMap<UUID, PlayerData> cache = new HashMap<>();
public void ensureDatabaseCreated() {
try {
var conn = database.connection();
var stmt = conn.prepareStatement(
"CREATE TABLE IF NOT EXISTS players (" +
"uuid UUID NOT NULL PRIMARY KEY," +
"firstJoined TIMESTAMP DEFAULT CURRENT_TIMESTAMP," +
"lastKnownName VARCHAR(16)," +
"discordId VARCHAR," +
"isBot BOOL DEFAULT FALSE," +
"isAlt BOOL DEFAULT FALSE" +
");");
stmt.executeUpdate();
stmt.close();
} catch (SQLException e) {
CtServer.LOGGER.error("Could not create players data tables", e);
}
}
public void refreshPlayerData(UUID uuid) {
cache.remove(uuid);
}
@Nullable
public PlayerData getPlayerData(UUID uuid) {
if (cache.containsKey(uuid)) {
return cache.get(uuid);
}
try {
var conn = database.connection();
var stmt = conn.prepareStatement("SELECT * FROM players WHERE uuid = ?;");
stmt.setObject(1, uuid);
var set = stmt.executeQuery();
if (!set.next()) {
return null;
}
var playerData = new PlayerData(set.getObject("uuid", UUID.class));
var firstJoinTimestamp = set.getObject("firstJoined", Timestamp.class);
playerData.firstJoinedDate(new Date(firstJoinTimestamp.getTime()));
playerData.name(set.getString("lastKnownName"));
playerData.discordId(set.getString("discordId"));
playerData.isBot(set.getBoolean("isBot"));
playerData.isAlt(set.getBoolean("isAlt"));
stmt.close();
cache.put(uuid, playerData);
return playerData;
} catch (SQLException e) {
CtServer.LOGGER.error("Could not get player data from database", e);
return null;
}
}
public boolean deletePlayerData(UUID uuid) {
try {
var conn = database.connection();
var stmt = conn.prepareStatement("DELETE FROM players WHERE uuid = ?;");
stmt.setObject(1, uuid);
stmt.execute();
stmt.close();
cache.remove(uuid);
return true;
} catch(SQLException e) {
CtServer.LOGGER.error("Could not delete player data from database", e);
return false;
}
}
public boolean updatePlayerData(PlayerData playerData) {
deletePlayerData(playerData.uuid());
try {
var conn = database.connection();
var stmt = conn.prepareStatement("INSERT INTO players(uuid, firstJoined, lastKnownName, discordId, isBot, isAlt) VALUES (?,?,?,?,?,?);");
stmt.setObject(1, playerData.uuid());
var timestamp = new Timestamp(playerData.firstJoinedDate().getTime());
stmt.setTimestamp(2, timestamp);
stmt.setString(3, playerData.name());
stmt.setString(4, playerData.discordId());
stmt.setBoolean(5, playerData.isBot());
stmt.setBoolean(6, playerData.isAlt());
stmt.execute();
stmt.close();
cache.put(playerData.uuid(), playerData);
return true;
} catch (SQLException e) {
CtServer.LOGGER.error("Could not get player data from database", e);
return false;
}
}
}