diff --git a/CommonCore/SQL/src/de/steamwar/sql/Leaderboard.java b/CommonCore/SQL/src/de/steamwar/sql/Leaderboard.java deleted file mode 100644 index 16ee2a41..00000000 --- a/CommonCore/SQL/src/de/steamwar/sql/Leaderboard.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2025 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.sql; - -import de.steamwar.sql.internal.Field; -import de.steamwar.sql.internal.SelectStatement; -import de.steamwar.sql.internal.Statement; -import de.steamwar.sql.internal.Table; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.sql.Timestamp; -import java.util.List; - -@AllArgsConstructor -@Getter -public class Leaderboard { - private static final Table table = new Table<>(Leaderboard.class); - - private static final SelectStatement LEADERBOARD = new SelectStatement<>(table, "SELECT * from Leaderboard WHERE LeaderboardName = ? ORDER BY Time ASC LIMIT 5"); - private static final SelectStatement PLAYER_TIME = new SelectStatement<>(table, "SELECT * FROM Leaderboard WHERE LeaderboardName = ? AND UserId = ?"); - private static final Statement PLAYER_PLACEMENT = new Statement("SELECT COUNT(*) AS Placement FROM Leaderboard WHERE LeaderboardName = ? AND time < (SELECT time FROM UserConfig WHERE WHERE = ? AND LeaderboardName = ?)"); - - private static final Statement INSERT = new Statement("INSERT INTO Leaderboard (UserId, LeaderboardName, Time, BestTime) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE Time = VALUES(Time), BestTime = VALUES(BestTime)"); - - public static List getLeaderboard(String leaderboardName) { - return LEADERBOARD.listSelect(leaderboardName); - } - - public static Leaderboard getPlayerTime(SteamwarUser user, String leaderboardName) { - return PLAYER_TIME.select(leaderboardName, user); - } - - public static int getPlayerPlacement(SteamwarUser user, String leaderboardName) { - return PLAYER_PLACEMENT.select(rs -> { - if(!rs.next()) - return Integer.MAX_VALUE; - return rs.getInt("Placement"); - }, leaderboardName, user, leaderboardName); - } - - public static void upsert(int userId, String leaderboardName, long time, boolean bestTime) { - INSERT.update(userId, leaderboardName, time, bestTime); - } - - @Field(keys = Table.PRIMARY) - private final int userId; - @Field(keys = Table.PRIMARY) - private final String leaderboardName; - @Field - private final long time; - @Field - private final Timestamp updatedAt; - @Field - private final boolean bestTime; -} diff --git a/CommonCore/SQL/src/de/steamwar/sql/Leaderboard.kt b/CommonCore/SQL/src/de/steamwar/sql/Leaderboard.kt new file mode 100644 index 00000000..d3399e5d --- /dev/null +++ b/CommonCore/SQL/src/de/steamwar/sql/Leaderboard.kt @@ -0,0 +1,96 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.sql + +import de.steamwar.sql.internal.useDb +import org.jetbrains.exposed.v1.core.SortOrder +import org.jetbrains.exposed.v1.core.and +import org.jetbrains.exposed.v1.core.count +import org.jetbrains.exposed.v1.core.dao.id.CompositeID +import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable +import org.jetbrains.exposed.v1.core.dao.id.EntityID +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.core.lessSubQuery +import org.jetbrains.exposed.v1.dao.CompositeEntity +import org.jetbrains.exposed.v1.dao.CompositeEntityClass +import org.jetbrains.exposed.v1.javatime.CurrentTimestamp +import org.jetbrains.exposed.v1.javatime.timestamp +import org.jetbrains.exposed.v1.jdbc.select + +object LeaderboardTable : CompositeIdTable("Leaderboard") { + val userId = reference("UserId", SteamwarUserTable) + val name = varchar("Name", 64).entityId() + val time = long("Time") + val updatedAt = timestamp("UpdatedAt").defaultExpression(CurrentTimestamp) + val bestTime = bool("BestTime") +} + +class Leaderboard(id: EntityID) : CompositeEntity(id) { + companion object : CompositeEntityClass(LeaderboardTable) { + @JvmStatic + fun getLeaderboard(name: String) = useDb { + find { LeaderboardTable.name eq name }.orderBy(LeaderboardTable.time to SortOrder.ASC).limit(5).toList() + } + + @JvmStatic + fun getPlayerTime(user: SteamwarUser, name: String) = useDb { + findById(CompositeID { + it[LeaderboardTable.userId] = user.id.value + it[LeaderboardTable.name] = name + }) + } + + @JvmStatic + fun getPlayerPlacement(user: SteamwarUser, name: String) = useDb { + LeaderboardTable.select(LeaderboardTable.time.count()) + .where { + (LeaderboardTable.name eq name) and (LeaderboardTable.time lessSubQuery LeaderboardTable.select( + LeaderboardTable.time + ).where { (LeaderboardTable.userId eq user.id.value) and (LeaderboardTable.name eq name) }) + } + .firstOrNull()?.get(LeaderboardTable.time.count())?.toInt() ?: Int.MAX_VALUE + } + + @JvmStatic + fun upsert(userId: Int, name: String, time: Long, bestTime: Boolean) = useDb { + findByIdAndUpdate(CompositeID { + it[LeaderboardTable.userId] = userId + it[LeaderboardTable.name] = name + }) { + it.time = time + it.bestTime = bestTime + } ?: new( + CompositeID { + it[LeaderboardTable.userId] = userId + it[LeaderboardTable.name] = name + } + ) { + this.time = time + this.bestTime = bestTime + } + } + } + + val user by LeaderboardTable.userId.transform({ EntityID(it, SteamwarUserTable) }, { it.value }) + val name by LeaderboardTable.name + var time by LeaderboardTable.time + var updatedAt by LeaderboardTable.updatedAt + var bestTime by LeaderboardTable.bestTime +} \ No newline at end of file diff --git a/LobbySystem/src/de/steamwar/lobby/util/LeaderboardManager.java b/LobbySystem/src/de/steamwar/lobby/util/LeaderboardManager.java index 50121e05..d5eb8cf9 100644 --- a/LobbySystem/src/de/steamwar/lobby/util/LeaderboardManager.java +++ b/LobbySystem/src/de/steamwar/lobby/util/LeaderboardManager.java @@ -50,7 +50,7 @@ public class LeaderboardManager implements Listener { this.server = server; this.configKey = configKey; this.location = location; - Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin()); + Bukkit.getPluginManager().registerEvents(this, LobbySystem.getInstance()); update(); } @@ -63,7 +63,7 @@ public class LeaderboardManager implements Listener { for (int i = 0; i < leaderboard.size(); i++) { Leaderboard entry = leaderboard.get(i); RArmorStand entity = new RArmorStand(server, location.clone().add(0, (leaderboard.size() - i - 1) * 0.32, 0), RArmorStand.Size.MARKER); - SteamwarUser user = SteamwarUser.byId(entry.user); + SteamwarUser user = SteamwarUser.byId(entry.getUser()); String color = "§7"; if (i == 0) { color = "§6§l";