diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index a8b9c4fa..ffef1449 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -85,6 +85,7 @@ public class BungeeCore extends Plugin { new WorldDownloader(); new BrandListener(); new Fabric(); + new SubserverProtocolFixer(); new Node.LocalNode(); //new Node.RemoteNode("lx"); diff --git a/src/de/steamwar/bungeecore/commands/TeamCommand.java b/src/de/steamwar/bungeecore/commands/TeamCommand.java index 0cd0277d..d92b5dad 100644 --- a/src/de/steamwar/bungeecore/commands/TeamCommand.java +++ b/src/de/steamwar/bungeecore/commands/TeamCommand.java @@ -20,6 +20,7 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; +import de.steamwar.bungeecore.Storage; import de.steamwar.bungeecore.inventory.SWItem; import de.steamwar.bungeecore.inventory.SWListInv; import de.steamwar.bungeecore.sql.Event; @@ -33,11 +34,16 @@ import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.net.InetSocketAddress; import java.time.Instant; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import static de.steamwar.bungeecore.Storage.teamInvitations; @@ -77,6 +83,7 @@ public class TeamCommand extends BasicCommand { Message.send("TEAM_HELP_HEADER", sender); Message.send("TEAM_HELP_LIST", sender); Message.send("TEAM_HELP_INFO", sender); + Message.send("TEAM_HELP_TP", sender); if(!(sender instanceof ProxiedPlayer)) return; @@ -90,7 +97,6 @@ public class TeamCommand extends BasicCommand { Message.send("TEAM_HELP_EVENT", sender); Message.send("TEAM_HELP_LEAVE", sender); - Team team = Team.get(user.getTeam()); if(user.isLeader()){ Message.send("TEAM_HELP_INVITE", sender); Message.send("TEAM_HELP_REMOVE", sender); @@ -99,6 +105,7 @@ public class TeamCommand extends BasicCommand { Message.send("TEAM_HELP_COLOR", sender); Message.send("TEAM_HELP_LEADER", sender); Message.send("TEAM_HELP_STEP_BACK", sender); + Message.send("TEAM_HELP_SERVER", sender); } } } @@ -157,6 +164,12 @@ public class TeamCommand extends BasicCommand { case "event": event(player, user, team, args); break; + case "tp": + tp(player, user, team, args); + break; + case "server": + server(player, user, team, args); + break; default: help(player); } @@ -549,6 +562,62 @@ public class TeamCommand extends BasicCommand { } } + private void tp(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){ + if(args.length == 1){ + if(notInTeam(player, user)) + return; + tp(player, team); + return; + } + Team targetTeam = Team.get(args[1]); + if(targetTeam == null){ + Message.send("TEAM_TP_NO_TEAM", player); + return; + } + tp(player, targetTeam); + } + + private void tp(ProxiedPlayer player, Team targetTeam) { + if (targetTeam.getAddress() == null) { + Message.send("TEAM_NO_ADDRESS", player); + return; + } + ServerInfo serverInfo = Storage.teamServers.computeIfAbsent(targetTeam.getTeamId(), integer -> { + InetSocketAddress address = new InetSocketAddress(targetTeam.getAddress(), targetTeam.getPort()); + ServerInfo info = ProxyServer.getInstance().constructServerInfo("Team " + targetTeam.getTeamKuerzel(), address, "SteamWar.de - Teamserver", false); + ProxyServer.getInstance().getServers().put(info.getName(), info); + return info; + }); + player.connect(serverInfo); + } + + private void server(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){ + if(notLeader(player, user, team)) + return; + if (args.length < 2) { + Message.send("TEAM_SERVER_USAGE", player); + return; + } + String server = args[1]; + int port = 25565; + if (args.length == 3) { + try { + port = Integer.parseInt(args[2]); + if (port < 1 || port > 65535) { + Message.send("TEAM_SERVER_PORT_INVALID", player); + return; + } + } catch (NumberFormatException e) { + Message.send("TEAM_SERVER_PORT_INVALID", player); + return; + } + } + team.setAddress(server); + team.setPort(port); + Storage.teamServers.remove(team.getTeamId()); + Message.send("TEAM_SERVER_SET", player); + } + private void changeColor(ProxiedPlayer player, SteamwarUser user, Team team) { if(notLeader(player, user, team)) return; @@ -649,11 +718,13 @@ public class TeamCommand extends BasicCommand { tab.add("changename"); tab.add("promote"); tab.add("changecolor"); + tab.add("tp"); + tab.add("server"); }else if(args.length == 2){ if(args[1].equalsIgnoreCase("event")){ List coming = Event.getComing(); coming.forEach(event -> tab.add(event.getEventName())); - }else if(args[1].equalsIgnoreCase("join") || args[1].equalsIgnoreCase("info")){ + }else if(args[1].equalsIgnoreCase("join") || args[1].equalsIgnoreCase("info") || args[1].equalsIgnoreCase("tp")){ List teams = Team.getAll(); teams.forEach(team -> { tab.add(team.getTeamName()); diff --git a/src/de/steamwar/bungeecore/listeners/BrandListener.java b/src/de/steamwar/bungeecore/listeners/BrandListener.java index cbc16a41..4c810de6 100644 --- a/src/de/steamwar/bungeecore/listeners/BrandListener.java +++ b/src/de/steamwar/bungeecore/listeners/BrandListener.java @@ -35,13 +35,18 @@ public class BrandListener extends BasicListener { @EventHandler public void onServerSwitch(PluginMessageEvent event) { - if(!event.getTag().equals("minecraft:brand") || !event.getTag().equals("MC|Brand")) { + if(!event.getTag().equals("minecraft:brand") && !event.getTag().equals("MC|Brand")) { return; } if(event.getReceiver().getAddress().getHostName().contains("localhost")) { return; } + event.setCancelled(true); + + if (!(event.getReceiver() instanceof ProxiedPlayer)) { + return; + } BungeeCore.get().getProxy().getScheduler().schedule(BungeeCore.get(), () -> { ProxiedPlayer player = (ProxiedPlayer) event.getReceiver(); diff --git a/src/de/steamwar/bungeecore/listeners/SubserverProtocolFixer.java b/src/de/steamwar/bungeecore/listeners/SubserverProtocolFixer.java new file mode 100644 index 00000000..b87c9603 --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/SubserverProtocolFixer.java @@ -0,0 +1,63 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.bungeecore.listeners; + +import io.github.waterfallmc.waterfall.utils.UUIDUtils; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.event.LoginEvent; +import net.md_5.bungee.connection.InitialHandler; +import net.md_5.bungee.connection.LoginResult; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.util.AddressUtil; + +import java.lang.reflect.Field; +import java.net.InetSocketAddress; +import java.util.logging.Level; + +public class SubserverProtocolFixer extends BasicListener { + + private final InetSocketAddress inetSocketAddress = new InetSocketAddress("127.127.127.127", 25565); + + private Field field; + + { + try { + field = InitialHandler.class.getDeclaredField("extraDataInHandshake"); + field.setAccessible(true); + } catch (NoSuchFieldException e) { + BungeeCord.getInstance().getLogger().log(Level.SEVERE, e.getMessage(), e); + } + } + + @EventHandler + public void loginEvent(LoginEvent e) { + InitialHandler initialHandler = ((InitialHandler) e.getConnection()); + LoginResult.Property[] properties = initialHandler.getLoginProfile().getProperties(); + try { + String extraData = "\00" + AddressUtil.sanitizeAddress(inetSocketAddress) + "\00" + UUIDUtils.undash(initialHandler.getUniqueId().toString()); + if (properties.length > 0) { + extraData += "\00" + BungeeCord.getInstance().gson.toJson(properties); + } + field.set(initialHandler, extraData); + } catch (IllegalAccessException ex) { + BungeeCord.getInstance().getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + } +} diff --git a/src/de/steamwar/bungeecore/sql/Team.java b/src/de/steamwar/bungeecore/sql/Team.java index be3bbec1..b00a64f4 100644 --- a/src/de/steamwar/bungeecore/sql/Team.java +++ b/src/de/steamwar/bungeecore/sql/Team.java @@ -29,7 +29,7 @@ public class Team { private static final Statement insert = new Statement("INSERT INTO Team (TeamKuerzel, TeamName) VALUES (?, ?)"); private static final Statement delete = new Statement("UPDATE Team SET TeamDeleted = 1 WHERE TeamID = ?"); - private static final Statement update = new Statement("INSERT INTO Team (TeamID, TeamKuerzel, TeamName, TeamColor) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE TeamName = VALUES(TeamName), TeamKuerzel = VALUES(TeamKuerzel), TeamColor = VALUES(TeamColor)"); + private static final Statement update = new Statement("INSERT INTO Team (TeamID, TeamKuerzel, TeamName, TeamColor, Address, Port) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE TeamName = VALUES(TeamName), TeamKuerzel = VALUES(TeamKuerzel), TeamColor = VALUES(TeamColor), Address = VALUES(Address), Port = VALUES(Port)"); private static final Statement getSize = new Statement("SELECT COUNT(id) FROM UserData WHERE Team = ?"); private static final Statement getMembers = new Statement("SELECT id FROM UserData WHERE Team = ?"); private static final Statement byId = new Statement("SELECT * FROM Team WHERE TeamID = ?"); @@ -37,14 +37,16 @@ public class Team { private static final Statement all = new Statement("SELECT * FROM Team WHERE NOT TeamDeleted"); private static final List teamCache = new LinkedList<>(); - private static final Team pub = new Team(0, "PUB", "Öffentlich", "8"); + private static final Team pub = new Team(0, "PUB", "Öffentlich", "8", null, 25565); private final int teamId; private String teamKuerzel; private String teamName; private String teamColor; + private String address; + private int port; - private Team(int id, String kuerzel, String name, String color){ + private Team(int id, String kuerzel, String name, String color, String address, int port){ teamId = id; teamKuerzel = kuerzel; teamName = name; @@ -52,10 +54,12 @@ public class Team { if (id != 0) { teamCache.add(this); } + this.address = address; + this.port = port; } private Team(ResultSet rs) throws SQLException { - this(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getString("TeamColor")); + this(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getString("TeamColor"), rs.getString("Address"), rs.getInt("Port")); } public static void create(String kuerzel, String name){ @@ -64,7 +68,7 @@ public class Team { public static Team get(int id){ if(id == -1) - return new Team(-1, "?", "?", "8"); + return new Team(-1, "?", "?", "8", null, 25565); if(id == 0) return pub; for(Team team : teamCache) @@ -101,7 +105,7 @@ public class Team { } private void updateDB(){ - update.update(teamId, teamKuerzel, teamName, teamColor); + update.update(teamId, teamKuerzel, teamName, teamColor, address, port); } public int getTeamId() { @@ -135,6 +139,24 @@ public class Team { updateDB(); } + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + updateDB(); + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + updateDB(); + } + public int size(){ return getSize.select(rs -> { rs.next(); diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index 6d65998b..15615e82 100644 --- a/src/de/steamwar/messages/BungeeCore.properties +++ b/src/de/steamwar/messages/BungeeCore.properties @@ -363,6 +363,7 @@ TEAM_NOT_IN_EVENT=§cDies ist während eines Events nicht möglich. TEAM_HELP_HEADER=§7Mit §e/team §7verwaltest du dein Team. TEAM_HELP_LIST=§8/§7team list §8- §7Liste alle Teams auf. TEAM_HELP_INFO=§8/§7team info §8- §7Informiere dich über ein Team. +TEAM_HELP_TP=§8/§7team tp §8(§7Team§8) §8- §7Teleportiert zum Teamserver. TEAM_HELP_CREATE=§8/§7team create §8- §7Erstelle dein eigenes Team. TEAM_HELP_JOIN=§8/§7team join §8- §7Trete einem Team bei. TEAM_HELP_CHAT=§8/§7teamchat §8- §7Sende Nachrichten an dein Team. @@ -375,6 +376,7 @@ TEAM_HELP_NAME=§8/§7team changename §8- §7Ändere deinen Teamnamen. TEAM_HELP_COLOR=§8/§7team changecolor §8- §7Ändere deine Teamfarbe. TEAM_HELP_LEADER=§8/§7team promote §8- §7Ernenne jemanden zum Teamleader. TEAM_HELP_STEP_BACK=§8/§7team stepback §8- §7Tritt als Leader zurück. +TEAM_HELP_SERVER=§8/§7team server §8[§eIP/Adresse§8] §8(§7Port§8) §8- §7Setzt Adresse des Teamservers. #Team Create TEAM_CREATE_USAGE=§8/§7team create §8[§eTeamkürzel§8] §8[§eTeamname§8] @@ -460,6 +462,13 @@ TEAM_EVENT_HOW_TO_LEAVE=§7Um die Teilnahme abzusagen, wiederhole den Befehl #Team Color TEAM_COLOR_TITLE=Farbe wählen +#Team Server +TEAM_SERVER_USAGE=§8/§7team server §8[§eIP/Adresse§8] §8(§7Port§8) §8- §7Setzt Adresse des Teamservers. +TEAM_SERVER_SET=§7Du hast die Teamserveradresse geändert§8! +TEAM_SERVER_PORT_INVALID=§cUnmögliche Portnummer. +TEAM_NO_ADDRESS=§cTeamserveradresse nicht gesetzt. +TEAM_TP_NO_TEAM=§cUnbekanntes Team. + #TpCommand TP_USAGE=§8/§7tp §8[§eSpieler§8] TP_USAGE_EVENT=§8/§7tp §8[§eSpieler §7oder §eTeam§8]