diff --git a/src/main/java/com/zenith/command/impl/DatabaseCommand.java b/src/main/java/com/zenith/command/impl/DatabaseCommand.java index ca22e8cf..843f595b 100644 --- a/src/main/java/com/zenith/command/impl/DatabaseCommand.java +++ b/src/main/java/com/zenith/command/impl/DatabaseCommand.java @@ -33,7 +33,8 @@ public CommandUsage commandUsage() { "deathMessages on/off", "restarts on/off", "playerCount on/off", - "tablist on/off" + "tablist on/off", + "playtime on/off" ), asList("db") ); @@ -53,89 +54,99 @@ public LiteralArgumentBuilder register() { })) .then(literal("queueWait") .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.queueWait.enabled = getToggle(c, "toggle"); - if (CONFIG.database.queueWait.enabled) DATABASE.startQueueWaitDatabase(); - else DATABASE.stopQueueWaitDatabase(); - c.getSource().getEmbed() - .title("Queue Wait Database " + toggleStrCaps(CONFIG.database.queueWait.enabled)); - return OK; + CONFIG.database.queueWaitEnabled = getToggle(c, "toggle"); + if (CONFIG.database.queueWaitEnabled) DATABASE.startQueueWaitDatabase(); + else DATABASE.stopQueueWaitDatabase(); + c.getSource().getEmbed() + .title("Queue Wait Database " + toggleStrCaps(CONFIG.database.queueWaitEnabled)); + return OK; }))) .then(literal("queueLength") .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.queueLength.enabled = getToggle(c, "toggle"); - if (CONFIG.database.queueLength.enabled) DATABASE.startQueueLengthDatabase(); - else DATABASE.stopQueueLengthDatabase(); - c.getSource().getEmbed() - .title("Queue Length Database " + toggleStrCaps(CONFIG.database.queueLength.enabled)); - return OK; + CONFIG.database.queueLengthEnabled = getToggle(c, "toggle"); + if (CONFIG.database.queueLengthEnabled) DATABASE.startQueueLengthDatabase(); + else DATABASE.stopQueueLengthDatabase(); + c.getSource().getEmbed() + .title("Queue Length Database " + toggleStrCaps(CONFIG.database.queueLengthEnabled)); + return OK; }))) .then(literal("publicChat") .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.chats.enabled = getToggle(c, "toggle"); - if (CONFIG.database.chats.enabled) DATABASE.startChatsDatabase(); - else DATABASE.stopChatsDatabase(); - c.getSource().getEmbed() - .title("Public Chat Database " + toggleStrCaps(CONFIG.database.chats.enabled)); - return OK; + CONFIG.database.chatsEnabled = getToggle(c, "toggle"); + if (CONFIG.database.chatsEnabled) DATABASE.startChatsDatabase(); + else DATABASE.stopChatsDatabase(); + c.getSource().getEmbed() + .title("Public Chat Database " + toggleStrCaps(CONFIG.database.chatsEnabled)); + return OK; }))) .then(literal("joinLeave") .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.connections.enabled = getToggle(c, "toggle"); - if (CONFIG.database.connections.enabled) DATABASE.startConnectionsDatabase(); - else DATABASE.stopConnectionsDatabase(); - c.getSource().getEmbed() - .title("Connections Database " + toggleStrCaps(CONFIG.database.connections.enabled)); - return OK; + CONFIG.database.connectionsEnabled = getToggle(c, "toggle"); + if (CONFIG.database.connectionsEnabled) DATABASE.startConnectionsDatabase(); + else DATABASE.stopConnectionsDatabase(); + c.getSource().getEmbed() + .title("Connections Database " + toggleStrCaps(CONFIG.database.connectionsEnabled)); + return OK; }))) .then(literal("deathMessages") .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.deaths.enabled = getToggle(c, "toggle"); - if (CONFIG.database.deaths.enabled) DATABASE.startDeathsDatabase(); - else DATABASE.stopDeathsDatabase(); - c.getSource().getEmbed() - .title("Death Messages Database " + toggleStrCaps(CONFIG.database.deaths.enabled)); - return OK; + CONFIG.database.deathsEnabled = getToggle(c, "toggle"); + if (CONFIG.database.deathsEnabled) DATABASE.startDeathsDatabase(); + else DATABASE.stopDeathsDatabase(); + c.getSource().getEmbed() + .title("Death Messages Database " + toggleStrCaps(CONFIG.database.deathsEnabled)); + return OK; }))) .then(literal("restarts") - .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.restarts.enabled = getToggle(c, "toggle"); - if (CONFIG.database.restarts.enabled) DATABASE.startRestartsDatabase(); - else DATABASE.stopRestartsDatabase(); - c.getSource().getEmbed() - .title("Restarts Database " + toggleStrCaps(CONFIG.database.restarts.enabled)); - return OK; - }))) + .then(argument("toggle", toggle()).executes(c -> { + CONFIG.database.restartsEnabled = getToggle(c, "toggle"); + if (CONFIG.database.restartsEnabled) DATABASE.startRestartsDatabase(); + else DATABASE.stopRestartsDatabase(); + c.getSource().getEmbed() + .title("Restarts Database " + toggleStrCaps(CONFIG.database.restartsEnabled)); + return OK; + }))) .then(literal("playerCount") - .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.playerCount.enabled = getToggle(c, "toggle"); - if (CONFIG.database.playerCount.enabled) DATABASE.startPlayerCountDatabase(); - else DATABASE.stopPlayerCountDatabase(); - c.getSource().getEmbed() - .title("Player Count Database " + toggleStrCaps(CONFIG.database.playerCount.enabled)); - return OK; - }))) + .then(argument("toggle", toggle()).executes(c -> { + CONFIG.database.playerCountEnabled = getToggle(c, "toggle"); + if (CONFIG.database.playerCountEnabled) DATABASE.startPlayerCountDatabase(); + else DATABASE.stopPlayerCountDatabase(); + c.getSource().getEmbed() + .title("Player Count Database " + toggleStrCaps(CONFIG.database.playerCountEnabled)); + return OK; + }))) .then(literal("tablist") - .then(argument("toggle", toggle()).executes(c -> { - CONFIG.database.tablist.enabled = getToggle(c, "toggle"); - if (CONFIG.database.tablist.enabled) DATABASE.startTablistDatabase(); - else DATABASE.stopTablistDatabase(); - c.getSource().getEmbed() - .title("Tablist Database " + toggleStrCaps(CONFIG.database.tablist.enabled)); - return OK; - }))); + .then(argument("toggle", toggle()).executes(c -> { + CONFIG.database.tablistEnabled = getToggle(c, "toggle"); + if (CONFIG.database.tablistEnabled) DATABASE.startTablistDatabase(); + else DATABASE.stopTablistDatabase(); + c.getSource().getEmbed() + .title("Tablist Database " + toggleStrCaps(CONFIG.database.tablistEnabled)); + return OK; + }))) + .then(literal("playtime") + .then(argument("toggle", toggle()).executes(c -> { + CONFIG.database.playtimeEnabled = getToggle(c, "toggle"); + if (CONFIG.database.playtimeEnabled) DATABASE.startPlaytimeDatabase(); + else DATABASE.stopPlaytimeDatabase(); + c.getSource().getEmbed() + .title("Playtime Database " + toggleStrCaps(CONFIG.database.playtimeEnabled)); + return OK; + }))); } @Override public void postPopulate(final Embed builder) { builder - .addField("Queue Wait", toggleStr(CONFIG.database.queueWait.enabled), false) - .addField("Queue Length", toggleStr(CONFIG.database.queueLength.enabled), false) - .addField("Public Chat", toggleStr(CONFIG.database.chats.enabled), false) - .addField("Join/Leave", toggleStr(CONFIG.database.connections.enabled), false) - .addField("Death Messages", toggleStr(CONFIG.database.deaths.enabled), false) - .addField("Restarts", toggleStr(CONFIG.database.restarts.enabled), false) - .addField("Player Count", toggleStr(CONFIG.database.playerCount.enabled), false) - .addField("Tablist", toggleStr(CONFIG.database.tablist.enabled), false) + .addField("Queue Wait", toggleStr(CONFIG.database.queueWaitEnabled), false) + .addField("Queue Length", toggleStr(CONFIG.database.queueLengthEnabled), false) + .addField("Public Chat", toggleStr(CONFIG.database.chatsEnabled), false) + .addField("Join/Leave", toggleStr(CONFIG.database.connectionsEnabled), false) + .addField("Death Messages", toggleStr(CONFIG.database.deathsEnabled), false) + .addField("Restarts", toggleStr(CONFIG.database.restartsEnabled), false) + .addField("Player Count", toggleStr(CONFIG.database.playerCountEnabled), false) + .addField("Tablist", toggleStr(CONFIG.database.tablistEnabled), false) + .addField("Playtime", toggleStr(CONFIG.database.playtimeEnabled), false) .primaryColor(); } } diff --git a/src/main/java/com/zenith/database/DatabaseManager.java b/src/main/java/com/zenith/database/DatabaseManager.java index e3192398..97a5997b 100644 --- a/src/main/java/com/zenith/database/DatabaseManager.java +++ b/src/main/java/com/zenith/database/DatabaseManager.java @@ -25,6 +25,7 @@ public class DatabaseManager { private RestartsDatabase restartsDatabase; private PlayerCountDatabase playerCountDatabase; private TablistDatabase tablistDatabase; + private PlaytimeDatabase playtimeDatabase; private QueryExecutor queryExecutor; private RedisClient redisClient; private ScheduledFuture databaseTickFuture; @@ -36,38 +37,41 @@ public DatabaseManager() { public void start() { try { this.queryExecutor = new QueryExecutor(getJdbi()); - if (CONFIG.database.queueWait.enabled) { + if (CONFIG.database.queueWaitEnabled) { startQueueWaitDatabase(); } - if (CONFIG.database.connections.enabled) { + if (CONFIG.database.connectionsEnabled) { startConnectionsDatabase(); } - if (CONFIG.database.chats.enabled) { + if (CONFIG.database.chatsEnabled) { startChatsDatabase(); } - if (CONFIG.database.deaths.enabled) { + if (CONFIG.database.deathsEnabled) { startDeathsDatabase(); } - if (CONFIG.database.queueLength.enabled) { + if (CONFIG.database.queueLengthEnabled) { startQueueLengthDatabase(); } - if (CONFIG.database.restarts.enabled) { + if (CONFIG.database.restartsEnabled) { startRestartsDatabase(); } - if (CONFIG.database.playerCount.enabled) { + if (CONFIG.database.playerCountEnabled) { startPlayerCountDatabase(); } - if (CONFIG.database.tablist.enabled) { + if (CONFIG.database.tablistEnabled) { startTablistDatabase(); } + if (CONFIG.database.playtimeEnabled) { + startPlaytimeDatabase(); + } if (databaseTickFuture != null) { databaseTickFuture.cancel(false); } databaseTickFuture = EXECUTOR .scheduleAtFixedRate(this::postDatabaseTick, - 1L, - 5L, - TimeUnit.MINUTES); + DatabaseTickEvent.TICK_INTERVAL_SECONDS, + DatabaseTickEvent.TICK_INTERVAL_SECONDS, + TimeUnit.SECONDS); } catch (final Exception e) { DATABASE_LOG.error("Failed starting databases", e); } @@ -84,6 +88,7 @@ public void stop() { stopRestartsDatabase(); stopPlayerCountDatabase(); stopTablistDatabase(); + stopPlaytimeDatabase(); } catch (final Exception e) { DATABASE_LOG.error("Failed stopping databases", e); } @@ -220,6 +225,21 @@ public void stopTablistDatabase() { } } + public void startPlaytimeDatabase() { + if (nonNull(this.playtimeDatabase)) { + this.playtimeDatabase.start(); + } else { + this.playtimeDatabase = new PlaytimeDatabase(queryExecutor, getRedisClient()); + this.playtimeDatabase.start(); + } + } + + public void stopPlaytimeDatabase() { + if (nonNull(this.playtimeDatabase)) { + this.playtimeDatabase.stop(); + } + } + private synchronized Jdbi getJdbi() { if (isNull(this.jdbi)) { this.jdbi = Jdbi.create(new HikariConnectionFactory(new ConnectionPool())); diff --git a/src/main/java/com/zenith/database/PlaytimeDatabase.java b/src/main/java/com/zenith/database/PlaytimeDatabase.java new file mode 100644 index 00000000..e427e8c0 --- /dev/null +++ b/src/main/java/com/zenith/database/PlaytimeDatabase.java @@ -0,0 +1,201 @@ +package com.zenith.database; + +import com.zenith.Proxy; +import com.zenith.database.dto.enums.Connectiontype; +import com.zenith.event.proxy.*; +import org.geysermc.mcprotocollib.auth.GameProfile; + +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static com.github.rfresh2.EventConsumer.of; +import static com.zenith.Shared.*; + +public class PlaytimeDatabase extends LockingDatabase { + private final Map> connectionEvents = new ConcurrentHashMap<>(); + private Instant prevSyncTime = Instant.now(); + + private record ConnectionEvent(Connectiontype type, Long time) {} + + public PlaytimeDatabase(final QueryExecutor queryExecutor, final RedisClient redisClient) { + super(queryExecutor, redisClient); + } + + @Override + public String getLockKey() { + return "Playtime"; + } + + // return value of this doesn't matter + // because we are not using the queue based insert system + @Override + public Instant getLastEntryTime() { + try (var handle = this.queryExecutor.jdbi().open()) { + // todo: add index to last_updated + var result = handle.select("SELECT last_updated FROM playtime ORDER BY last_updated DESC LIMIT 1;") + .mapTo(OffsetDateTime.class) + .findOne(); + if (result.isEmpty()) { + DATABASE_LOG.warn("Playtime database unable to sync. Database empty?"); + prevSyncTime = Instant.now(); + return prevSyncTime; + } + var handoffTime = result.get().toInstant(); + var nowMinusInterval = Instant.now().minusSeconds(DatabaseTickEvent.TICK_INTERVAL_SECONDS); + if (handoffTime.isAfter(nowMinusInterval)) { + prevSyncTime = handoffTime; + } else { + // we acquired lock sometime after the last playtime write tick + prevSyncTime = Instant.now(); + } + return handoffTime; + } + } + + @Override + public void subscribeEvents() { + resetConnectionEvents(); + EVENT_BUS.subscribe( + this, + of(DatabaseTickEvent.class, this::handleDatabaseTick), + of(ServerPlayerConnectedEvent.class, this::handleServerPlayerConnectedEvent), + of(ServerPlayerDisconnectedEvent.class, this::handleServerPlayerDisconnectedEvent), + of(PlayerOnlineEvent.class, (e) -> resetConnectionEvents()), + of(ConnectEvent.class, (e) -> resetConnectionEvents()), + of(DisconnectEvent.class, (e) -> resetConnectionEvents()) + ); + } + + private void resetConnectionEvents() { + synchronized (this) { + connectionEvents.clear(); + } + } + + private void handleDatabaseTick(DatabaseTickEvent databaseTickEvent) { + synchronized (this) { + if (Proxy.getInstance().isOn2b2t() && !Proxy.getInstance().isInQueue()) { + if (this.lockAcquired.get()) { + updatePlaytime(); + } + } + } + resetConnectionEvents(); + } + + public void handleServerPlayerConnectedEvent(ServerPlayerConnectedEvent event) { + if (!Proxy.getInstance().isOn2b2t() || Proxy.getInstance().isInQueue()) return; + synchronized (this) { + connectionEvents.compute(event.playerEntry().getProfile(), (k, v) -> { + if (v == null) v = new ArrayList<>(); + v.add(new ConnectionEvent(Connectiontype.JOIN, Instant.now().getEpochSecond())); + return v; + }); + } + } + + public void handleServerPlayerDisconnectedEvent(ServerPlayerDisconnectedEvent event) { + if (!Proxy.getInstance().isOn2b2t() || Proxy.getInstance().isInQueue()) return; + synchronized (this) { + connectionEvents.compute(event.playerEntry().getProfile(), (k, v) -> { + if (v == null) v = new ArrayList<>(); + v.add(new ConnectionEvent(Connectiontype.LEAVE, Instant.now().getEpochSecond())); + return v; + }); + } + } + + private void updatePlaytime() { + var beforeTime = prevSyncTime.getEpochSecond(); + prevSyncTime = Instant.now(); + var now = Instant.now().atOffset(ZoneOffset.UTC); + var nowSeconds = now.toEpochSecond(); + var timeDelta = nowSeconds - beforeTime; + if (timeDelta < 0) { + DATABASE_LOG.error("playtime interval delta is negative: {} - {} - {}", timeDelta, now.toEpochSecond(), beforeTime); + return; + } + try (var handle = this.queryExecutor.jdbi().open()) { + handle.inTransaction(transaction -> { + var tablistEntries = CACHE.getTabListCache().getEntries(); + var batch = transaction.prepareBatch( + """ + INSERT INTO playtime (player_uuid, player_name, playtime_seconds, last_updated) VALUES (:player_uuid, :player_name, :playtime_seconds, :last_updated) \ + ON CONFLICT (player_uuid) DO UPDATE SET \ + playtime_seconds = playtime.playtime_seconds + excluded.playtime_seconds, \ + player_name = excluded.player_name, \ + last_updated = excluded.last_updated; + """); + for (var entry : tablistEntries) { + if (connectionEvents.containsKey(entry.getProfile())) continue; + // the player has been online since the last db tick + var playerUuid = entry.getProfileId(); + var playerName = entry.getName(); + batch.bind("player_uuid", playerUuid) + .bind("player_name", playerName) + .bind("playtime_seconds", timeDelta) + .bind("last_updated", now) + .add(); + } + for (var entry : connectionEvents.entrySet()) { + var gameProfile = entry.getKey(); + var playerUuid = gameProfile.getId(); + var playerName = gameProfile.getName(); + var events = entry.getValue(); + long prevTime = beforeTime; + Connectiontype lastType = null; + for (int i = 0; i < events.size(); i++) { + final var event = events.get(i); + if (lastType == event.type()) { + DATABASE_LOG.error("consecutive events of the same type: {} - {}", lastType, event.type()); + continue; + } + lastType = event.type(); + switch (event.type()) { + case JOIN -> { + if (i+1 < events.size()) { + // there are more events coming up + prevTime = event.time(); + } else { + if (CACHE.getTabListCache().get(playerUuid).isEmpty()) { + DATABASE_LOG.error("last join event player not in tablist: {} - {}", playerUuid, playerName); + continue; + } + // last event and player is currently online + long playtimeDelta = nowSeconds - prevTime; + if (playtimeDelta < 0) { + DATABASE_LOG.error("last join playtime delta is negative: {} - {} - {}", playtimeDelta, nowSeconds, prevTime); + continue; + } + batch.bind("player_uuid", playerUuid) + .bind("player_name", playerName) + .bind("playtime_seconds", playtimeDelta) + .bind("last_updated", now) + .add(); + } + } + case LEAVE -> { + long playtimeDelta = event.time() - prevTime; + if (playtimeDelta < 0) { + DATABASE_LOG.error("leave playtime delta is negative: {} - {} - {}", playtimeDelta, nowSeconds, prevTime); + continue; + } + batch.bind("player_uuid", playerUuid) + .bind("player_name", playerName) + .bind("playtime_seconds", playtimeDelta) + .bind("last_updated", Instant.ofEpochSecond(event.time()).atOffset(ZoneOffset.UTC)) + .add(); + } + } + } + } + return batch.execute(); + }); + } + } +} diff --git a/src/main/java/com/zenith/database/TablistDatabase.java b/src/main/java/com/zenith/database/TablistDatabase.java index 4c2d2dda..4d2adfd4 100644 --- a/src/main/java/com/zenith/database/TablistDatabase.java +++ b/src/main/java/com/zenith/database/TablistDatabase.java @@ -3,10 +3,10 @@ import com.zenith.event.proxy.DatabaseTickEvent; import java.time.Instant; -import java.time.OffsetDateTime; import java.time.ZoneOffset; -import static com.zenith.Shared.*; +import static com.zenith.Shared.CACHE; +import static com.zenith.Shared.EVENT_BUS; public class TablistDatabase extends LockingDatabase { public TablistDatabase(final QueryExecutor queryExecutor, final RedisClient redisClient) { @@ -27,16 +27,7 @@ public String getLockKey() { @Override public Instant getLastEntryTime() { - try (var handle = this.queryExecutor.jdbi().open()) { - var result = handle.select("SELECT time FROM tablist ORDER BY time DESC LIMIT 1;") - .mapTo(OffsetDateTime.class) - .findOne(); - if (result.isEmpty()) { - DATABASE_LOG.warn("Tablist database unable to sync. Database empty?"); - return Instant.EPOCH; - } - return result.get().toInstant(); - } + return Instant.now(); } private void handleTickEvent(DatabaseTickEvent event) { diff --git a/src/main/java/com/zenith/event/proxy/DatabaseTickEvent.java b/src/main/java/com/zenith/event/proxy/DatabaseTickEvent.java index e36f5df8..fe1960e9 100644 --- a/src/main/java/com/zenith/event/proxy/DatabaseTickEvent.java +++ b/src/main/java/com/zenith/event/proxy/DatabaseTickEvent.java @@ -2,5 +2,6 @@ // Constant tick when we are connected on 2b2t every 5 minutes public record DatabaseTickEvent() { + public static final int TICK_INTERVAL_SECONDS = 300; public static final DatabaseTickEvent INSTANCE = new DatabaseTickEvent(); } diff --git a/src/main/java/com/zenith/feature/deathmessages/DeathMessagesParser.java b/src/main/java/com/zenith/feature/deathmessages/DeathMessagesParser.java index 1af0e4ab..d980ddef 100644 --- a/src/main/java/com/zenith/feature/deathmessages/DeathMessagesParser.java +++ b/src/main/java/com/zenith/feature/deathmessages/DeathMessagesParser.java @@ -54,7 +54,7 @@ public Optional parse(final Component component, final final Optional parse = instance.parse(inputSplit, playerNames); if (parse.isPresent()) return parse; } - if (CONFIG.database.deaths.enabled && CONFIG.database.deaths.unknownDeathDiscordMsg && DISCORD.isRunning()) { + if (CONFIG.database.deathsEnabled && CONFIG.database.unknownDeathDiscordMsg && DISCORD.isRunning()) { DISCORD.sendEmbedMessage(Embed.builder() .title("Unknown death message") .description(ComponentSerializer.serializeJson(component)) diff --git a/src/main/java/com/zenith/util/Config.java b/src/main/java/com/zenith/util/Config.java index edb5369b..8accbd24 100644 --- a/src/main/java/com/zenith/util/Config.java +++ b/src/main/java/com/zenith/util/Config.java @@ -609,55 +609,24 @@ public static final class Database { public int port = 5432; public String username = ""; public String password = ""; - public final QueueWait queueWait = new QueueWait(); - public final Connections connections = new Connections(); - public final Chats chats = new Chats(); - public final Deaths deaths = new Deaths(); - public final QueueLength queueLength = new QueueLength(); - public final Restarts restarts = new Restarts(); - public final PlayerCount playerCount = new PlayerCount(); - public final Tablist tablist = new Tablist(); + public boolean queueWaitEnabled = true; + public boolean connectionsEnabled = true; + public boolean chatsEnabled = true; + public boolean deathsEnabled = true; + public boolean unknownDeathDiscordMsg = true; + public boolean queueLengthEnabled = true; + public boolean restartsEnabled = true; + public boolean playerCountEnabled = true; + public boolean tablistEnabled = true; + public boolean playtimeEnabled = true; public final Lock lock = new Lock(); - public static final class QueueWait { - public boolean enabled = true; - } - public static final class Lock { // use "rediss://" for SSL connection public String redisAddress = "redis://localhost:7181"; public String redisUsername = ""; public String redisPassword = ""; } - - public static final class Connections { - public boolean enabled = true; - } - - public static final class Chats { - public boolean enabled = true; - } - - public static final class Deaths { - public boolean enabled = true; - public boolean unknownDeathDiscordMsg = false; - } - - public static final class QueueLength { - public boolean enabled = true; - } - - public static final class Restarts { - public boolean enabled = true; - } - - public static final class PlayerCount { - public boolean enabled = true; - } - - public static final class Tablist { - public boolean enabled = true; - } } public static final class AutoUpdater { diff --git a/src/main/resources/META-INF/native-image/reachability-metadata.json b/src/main/resources/META-INF/native-image/reachability-metadata.json index 450f4f1c..b7aee724 100644 --- a/src/main/resources/META-INF/native-image/reachability-metadata.json +++ b/src/main/resources/META-INF/native-image/reachability-metadata.json @@ -2282,36 +2282,6 @@ } ] }, - { - "type": "com.zenith.util.Config$Database$Chats", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.zenith.util.Config$Database$Connections", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.zenith.util.Config$Database$Deaths", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "type": "com.zenith.util.Config$Database$Lock", "allDeclaredFields": true, @@ -2322,56 +2292,6 @@ } ] }, - { - "type": "com.zenith.util.Config$Database$PlayerCount", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.zenith.util.Config$Database$QueueLength", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.zenith.util.Config$Database$QueueWait", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.zenith.util.Config$Database$Restarts", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.zenith.util.Config$Database$Tablist", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "type": "com.zenith.util.Config$Debug", "allDeclaredFields": true, @@ -3678,6 +3598,9 @@ } ] }, + { + "type": "java.util.Collections" + }, { "type": "java.util.Collections$UnmodifiableMap", "methods": [ @@ -3898,6 +3821,12 @@ "name": "getConnectionId", "parameterTypes": [] }, + { + "name": "getDefaultDomain", + "parameterTypes": [ + "javax.security.auth.Subject" + ] + }, { "name": "isInstanceOf", "parameterTypes": [ @@ -6429,6 +6358,13 @@ ] } ] + }, + { + "type": { + "proxy": [ + "java.sql.Connection" + ] + } } ], "serialization": [ @@ -7279,4 +7215,4 @@ ] } ] -} \ No newline at end of file +}