diff --git a/.gitignore b/.gitignore index e038e02a..b0a7fe1b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,8 @@ bin/ .vscode # Other -lib \ No newline at end of file +lib +/WebsiteBackend/data +/WebsiteBackend/logs +/WebsiteBackend/skins +/WebsiteBackend/config.json \ No newline at end of file diff --git a/CommonCore/SQL/src/de/steamwar/sql/EventFight.java b/CommonCore/SQL/src/de/steamwar/sql/EventFight.java index fe91e3be..9aa57510 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/EventFight.java +++ b/CommonCore/SQL/src/de/steamwar/sql/EventFight.java @@ -39,6 +39,7 @@ public class EventFight implements Comparable { private static final SelectStatement byId = table.select(Table.PRIMARY); private static final SelectStatement allComing = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE StartTime > now() ORDER BY StartTime ASC"); private static final SelectStatement event = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE EventID = ? ORDER BY StartTime ASC"); + private static final SelectStatement activeFights = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE Fight IS NOT NULL AND StartTime < now() AND DATEDIFF(StartTime, now()) < 0"); 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"); @@ -63,6 +64,19 @@ public class EventFight implements Comparable { return event.listSelect(eventID); } + private static List activeFightsCache = null; + + public static void clearActiveFightsCache() { + activeFightsCache = null; + } + + public static List 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)); } diff --git a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java index 15c16b64..0b21cef1 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java @@ -23,7 +23,9 @@ import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; import de.steamwar.persistent.Subserver; import de.steamwar.sql.EventFight; +import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.Team; +import lombok.Getter; import net.kyori.adventure.text.event.ClickEvent; import java.sql.Timestamp; @@ -36,6 +38,7 @@ import static de.steamwar.persistent.Storage.eventServer; public class EventStarter { + @Getter private static final Map spectatePorts = new HashMap<>(); public static void addSpectateServer(int port, String command) { @@ -68,6 +71,15 @@ public class EventStarter { starter.callback(subserver -> { eventServer.put(blue.getTeamId(), subserver); eventServer.put(red.getTeamId(), subserver); + + if (VelocityCore.get().getConfig().isEventmode()) { + VelocityCore.getProxy().getAllPlayers().forEach(player -> { + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + if (user.getTeam() == blue.getTeamId() || user.getTeam() == red.getTeamId()) { + subserver.sendPlayer(player); + } + }); + } }).start(); command = "/event " + blue.getTeamKuerzel(); @@ -76,6 +88,7 @@ public class EventStarter { } Chatter.broadcast().system("EVENT_FIGHT_BROADCAST", new Message("EVENT_FIGHT_BROADCAST_HOVER"), ClickEvent.runCommand(command), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName()); } + EventFight.clearActiveFightsCache(); } private EventFight nextFight(Queue fights){ diff --git a/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java b/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java index 3cec098b..40432704 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java +++ b/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java @@ -217,6 +217,7 @@ public class VelocityCore implements ReloadablePlugin { new TutorialCommand(); new Broadcaster(); + new CookieEvents(); }else{ new EventModeListener(); } @@ -288,7 +289,7 @@ public class VelocityCore implements ReloadablePlugin { if(server.getSpectatePort() != 0) EventStarter.addSpectateServer(server.getSpectatePort(), cmd); - new ServerSwitchCommand(cmd, entry.getKey(), cmds.toArray(new String[0])); + new ServerSwitchCommand(cmd, entry.getKey(), server.getSpectatePort() != 0, cmds.toArray(new String[0])); } } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/ServerSwitchCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/ServerSwitchCommand.java index 142c5f56..3586f150 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/ServerSwitchCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/ServerSwitchCommand.java @@ -19,22 +19,41 @@ package de.steamwar.velocitycore.commands; +import java.net.InetSocketAddress; +import java.util.List; + +import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.server.RegisteredServer; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.command.SWCommand; import de.steamwar.messages.PlayerChatter; +import de.steamwar.sql.EventFight; +import de.steamwar.sql.SteamwarUser; public class ServerSwitchCommand extends SWCommand { private final RegisteredServer server; + private final boolean isSpectateServer; - public ServerSwitchCommand(String cmd, String name, String... aliases) { + public ServerSwitchCommand(String cmd, String name, boolean isSpectateServer, String... aliases) { super(cmd, null, aliases); server = VelocityCore.getProxy().getServer(name).orElseThrow(); + this.isSpectateServer = isSpectateServer; } @Register public void genericCommand(PlayerChatter sender) { + if (isSpectateServer && sender.getPlayer().getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_20_5)) { + SteamwarUser user = SteamwarUser.get(sender.getPlayer().getUniqueId()); + List activeFights = EventFight.getActiveFights(); + + if (activeFights.stream() + .anyMatch(fight -> fight.getTeamRed() == user.getTeam() || fight.getTeamBlue() == user.getTeam())) { + sender.getPlayer().transferToHost(new InetSocketAddress("steamwar.de", 25566)); + return; + } + } + sender.getPlayer().createConnectionRequest(server).fireAndForget(); } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java index 95edeabb..f18288f6 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/ConnectionListener.java @@ -23,6 +23,7 @@ import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.connection.PostLoginEvent; import com.velocitypowered.api.event.permission.PermissionsSetupEvent; +import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.permission.Tristate; import com.velocitypowered.api.proxy.Player; import de.steamwar.messages.Chatter; @@ -30,6 +31,7 @@ import de.steamwar.messages.Message; import de.steamwar.persistent.Subserver; import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.UserPerm; +import de.steamwar.velocitycore.EventStarter; import de.steamwar.velocitycore.commands.*; import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.discord.util.DiscordRanks; @@ -88,6 +90,10 @@ public class ConnectionListener extends BasicListener { } DiscordBot.withBot(bot -> DiscordRanks.update(user)); + + if (player.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_20_5)) { + player.requestCookie(EventModeListener.EVENT_TO_SPECTATE_KEY); + } } @Subscribe diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/CookieEvents.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/CookieEvents.java new file mode 100644 index 00000000..4fb59b62 --- /dev/null +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/CookieEvents.java @@ -0,0 +1,47 @@ +/* + * 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.velocitycore.listeners; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.CookieReceiveEvent; +import com.velocitypowered.api.proxy.Player; +import de.steamwar.sql.EventFight; +import de.steamwar.sql.SteamwarUser; +import de.steamwar.velocitycore.EventStarter; +import de.steamwar.velocitycore.VelocityCore; + +public class CookieEvents extends BasicListener { + + @Subscribe + public void handleCookies(CookieReceiveEvent e) { + if (e.getOriginalKey().equals(EventModeListener.EVENT_TO_SPECTATE_KEY)) { + Player player = e.getPlayer(); + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + + EventFight.getActiveFights().stream() + .filter(fight -> fight.getTeamRed() == user.getTeam() || fight.getTeamBlue() == user.getTeam()) + .filter(fight -> fight.getSpectatePort() != null) + .filter(fight -> fight.getSpectatePort() != 0) + .findFirst() + .flatMap(fight -> VelocityCore.getProxy().getServer(EventStarter.getSpectatePorts().get(fight.getSpectatePort()))) + .ifPresent(registeredServer -> player.createConnectionRequest(registeredServer).fireAndForget()); + } + } +} diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/EventModeListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/EventModeListener.java index 5cc55757..cdc76b1e 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/EventModeListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/EventModeListener.java @@ -19,31 +19,88 @@ package de.steamwar.velocitycore.listeners; +import java.net.InetSocketAddress; +import java.nio.charset.Charset; +import java.util.List; + import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.PostLoginEvent; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.network.ProtocolVersion; +import com.velocitypowered.api.proxy.Player; + import de.steamwar.messages.Chatter; +import de.steamwar.persistent.Subserver; import de.steamwar.sql.Event; +import de.steamwar.sql.EventFight; import de.steamwar.sql.Referee; +import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.TeamTeilnahme; +import de.steamwar.velocitycore.EventStarter; +import de.steamwar.velocitycore.VelocityCore; +import net.kyori.adventure.key.Key; public class EventModeListener extends BasicListener { + public static final Key EVENT_TO_SPECTATE_KEY = Key.key("sw", "event_to_spectate"); + @Subscribe public void onPostLogin(PostLoginEvent e) { - Chatter sender = Chatter.disconnect(e.getPlayer()); + Player player = e.getPlayer(); + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + Chatter sender = Chatter.disconnect(player); Event event = Event.get(); - if(event == null) { - sender.system("EVENTMODE_KICK"); + if (event == null) { + if (player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_20_5)) { + sender.system("EVENTMODE_KICK"); + } else { + player.transferToHost(new InetSocketAddress("steamwar.de", 25565)); + } return; } - if(TeamTeilnahme.nimmtTeil(sender.user().getTeam(), event.getEventID())) + if (TeamTeilnahme.nimmtTeil(user.getTeam(), event.getEventID())) { + if (player.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_20_5) && VelocityCore.getProxy().getAllPlayers().stream().map(p -> SteamwarUser.get(p.getUniqueId())).filter(u -> u.getTeam() == user.getTeam()).count() > event.getMaximumTeamMembers()) { + player.storeCookie(EVENT_TO_SPECTATE_KEY, "TRUE".getBytes()); + player.transferToHost(new InetSocketAddress("steamwar.de", 25565)); + return; + } + + Subserver server = EventStarter.getEventServer().get(user.getTeam()); + + if (server != null) { + server.sendPlayer(player); + } + + return; + } + + if (Referee.get(event.getEventID()).contains(user.getId())) return; - if(Referee.get(event.getEventID()).contains(sender.user().getId())) - return; + if (player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_20_5)) { + sender.system("EVENTMODE_KICK"); + } else { + player.transferToHost(new InetSocketAddress("steamwar.de", 25565)); + } + } - sender.system("EVENTMODE_KICK"); + @Subscribe + public void onLobby(ServerConnectedEvent e) { + Player player = e.getPlayer(); + + if (player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_20_5)) { + return; + } + + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + + List activeFights = EventFight.getActiveFights(); + + if (activeFights.stream() + .noneMatch(fight -> fight.getTeamRed() == user.getTeam() || fight.getTeamBlue() == user.getTeam())) { + player.transferToHost(new InetSocketAddress("steamwar.de", 25565)); + } } }