forked from SteamWar/SteamWar
Remove Event-related SQL classes and update relevant references across modules
Signed-off-by: Chaoscaot <max@maxsp.de>
This commit is contained in:
@@ -1,216 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 lombok.Setter;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class EventFight implements Comparable<EventFight> {
|
||||
|
||||
private static final Table<EventFight> table = new Table<>(EventFight.class);
|
||||
private static final SelectStatement<EventFight> byId = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<EventFight> byGroup = new SelectStatement<EventFight>(table, "SELECT * FROM EventFight WHERE GroupID = ? ORDER BY StartTime ASC");
|
||||
private static final SelectStatement<EventFight> byGroupLast = new SelectStatement<EventFight>(table, "SELECT * FROM EventFight WHERE GroupID = ? ORDER BY StartTime DESC LIMIT 1");
|
||||
private static final SelectStatement<EventFight> allComing = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE StartTime > now() ORDER BY StartTime ASC");
|
||||
private static final SelectStatement<EventFight> event = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE EventID = ? ORDER BY StartTime ASC");
|
||||
private static final SelectStatement<EventFight> activeFights = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE EventID IN (SELECT EventID FROM Event WHERE Start < now() and End > now()) AND Fight IS NULL AND StartTime < now()");
|
||||
private static final Statement reschedule = table.update(Table.PRIMARY, "StartTime");
|
||||
private static final Statement setResult = table.update(Table.PRIMARY, "Ergebnis");
|
||||
private static final Statement setFight = table.update(Table.PRIMARY, "Fight");
|
||||
|
||||
private static final Statement create = table.insertFields(true, "eventID", "startTime", "spielmodus", "map", "teamBlue", "teamRed", "spectatePort");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "startTime", "spielModus", "map", "teamBlue", "teamRed", "spectatePort");
|
||||
private static final Statement setGroup = table.update(Table.PRIMARY, "GroupID");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
@Getter
|
||||
private static final Queue<EventFight> fights = new PriorityQueue<>();
|
||||
|
||||
public static EventFight get(int fightID) {
|
||||
return byId.select(fightID);
|
||||
}
|
||||
|
||||
public static List<EventFight> get(EventGroup group) {
|
||||
return byGroup.listSelect(group.getId());
|
||||
}
|
||||
|
||||
public static Optional<EventFight> getLast(EventGroup group) {
|
||||
return Optional.ofNullable(byGroupLast.select(group.getId()));
|
||||
}
|
||||
|
||||
public static void loadAllComingFights() {
|
||||
fights.clear();
|
||||
fights.addAll(allComing.listSelect());
|
||||
}
|
||||
|
||||
public static List<EventFight> getEvent(int eventID) {
|
||||
return event.listSelect(eventID);
|
||||
}
|
||||
|
||||
private static List<EventFight> activeFightsCache = null;
|
||||
|
||||
public static void clearActiveFightsCache() {
|
||||
activeFightsCache = null;
|
||||
}
|
||||
|
||||
public static List<EventFight> getActiveFights() {
|
||||
if (activeFightsCache == null) {
|
||||
activeFightsCache = activeFights.listSelect();
|
||||
}
|
||||
return activeFightsCache;
|
||||
}
|
||||
|
||||
public static EventFight create(int event, Timestamp from, String spielmodus, String map, int blueTeam, int redTeam, Integer spectatePort) {
|
||||
return get(create.insertGetKey(event, from, spielmodus, map, blueTeam, redTeam, spectatePort));
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field
|
||||
private final int eventID;
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int fightID;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field(nullable = true, def = "null")
|
||||
private Integer groupId;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private Timestamp startTime;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private String spielmodus;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private String map;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private int teamBlue;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field
|
||||
private int teamRed;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field(nullable = true)
|
||||
private Integer spectatePort;
|
||||
@Getter
|
||||
@Setter
|
||||
@Field(def = "1")
|
||||
private int bestOf;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private int ergebnis;
|
||||
@Field(nullable = true)
|
||||
private int fight;
|
||||
|
||||
public Optional<EventGroup> getGroup() {
|
||||
return Optional.ofNullable(groupId).flatMap(EventGroup::get);
|
||||
}
|
||||
|
||||
public Optional<Team> getWinner() {
|
||||
if(ergebnis == 0)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(ergebnis == 1 ? Team.get(teamBlue) : Team.get(teamRed));
|
||||
}
|
||||
|
||||
public Optional<Team> getLosser() {
|
||||
if(ergebnis == 0)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(ergebnis == 1 ? Team.get(teamRed) : Team.get(teamBlue));
|
||||
}
|
||||
|
||||
public List<EventRelation> getDependents() {
|
||||
return EventRelation.getFightRelations(this);
|
||||
}
|
||||
|
||||
public void setErgebnis(int winner) {
|
||||
this.ergebnis = winner;
|
||||
setResult.update(winner, fightID);
|
||||
}
|
||||
|
||||
public void setFight(int fight) {
|
||||
//Fight.FightID, not EventFight.FightID
|
||||
this.fight = fight;
|
||||
setFight.update(fight, fightID);
|
||||
}
|
||||
|
||||
public void setGroup(Integer group) {
|
||||
setGroup.update(group, fightID);
|
||||
this.groupId = group;
|
||||
}
|
||||
|
||||
public boolean hasFinished() {
|
||||
return fight != 0 || ergebnis != 0;
|
||||
}
|
||||
|
||||
public void reschedule() {
|
||||
startTime = Timestamp.from(new Date().toInstant().plus(30, SECONDS));
|
||||
reschedule.update(startTime, fightID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return fightID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
if(o == null)
|
||||
return false;
|
||||
if(!(o instanceof EventFight))
|
||||
return false;
|
||||
return fightID == ((EventFight) o).fightID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(EventFight o) {
|
||||
return startTime.compareTo(o.startTime);
|
||||
}
|
||||
|
||||
public void update(Timestamp startTime, String spielmodus, String map, int teamBlue, int teamRed, Integer spectatePort) {
|
||||
update.update(startTime, spielmodus, map, teamBlue, teamRed, spectatePort, fightID);
|
||||
this.startTime = startTime;
|
||||
this.spielmodus = spielmodus;
|
||||
this.map = map;
|
||||
this.teamBlue = teamBlue;
|
||||
this.teamRed = teamRed;
|
||||
this.spectatePort = spectatePort;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(fightID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.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.greaterEq
|
||||
import org.jetbrains.exposed.v1.core.inList
|
||||
import org.jetbrains.exposed.v1.core.inSubQuery
|
||||
import org.jetbrains.exposed.v1.core.isNull
|
||||
import org.jetbrains.exposed.v1.core.less
|
||||
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.select
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
import java.util.Optional
|
||||
import java.util.PriorityQueue
|
||||
import java.util.Queue
|
||||
|
||||
object EventFightTable : IntIdTable("EventFight", "FightID") {
|
||||
val eventId = reference("EventID", EventTable)
|
||||
val startTime = timestamp("StartTime")
|
||||
val gamemode = text("Spielmodus")
|
||||
val map = text("Map")
|
||||
val groupId = optReference("GroupId", EventGroupTable)
|
||||
val teamBlue = reference("TeamBlue", TeamTable)
|
||||
val teamRed = reference("TeamRed", TeamTable)
|
||||
val spectatePort = integer("SpectatePort").nullable()
|
||||
val bestOf = integer("BestOf")
|
||||
val ergebnis = integer("Ergebnis")
|
||||
val fight = integer("Fight").entityId().nullable()
|
||||
}
|
||||
|
||||
class EventFight(id: EntityID<Int>) : IntEntity(id), Comparable<EventFight> {
|
||||
companion object : IntEntityClass<EventFight>(EventFightTable) {
|
||||
val fights: Queue<EventFight> = PriorityQueue()
|
||||
@JvmStatic get
|
||||
|
||||
@JvmStatic
|
||||
fun byId(fightId: Int) = useDb { findById(fightId) }
|
||||
|
||||
@JvmStatic
|
||||
fun byId(group: EventGroup) = useDb {
|
||||
find { EventFightTable.groupId eq group.id }.orderBy(EventFightTable.startTime to SortOrder.DESC).toList()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLast(group: EventGroup) = useDb {
|
||||
Optional.ofNullable(
|
||||
find { EventFightTable.groupId eq group.id }.orderBy(EventFightTable.startTime to SortOrder.DESC)
|
||||
.firstOrNull()
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun loadAllComingFights() = useDb {
|
||||
fights.clear()
|
||||
fights.addAll(find { EventFightTable.startTime greaterEq Instant.now() }.orderBy(EventFightTable.startTime to SortOrder.ASC))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getEvent(eventId: Int) = useDb {
|
||||
find { EventFightTable.eventId eq eventId }.orderBy(EventFightTable.startTime to SortOrder.ASC).toList()
|
||||
}
|
||||
|
||||
private var activeFightsCache: List<EventFight>? = null
|
||||
|
||||
@JvmStatic
|
||||
fun clearActiveFightsCache() {
|
||||
activeFightsCache = null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getActiveFights(): List<EventFight> {
|
||||
if (activeFightsCache == null) {
|
||||
activeFightsCache = useDb {
|
||||
find {
|
||||
EventFightTable.fight.isNull() and (EventFightTable.startTime less Instant.now()) and (EventFightTable.eventId.inSubQuery(
|
||||
EventTable.select(
|
||||
EventTable.id
|
||||
)
|
||||
.where { (EventTable.start less Instant.now()) and (EventTable.end greater Instant.now()) }))
|
||||
}.orderBy(EventFightTable.startTime to SortOrder.ASC).toList()
|
||||
}
|
||||
}
|
||||
|
||||
return activeFightsCache!!
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun create(
|
||||
event: Int,
|
||||
from: Timestamp,
|
||||
spielmodus: String,
|
||||
map: String,
|
||||
blueTeam: Int,
|
||||
redTeam: Int,
|
||||
spectatePort: Int?
|
||||
) = useDb {
|
||||
get(
|
||||
EventFightTable.insertAndGetId {
|
||||
it[eventId] = EntityID(event, EventTable)
|
||||
it[startTime] = from.toInstant()
|
||||
it[gamemode] = spielmodus
|
||||
it[EventFightTable.map] = map
|
||||
it[teamBlue] = EntityID(blueTeam, TeamTable)
|
||||
it[teamRed] = EntityID(redTeam, TeamTable)
|
||||
it[EventFightTable.spectatePort] = spectatePort
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val fightID by EventFightTable.id.transform({ EntityID(it, EventFightTable) }, { it.value })
|
||||
var teamBlue by EventFightTable.teamBlue.transform({ EntityID(it, TeamTable) }, { it.value })
|
||||
var teamRed by EventFightTable.teamRed.transform({ EntityID(it, TeamTable) }, { it.value })
|
||||
private var fightErgebnis by EventFightTable.ergebnis
|
||||
var ergebnis: Int
|
||||
get() = fightErgebnis
|
||||
set(value) = useDb {
|
||||
fightErgebnis = value
|
||||
}
|
||||
var eventID by EventFightTable.eventId.transform({ EntityID(it, EventTable) }, { it.value })
|
||||
var startTime by EventFightTable.startTime.transform({ it.toInstant() }, { Timestamp.from(it) })
|
||||
var spielmodus by EventFightTable.gamemode
|
||||
var map by EventFightTable.map
|
||||
var groupId by EventFightTable.groupId
|
||||
val group by lazy { Optional.ofNullable(groupId).map { EventGroup[it] } }
|
||||
var spectatePort by EventFightTable.spectatePort
|
||||
private var fightStat by EventFightTable.fight.transform({ it?.let { EntityID(it, EventFightTable) } }, { it?.value })
|
||||
var fight: Int?
|
||||
get() = fightStat
|
||||
set(value) = useDb {
|
||||
fightStat = value
|
||||
}
|
||||
val dependents by lazy { useDb { EventRelation.getFightRelations(this@EventFight) } }
|
||||
|
||||
val winner: Team?
|
||||
get() = if (ergebnis == 1) Team[teamBlue] else if (ergebnis == 2) Team[teamRed] else null
|
||||
val losser: Team?
|
||||
get() = if (ergebnis == 1) Team[teamRed] else if (ergebnis == 2) Team[teamBlue] else null
|
||||
|
||||
fun setGroup(group: Int?) = useDb { groupId = group?.let { EntityID(it, EventGroupTable) } }
|
||||
fun hasFinished() = fight != null || ergebnis != 0
|
||||
|
||||
fun reschedule() = useDb {
|
||||
startTime = Timestamp.from(Instant.now().plusSeconds(30))
|
||||
}
|
||||
|
||||
override fun hashCode() = fightID
|
||||
override fun equals(other: Any?) = other is EventFight && other.fightID == fightID
|
||||
override fun compareTo(other: EventFight): Int = startTime.compareTo(other.startTime)
|
||||
|
||||
fun update(
|
||||
startTime: Timestamp,
|
||||
spielmodus: String,
|
||||
map: String,
|
||||
teamBlue: Int,
|
||||
teamRed: Int,
|
||||
spectatePort: Int?
|
||||
) = useDb {
|
||||
this@EventFight.startTime = startTime
|
||||
this@EventFight.spielmodus = spielmodus
|
||||
this@EventFight.map = map
|
||||
this@EventFight.teamBlue = teamBlue
|
||||
this@EventFight.teamRed = teamRed
|
||||
this@EventFight.spectatePort = spectatePort
|
||||
}
|
||||
}
|
||||
@@ -1,173 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class EventGroup {
|
||||
static {
|
||||
SqlTypeMapper.ordinalEnumMapper(EventGroupType.class);
|
||||
}
|
||||
|
||||
private static final Table<EventGroup> table = new Table<>(EventGroup.class);
|
||||
|
||||
private static final SelectStatement<EventGroup> get = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<EventGroup> byEvent = new SelectStatement<>(table, "SELECT * FROM EventGroup WHERE EventID = ?");
|
||||
|
||||
private static final Statement insert = table.insertFields(true, "EventID", "Name", "Type");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "Name", "Type", "PointsPerWin", "PointsPerLoss", "PointsPerDraw");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
public static List<EventGroup> get(Event eventID) {
|
||||
return byEvent.listSelect(eventID.getEventID());
|
||||
}
|
||||
|
||||
public static EventGroup create(Event event, String name, EventGroupType type) {
|
||||
int key = insert.insertGetKey(event.getEventID(), name, type);
|
||||
return EventGroup.get(key).get();
|
||||
}
|
||||
|
||||
public static Optional<EventGroup> get(int id) {
|
||||
return Optional.ofNullable(get.select(id));
|
||||
}
|
||||
|
||||
@Field(keys = Table.PRIMARY)
|
||||
private final int id;
|
||||
|
||||
@Field(keys = "EVENT_NAME")
|
||||
private int eventID;
|
||||
|
||||
@Field(keys = "EVENT_NAME")
|
||||
private String name;
|
||||
|
||||
@Field
|
||||
private EventGroupType type;
|
||||
|
||||
@Field
|
||||
private int pointsPerWin;
|
||||
|
||||
@Field
|
||||
private int pointsPerLoss;
|
||||
|
||||
@Field
|
||||
private int pointsPerDraw;
|
||||
|
||||
public EventGroup(int id, int eventID, String name, EventGroupType type, int pointsPerWin, int pointsPerLoss, int pointsPerDraw) {
|
||||
this.id = id;
|
||||
this.eventID = eventID;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.pointsPerWin = pointsPerWin;
|
||||
this.pointsPerLoss = pointsPerLoss;
|
||||
this.pointsPerDraw = pointsPerDraw;
|
||||
}
|
||||
|
||||
private Map<Team, Integer> points;
|
||||
|
||||
public List<EventFight> getFights() {
|
||||
return EventFight.get(this);
|
||||
}
|
||||
|
||||
public Set<Integer> getTeamsId() {
|
||||
return getFights().stream().flatMap(fight -> Stream.of(fight.getTeamBlue(), fight.getTeamRed()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Set<Team> getTeams() {
|
||||
return getTeamsId().stream().map(Team::get).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Optional<EventFight> getLastFight() {
|
||||
return EventFight.getLast(this);
|
||||
}
|
||||
|
||||
public List<EventRelation> getDependents() {
|
||||
return EventRelation.getGroupRelations(this);
|
||||
}
|
||||
|
||||
public Map<Team, Integer> calculatePoints() {
|
||||
if (points == null) {
|
||||
Map<Integer, Integer> p = getTeamsId().stream().collect(Collectors.toMap(team -> team, team -> 0));
|
||||
|
||||
for (EventFight fight : getFights()) {
|
||||
int blueTeamAdd = 0;
|
||||
int redTeamAdd = 0;
|
||||
|
||||
if (!fight.hasFinished()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (fight.getErgebnis()) {
|
||||
case 1:
|
||||
blueTeamAdd += pointsPerWin;
|
||||
redTeamAdd += pointsPerLoss;
|
||||
break;
|
||||
case 2:
|
||||
blueTeamAdd += pointsPerLoss;
|
||||
redTeamAdd += pointsPerWin;
|
||||
break;
|
||||
case 0:
|
||||
if (fight.getFightID() != 0) {
|
||||
blueTeamAdd += pointsPerDraw;
|
||||
redTeamAdd += pointsPerDraw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
p.put(fight.getTeamBlue(), p.get(fight.getTeamBlue()) + blueTeamAdd);
|
||||
p.put(fight.getTeamRed(), p.get(fight.getTeamRed()) + redTeamAdd);
|
||||
}
|
||||
|
||||
points = p.entrySet().stream().collect(Collectors.toMap(integerIntegerEntry -> Team.get(integerIntegerEntry.getKey()), Map.Entry::getValue));
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
public void update(String name, EventGroupType type, int pointsPerWin, int pointsPerLoss, int pointsPerDraw) {
|
||||
update.update(name, type, pointsPerWin, pointsPerLoss, pointsPerDraw, id);
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.pointsPerWin = pointsPerWin;
|
||||
this.pointsPerLoss = pointsPerLoss;
|
||||
this.pointsPerDraw = pointsPerDraw;
|
||||
}
|
||||
|
||||
public boolean needsTieBreak() {
|
||||
return calculatePoints().values().stream().sorted().limit(2).distinct().count() < 2;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(id);
|
||||
}
|
||||
|
||||
public static enum EventGroupType {
|
||||
GROUP_STAGE,
|
||||
ELIMINATION_STAGE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
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.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import java.util.Optional
|
||||
|
||||
object EventGroupTable : IntIdTable("EventGroup", "Id") {
|
||||
val event = reference("EventID", EventTable)
|
||||
val name = varchar("Name", 64)
|
||||
val type = enumeration("Type", EventGroup.EventGroupType::class)
|
||||
val pointsPerWin = integer("PointsPerWin")
|
||||
val pointsPerLoss = integer("PointsPerLoss")
|
||||
val pointsPerDraw = integer("PointsPerDraw")
|
||||
}
|
||||
|
||||
class EventGroup(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<EventGroup>(EventGroupTable) {
|
||||
|
||||
@JvmStatic
|
||||
fun get(event: Event) = useDb { find { EventGroupTable.event eq event.id }.toList() }
|
||||
|
||||
@JvmStatic
|
||||
fun byId(groupId: Int) = useDb { Optional.ofNullable(findById(groupId)) }
|
||||
|
||||
@JvmStatic
|
||||
fun create(event: Event, name: String, type: EventGroupType) = useDb {
|
||||
new {
|
||||
this.eventID = event.id.value
|
||||
this.groupName = name
|
||||
this.groupType = type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var eventID by EventGroupTable.event.transform({ EntityID(it, EventTable) }, { it.value })
|
||||
private set
|
||||
private var groupName by EventGroupTable.name
|
||||
private var groupType by EventGroupTable.type
|
||||
private var groupPointsPerWin by EventGroupTable.pointsPerWin
|
||||
private var groupPointsPerLoss by EventGroupTable.pointsPerLoss
|
||||
private var groupPointsPerDraw by EventGroupTable.pointsPerDraw
|
||||
val fights by lazy { useDb { EventFight.find { EventFightTable.groupId eq id }.toList() } }
|
||||
val teamsId by lazy { fights.flatMap { listOf(it.teamBlue, it.teamRed) }.toSet() }
|
||||
|
||||
var name: String
|
||||
get() = groupName
|
||||
set(value) {
|
||||
groupName = value
|
||||
}
|
||||
var type: EventGroupType
|
||||
get() = groupType
|
||||
set(value) {
|
||||
groupType = value
|
||||
}
|
||||
var pointsPerWin: Int
|
||||
get() = groupPointsPerWin
|
||||
set(value) {
|
||||
groupPointsPerWin = value
|
||||
}
|
||||
var pointsPerLoss: Int
|
||||
get() = groupPointsPerLoss
|
||||
set(value) {
|
||||
groupPointsPerLoss = value
|
||||
}
|
||||
var pointsPerDraw: Int
|
||||
get() = groupPointsPerDraw
|
||||
set(value) {
|
||||
groupPointsPerDraw = value
|
||||
}
|
||||
val dependents by lazy { EventRelation.getGroupRelations(this) }
|
||||
val lastFight by lazy { Optional.ofNullable(fights.maxByOrNull { it.startTime }) }
|
||||
|
||||
fun getId() = id.value
|
||||
|
||||
private var points: Map<Team, Int>? = null
|
||||
|
||||
fun calculatePoints(): Map<Team, Int> {
|
||||
if (points == null) {
|
||||
val p: MutableMap<Int, Int> = teamsId.associateWith { 0 }.toMutableMap()
|
||||
|
||||
for (fight in fights) {
|
||||
var blueTeamAdd = 0
|
||||
var redTeamAdd = 0
|
||||
|
||||
if (!fight.hasFinished()) {
|
||||
continue
|
||||
}
|
||||
|
||||
when (fight.ergebnis) {
|
||||
1 -> {
|
||||
blueTeamAdd += pointsPerWin
|
||||
redTeamAdd += pointsPerLoss
|
||||
}
|
||||
2 -> {
|
||||
blueTeamAdd += pointsPerLoss
|
||||
redTeamAdd += pointsPerWin
|
||||
}
|
||||
0 -> if (fight.fight != null) {
|
||||
blueTeamAdd += pointsPerDraw
|
||||
redTeamAdd += pointsPerDraw
|
||||
}
|
||||
}
|
||||
|
||||
p[fight.teamBlue] = p[fight.teamBlue]?.plus(blueTeamAdd) ?: blueTeamAdd
|
||||
p[fight.teamRed] = p[fight.teamRed]?.plus(redTeamAdd) ?: redTeamAdd
|
||||
}
|
||||
|
||||
return p.mapKeys { Team.byId(it.key) }.also { points = it }
|
||||
} else {
|
||||
return points!!
|
||||
}
|
||||
}
|
||||
|
||||
fun needsTieBreak() = calculatePoints().values.let { it.size == it.toSet().size }
|
||||
|
||||
fun update(name: String, type: EventGroupType, pointsPerWin: Int, pointsPerLoss: Int, pointsPerDraw: Int) = useDb {
|
||||
this@EventGroup.name = name
|
||||
this@EventGroup.type = type
|
||||
this@EventGroup.pointsPerWin = pointsPerWin
|
||||
this@EventGroup.pointsPerLoss = pointsPerLoss
|
||||
this@EventGroup.pointsPerDraw = pointsPerDraw
|
||||
}
|
||||
|
||||
enum class EventGroupType {
|
||||
GROUP_STAGE,
|
||||
ELIMINATION_STAGE
|
||||
}
|
||||
}
|
||||
@@ -1,192 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class EventRelation {
|
||||
|
||||
static {
|
||||
SqlTypeMapper.ordinalEnumMapper(FightTeam.class);
|
||||
SqlTypeMapper.ordinalEnumMapper(FromType.class);
|
||||
}
|
||||
|
||||
private static final Table<EventRelation> table = new Table<>(EventRelation.class);
|
||||
|
||||
private static final SelectStatement<EventRelation> get = new SelectStatement<>(table, "SELECT * FROM EventRelation WHERE FromType = ? AND FromId = ?");
|
||||
private static final SelectStatement<EventRelation> byId = new SelectStatement<>(table, "SELECT * FROM EventRelation WHERE id = ?");
|
||||
private static final SelectStatement<EventRelation> byEvent = new SelectStatement<>(table, "SELECT ER.* FROM EventRelation ER JOIN EventFight EF ON EF.fightId = ER.fightId WHERE EF.EventID = ?");
|
||||
private static final Statement insert = table.insertFields(true, "fightId", "fightTeam", "fromType", "fromId", "fromPlace");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "fromType", "fromId", "fromPlace");
|
||||
private static final Statement updateTeam = table.update(Table.PRIMARY, "fightTeam");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
public static List<EventRelation> get(Event event) {
|
||||
return byEvent.listSelect(event.getEventID());
|
||||
}
|
||||
|
||||
public static EventRelation get(int id) {
|
||||
return byId.select(id);
|
||||
}
|
||||
|
||||
public static List<EventRelation> getFightRelations(EventFight fight) {
|
||||
return get.listSelect(FromType.FIGHT, fight.getFightID());
|
||||
}
|
||||
|
||||
public static List<EventRelation> getGroupRelations(EventGroup group) {
|
||||
return get.listSelect(FromType.GROUP, group.getId());
|
||||
}
|
||||
|
||||
public static EventRelation create(EventFight fight, FightTeam fightTeam, FromType fromType, int fromId, int fromPlace) {
|
||||
int id = insert.insertGetKey(fight.getFightID(), fightTeam, fromType, fromId, fromPlace);
|
||||
return get(id);
|
||||
}
|
||||
|
||||
@Field(keys = Table.PRIMARY)
|
||||
private final int id;
|
||||
|
||||
@Field
|
||||
private int fightId;
|
||||
|
||||
@Field
|
||||
private FightTeam fightTeam;
|
||||
|
||||
@Field
|
||||
private FromType fromType;
|
||||
|
||||
@Field
|
||||
private int fromId;
|
||||
|
||||
@Field
|
||||
private int fromPlace;
|
||||
|
||||
public EventFight getFight() {
|
||||
return EventFight.get(fightId);
|
||||
}
|
||||
|
||||
public Optional<EventFight> getFromFight() {
|
||||
if(fromType == FromType.FIGHT) {
|
||||
return Optional.of(EventFight.get(fromId));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<EventGroup> getFromGroup() {
|
||||
if(fromType == FromType.GROUP) {
|
||||
return EventGroup.get(fromId);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete.update(id);
|
||||
}
|
||||
|
||||
public void setUpdateTeam(FightTeam team) {
|
||||
updateTeam.update(id, team);
|
||||
this.fightTeam = team;
|
||||
}
|
||||
|
||||
public void setFromFight(EventFight fight, int place) {
|
||||
setFrom(fight.getFightID(), place, FromType.FIGHT);
|
||||
}
|
||||
|
||||
public void setFromGroup(EventGroup group, int place) {
|
||||
setFrom(group.getId(), place, FromType.GROUP);
|
||||
}
|
||||
|
||||
private void setFrom(int fightId, int place, FromType type) {
|
||||
update.update(type, fightId, place, id);
|
||||
this.fromType = type;
|
||||
this.fromId = fightId;
|
||||
this.fromPlace = place;
|
||||
}
|
||||
|
||||
public Optional<Team> getAdvancingTeam() {
|
||||
if (fromType == FromType.FIGHT) {
|
||||
if (fromPlace == 0) {
|
||||
return getFromFight().flatMap(EventFight::getWinner);
|
||||
} else {
|
||||
return getFromFight().flatMap(EventFight::getLosser);
|
||||
}
|
||||
} else if (fromType == FromType.GROUP) {
|
||||
return getFromGroup().map(EventGroup::calculatePoints)
|
||||
.flatMap(points -> points.entrySet().stream()
|
||||
.sorted(Map.Entry.<Team, Integer>comparingByValue().reversed())
|
||||
.skip(fromPlace)
|
||||
.findFirst()
|
||||
.map(Map.Entry::getKey));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean apply() {
|
||||
Optional<Integer> team = getAdvancingTeam().map(Team::getTeamId);
|
||||
if(!team.isPresent())
|
||||
return false;
|
||||
|
||||
EventFight fight = getFight();
|
||||
if(fightTeam == FightTeam.RED) {
|
||||
fight.update(
|
||||
fight.getStartTime(),
|
||||
fight.getSpielmodus(),
|
||||
fight.getMap(),
|
||||
fight.getTeamBlue(),
|
||||
team.get(),
|
||||
fight.getSpectatePort()
|
||||
);
|
||||
} else {
|
||||
fight.update(
|
||||
fight.getStartTime(),
|
||||
fight.getSpielmodus(),
|
||||
fight.getMap(),
|
||||
team.get(),
|
||||
fight.getTeamRed(),
|
||||
fight.getSpectatePort()
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static enum FightTeam {
|
||||
BLUE,
|
||||
RED
|
||||
}
|
||||
|
||||
public static enum FromType {
|
||||
FIGHT,
|
||||
GROUP
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.jdbc.select
|
||||
import java.util.Optional
|
||||
|
||||
object EventRelationTable : IntIdTable("EventRelation") {
|
||||
val fightId = reference("FightId", EventFightTable)
|
||||
val fightTeam = enumeration("FightTeam", EventRelation.FightTeam::class)
|
||||
val fromType = enumeration("FromType", EventRelation.FromType::class)
|
||||
val fromId = integer("FromId")
|
||||
val fromPlace = integer("FromPlace")
|
||||
}
|
||||
|
||||
class EventRelation(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<EventRelation>(EventRelationTable) {
|
||||
@JvmStatic
|
||||
fun get(event: Event) = useDb {
|
||||
EventRelationTable.innerJoin(EventFightTable)
|
||||
.select(EventRelationTable.columns)
|
||||
.where { EventFightTable.eventId eq event.id }
|
||||
.map { wrapRow(it) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun byId(id: Int) = useDb { findById(id) }
|
||||
|
||||
@JvmStatic
|
||||
fun getFightRelations(fight: EventFight) =
|
||||
useDb { find { (EventRelationTable.fromId eq fight.id.value) and (EventRelationTable.fromType eq FromType.FIGHT) } }
|
||||
|
||||
@JvmStatic
|
||||
fun getGroupRelations(group: EventGroup) =
|
||||
useDb { find { (EventRelationTable.fromId eq group.id.value) and (EventRelationTable.fromType eq FromType.GROUP) } }
|
||||
|
||||
@JvmStatic
|
||||
fun create(fight: EventFight, fightTeam: FightTeam, fromType: FromType, fromId: Int, fromPlace: Int) = useDb {
|
||||
new {
|
||||
this.fightEntityId = fight.id
|
||||
this.fightTeam = fightTeam
|
||||
this.fromType = fromType
|
||||
this.fromId = fromId
|
||||
this.fromPlace = fromPlace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fightEntityId by EventRelationTable.fightId
|
||||
var fightId: Int
|
||||
get() = fightEntityId.value
|
||||
set(value) = useDb { fightEntityId = EntityID(value, EventFightTable) }
|
||||
val fight by lazy { useDb { EventFight[fightEntityId] } }
|
||||
var fightTeam by EventRelationTable.fightTeam
|
||||
private set
|
||||
var fromType by EventRelationTable.fromType
|
||||
private set
|
||||
var fromId by EventRelationTable.fromId
|
||||
private set
|
||||
|
||||
var fromFightId: Int?
|
||||
get() = if (fromType == FromType.FIGHT) fromId else null
|
||||
set(value) = useDb {
|
||||
fromType = FromType.FIGHT
|
||||
fromId = value!!
|
||||
}
|
||||
val fromFight: EventFight?
|
||||
get() = fromFightId?.let { EventFight[it] }
|
||||
var fromGroupId: Int?
|
||||
get() = if (fromType == FromType.GROUP) fromId else null
|
||||
set(value) = useDb {
|
||||
fromType = FromType.GROUP
|
||||
fromId = value!!
|
||||
}
|
||||
val fromGroup: EventGroup?
|
||||
get() = fromGroupId?.let { EventGroup[it] }
|
||||
var fromPlace by EventRelationTable.fromPlace
|
||||
private set
|
||||
|
||||
fun getId() = id.value
|
||||
fun setUpdateTeam(team: FightTeam) = useDb {
|
||||
fightTeam = team
|
||||
}
|
||||
|
||||
fun setFromFight(fight: EventFight, place: Int) = useDb {
|
||||
fromType = FromType.FIGHT
|
||||
fromId = fight.id.value
|
||||
fromPlace = place
|
||||
}
|
||||
|
||||
fun setFromGroup(group: EventGroup, place: Int) = useDb {
|
||||
fromType = FromType.GROUP
|
||||
fromId = group.id.value
|
||||
fromPlace = place
|
||||
}
|
||||
|
||||
fun getAdvancingTeam(): Team? = when(fromType) {
|
||||
FromType.FIGHT -> if (fromPlace == 0) fromFight?.winner else fromFight?.losser
|
||||
FromType.GROUP -> fromGroup?.calculatePoints()?.toList()?.sortedBy { (_, v) -> v }?.reversed()?.elementAt(fromPlace)?.first
|
||||
}
|
||||
|
||||
fun apply(): Boolean {
|
||||
val team = getAdvancingTeam() ?: return false
|
||||
|
||||
useDb {
|
||||
when(fightTeam) {
|
||||
FightTeam.BLUE -> fight.teamBlue = team.teamId
|
||||
FightTeam.RED -> fight.teamRed = team.teamId
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
enum class FightTeam {
|
||||
BLUE, RED
|
||||
}
|
||||
|
||||
enum class FromType {
|
||||
FIGHT, GROUP
|
||||
}
|
||||
}
|
||||
@@ -1,140 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Team {
|
||||
|
||||
private static final Map<Integer, Team> teamCache = new HashMap<>();
|
||||
|
||||
public static void clear() {
|
||||
teamCache.clear();
|
||||
}
|
||||
|
||||
private static final Table<Team> table = new Table<>(Team.class);
|
||||
private static final SelectStatement<Team> byId = table.select(Table.PRIMARY);
|
||||
private static final SelectStatement<Team> byName = new SelectStatement<>(table, "SELECT * FROM Team WHERE (lower(TeamName) = ? OR lower(TeamKuerzel) = ?) AND NOT TeamDeleted");
|
||||
private static final SelectStatement<Team> all = table.selectFields("TeamDeleted");
|
||||
private static final Statement insert = table.insertFields("TeamKuerzel", "TeamName");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "TeamKuerzel", "TeamName", "TeamColor", "Address", "Port");
|
||||
private static final Statement delete = table.update(Table.PRIMARY, "TeamDeleted");
|
||||
private static final Statement getSize = new Statement("SELECT COUNT(id) FROM UserData WHERE Team = ?");
|
||||
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
@Getter
|
||||
private final int teamId;
|
||||
@Field
|
||||
@Getter
|
||||
private String teamKuerzel;
|
||||
@Field
|
||||
@Getter
|
||||
private String teamName;
|
||||
@Field(def = "'8'")
|
||||
@Getter
|
||||
private String teamColor;
|
||||
@Field(nullable = true)
|
||||
@Getter
|
||||
private String address;
|
||||
@Field(def = "'25565'")
|
||||
@Getter
|
||||
private int port;
|
||||
@Field(def = "0")
|
||||
private boolean teamDeleted;
|
||||
|
||||
public static void create(String kuerzel, String name){
|
||||
insert.update(kuerzel, name);
|
||||
}
|
||||
|
||||
public static Team get(int id) {
|
||||
return teamCache.computeIfAbsent(id, byId::select);
|
||||
}
|
||||
|
||||
public static Team get(String name){
|
||||
// No cache lookup due to low frequency use
|
||||
name = name.toLowerCase();
|
||||
return byName.select(name, name);
|
||||
}
|
||||
|
||||
public static List<Team> getAll(){
|
||||
clear();
|
||||
List<Team> teams = all.listSelect(false);
|
||||
teams.forEach(team -> teamCache.put(team.getTeamId(), team));
|
||||
return teams;
|
||||
}
|
||||
|
||||
public List<Integer> getMembers(){
|
||||
return SteamwarUser.getTeam(teamId).stream().map(SteamwarUser::getId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int size(){
|
||||
return getSize.select(rs -> {
|
||||
rs.next();
|
||||
return rs.getInt("COUNT(id)");
|
||||
}, teamId);
|
||||
}
|
||||
|
||||
public void disband(SteamwarUser user){
|
||||
user.setLeader(false);
|
||||
delete.update(true, teamId);
|
||||
teamCache.remove(teamId);
|
||||
TeamTeilnahme.deleteFuture(teamId);
|
||||
}
|
||||
|
||||
public void setTeamKuerzel(String teamKuerzel) {
|
||||
this.teamKuerzel = teamKuerzel;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public void setTeamName(String teamName) {
|
||||
this.teamName = teamName;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public void setTeamColor(String teamColor) {
|
||||
this.teamColor = teamColor;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
private void updateDB(){
|
||||
update.update(teamKuerzel, teamName, teamColor, address, port, teamId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql
|
||||
|
||||
import de.steamwar.sql.internal.useDb
|
||||
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.lowerCase
|
||||
import org.jetbrains.exposed.v1.dao.IntEntity
|
||||
import org.jetbrains.exposed.v1.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.v1.jdbc.select
|
||||
|
||||
object TeamTable : IntIdTable("Team", "TeamID") {
|
||||
val kuerzel = varchar("TeamKuerzel", 10)
|
||||
val color = char("TeamColor", 1)
|
||||
val name = varchar("TeamName", 16)
|
||||
val deleted = bool("TeamDeleted")
|
||||
val address = text("Address")
|
||||
val port = ushort("Port")
|
||||
}
|
||||
|
||||
class Team(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<Team>(TeamTable) {
|
||||
private val teamCache = mutableMapOf<Int, Team>()
|
||||
|
||||
@JvmStatic
|
||||
fun clear() = teamCache.clear()
|
||||
|
||||
@JvmStatic
|
||||
fun byId(id: Int) = teamCache.computeIfAbsent(id) { useDb { Team[id] } }
|
||||
|
||||
@JvmStatic
|
||||
fun get(name: String) = useDb { find { TeamTable.name.lowerCase() eq name.lowercase() }.firstOrNull() }
|
||||
|
||||
@JvmStatic
|
||||
fun getAll() = useDb { all().toList() }
|
||||
|
||||
@JvmStatic
|
||||
fun create(kuerzel: String, name: String) = useDb {
|
||||
new {
|
||||
this.kuerzel = kuerzel
|
||||
this.name = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val teamId by TeamTable.id.transform({ EntityID(it, TeamTable) }, { it.value })
|
||||
private var kuerzel by TeamTable.kuerzel
|
||||
private var color by TeamTable.color
|
||||
private var name by TeamTable.name
|
||||
var deleted by TeamTable.deleted
|
||||
private set
|
||||
private var teamAddress by TeamTable.address
|
||||
private var teamPort by TeamTable.port
|
||||
val members by lazy { SteamwarUserTable.select(SteamwarUserTable.id).where { SteamwarUserTable.team eq teamId }.map { it[SteamwarUserTable.id].value } }
|
||||
|
||||
fun size() = useDb { SteamwarUser.find { SteamwarUserTable.team eq teamId }.count().toInt() }
|
||||
fun disband(user: SteamwarUser) = useDb {
|
||||
user.team = 0
|
||||
deleted = true
|
||||
teamCache.remove(teamId)
|
||||
TeamTeilnahme.deleteFuture(teamId)
|
||||
}
|
||||
|
||||
var teamKuerzel: String
|
||||
get() = kuerzel
|
||||
set(value) = useDb {
|
||||
kuerzel = value
|
||||
}
|
||||
|
||||
var teamColor: String
|
||||
get() = color
|
||||
set(value) = useDb {
|
||||
color = value
|
||||
}
|
||||
|
||||
var teamName: String
|
||||
get() = name
|
||||
set(value) = useDb {
|
||||
name = value
|
||||
}
|
||||
|
||||
var address: String
|
||||
get() = teamAddress
|
||||
set(value) = useDb {
|
||||
teamAddress = value
|
||||
}
|
||||
|
||||
var port: Int
|
||||
get() = teamPort.toInt()
|
||||
set(value) = useDb {
|
||||
teamPort = value.toUShort()
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class TeamTeilnahme {
|
||||
}
|
||||
|
||||
public static Set<Team> getTeams(int eventID){
|
||||
return selectTeams.listSelect(eventID).stream().map(tt -> Team.get(tt.teamId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries)
|
||||
return selectTeams.listSelect(eventID).stream().map(tt -> Team.byId(tt.teamId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries)
|
||||
}
|
||||
|
||||
public static Set<Event> getEvents(int teamID){
|
||||
|
||||
Reference in New Issue
Block a user