From eea1073892c6a6b622e95ccf8fa4c52e2b8143f1 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Wed, 29 Oct 2025 23:17:17 +0100 Subject: [PATCH] Migrate Event class to Kotlin and update references across modules Signed-off-by: Chaoscaot --- CommonCore/SQL/src/de/steamwar/sql/Event.java | 125 ------------------ CommonCore/SQL/src/de/steamwar/sql/Event.kt | 123 +++++++++++++++++ .../src/de/steamwar/sql/TeamTeilnahme.java | 2 +- .../src/de/steamwar/fightsystem/Config.java | 2 +- .../lobby/particle/ParticleRequirement.java | 4 +- .../src/de/steamwar/misslewars/Config.java | 2 +- .../tntleague/config/TNTLeagueConfig.kt | 2 +- .../de/steamwar/towerrun/config/Config.java | 2 +- .../discord/listeners/DiscordTeamEvent.java | 2 +- .../src/de/steamwar/routes/Events.kt | 6 +- 10 files changed, 134 insertions(+), 136 deletions(-) delete mode 100644 CommonCore/SQL/src/de/steamwar/sql/Event.java create mode 100644 CommonCore/SQL/src/de/steamwar/sql/Event.kt diff --git a/CommonCore/SQL/src/de/steamwar/sql/Event.java b/CommonCore/SQL/src/de/steamwar/sql/Event.java deleted file mode 100644 index e65a1533..00000000 --- a/CommonCore/SQL/src/de/steamwar/sql/Event.java +++ /dev/null @@ -1,125 +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.time.Instant; -import java.util.List; - -@AllArgsConstructor -public class Event { - - static { - SchematicType.Normal.name(); // Ensure SchematicType is loaded. - } - - private static final Table table = new Table<>(Event.class); - - private static final SelectStatement byCurrent = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start < now() AND End > now()"); - private static final SelectStatement byId = table.select(Table.PRIMARY); - private static final SelectStatement byName = table.select("eventName"); - private static final SelectStatement byComing = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start > now()"); - private static final SelectStatement all = new SelectStatement<>(table, "SELECT * FROM Event"); - - private static final Statement create = table.insertFields(true, "eventName", "deadline", "start", "end", "maximumTeamMembers", "publicSchemsOnly"); - private static final Statement update = table.update(Table.PRIMARY, "eventName", "deadline", "start", "end", "schemType", "maximumTeamMembers", "publicSchemsOnly"); - private static final Statement delete = table.delete(Table.PRIMARY); - - private static Event current = null; - - public static Event get(){ - if(current != null && current.now()) - return current; - - current = byCurrent.select(); - return current; - } - - public static List getAll(){ - return all.listSelect(); - } - - public static Event create(String eventName, Timestamp start, Timestamp end){ - return get(create.insertGetKey(eventName, start, start, end, 5, false)); - } - - public static Event get(int eventID){ - return byId.select(eventID); - } - - public static Event get(String eventName) { - return byName.select(eventName); - } - - public static List getComing() { - return byComing.listSelect(); - } - - @Getter - @Field(keys = {Table.PRIMARY}, autoincrement = true) - private final int eventID; - @Getter - @Field(keys = {"eventName"}) - private final String eventName; - @Getter - @Field - private final Timestamp deadline; - @Getter - @Field - private final Timestamp start; - @Getter - @Field - private final Timestamp end; - @Getter - @Field - private final int maximumTeamMembers; - @Field(nullable = true) - private final SchematicType schemType; - @Field - private final boolean publicSchemsOnly; - - public boolean publicSchemsOnly() { - return publicSchemsOnly; - } - - public SchematicType getSchematicType() { - return schemType; - } - - private boolean now() { - Instant now = Instant.now(); - return now.isAfter(start.toInstant()) && now.isBefore(end.toInstant()); - } - - public void update(String eventName, Timestamp deadline, Timestamp start, Timestamp end, SchematicType schemType, int maximumTeamMembers, boolean publicSchemsOnly) { - update.update(eventName, deadline, start, end, schemType, maximumTeamMembers, publicSchemsOnly, eventID); - } - - public void delete() { - delete.update(eventID); - } -} diff --git a/CommonCore/SQL/src/de/steamwar/sql/Event.kt b/CommonCore/SQL/src/de/steamwar/sql/Event.kt new file mode 100644 index 00000000..5ca83078 --- /dev/null +++ b/CommonCore/SQL/src/de/steamwar/sql/Event.kt @@ -0,0 +1,123 @@ +/* + * 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.and +import org.jetbrains.exposed.v1.core.dao.id.EntityID +import org.jetbrains.exposed.v1.core.dao.id.IntIdTable +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.core.greater +import org.jetbrains.exposed.v1.core.lessEq +import org.jetbrains.exposed.v1.dao.IntEntity +import org.jetbrains.exposed.v1.dao.IntEntityClass +import org.jetbrains.exposed.v1.javatime.timestamp +import org.jetbrains.exposed.v1.jdbc.insertAndGetId +import org.jetbrains.exposed.v1.jdbc.update +import java.sql.Timestamp +import java.time.Instant +import kotlin.math.max + +object EventTable : IntIdTable("Event", "EventId") { + val name = varchar("EventName", 100).uniqueIndex() + val deadline = timestamp("Deadline") + val start = timestamp("Start") + val end = timestamp("End") + val maxPlayers = integer("MaximumTeamMembers") + val schemType = varchar("SchemType", 16).nullable() + val publicsOnly = bool("PublicSchemsOnly") +} + +class Event(id: EntityID) : IntEntity(id) { + companion object : IntEntityClass(EventTable) { + private var current: Event? = null + + @JvmStatic + fun get(): Event? = if (current?.now() == true) { + current + } else useDb { + find { EventTable.start.lessEq(Instant.now()) and EventTable.end.greater(Instant.now()) }.firstOrNull() + ?.also { current == it } + } + + @JvmStatic + fun getAll() = useDb { all().toList() } + + @JvmStatic + fun create(name: String, start: Timestamp, end: Timestamp) = useDb { + EventTable.insertAndGetId { + it[this.name] = name + it[this.deadline] = start.toInstant() + it[this.start] = start.toInstant() + it[this.end] = end.toInstant() + it[this.maxPlayers] = 5 + it[this.publicsOnly] = false + }.let { get(it) } + } + + @JvmStatic + fun byId(id: Int) = useDb { findById(id) } + + @JvmStatic + fun get(name: String) = useDb { find { EventTable.name eq name }.firstOrNull() } + + @JvmStatic + fun getComing() = useDb { find { EventTable.start greater Instant.now() }.toList() } + } + + val eventID by EventTable.id.transform({ EntityID(it, EventTable) }, { it.value }) + var eventName by EventTable.name + private set + var deadline: Timestamp by EventTable.deadline.transform({ it.toInstant() }, { Timestamp.from(it) }) + private set + var start: Timestamp by EventTable.start.transform({ it.toInstant() }, { Timestamp.from(it) }) + private set + var end: Timestamp by EventTable.end.transform({ it.toInstant() }, { Timestamp.from(it) }) + private set + var maximumTeamMembers by EventTable.maxPlayers + private set + var schematicType by EventTable.schemType.transform({ it?.toDB() }, { it?.let { SchematicType.fromDB(it) } }) + private set + var publicSchemsOnly by EventTable.publicsOnly + private set + + fun publicSchemsOnly() = publicSchemsOnly + fun now() = Instant.now().let { it.isAfter(start.toInstant()) && it.isBefore(end.toInstant()) } + + fun update( + name: String, + deadline: Timestamp, + start: Timestamp, + end: Timestamp, + schematicType: SchematicType?, + maxPlayers: Int, + publicSchemsOnly: Boolean + ) = useDb { + this@Event.eventName = name + this@Event.deadline = deadline + this@Event.start = start + this@Event.end = end + this@Event.maximumTeamMembers = maxPlayers + this@Event.schematicType = schematicType + this@Event.publicSchemsOnly = publicSchemsOnly + } + + override fun delete() = useDb { super.delete() } +} \ No newline at end of file diff --git a/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.java b/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.java index 499a1a66..620710ff 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.java +++ b/CommonCore/SQL/src/de/steamwar/sql/TeamTeilnahme.java @@ -65,6 +65,6 @@ public class TeamTeilnahme { } public static Set getEvents(int teamID){ - return selectEvents.listSelect(teamID).stream().map(tt -> Event.get(tt.eventId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries) + return selectEvents.listSelect(teamID).stream().map(tt -> Event.byId(tt.eventId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries) } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java index a5c89bca..8d2b722d 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/Config.java @@ -239,7 +239,7 @@ public class Config { LiveReplay = SpectatePort != 0; Referees = Referee.get(Config.EventKampf.getEventID()); - Event event = Event.get(EventKampf.getEventID()); + Event event = Event.byId(EventKampf.getEventID()); if(BothTeamsPublic) { OnlyPublicSchematics = true; MaximumTeamMembers = Integer.MAX_VALUE; diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleRequirement.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleRequirement.java index 1ac5679a..754f5d2b 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleRequirement.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/ParticleRequirement.java @@ -123,7 +123,7 @@ public interface ParticleRequirement { } static ParticleRequirement eventParticipation(int eventId) { - String eventName = Event.get(eventId).getEventName(); + String eventName = Event.byId(eventId).getEventName(); return new ParticleRequirement() { @Override public String getRequirementName(Player player) { @@ -138,7 +138,7 @@ public interface ParticleRequirement { } static ParticleRequirement eventPlacement(int eventId, int... placementTeams) { - String eventName = Event.get(eventId).getEventName(); + String eventName = Event.byId(eventId).getEventName(); Set teams = new HashSet<>(); for (int i : placementTeams) teams.add(i); return new ParticleRequirement() { diff --git a/MissileWars/src/de/steamwar/misslewars/Config.java b/MissileWars/src/de/steamwar/misslewars/Config.java index b9ebc688..eb223c5d 100644 --- a/MissileWars/src/de/steamwar/misslewars/Config.java +++ b/MissileWars/src/de/steamwar/misslewars/Config.java @@ -148,7 +148,7 @@ public class Config { EventTeamBlueID = team1.getTeamId(); EventTeamRedID = team2.getTeamId(); - Event event = Event.get(EventKampf.getEventID()); + Event event = Event.byId(EventKampf.getEventID()); if (EventTeamBlueID == 0 && EventTeamRedID == 0) { MaximumTeamMembers = Integer.MAX_VALUE; } else { diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index 3f51d535..7f0e7526 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -55,7 +55,7 @@ data class TNTLeagueConfig( if (eventFightId != null && eventFightId > 0) { eventFight = EventFight.get(eventFightId) ?: throw IllegalArgumentException("EventFight with ID $eventFightId not found") - event = Event.get(eventFight.eventID) + event = Event.byId(eventFight.eventID)!! eventTeamBlue = Team.get(eventFight.teamBlue) eventTeamRed = Team.get(eventFight.teamRed) diff --git a/TowerRun/src/de/steamwar/towerrun/config/Config.java b/TowerRun/src/de/steamwar/towerrun/config/Config.java index 1d262066..7a7b6795 100644 --- a/TowerRun/src/de/steamwar/towerrun/config/Config.java +++ b/TowerRun/src/de/steamwar/towerrun/config/Config.java @@ -74,7 +74,7 @@ public class Config { throw new IllegalStateException("Event not found"); } - Event event = Event.get(EVENT_FIGHT.getEventID()); + Event event = Event.byId(EVENT_FIGHT.getEventID()); EVENT_TEAM_BLUE_ID = EVENT_FIGHT.getTeamBlue(); EVENT_TEAM_RED_ID = EVENT_FIGHT.getTeamRed(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTeamEvent.java b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTeamEvent.java index 146c06d0..8e0f3955 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTeamEvent.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTeamEvent.java @@ -55,7 +55,7 @@ public class DiscordTeamEvent extends ListenerAdapter { return; } - Event tournament = Event.get(eventId); + Event tournament = Event.byId(eventId); if(tournament == null){ reply.system("UNKNOWN_EVENT"); return; diff --git a/WebsiteBackend/src/de/steamwar/routes/Events.kt b/WebsiteBackend/src/de/steamwar/routes/Events.kt index ed5ad9ef..faeae862 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Events.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Events.kt @@ -231,7 +231,7 @@ fun Route.configureEventsRoute() { } } event.update(eventName, deadline, start, end, schemType, maxTeamMembers, publicSchemsOnly) - call.respond(ResponseEvent(Event.get(event.eventID))) + call.respond(ResponseEvent(Event.byId(event.eventID)!!)) } delete { val id = call.parameters["id"]?.toIntOrNull() @@ -239,7 +239,7 @@ fun Route.configureEventsRoute() { call.respond(HttpStatusCode.BadRequest, ResponseError("Invalid ID")) return@delete } - val event = Event.get(id) + val event = Event.byId(id) if (event == null) { call.respond(HttpStatusCode.NotFound, ResponseError("Event not found")) return@delete @@ -263,7 +263,7 @@ suspend fun ApplicationCall.receiveEvent(fieldName: String = "id"): Event? { return null } - val event = Event.get(eventId) + val event = Event.byId(eventId) if (event == null) { respond(HttpStatusCode.NotFound, ResponseError("Event not found")) return null