diff --git a/BauSystem/BauSystem_Main/build.gradle.kts b/BauSystem/BauSystem_Main/build.gradle.kts index 8f46699d..5b8f0a89 100644 --- a/BauSystem/BauSystem_Main/build.gradle.kts +++ b/BauSystem/BauSystem_Main/build.gradle.kts @@ -38,7 +38,6 @@ dependencies { compileOnly(libs.spigotapi) compileOnly(libs.axiom) compileOnly(libs.authlib) - compileOnly(libs.viaapi) compileOnly(libs.fawe18) diff --git a/BauSystem/BauSystem_Main/src/BauSystem.properties b/BauSystem/BauSystem_Main/src/BauSystem.properties index c9116dce..929d0c67 100644 --- a/BauSystem/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem/BauSystem_Main/src/BauSystem.properties @@ -1013,6 +1013,4 @@ XRAY_OFF=§cXray deactivated COLORREPLACE_HELP=§8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §7Replace all blocks of one color with another TYPEREPLACE_HELP=§8//§etypereplace §8[§7type§8] §8[§7type§8] §8- §7Replace all blocks of one type with another # Schematic -SCHEMATIC_GUI_ITEM=§eSchematics -#VersionAnnouncer -SERVER_VERSION=§7This server runs on Minecraft version §e{0} \ No newline at end of file +SCHEMATIC_GUI_ITEM=§eSchematics \ No newline at end of file diff --git a/BauSystem/BauSystem_Main/src/BauSystem_de.properties b/BauSystem/BauSystem_Main/src/BauSystem_de.properties index 45e60f84..4cb20d95 100644 --- a/BauSystem/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem/BauSystem_Main/src/BauSystem_de.properties @@ -954,6 +954,4 @@ XRAY_OFF=§cXray deaktiviert COLORREPLACE_HELP=§8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §7Ersetzt eine Farbe mit einer anderen TYPEREPLACE_HELP=§8//§etyreplace §8[§7type§8] §8[§7type§8] §8- §7Ersetzt einen Blockgruppe mit einer anderen # Schematics -SCHEMATIC_GUI_ITEM=§eSchematics -#VersionAnnouncer -SERVER_VERSION=§7Dieser Server läuft auf Minecraft-Version §e{0} \ No newline at end of file +SCHEMATIC_GUI_ITEM=§eSchematics \ No newline at end of file diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java index 3eb099aa..4c5feada 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java @@ -24,7 +24,6 @@ import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.script.ScriptRunner; import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin; import de.steamwar.bausystem.features.script.lua.libs.StorageLib; -import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.utils.RegionExtensionType; import de.steamwar.bausystem.region.utils.RegionType; @@ -32,7 +31,6 @@ import de.steamwar.core.TrickyTrialsWrapper; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -72,9 +70,10 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onPlayerQuit(PlayerQuitEvent event) { + if(Permission.BUILD.hasPermission(event.getPlayer())) { + ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event); + } StorageLib.removePlayer(event.getPlayer()); - if(!Permission.BUILD.hasPermission(event.getPlayer())) return; - ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event); } @EventHandler(priority = EventPriority.HIGH) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/VersionAnnouncer.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/VersionAnnouncer.java deleted file mode 100644 index ee9e91be..00000000 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/VersionAnnouncer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2024 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.bausystem.utils; - -import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.ViaAPI; -import de.steamwar.bausystem.BauSystem; -import de.steamwar.linkage.Linked; -import net.md_5.bungee.api.ChatMessageType; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; - -@Linked -public class VersionAnnouncer implements Listener { - - private final String versionString = Bukkit.getBukkitVersion().split("-", 2)[0]; - - @SuppressWarnings("unchecked") - private final ViaAPI via = Via.getAPI(); - - @EventHandler - public void onJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - if(via.getServerVersion().supportedVersions().contains(via.getPlayerVersion(player))) - return; - - BauSystem.MESSAGE.sendPrefixless("SERVER_VERSION", player, ChatMessageType.ACTION_BAR, versionString); - } -} diff --git a/BauSystem/BauSystem_Main/src/plugin.yml b/BauSystem/BauSystem_Main/src/plugin.yml index 53585eaa..71b08d95 100644 --- a/BauSystem/BauSystem_Main/src/plugin.yml +++ b/BauSystem/BauSystem_Main/src/plugin.yml @@ -2,8 +2,6 @@ name: BauSystem authors: [ Lixfel, YoyoNow, Chaoscaot, Zeanon, D4rkr34lm ] version: "2.0" depend: [ WorldEdit, SpigotCore ] -softdepend: - - ViaVersion load: POSTWORLD main: de.steamwar.bausystem.BauSystem api-version: "1.13" diff --git a/CommonCore/SQL/src/de/steamwar/sql/NodeData.java b/CommonCore/SQL/src/de/steamwar/sql/NodeData.java index 52743811..0de6c6c5 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/NodeData.java +++ b/CommonCore/SQL/src/de/steamwar/sql/NodeData.java @@ -28,12 +28,15 @@ import java.sql.PreparedStatement; import java.util.zip.GZIPInputStream; @AllArgsConstructor +@Getter public class NodeData { static { new SqlTypeMapper<>(PipedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("PipedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream); new SqlTypeMapper<>(ByteArrayInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("ByteArrayInputStream is write only datatype"); }, PreparedStatement::setBinaryStream); new SqlTypeMapper<>(BufferedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("BufferedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream); + + SqlTypeMapper.ordinalEnumMapper(SchematicFormat.class); } private static final Table table = new Table<>(NodeData.class); @@ -48,19 +51,18 @@ public class NodeData { throw new IllegalArgumentException("Node is a directory"); return get.select(rs -> { if(rs.next()) { - return new NodeData(node.getId(), rs.getBoolean("NodeFormat")); + return new NodeData(node.getId(), SchematicFormat.values()[rs.getInt("NodeFormat")]); } else { - return new NodeData(node.getId(), false); + return new NodeData(node.getId(), SchematicFormat.MCEDIT); } }, node); } - @Getter @Field(keys = {Table.PRIMARY}) private final int nodeId; @Field - private boolean nodeFormat; + private SchematicFormat nodeFormat; public InputStream schemData() throws IOException { try { @@ -81,12 +83,18 @@ public class NodeData { } } - public void saveFromStream(InputStream blob, boolean newFormat) { + public void saveFromStream(InputStream blob, SchematicFormat newFormat) { updateDatabase.update(nodeId, newFormat, blob); nodeFormat = newFormat; } - public boolean getNodeFormat() { - return nodeFormat; + @AllArgsConstructor + @Getter + public enum SchematicFormat { + MCEDIT(".schematic"), + SPONGE_V2(".schem"), + SPONGE_V3(".schem"); + + private final String fileEnding; } } diff --git a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java index 3df740da..bece8549 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java +++ b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java @@ -375,11 +375,10 @@ public class SchematicNode { return nodeType == null; } - @Deprecated - public boolean getSchemFormat() { + public String getFileEnding() { if(isDir()) throw new SecurityException("Node is Directory"); - return NodeData.get(this).getNodeFormat(); + return NodeData.get(this).getNodeFormat().getFileEnding(); } public int getRank() { diff --git a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java index 96974c61..d5b87b6e 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java +++ b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java @@ -73,6 +73,7 @@ public class SteamwarUser { private static final Statement getPlaytime = new Statement("SELECT SUM(UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime)) as Playtime FROM Session WHERE UserID = ?"); private static final Statement getFirstjoin = new Statement("SELECT MIN(StartTime) AS FirstJoin FROM Session WHERE UserID = ?"); + private static final Statement getLastonline = new Statement("SELECT MAX(EndTime) AS LastOnline FROM Session WHERE UserID = ?"); private static final Map usersById = new HashMap<>(); private static final Map usersByUUID = new HashMap<>(); @@ -276,6 +277,14 @@ public class SteamwarUser { }, id); } + public Timestamp getLastOnline() { + return getLastonline.select(rs -> { + if (rs.next()) + return rs.getTimestamp("LastOnline"); + return null; + }, id); + } + public void punish(Punishment.PunishmentType punishment, Timestamp time, String banReason, int from, boolean perma) { initPunishments(); punishments.remove(punishment); diff --git a/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java b/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java index 288b89e8..9a0ae4b5 100644 --- a/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java +++ b/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java @@ -42,6 +42,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; +import de.steamwar.sql.NodeData; import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; import org.bukkit.DyeColor; @@ -144,6 +145,6 @@ public class WorldeditWrapper14 implements WorldeditWrapper { throw new SecurityException(e); } - new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), true); + new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), NodeData.SchematicFormat.SPONGE_V2); } } diff --git a/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java index 19854db8..018552f2 100644 --- a/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java +++ b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java @@ -39,6 +39,7 @@ import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.World; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; +import de.steamwar.sql.NodeData; import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; import org.bukkit.DyeColor; @@ -142,6 +143,6 @@ public class WorldeditWrapper8 implements WorldeditWrapper { throw new SecurityException(e); } - new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), false); + new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), NodeData.SchematicFormat.MCEDIT); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index 6e6b1c40..57400063 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -153,7 +153,6 @@ public class FightSystem extends JavaPlugin { new GamemodeCommand(); new ReadyCommand(); new AkCommand(); - new LeaderCommand(); new LockschemCommand(); new StateCommand(); new SkipCommand(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties index 9f80ab7e..3d9a9218 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties @@ -34,9 +34,6 @@ GAMEMODE_NOT_ALLOWED=§cChanging gamemode is not permitted GAMEMODE_UNKNOWN=§cUnknown gamemode {0} GAMEMODE_HELP=§8/§7gm §8[§egamemode§8] -LEADER_FULL=§cAll teams already have a leader -ALREADY_IN_TEAM=§cYou are already in a team - LOCKSCHEM_HELP=§8/§7lockschem §8[§eteam§8] UNKNOWN_TEAM=§cThis team does not exist LOCKSCHEM_LOCKED=§7Schematic locked @@ -65,7 +62,9 @@ STATE_RUNNING=§eFighting phase STATE_SPECTATE_WIN=§7Victory {0} STATE_SPECTATE_TIE=§7Draw -REMOVE_TITLE=Kick player +MANAGE_TITLE=Manage players +MANAGE_LORE1=§eLeft §7click§8: §ekick +MANAGE_LORE2=§eRight §7click§8: §epromote KIT_SELECTION_TITLE=Kit selection KIT_NO_KITS=§cNo kits found @@ -113,7 +112,7 @@ SKIP_NOT_READY=§c§mSkipping to next event TEAM_CHAT={0}{1}§8» {0}{2} CHOOSE_KIT=§eChoose kit RESPAWN=§eRespawn -REMOVE_PLAYERS=§cKick player +MANAGE_PLAYERS=§cManage players CHOOSE_SCHEMATIC=§eChoose {0} SCHEMATIC_REQUIRED=§cChoose a schematic first ADD_AI=§eAdd AI @@ -141,7 +140,6 @@ NO_TELEPORT=§cYou are not allowed to use this teleport function OPEN_INVENTORY_TO_CUSTOMIZE=§eOpen inventory to customize your kit NO_ENTERN=§cYou may not board NO_TEAMAREA=§cYou are not allowed in the team area -TEST_BECOME_LEADER=§7Become a team leader with §8/§eleader PREPARE_SCHEM_DELETED=§cApparently the schematic to be submitted was deleted. submission aborted. PREPARE_SCHEM_EXISTS=§cThere is already a schematic with the suffix -prepared, please rename or delete it, submission aborted. PREPARE_ACTIVE_PISTON=§cMoving pistons were found in the team area, submission aborted. diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties index 6723bcfb..d45cdfd0 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties @@ -32,9 +32,6 @@ GAMEMODE_NOT_ALLOWED=§cSpielmodusänderung verboten GAMEMODE_UNKNOWN=§cUnbekannter Spielmodus {0} GAMEMODE_HELP=§8/§7gm §8[§eSpielmodus§8] -LEADER_FULL=§cAlle Teams haben bereits einen Leader -ALREADY_IN_TEAM=§cDu bist bereits in einem Team - LOCKSCHEM_HELP=§8/§7lockschem §8[§eTeam§8] UNKNOWN_TEAM=§cDieses Team existiert nicht LOCKSCHEM_LOCKED=§7Schematic gesperrt @@ -59,7 +56,9 @@ STATE_RUNNING=§eKampfphase STATE_SPECTATE_WIN=§7Sieg {0} STATE_SPECTATE_TIE=§7Unentschieden -REMOVE_TITLE=Spieler rauswerfen +MANAGE_TITLE=Mitspieler verwalten +MANAGE_LORE1=§eLinksklick§8: §eRauswurf +MANAGE_LORE2=§eRechtsklick§8: §eBefördern KIT_SELECTION_TITLE=Kitauswahl KIT_NO_KITS=§cKeine Kits gefunden @@ -106,7 +105,7 @@ SKIP_READY=§aBeschleunigung zum nächsten Event SKIP_NOT_READY=§c§mBeschleunigung zum nächsten Event CHOOSE_KIT=§eKit wählen RESPAWN=§eRespawn -REMOVE_PLAYERS=§cSpieler rauswerfen +MANAGE_PLAYERS=§cMitspieler verwalten CHOOSE_SCHEMATIC=§e{0} wählen SCHEMATIC_REQUIRED=§cZuerst muss eine Schematic gewählt sein ADD_AI=§eKI hinzufügen @@ -134,7 +133,6 @@ NO_TELEPORT=§cDu darfst diese Teleportfunktion nicht benutzen OPEN_INVENTORY_TO_CUSTOMIZE=§eInventar zum Anpassen des Kits öffnen NO_ENTERN=§cDu darfst nicht entern NO_TEAMAREA=§cDu darfst nicht zu den Teams -TEST_BECOME_LEADER=§7Werde zum Teamleader mit §8/§eleader PREPARE_SCHEM_DELETED=§cAnscheinend wurde die auszufahrende Schematic gelöscht, Einsenden wird abgebrochen. PREPARE_SCHEM_EXISTS=§cEs existiert bereits eine Schem mit Namenszusatz -prepared, diese bitte umbenennen oder löschen, Einsenden wird abgebrochen. PREPARE_ACTIVE_PISTON=§cIm Teambereich wurden sich noch bewegende Pistons gefunden, Einsenden wird abgebrochen. diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java index 4834bb0a..2ca6849c 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java @@ -36,6 +36,7 @@ import de.steamwar.sql.SteamwarUser; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -53,7 +54,11 @@ public class GUI { String name = team.getLeader() != null ? team.getLeader().getEntity().getName() : team.getName(); inv.setItem(pos, SWItem.getDye(colorCode), colorCode, msg.parse("JOIN_REQUEST_TEAM", p, team.getColor() + name), click -> { p.closeInventory(); - JoinRequest.forPlayer(p, team); + + if(ArenaMode.ManualTeams.contains(Config.mode) && team.canbeLeader(p)) + team.addMember(p); + else + JoinRequest.forPlayer(p, team); }); } @@ -117,14 +122,21 @@ public class GUI { inv.open(); } - public static void chooseRemove(Player p){ + public static void managePlayers(Player p){ List> players = SWListInv.createPlayerList(p.getUniqueId()); FightTeam team = Fight.getPlayerTeam(p); if(team == null) return; - players.removeIf(swItemUUIDPair -> !team.equals(Fight.getPlayerTeam(Bukkit.getPlayer(swItemUUIDPair.getObject())))); - SWListInv inv = new SWListInv<>(p, msg.parse("REMOVE_TITLE", p), players, (ClickType click, UUID player) -> { - Commands.kick(p, SteamwarUser.get(player).getUserName()); + players.removeIf(listEntry -> !team.equals(Fight.getPlayerTeam(Bukkit.getPlayer(listEntry.getObject())))); + players.forEach(listEntry -> listEntry.getItem().setLore(msg.parse("MANAGE_LORE1", p), msg.parse("MANAGE_LORE2", p))); + SWListInv inv = new SWListInv<>(p, msg.parse("MANAGE_TITLE", p), players, (ClickType click, UUID player) -> { + if(click.isLeftClick()) { + Commands.kick(p, SteamwarUser.get(player).getUserName()); + } else if(click.isRightClick()) { + LivingEntity target = (LivingEntity) Bukkit.getEntity(player); + if(target != null) + team.setLeader(team.getFightPlayer(target), false); + } p.closeInventory(); }); inv.setCallback(-999, (ClickType click) -> p.closeInventory()); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/LeaderCommand.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/LeaderCommand.java deleted file mode 100644 index e2151956..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/LeaderCommand.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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.fightsystem.commands; - -import de.steamwar.fightsystem.ArenaMode; -import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.fight.Fight; -import de.steamwar.fightsystem.fight.FightTeam; -import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependentCommand; -import net.md_5.bungee.api.ChatMessageType; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class LeaderCommand implements CommandExecutor { - - public LeaderCommand() { - new StateDependentCommand(ArenaMode.ManualTeams, FightState.Setup, "leader", this); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if(!(sender instanceof Player)) - return false; - Player player = (Player) sender; - - if(Fight.getFightPlayer(player) != null) { - FightSystem.getMessage().sendPrefixless("ALREADY_IN_TEAM", player, ChatMessageType.ACTION_BAR); - return false; - } - - for(FightTeam team : Fight.teams()) { - if(team.canbeLeader(player)) { - team.addMember(player); - return false; - } - } - FightSystem.getMessage().sendPrefixless("LEADER_FULL", player, ChatMessageType.ACTION_BAR); - return false; - } -} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java index 334f3f83..3a6a12a2 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -73,7 +73,7 @@ public class FightTeam { if(ArenaMode.VariableTeams.contains(Config.mode)){ notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).build(), GUI::chooseJoinRequests); - notReadyKit.setItem(3, "REMOVE_PLAYERS", new ItemBuilder(SWItem.getMaterial("FIREWORK_CHARGE")).build(), GUI::chooseRemove); + notReadyKit.setItem(3, "MANAGE_PLAYERS", SWItem.getPlayerSkull("AdmiralSeekrank").getItemStack(), GUI::managePlayers); if(!AIManager.availableAIs().isEmpty()) notReadyKit.setItem(6, "ADD_AI", new ItemBuilder(Material.REDSTONE).build(), GUI::addAI); } @@ -343,7 +343,10 @@ public class FightTeam { } } - private void setLeader(FightPlayer leader, boolean silent) { + public void setLeader(FightPlayer leader, boolean silent) { + if(this.leader != null) + this.leader.ifPlayer(memberKit::loadToPlayer); + leader.ifPlayer(PersonalKitCreator::closeIfInKitCreator); this.leader = leader; diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TestJoin.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TestJoin.java index 77240153..13a512a4 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TestJoin.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TestJoin.java @@ -22,8 +22,6 @@ package de.steamwar.fightsystem.listener; import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.fight.Fight; -import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.sql.SteamwarUser; @@ -42,7 +40,6 @@ public class TestJoin implements Listener { @EventHandler public void handlePlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - FightTeam fightTeam = Fight.getPlayerTeam(player); if(Config.ReplayID != 0 && !SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.MODERATION)) { FightSystem.getMessage().send("CHECK_JOIN_DENIED", player); @@ -50,10 +47,6 @@ public class TestJoin implements Listener { return; } - if (fightTeam == null && Fight.teams().stream().anyMatch(team -> team.canbeLeader(player))) { - FightSystem.getMessage().send("TEST_BECOME_LEADER", player); - } - player.setOp(true); if(FightState.getFightState() == FightState.PRE_LEADER_SETUP){ diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java index 825c5eb6..47efc09d 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -22,6 +22,7 @@ package de.steamwar.fightsystem.record; import com.sk89q.worldedit.extent.clipboard.Clipboard; import de.steamwar.core.Core; import de.steamwar.core.TrickyTrialsWrapper; +import de.steamwar.core.WorldEditWrapper; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RPlayer; @@ -523,7 +524,7 @@ public class PacketProcessor implements Listener { public void close() { // FAWE 1.12 calls close... } - }, Core.getVersion() > 12); + }, WorldEditWrapper.impl.getNativeFormat()); execSync(() -> team.pasteSchem(schemId, clipboard)); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BungeeFightInfo.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BungeeFightInfo.java index 6ffa0e98..783917bb 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BungeeFightInfo.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BungeeFightInfo.java @@ -40,10 +40,6 @@ public class BungeeFightInfo { } private void send() { - Player player = Bukkit.getOnlinePlayers().stream().findAny().orElse(null); - if(player == null) - return; - NetworkSender.send(new FightInfoPacket( Config.world.getName(), Config.SchematicType.toDB(), diff --git a/FightSystem/FightSystem_Core/src/plugin.yml b/FightSystem/FightSystem_Core/src/plugin.yml index d8763954..64ece716 100644 --- a/FightSystem/FightSystem_Core/src/plugin.yml +++ b/FightSystem/FightSystem_Core/src/plugin.yml @@ -19,7 +19,6 @@ commands: ready: kit: remove: - leader: lockschem: state: skip: diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties b/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties index 2d3aa782..275a99a8 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties @@ -10,6 +10,13 @@ NPC_CHAT_2 = §eSteam§8War§f was established in 2019. NPC_CHAT_3 = §fBecome a part of our team by applying via our Discord server (https://steamwar.de/discord). NPC_CHAT_4 = §fYou can develop your own buildserver features with our Lua script system. NPC_CHAT_5 = §fThere are many secrets to discover in this lobby. +## TheBreadBeard +NPC_CHAT_3266_0 = §fI collect Alts like Infinity Stones. +NPC_CHAT_3266_1 = &fYou want my Bread? You can have it! Just look for it! I've hidden the best bakery in the world somewhere! +NPC_CHAT_3266_2 = &fHey, I am TheBreadBeard, ex- EuropSuchties Player, formerly (un)known as WarGear_Titan. +NPC_CHAT_3266_3 = &fInventor of Lactose Intolerance, the Placeholder and Infinity-Ring. All technical principles no one knows or needs. +NPC_CHAT_3266_4 = &fKnown for the Lobby-Banners, logos, spontaneous Arenas, as well as an Organizer and Moderator of many Events. +NPC_CHAT_3266_5 = &fFrom Supporter to Moderator to Builder ... Maybe the journey takes me to being a Developer next. # Portal Command PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Lists all portals diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties b/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties index 73808174..bf382639 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties @@ -10,6 +10,13 @@ NPC_CHAT_2 = §eSteam§8War§f gibt es seit 2019. NPC_CHAT_3 = §fBewerbe dich gerne für unser Team über unseren Discord-Server (https://steamwar.de/discord). NPC_CHAT_4 = §fDu kannst mit unserm Lua Script-System deine eigenen Bau Features programmieren. NPC_CHAT_5 = §fAuf dieser Lobby sind so einige secrets versteckt. +## TheBreadBeard +NPC_CHAT_3266_0 = §fIch sammel Alts wie Infinity Stones. +NPC_CHAT_3266_1 = &fIhr wollt meine Teigwaren? Die könnt ihr haben! Sucht sie doch! Irgendwo hab ich die beste Bäckerei der Welt versteckt! +NPC_CHAT_3266_2 = &fMoin, Ich bin TheBreadBeard, ehemaliger EuropSuchties Spieler, damals (un)bekannt als WarGear_Titan. +NPC_CHAT_3266_3 = &fErfinder der Laktoseintoleranz, des Platzhalters und des Infinity-Rings. Alles Prinzipien, die keiner kennt und keiner braucht. +NPC_CHAT_3266_4 = &fBekannt für die Lobbybanner, Logos, spontane Arenen, sowie als Leiter von so manchem Event. +NPC_CHAT_3266_5 = &fVon Supporter zu Moderator zu Builder ... Vielleicht führt mich die Reise als Nächstes zum Developer. # Portal Command PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Listet alle Portale auf diff --git a/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java b/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java index 2829ec2f..989fca7a 100644 --- a/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java +++ b/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java @@ -23,7 +23,6 @@ import de.steamwar.lobby.LobbySystem; import de.steamwar.lobby.display.NPC; import de.steamwar.lobby.listener.BasicListener; import de.steamwar.sql.SteamwarUser; -import de.steamwar.sql.UserPerm; import lombok.AllArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -135,6 +134,10 @@ public class TeamPlayer extends BasicListener { return false; } + private String parseRandomMessage(Player player, SteamwarUser target, String message) throws MissingResourceException { + return LobbySystem.getMessage().parsePrefixed(message + random.nextInt(6), player, target.getUserName(), target.prefix().getColorCode() + target.prefix().getChatPrefix()); + } + @EventHandler public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { if (!(event.getRightClicked() instanceof Villager)) { @@ -145,10 +148,14 @@ public class TeamPlayer extends BasicListener { return; } - String message = "NPC_CHAT_" + random.nextInt(6); - SteamwarUser user = SteamwarUser.get(event.getRightClicked().getName()); - UserPerm.Prefix prefix = user.prefix(); - LobbySystem.getMessage().send(message, event.getPlayer(), event.getRightClicked().getName(), prefix.getColorCode() + prefix.getChatPrefix()); + SteamwarUser target = SteamwarUser.get(event.getRightClicked().getName()); + String message; + try { + message = parseRandomMessage(event.getPlayer(), target, "NPC_CHAT_" + target.getId() + "_"); + } catch (MissingResourceException e) { + message = parseRandomMessage(event.getPlayer(), target, "NPC_CHAT_"); + } + event.getPlayer().sendMessage(message); } @EventHandler diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java index 2b953b74..860435b9 100644 --- a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java @@ -245,7 +245,7 @@ public class SchematicCommandUtils { SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_ELO", player, node.getElo(Season.getSeason())); } - SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_FORMAT", player, node.getSchemFormat() ? ".schem" : ".schematic"); + SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_FORMAT", player, node.getFileEnding()); CheckedSchematic.getLastDeclinedOfNode(node.getId()).stream().findFirst().ifPresent(checkedSchematic -> SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_STATUS", player, checkedSchematic.getEndTime(), checkedSchematic.getDeclineReason())); } else { SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_TYPE", player, SchematicSystem.MESSAGE.parse("UTIL_INFO_TYPE_DIR", player)); diff --git a/SpigotCore/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java b/SpigotCore/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java index cd116bac..3251e5bc 100644 --- a/SpigotCore/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java +++ b/SpigotCore/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java @@ -22,7 +22,6 @@ package de.steamwar.core; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.sk89q.jnbt.*; -import com.sk89q.worldedit.EmptyClipboardException; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extension.input.InputParseException; @@ -45,36 +44,30 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; import de.steamwar.sql.NoClipboardException; +import de.steamwar.sql.NodeData; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.io.*; import java.util.*; -import java.util.logging.Level; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; +@SuppressWarnings("removal") public class WorldEditWrapper14 implements WorldEditWrapper { - private static final ClipboardFormat SCHEMATIC = BuiltInClipboardFormat.MCEDIT_SCHEMATIC; - private static final ClipboardFormat SCHEM = BuiltInClipboardFormat.SPONGE_SCHEMATIC; - @Override - public InputStream getPlayerClipboard(Player player, boolean schemFormat) { - return WorldEditWrapper.getPlayerClipboard(player, schemFormat, (outputStream, clipboard, clipboardHolder) -> { - if(schemFormat){ - ClipboardWriter writer = SCHEM.getWriter(outputStream); - writer.write(clipboard); - writer.close(); - }else{ - SCHEMATIC.getWriter(outputStream).write(clipboard); - } + public InputStream getPlayerClipboard(Player player) { + return WorldEditWrapper.getPlayerClipboard(player, (outputStream, clipboard, clipboardHolder) -> { + ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(outputStream); + writer.write(clipboard); + writer.close(); }); } @Override - public void setPlayerClipboard(Player player, InputStream is, boolean schemFormat) { + public void setPlayerClipboard(Player player, InputStream is, NodeData.SchematicFormat schemFormat) { Clipboard clipboard = null; try { clipboard = getClipboard(is, schemFormat); @@ -90,12 +83,17 @@ public class WorldEditWrapper14 implements WorldEditWrapper { } @Override - public Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException { + public Clipboard getClipboard(InputStream is, NodeData.SchematicFormat schemFormat) throws IOException { try { - if(schemFormat){ - return new SpongeSchematicReader(new NBTInputStream(is)).read(); - }else{ - return new MCEditSchematicReader(new NBTInputStream(is)).read(); + + switch (schemFormat) { + case SPONGE_V2: + case SPONGE_V3: + return new SpongeSchematicReader(new NBTInputStream(is), this).read(); + case MCEDIT: + return new MCEditSchematicReader(new NBTInputStream(is)).read(); + default: + throw new IOException("This schematic format is currently not supported"); } } catch (NullPointerException e) { throw new NoClipboardException(); @@ -124,6 +122,15 @@ public class WorldEditWrapper14 implements WorldEditWrapper { return new org.bukkit.util.Vector(v.getX(), v.getY(), v.getZ()); } + @Override + public NodeData.SchematicFormat getNativeFormat() { + return NodeData.SchematicFormat.SPONGE_V2; + } + + public Map applyDataFixer(DataFixer fixer, int dataVersion, Map values) { + return fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, new CompoundTag(values), dataVersion).getValue(); + } + private static class MCEditSchematicReader extends NBTSchematicReader { private final NBTInputStream inputStream; @@ -387,22 +394,24 @@ public class WorldEditWrapper14 implements WorldEditWrapper { inputStream.close(); } } - private static class SpongeSchematicReader extends NBTSchematicReader { + public static class SpongeSchematicReader extends NBTSchematicReader { private final NBTInputStream inputStream; private DataFixer fixer = null; private int schematicVersion = -1; private int dataVersion = -1; private boolean faweSchem = false; + private final WorldEditWrapper14 wrapper; /** * Create a new instance. * * @param inputStream the input stream to read from */ - public SpongeSchematicReader(NBTInputStream inputStream) { + public SpongeSchematicReader(NBTInputStream inputStream, WorldEditWrapper14 wrapper) { checkNotNull(inputStream); this.inputStream = inputStream; + this.wrapper = wrapper; } @Override @@ -418,7 +427,7 @@ public class WorldEditWrapper14 implements WorldEditWrapper { dataVersion = 1631; // this is a relatively safe assumption unless someone imports a schematic from 1.12, e.g. sponge 7.1- fixer = platform.getDataFixer(); return readVersion1(schematicTag); - } else if (schematicVersion == 2) { + } else if (schematicVersion == 2 || schematicVersion == 3) { dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue(); if (dataVersion < liveDataVersion) { fixer = platform.getDataFixer(); @@ -447,14 +456,18 @@ public class WorldEditWrapper14 implements WorldEditWrapper { private CompoundTag getBaseTag() throws IOException { NamedTag rootTag = inputStream.readNamedTag(); - if (!rootTag.getName().equals("Schematic")) { - throw new IOException("Tag 'Schematic' does not exist or is not first"); - } CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); // Check Map schematic = schematicTag.getValue(); + if (schematic.size() == 1) { + schematicTag = requireTag(schematic, "Schematic", CompoundTag.class); + schematic = schematicTag.getValue(); + } else if (!rootTag.getName().equals("Schematic")) { + throw new IOException("Tag 'Schematic' does not exist or is not first"); + } + schematicVersion = requireTag(schematic, "Version", IntTag.class).getValue(); return schematicTag; } @@ -499,12 +512,16 @@ public class WorldEditWrapper14 implements WorldEditWrapper { region = new CuboidRegion(origin, origin.add(width, height, length).subtract(BlockVector3.ONE)); } - IntTag paletteMaxTag = getTag(schematic, "PaletteMax", IntTag.class); - Map paletteObject = requireTag(schematic, "Palette", CompoundTag.class).getValue(); - if (paletteMaxTag != null && paletteObject.size() != paletteMaxTag.getValue()) { - throw new IOException("Block palette size does not match expected size."); + Map blockContainer = null; + boolean v3Mode = false; + + if (schematicVersion == 3) { + blockContainer = requireTag(schematic, "Blocks", CompoundTag.class).getValue(); + v3Mode = true; } + Map paletteObject = requireTag(v3Mode ? blockContainer: schematic, "Palette", CompoundTag.class).getValue(); + Map palette = new HashMap<>(); ParserContext parserContext = new ParserContext(); @@ -526,12 +543,12 @@ public class WorldEditWrapper14 implements WorldEditWrapper { palette.put(id, state); } - byte[] blocks = requireTag(schematic, "BlockData", ByteArrayTag.class).getValue(); + byte[] blocks = requireTag(v3Mode ? blockContainer: schematic, v3Mode ? "Data" : "BlockData", ByteArrayTag.class).getValue(); Map> tileEntitiesMap = new HashMap<>(); - ListTag tileEntities = getTag(schematic, "BlockEntities", ListTag.class); + ListTag tileEntities = getTag(v3Mode ? blockContainer: schematic, "BlockEntities", ListTag.class); if (tileEntities == null) { - tileEntities = getTag(schematic, "TileEntities", ListTag.class); + tileEntities = getTag(v3Mode ? blockContainer: schematic, "TileEntities", ListTag.class); } if (tileEntities != null) { List> tileEntityTags = tileEntities.getValue().stream() @@ -562,7 +579,7 @@ public class WorldEditWrapper14 implements WorldEditWrapper { values.remove("Id"); values.remove("Pos"); if (fixer != null) { - tileEntity = fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, new CompoundTag(values), dataVersion).getValue(); + tileEntity = wrapper.applyDataFixer(fixer, dataVersion, values); } else { tileEntity = values; } diff --git a/SpigotCore/SpigotCore_18/src/de/steamwar/core/WorldEditWrapper18.java b/SpigotCore/SpigotCore_18/src/de/steamwar/core/WorldEditWrapper18.java index 903113c4..1c216a1a 100644 --- a/SpigotCore/SpigotCore_18/src/de/steamwar/core/WorldEditWrapper18.java +++ b/SpigotCore/SpigotCore_18/src/de/steamwar/core/WorldEditWrapper18.java @@ -19,25 +19,18 @@ package de.steamwar.core; -import com.sk89q.jnbt.NBTInputStream; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.extent.clipboard.io.*; -import de.steamwar.sql.NoClipboardException; +import com.sk89q.jnbt.AdventureNBTConverter; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.world.DataFixer; -import java.io.IOException; -import java.io.InputStream; +import java.util.Map; public class WorldEditWrapper18 extends WorldEditWrapper14 { @Override @SuppressWarnings("removal") - public Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException { - NBTInputStream nbtStream = new NBTInputStream(is); - //Use FAWE reader due to FAWE capability of reading corrupt FAWE schems - try { - return (schemFormat ? new SpongeSchematicReader(nbtStream) : new MCEditSchematicReader(nbtStream)).read(); - } catch (NullPointerException e) { - throw new NoClipboardException(); - } + public Map applyDataFixer(DataFixer fixer, int dataVersion, Map values) { + return ((CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, new CompoundTag(values).asBinaryTag(), dataVersion))).getValue(); } } diff --git a/SpigotCore/SpigotCore_21/build.gradle.kts b/SpigotCore/SpigotCore_21/build.gradle.kts index b9a7805e..8f2acba4 100644 --- a/SpigotCore/SpigotCore_21/build.gradle.kts +++ b/SpigotCore/SpigotCore_21/build.gradle.kts @@ -21,7 +21,13 @@ plugins { steamwar.java } +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + dependencies { + compileOnly(project(":CommonCore", "default")) compileOnly(project(":SpigotCore:SpigotCore_Main", "default")) compileOnly(project(":SpigotCore:SpigotCore_18", "default")) compileOnly(project(":SpigotCore:SpigotCore_14", "default")) @@ -29,16 +35,6 @@ dependencies { compileOnly(libs.fawe21) - compileOnly(libs.paperapi21) { - attributes { - // Very Hacky, but it works - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21) - } - } - compileOnly(libs.nms21) { - attributes { - // Very Hacky, but it works - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21) - } - } + compileOnly(libs.paperapi21) + compileOnly(libs.nms21) } diff --git a/SpigotCore/SpigotCore_21/src/de/steamwar/core/BountifulWrapper21.java b/SpigotCore/SpigotCore_21/src/de/steamwar/core/BountifulWrapper21.java index b749f834..e01a06fc 100644 --- a/SpigotCore/SpigotCore_21/src/de/steamwar/core/BountifulWrapper21.java +++ b/SpigotCore/SpigotCore_21/src/de/steamwar/core/BountifulWrapper21.java @@ -33,7 +33,7 @@ public class BountifulWrapper21 extends BountifulWrapper9 { return (packet, x, y, z, pitch, yaw) -> { PositionMoveRotation pos = field.get(packet); - field.set(packet, new PositionMoveRotation(new Vec3D(x, y, z), pos.b(), pitch, yaw)); + field.set(packet, new PositionMoveRotation(new Vec3D(x, y, z), pos.b(), yaw, pitch)); }; } catch (IllegalArgumentException e) { return super.getPositionSetter(packetClass, fieldOffset); diff --git a/SpigotCore/SpigotCore_21/src/de/steamwar/core/WorldEditWrapper21.java b/SpigotCore/SpigotCore_21/src/de/steamwar/core/WorldEditWrapper21.java index 4ae22cac..52947f3a 100644 --- a/SpigotCore/SpigotCore_21/src/de/steamwar/core/WorldEditWrapper21.java +++ b/SpigotCore/SpigotCore_21/src/de/steamwar/core/WorldEditWrapper21.java @@ -20,33 +20,30 @@ package de.steamwar.core; import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV2; -import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV3; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader; -import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV1Reader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV2Reader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV3Reader; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.ClipboardHolder; +import de.steamwar.sql.NodeData; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import org.enginehub.linbus.stream.LinBinaryIO; -import org.enginehub.linbus.stream.LinStream; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinRootEntry; -import org.enginehub.linbus.tree.LinTagType; import java.io.*; public class WorldEditWrapper21 implements WorldEditWrapper { @Override - public InputStream getPlayerClipboard(Player player, boolean schemFormat) { - return WorldEditWrapper.getPlayerClipboard(player, schemFormat, (outputStream, clipboard, clipboardHolder) -> { + public InputStream getPlayerClipboard(Player player) { + return WorldEditWrapper.getPlayerClipboard(player, (outputStream, clipboard, clipboardHolder) -> { ClipboardWriter writer = BuiltInClipboardFormat.FAST_V3.getWriter(outputStream); writer.write(clipboard); writer.close(); @@ -54,7 +51,7 @@ public class WorldEditWrapper21 implements WorldEditWrapper { } @Override - public void setPlayerClipboard(Player player, InputStream is, boolean schemFormat) { + public void setPlayerClipboard(Player player, InputStream is, NodeData.SchematicFormat schemFormat) { Clipboard clipboard = null; try { clipboard = getClipboard(is, schemFormat); @@ -70,35 +67,13 @@ public class WorldEditWrapper21 implements WorldEditWrapper { } @Override - public Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException { - if (!schemFormat) { - return new MCEditSchematicReader(new NBTInputStream(is)).read(); - } else { - BufferedInputStream bis = new BufferedInputStream(is); - - bis.mark(Integer.MAX_VALUE); - - LinStream linStream = LinBinaryIO.read(new DataInputStream(bis)); - - LinCompoundTag entry = LinRootEntry.readFrom(linStream).value(); - - if (entry.value().size() == 1) { - entry = entry.getTag("Schematic", LinTagType.compoundTag()); - } - - bis.reset(); - - switch (entry.getTag("Version", LinTagType.intTag()).valueAsInt()) { - case 1: - return new SpongeSchematicV1Reader(entry.linStream()).read(); - case 2: - return new FastSchematicReaderV2(new NBTInputStream(bis)).read(); - case 3: - return new FastSchematicReaderV3(bis).read(); - default: - throw new IOException("Unknown schematic version"); - } - } + @SuppressWarnings("removal") + public Clipboard getClipboard(InputStream is, NodeData.SchematicFormat schemFormat) throws IOException { + return switch (schemFormat) { + case MCEDIT -> new MCEditSchematicReader(new NBTInputStream(is)).read(); + case SPONGE_V2 -> new SpongeSchematicV2Reader(LinBinaryIO.read(new DataInputStream(is))).read(); + case SPONGE_V3 -> new SpongeSchematicV3Reader(LinBinaryIO.read(new DataInputStream(is))).read(); + }; } @Override @@ -122,4 +97,9 @@ public class WorldEditWrapper21 implements WorldEditWrapper { v = transform.apply(v); return new org.bukkit.util.Vector(v.x(), v.y(), v.z()); } + + @Override + public NodeData.SchematicFormat getNativeFormat() { + return NodeData.SchematicFormat.SPONGE_V3; + } } diff --git a/SpigotCore/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java b/SpigotCore/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java index 14e84923..8665a815 100644 --- a/SpigotCore/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java +++ b/SpigotCore/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java @@ -70,15 +70,15 @@ public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper { Reflection.Field posX = Reflection.getField(packetClass, int.class, fieldOffset); Reflection.Field posY = Reflection.getField(packetClass, int.class, fieldOffset +1); Reflection.Field posZ = Reflection.getField(packetClass, int.class, fieldOffset +2); - Reflection.Field lookPitch = Reflection.getField(packetClass, byte.class, 0); - Reflection.Field lookYaw = Reflection.getField(packetClass, byte.class, 1); + Reflection.Field lookYaw = Reflection.getField(packetClass, byte.class, 0); + Reflection.Field lookPitch = Reflection.getField(packetClass, byte.class, 1); return (packet, x, y, z, pitch, yaw) -> { posX.set(packet, MathHelper.floor(x * 32)); posY.set(packet, MathHelper.floor(y * 32)); posZ.set(packet, MathHelper.floor(z * 32)); - lookPitch.set(packet, (byte)(pitch * 256 / 360)); lookYaw.set(packet, (byte)(yaw * 256 / 360)); + lookPitch.set(packet, (byte)(pitch * 256 / 360)); }; } diff --git a/SpigotCore/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java b/SpigotCore/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java index f3fc2800..75957933 100644 --- a/SpigotCore/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java +++ b/SpigotCore/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java @@ -37,6 +37,7 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.registry.WorldData; +import de.steamwar.sql.NodeData; import org.bukkit.entity.Player; import java.io.IOException; @@ -50,13 +51,13 @@ import java.util.stream.Collectors; public class WorldEditWrapper8 implements WorldEditWrapper { @Override - public InputStream getPlayerClipboard(Player player, boolean schemFormat) { - return WorldEditWrapper.getPlayerClipboard(player, schemFormat, (outputStream, clipboard, clipboardHolder) -> + public InputStream getPlayerClipboard(Player player) { + return WorldEditWrapper.getPlayerClipboard(player, (outputStream, clipboard, clipboardHolder) -> ClipboardFormat.SCHEMATIC.getWriter(outputStream).write(clipboard, clipboardHolder.getWorldData())); } @Override - public void setPlayerClipboard(Player player, InputStream is, boolean schemFormat) { + public void setPlayerClipboard(Player player, InputStream is, NodeData.SchematicFormat schemFormat) { WorldData world = new BukkitWorld(player.getWorld()).getWorldData(); Clipboard clipboard; try { @@ -70,11 +71,16 @@ public class WorldEditWrapper8 implements WorldEditWrapper { } @Override - public Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException { - if(schemFormat) - return new SpongeSchematicReader(new NBTInputStream(is)).read(WorldEdit.getInstance().getServer().getWorlds().get(0).getWorldData()); - else - return new SchematicReader(new NBTInputStream(is)).read(WorldEdit.getInstance().getServer().getWorlds().get(0).getWorldData()); + public Clipboard getClipboard(InputStream is, NodeData.SchematicFormat schemFormat) throws IOException { + switch (schemFormat) { + case MCEDIT: + return new SchematicReader(new NBTInputStream(is)).read(WorldEdit.getInstance().getServer().getWorlds().get(0).getWorldData()); + case SPONGE_V2: + case SPONGE_V3: + return new SpongeSchematicReader(new NBTInputStream(is)).read(WorldEdit.getInstance().getServer().getWorlds().get(0).getWorldData()); + default: + throw new IllegalArgumentException("Unsupported schematic format"); + } } @Override @@ -99,6 +105,11 @@ public class WorldEditWrapper8 implements WorldEditWrapper { return new org.bukkit.util.Vector(v.getX(), v.getY(), v.getZ()); } + @Override + public NodeData.SchematicFormat getNativeFormat() { + return NodeData.SchematicFormat.MCEDIT; + } + private static class SpongeSchematicReader implements ClipboardReader { private final NBTInputStream inputStream; @@ -137,6 +148,13 @@ public class WorldEditWrapper8 implements WorldEditWrapper { IDConverter8 ids = new IDConverter8(); Map schematic = schematicTag.getValue(); + boolean v3Mode = false; + + if (schematic.size() == 1) { + schematic = (requireTag(schematic, "Schematic", CompoundTag.class)).getValue(); + v3Mode = true; + } + int width = (requireTag(schematic, "Width", ShortTag.class)).getValue(); int height = (requireTag(schematic, "Height", ShortTag.class)).getValue(); int length = (requireTag(schematic, "Length", ShortTag.class)).getValue(); @@ -167,10 +185,13 @@ public class WorldEditWrapper8 implements WorldEditWrapper { region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector.ONE)); } - IntTag paletteMaxTag = getTag(schematic, "PaletteMax", IntTag.class); - Map paletteObject = requireTag(schematic, "Palette", CompoundTag.class).getValue(); - if (paletteMaxTag != null && paletteObject.size() != paletteMaxTag.getValue()) - throw new IOException("Block palette size does not match expected size."); + Map blockContainer = null; + + if (v3Mode) { + blockContainer = getTag(schematic, "Blocks", CompoundTag.class).getValue(); + } + + Map paletteObject = requireTag(v3Mode ? blockContainer : schematic, "Palette", CompoundTag.class).getValue(); Map palette = new HashMap<>(); ParserContext parserContext = new ParserContext(); @@ -182,11 +203,11 @@ public class WorldEditWrapper8 implements WorldEditWrapper { palette.put(requireTag(paletteObject, palettePart, IntTag.class).getValue(), new BaseBlock(blockID.getBlockId(), blockID.getDataId())); } - byte[] blocks = requireTag(schematic, "BlockData", ByteArrayTag.class).getValue(); + byte[] blocks = requireTag(v3Mode ? blockContainer : schematic, v3Mode ? "Data" : "BlockData", ByteArrayTag.class).getValue(); Map> tileEntitiesMap = new HashMap<>(); - ListTag tileEntities = getTag(schematic, "BlockEntities", ListTag.class); + ListTag tileEntities = getTag(v3Mode ? blockContainer : schematic, "BlockEntities", ListTag.class); if (tileEntities == null) { - tileEntities = getTag(schematic, "TileEntities", ListTag.class); + tileEntities = getTag(v3Mode ? blockContainer : schematic, "TileEntities", ListTag.class); } if (tileEntities != null) { diff --git a/SpigotCore/SpigotCore_9/build.gradle.kts b/SpigotCore/SpigotCore_9/build.gradle.kts index 3463498a..a888faf1 100644 --- a/SpigotCore/SpigotCore_9/build.gradle.kts +++ b/SpigotCore/SpigotCore_9/build.gradle.kts @@ -26,6 +26,4 @@ dependencies { compileOnly(project(":SpigotCore:SpigotCore_8", "default")) compileOnly(libs.nms9) - - compileOnly(libs.viaapi) } diff --git a/SpigotCore/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java b/SpigotCore/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java index 43037fd3..f3642096 100644 --- a/SpigotCore/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java +++ b/SpigotCore/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java @@ -20,7 +20,6 @@ package de.steamwar.core; import de.steamwar.Reflection; -import com.viaversion.viaversion.api.Via; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.BaseComponent; import org.bukkit.Sound; @@ -37,7 +36,7 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { @Override public void sendMessage(Player player, ChatMessageType type, BaseComponent... msg) { - if(type == ChatMessageType.CHAT && Via.getAPI().getPlayerVersion(player.getUniqueId()) >= 759) + if(type == ChatMessageType.CHAT) type = ChatMessageType.SYSTEM; player.spigot().sendMessage(type, msg); @@ -66,19 +65,19 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { Reflection.Field posZ = Reflection.getField(packetClass, double.class, fieldOffset+2); boolean isByteClass = packetClass.getSimpleName().contains("PacketPlayOutEntityTeleport") || packetClass.getSimpleName().contains("PacketPlayOutNamedEntitySpawn"); Class pitchYawType = isByteClass ? byte.class : int.class; - Reflection.Field lookPitch = Reflection.getField(packetClass, pitchYawType, isByteClass ? 0 : 1); - Reflection.Field lookYaw = Reflection.getField(packetClass, pitchYawType, isByteClass ? 1 : 2); + Reflection.Field lookYaw = Reflection.getField(packetClass, pitchYawType, isByteClass ? 0 : 1); + Reflection.Field lookPitch = Reflection.getField(packetClass, pitchYawType, isByteClass ? 1 : 2); return (packet, x, y, z, pitch, yaw) -> { posX.set(packet, x); posY.set(packet, y); posZ.set(packet, z); if (isByteClass) { - lookPitch.set(packet, (byte) (pitch*256/360)); lookYaw.set(packet, (byte) (yaw*256/360)); + lookPitch.set(packet, (byte) (pitch*256/360)); } else { - lookPitch.set(packet, (int) (pitch*256/360)); lookYaw.set(packet, (int) (yaw*256/360)); + lookPitch.set(packet, (int) (pitch*256/360)); } }; } @@ -89,15 +88,15 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { Reflection.Field moveX = Reflection.getField(packetClass, "b", type); Reflection.Field moveY = Reflection.getField(packetClass, "c", type); Reflection.Field moveZ = Reflection.getField(packetClass, "d", type); - Reflection.Field movePitch = Reflection.getField(packetClass, "e", byte.class); - Reflection.Field moveYaw = Reflection.getField(packetClass, "f", byte.class); + Reflection.Field moveYaw = Reflection.getField(packetClass, "e", byte.class); + Reflection.Field movePitch = Reflection.getField(packetClass, "f", byte.class); return (packet, x, y, z, pitch, yaw) -> { moveX.set(packet, (short)(x*4096)); moveY.set(packet, (short)(y*4096)); moveZ.set(packet, (short)(z*4096)); - movePitch.set(packet, (byte)(pitch*256/360)); moveYaw.set(packet, (byte)(yaw*256/360)); + movePitch.set(packet, (byte)(pitch*256/360)); }; } diff --git a/SpigotCore/SpigotCore_Main/build.gradle.kts b/SpigotCore/SpigotCore_Main/build.gradle.kts index 88825bc9..cc941d8c 100644 --- a/SpigotCore/SpigotCore_Main/build.gradle.kts +++ b/SpigotCore/SpigotCore_Main/build.gradle.kts @@ -35,7 +35,6 @@ dependencies { compileOnly(libs.spigotapi) compileOnly(libs.netty) compileOnly(libs.authlib) - compileOnly(libs.viaapi) compileOnly(libs.fastutil) implementation(libs.anvilgui) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java index 61788dfa..e5edcfae 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java @@ -21,7 +21,6 @@ package de.steamwar.core; import de.steamwar.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; -import com.viaversion.viaversion.api.Via; import de.steamwar.sql.internal.Statement; import io.netty.channel.ChannelFuture; import org.bukkit.Bukkit; @@ -99,7 +98,6 @@ class CheckpointUtilsJ9 { Statement.closeAll(); // Close socket - Via.getManager().getInjector().uninject(); Object serverConnection = TinyProtocol.getServerConnection(Core.getInstance()); List channels = channelFutures.get(serverConnection); for(Object future : channels) { @@ -140,7 +138,6 @@ class CheckpointUtilsJ9 { ((ChannelFuture) future).channel().config().setAutoRead(true); } } - Via.getManager().getInjector().inject(); Bukkit.getPluginManager().callEvent(new CRIUWakeupEvent()); Core.getInstance().getLogger().log(Level.INFO, "Checkpoint restored"); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java index b17b2ca8..4e7b7576 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -99,9 +99,6 @@ public class Core extends JavaPlugin{ CheckpointUtils.signalHandler(); new AntiNocom(); - if(Core.getVersion() < 17 && Bukkit.getPluginManager().getPlugin("ViaVersion") != null) - new PartialChunkFixer(); - if(Core.getVersion() >= 19) new ServerDataHandler(); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java index 87906944..9928b947 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java @@ -26,6 +26,7 @@ import com.sk89q.worldedit.session.ClipboardHolder; import de.steamwar.sql.NoClipboardException; import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.regions.Region; +import de.steamwar.sql.NodeData; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.util.Vector; @@ -36,20 +37,22 @@ import java.util.logging.Level; public interface WorldEditWrapper { WorldEditWrapper impl = VersionDependent.getVersionImpl(Core.getInstance()); - InputStream getPlayerClipboard(Player player, boolean schemFormat); - void setPlayerClipboard(Player player, InputStream is, boolean schemFormat); - Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException; + InputStream getPlayerClipboard(Player player); + void setPlayerClipboard(Player player, InputStream is, NodeData.SchematicFormat schemFormat); + Clipboard getClipboard(InputStream is, NodeData.SchematicFormat schemFormat) throws IOException; Vector getOrigin(Clipboard clipboard); Vector getMinimum(Region region); Vector getMaximum(Region region); Vector applyTransform(Vector vector, Transform transform); + NodeData.SchematicFormat getNativeFormat(); + static WorldEditPlugin getWorldEditPlugin() { return (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"); } - public static InputStream getPlayerClipboard(Player player, boolean schemFormat, SchematicWriter consumer) { + static InputStream getPlayerClipboard(Player player, SchematicWriter consumer) { ClipboardHolder clipboardHolder; try { clipboardHolder = WorldEditWrapper.getWorldEditPlugin().getSession(player).getClipboard(); @@ -85,7 +88,7 @@ public interface WorldEditWrapper { return inputStream; } - public static interface SchematicWriter { + interface SchematicWriter { void write(OutputStream outputStream, Clipboard clipboard, ClipboardHolder holder) throws IOException; } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java deleted file mode 100644 index bca606ec..00000000 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2022 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.core.events; - -import de.steamwar.Reflection; -import com.comphenix.tinyprotocol.TinyProtocol; -import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.ViaAPI; -import de.steamwar.core.Core; -import de.steamwar.core.CraftbukkitWrapper; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; - -/** - * TinyProtocol can't translate BlockEntities during 1.16 to 1.17 conversions du to removed partial chunk update support. This class cancels PartialChunkUpdates for this players and sends them a complete chunk instead. - * This class can only be loaded on 1.9 to 1.15 with active ViaVersion. - **/ -public class PartialChunkFixer { - - private static final int PROTOCOL1_17 = 755; - private static final Class mapChunk = Reflection.getClass("{nms}.PacketPlayOutMapChunk"); - private static final Reflection.Field fullChunkFlag = Reflection.getField(mapChunk, boolean.class, 0); - private static final Reflection.Field chunkX = Reflection.getField(mapChunk, int.class, 0); - private static final Reflection.Field chunkZ = Reflection.getField(mapChunk, int.class, 1); - - private final ViaAPI via = Via.getAPI(); - - private final List chunksToResend = new ArrayList<>(); - - public PartialChunkFixer() { - TinyProtocol.instance.addFilter(mapChunk, this::chunkFilter); - Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { - synchronized (chunksToResend) { - for(ResendChunk chunk : chunksToResend) { - CraftbukkitWrapper.impl.sendChunk(chunk.player, chunk.x, chunk.z); - } - chunksToResend.clear(); - } - }, 1, 1); - } - - private Object chunkFilter(Player player, Object packet) { - if(via.getPlayerVersion(player) >= PROTOCOL1_17 && !fullChunkFlag.get(packet)) { - // partial chunk update - synchronized (chunksToResend) { - chunksToResend.add(new ResendChunk(player, chunkX.get(packet), chunkZ.get(packet))); - } - return null; - } - return packet; - } - - private static class ResendChunk { - private final Player player; - private final int x; - private final int z; - - private ResendChunk(Player player, int x, int z) { - this.player = player; - this.x = x; - this.z = z; - } - } -} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWItem.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWItem.java index bc401476..1f9c9813 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWItem.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/inventory/SWItem.java @@ -21,21 +21,19 @@ package de.steamwar.inventory; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import de.steamwar.core.Core; import de.steamwar.core.FlatteningWrapper; import de.steamwar.core.TrickyTrialsWrapper; -import de.steamwar.core.VersionDependent; import org.bukkit.Material; import org.bukkit.OfflinePlayer; -import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import java.util.ArrayList; -import java.util.Collection; +import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.stream.Collectors; public class SWItem { @@ -192,6 +190,11 @@ public class SWItem { itemStack.setItemMeta(itemMeta); } + public void setLore(String... lore) { + itemMeta.setLore(Arrays.stream(lore).collect(Collectors.toList())); + itemStack.setItemMeta(itemMeta); + } + public void setEnchanted(boolean enchanted) { if (enchanted){ itemMeta.addEnchant(TrickyTrialsWrapper.impl.getUnbreakingEnchantment() , 10, true); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java index ecbf86aa..62f00369 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java @@ -36,7 +36,7 @@ import java.util.zip.GZIPInputStream; public class SchematicData { - public static Clipboard clipboardFromStream(InputStream is, boolean schemFormat) { + public static Clipboard clipboardFromStream(InputStream is, NodeData.SchematicFormat schemFormat) { try { return WorldEditWrapper.impl.getClipboard(is, schemFormat); } catch (IOException e) { @@ -61,15 +61,11 @@ public class SchematicData { } public void saveFromPlayer(Player player) throws IOException, NoClipboardException { - saveFromPlayer(player, Core.getVersion() > 12); - } - - public void saveFromPlayer(Player player, boolean newFormat) throws IOException, NoClipboardException { - data.saveFromStream(WorldEditWrapper.impl.getPlayerClipboard(player, newFormat), newFormat); + data.saveFromStream(WorldEditWrapper.impl.getPlayerClipboard(player), WorldEditWrapper.impl.getNativeFormat()); } @Deprecated - public void saveFromBytes(byte[] bytes, boolean newFormat) { + public void saveFromBytes(byte[] bytes, NodeData.SchematicFormat newFormat) { data.saveFromStream(new ByteArrayInputStream(bytes), newFormat); } } diff --git a/SpigotCore/SpigotCore_Main/src/plugin.yml b/SpigotCore/SpigotCore_Main/src/plugin.yml index 75652668..a29249d2 100644 --- a/SpigotCore/SpigotCore_Main/src/plugin.yml +++ b/SpigotCore/SpigotCore_Main/src/plugin.yml @@ -4,7 +4,6 @@ author: Lixfel api-version: "1.13" load: STARTUP softdepend: - - ViaVersion - WorldEdit main: de.steamwar.core.Core diff --git a/SpigotCore/build.gradle.kts b/SpigotCore/build.gradle.kts index b7ff647e..d615cfc7 100644 --- a/SpigotCore/build.gradle.kts +++ b/SpigotCore/build.gradle.kts @@ -40,5 +40,10 @@ dependencies { implementation(project(":SpigotCore:SpigotCore_18")) implementation(project(":SpigotCore:SpigotCore_19")) implementation(project(":SpigotCore:SpigotCore_20")) - implementation(project(":SpigotCore:SpigotCore_21")) + implementation(project(":SpigotCore:SpigotCore_21")) { + attributes { + // Very Hacky, but it works + attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21) + } + } } diff --git a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt index 1d9eb19d..b01dffd9 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt @@ -46,7 +46,6 @@ object GlobalListener: Listener { with(e.player) { teleport(TNTLeagueWorldConfig.lobby) inventory.clear() - isOp = false gameMode = GameMode.SPECTATOR respawnLocation = TNTLeagueWorldConfig.lobby } diff --git a/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt index e48ea7e6..ca379821 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt @@ -27,13 +27,11 @@ import de.steamwar.tntleague.inventory.DealerInventory import de.steamwar.tntleague.util.TNTLeagueScoreboard import org.bukkit.GameMode import org.bukkit.Location -import org.bukkit.Material import org.bukkit.entity.EntityType import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.entity.EntityExplodeEvent import org.bukkit.event.player.PlayerAttemptPickupItemEvent -import org.bukkit.event.player.PlayerDropItemEvent import org.bukkit.event.player.PlayerInteractEntityEvent import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerMoveEvent @@ -74,13 +72,6 @@ object IngameListener: Listener { } } - @EventHandler - fun onDropPickaxe(e: PlayerDropItemEvent) { - if (e.itemDrop.itemStack.type == Material.DIAMOND_PICKAXE) { - e.isCancelled = true - } - } - @EventHandler fun onPickupCoins(e: PlayerAttemptPickupItemEvent) { if (e.item.itemStack.isSimilar(DealerInventory.coins)) { diff --git a/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java b/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java index 072f1467..9050255e 100644 --- a/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java +++ b/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java @@ -220,25 +220,22 @@ public class Subserver { try { if (checkpoint) { start(process.getErrorStream(), line -> line.contains("Restore finished successfully.")); + Thread.sleep(300); //Wait for port to be reopened } else { start(process.getInputStream(), line -> { if (line.contains("Loading libraries, please wait")) sendProgress(2); else if (line.contains("Starting Minecraft server on")) - sendProgress(4); + sendProgress(5); else if (line.contains("Preparing start region")) - sendProgress(6); - return line.contains("Finished mapping loading"); + sendProgress(8); + return line.contains("Done ("); }); } if (!started) return; - sendProgress(8); - - Thread.sleep(300); - sendProgress(10); for (Player cachedPlayer : cachedPlayers) { sendPlayer(cachedPlayer); diff --git a/VelocityCore/build.gradle.kts b/VelocityCore/build.gradle.kts index 78603f8c..844e9f21 100644 --- a/VelocityCore/build.gradle.kts +++ b/VelocityCore/build.gradle.kts @@ -47,6 +47,8 @@ java { dependencies { annotationProcessor(libs.velocityapi) compileOnly(libs.velocity) + compileOnly(libs.viaapi) + compileOnly(libs.viavelocity) compileOnly(project(":VelocityCore:Persistent", "default")) @@ -61,6 +63,7 @@ dependencies { } implementation(libs.msgpack) - implementation(libs.apolloprotos) + + implementation(libs.nbt) } \ No newline at end of file diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index b133d99b..887a73d6 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -626,6 +626,7 @@ WHOIS_ID=§7ID§8: §e{0} WHOIS_PERMS=§7Perms§8: §7{0} WHOIS_DISCORD_ID=§7Discord-ID§8: §e{0} WHOIS_JOINED_FIRST=§7Joined on§8: §e{0} +WHOIS_LAST_ONLINE=§7Last on§8: §e{0} WHOIS_HOURS_PLAYED=§7Online Time§8: §e{0}h WHOIS_CURRENT_PLAYED=§7Current Online Time§8: §e{0}m WHOIS_CURRENT_SERVER=§7Current Server§8: §e{0} @@ -728,6 +729,9 @@ MOD_ITEM_BACK=§7Back INV_PAGE_BACK=§{0}Seite zurück INV_PAGE_NEXT=§{0}Seite vor +#VersionAnnouncer +SERVER_VERSION=§7This server runs on Minecraft version §e{0} + #Discord DC_UNLINKED=For this action your Discord account has to be linked to your Minecraft account. To link your accounts go onto the SteamWar Discord to the `regeln-infos` Channel and click on `Minecraft Verknüpfen`. DC_TITLE_SCHEMINFO=Schematic Info diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index 9299064f..364988e1 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -602,6 +602,7 @@ WHOIS_UUID_HOVER=§eUUID Kopieren WHOIS_ID=§7ID§8: §e{0} WHOIS_DISCORD_ID=§7Discord-ID§8: §e{0} WHOIS_JOINED_FIRST=§7Beigetreten am§8: §e{0} +WHOIS_LAST_ONLINE=§7Zuletzt online§8: §e{0} WHOIS_HOURS_PLAYED=§7Spielzeit§8: §e{0}h WHOIS_CURRENT_PLAYED=§7Aktuell online§8: §e{0}m WHOIS_CURRENT_SERVER=§7Aktueller Server§8: §e{0} @@ -681,6 +682,9 @@ ADVENT_CALENDAR_OPEN=§7Du hast §e{0}§7 aus dem Adventskalender erhalten! INV_PAGE_BACK=§{0}Page back INV_PAGE_NEXT=§{0}Next page +#VersionAnnouncer +SERVER_VERSION=§7Dieser Server läuft auf Minecraft-Version §e{0} + #Discord DC_UNLINKED=Für diese Aktion muss dein Minecraftaccount mit deinem Discordaccount verknüpft sein, gehe dazu auf dem SteamWar-Discord in den `regeln-infos` Channel und Klicke auf `Minecraft Verknüpfen`. DC_TITLE_SCHEMINFO=Schematicinfo diff --git a/VelocityCore/src/de/steamwar/velocitycore/GameModeConfig.java b/VelocityCore/src/de/steamwar/velocitycore/GameModeConfig.java index 8dab4d8d..208f6df3 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/GameModeConfig.java +++ b/VelocityCore/src/de/steamwar/velocitycore/GameModeConfig.java @@ -27,10 +27,14 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.BiConsumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Getter public class GameModeConfig { + private static final Pattern terminatingNumber = Pattern.compile("(\\d+)$"); + public static void loadAll(Class config, BiConsumer consumer) { File folder = new File(VelocityCore.get().getDataDirectory().getParent().toFile(), "FightSystem"); if(!folder.exists()) @@ -51,9 +55,9 @@ public class GameModeConfig { @Getter public static class Server { private String Folder; - private String ServerJar; private List ChatNames = Collections.emptyList(); private List Maps; + private boolean Spigot = false; private boolean Ranked = false; private boolean Historic = false; } @@ -66,8 +70,10 @@ public class GameModeConfig { private boolean ManualCheck = true; } - public String getServerJar() { - return getServer().getServerJar(); + public ServerVersion getVersion() { + Matcher matcher = terminatingNumber.matcher(getServer().getFolder()); + matcher.find(); + return ServerVersion.valueOf((getServer().isSpigot() ? "SPIGOT_" : "PAPER_") + matcher.group(1)); } public String getFolder() { diff --git a/VelocityCore/src/de/steamwar/velocitycore/Node.java b/VelocityCore/src/de/steamwar/velocitycore/Node.java index b97ef0ba..23cf808a 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/Node.java +++ b/VelocityCore/src/de/steamwar/velocitycore/Node.java @@ -63,7 +63,7 @@ public abstract class Node { nodes.forEach(consumer); } - public abstract ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams); + public abstract ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String... dParams); protected abstract ProcessBuilder prepareExecution(String... command); protected abstract void calcLoadLimit(); @@ -95,7 +95,7 @@ public abstract class Node { return hostname; } - protected void constructServerstart(File directory, List cmd, String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams) { + protected void constructServerstart(File directory, List cmd, String serverJar, String worldDir, String levelName, int port, String... dParams) { if (JAVA_8.contains(serverJar)) cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java"); else @@ -105,7 +105,7 @@ public abstract class Node { cmd.add("-D" + param); } cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName()); - cmd.add("-Xmx" + xmx); + cmd.add("-Xmx768M"); cmd.addAll(OPENJ9_ARGS); if (!JAVA_8.contains(serverJar)) { cmd.add("--add-opens"); @@ -142,9 +142,9 @@ public abstract class Node { } @Override - public ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams) { + public ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String... dParams) { List cmd = new ArrayList<>(); - constructServerstart(directory, cmd, serverJar, worldDir, levelName, port, xmx, dParams); + constructServerstart(directory, cmd, serverJar, worldDir, levelName, port, dParams); ProcessBuilder builder = new ProcessBuilder(cmd); builder.directory(directory); return builder; @@ -174,7 +174,7 @@ public abstract class Node { } @Override - public ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams) { + public ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String... dParams) { List cmd = new ArrayList<>(); cmd.add("ssh"); cmd.add("-L"); @@ -183,7 +183,7 @@ public abstract class Node { cmd.add("cd"); cmd.add(directory.getPath()); cmd.add(";"); - constructServerstart(directory, cmd, serverJar, worldDir, levelName, port, xmx, dParams); + constructServerstart(directory, cmd, serverJar, worldDir, levelName, port, dParams); return new ProcessBuilder(cmd); } diff --git a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java index 1b834390..0fbdf696 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java @@ -20,6 +20,8 @@ package de.steamwar.velocitycore; import com.velocitypowered.api.proxy.Player; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.velocity.platform.VelocityViaConfig; import de.steamwar.messages.Chatter; import de.steamwar.persistent.Arenaserver; import de.steamwar.persistent.Bauserver; @@ -56,8 +58,7 @@ public class ServerStarter { private String worldDir = null; private Node node = null; - private String serverJar = "spigot-1.15.2.jar"; - private String xmx = "768M"; + private ServerVersion version = ServerVersion.PAPER_20; private Portrange portrange = BAU_PORTS; private Function serverNameProvider = port -> node.getName() + port; private BooleanSupplier startCondition = () -> true; @@ -78,7 +79,7 @@ public class ServerStarter { public ServerStarter arena(ArenaMode mode, String map) { portrange = ARENA_PORTS; serverNameProvider = port -> mode.getGameName() + (port - portrange.start); - serverJar = mode.getServerJar(); + version = mode.getVersion(); allowMerge = true; fightMap = map; gameMode = mode.getInternalName(); @@ -145,8 +146,8 @@ public class ServerStarter { } public ServerStarter build(ServerVersion version, UUID owner) { + this.version = version; directory = version.getServerDirectory("Bau"); - serverJar = version.getServerJar(); worldDir = version.getWorldFolder(WORLDS_BASE_PATH); worldName = version != ServerVersion.SPIGOT_12 ? String.valueOf(SteamwarUser.get(owner).getId()) : owner.toString(); checkpoint = true; @@ -219,7 +220,7 @@ public class ServerStarter { } public ServerStarter builder(ServerVersion version, String map, File generator) { - serverJar = version.getServerJar(); + this.version = version; directory = version.getServerDirectory("Builder"); worldDir = version.getWorldFolder(BUILDER_BASE_PATH); worldName = map; @@ -294,6 +295,7 @@ public class ServerStarter { if(checkpoint) arguments.put("checkpoint", checkpointDir.getPath()); + ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols().put(serverName, version.getProtocolVersion().getProtocol()); if(checkpoint && checkpointDir.exists()) { try(DataOutputStream out = new DataOutputStream(Files.newOutputStream(new File(checkpointDir, "port").toPath()))) { out.writeInt(port); @@ -313,7 +315,7 @@ public class ServerStarter { private void regularStart(String serverName, int port) { postStart(constructor.construct(serverName, port, node.startServer( - serverJar, directory, worldDir, worldName, port, xmx, arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new) + version.getServerJar(), directory, worldDir, worldName, port, arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new) ), worldCleanup, null)); } diff --git a/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java b/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java index 31b8e39e..fd505e77 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java @@ -19,6 +19,8 @@ package de.steamwar.velocitycore; +import com.velocitypowered.api.network.ProtocolVersion; +import lombok.AllArgsConstructor; import lombok.Getter; import java.io.File; @@ -27,12 +29,23 @@ import java.util.Map; import java.util.Set; @Getter +@AllArgsConstructor public enum ServerVersion { - SPIGOT_12("spigot-1.12.2.jar", 12), - SPIGOT_15("spigot-1.15.2.jar", 15), - PAPER_19("paper-1.19.3.jar", 19), - PAPER_20("paper-1.20.1.jar", 20), - PAPER_21("paper-1.21.jar", 21); + SPIGOT_8("spigot-1.8.8.jar", 8, ProtocolVersion.MINECRAFT_1_8), + SPIGOT_9("spigot-1.9.4.jar", 9, ProtocolVersion.MINECRAFT_1_9), + SPIGOT_10("spigot-1.10.2.jar", 10, ProtocolVersion.MINECRAFT_1_10), + SPIGOT_12("spigot-1.12.2.jar", 12, ProtocolVersion.MINECRAFT_1_12_2), + SPIGOT_14("spigot-1.14.4.jar", 14, ProtocolVersion.MINECRAFT_1_14_4), + SPIGOT_15("spigot-1.15.2.jar", 15, ProtocolVersion.MINECRAFT_1_15_2), + + PAPER_8("paper-1.8.8.jar", 8, ProtocolVersion.MINECRAFT_1_8), + PAPER_10("paper-1.10.2.jar", 10, ProtocolVersion.MINECRAFT_1_10), + PAPER_12("paper-1.12.2.jar", 12, ProtocolVersion.MINECRAFT_1_12_2), + PAPER_15("paper-1.15.2.jar", 15, ProtocolVersion.MINECRAFT_1_15_2), + PAPER_18("paper-1.18.2.jar", 15, ProtocolVersion.MINECRAFT_1_18_2), + PAPER_19("paper-1.19.3.jar", 19, ProtocolVersion.MINECRAFT_1_19_3), + PAPER_20("paper-1.20.1.jar", 20, ProtocolVersion.MINECRAFT_1_20), + PAPER_21("paper-1.21.jar", 21, ProtocolVersion.MINECRAFT_1_21_2); private static final Map chatMap = new HashMap<>(); @@ -76,11 +89,7 @@ public enum ServerVersion { private final String serverJar; private final int versionSuffix; - - ServerVersion(String serverJar, int versionSuffix) { - this.serverJar = serverJar; - this.versionSuffix = versionSuffix; - } + private final ProtocolVersion protocolVersion; public String getWorldFolder(String base) { return base + versionSuffix + "/"; diff --git a/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java b/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java index 6a5b3ade..5e6dca1d 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java +++ b/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java @@ -152,6 +152,7 @@ public class VelocityCore implements ReloadablePlugin { new BanListener(); new CheckListener(); new IPSanitizer(); + new VersionAnnouncer(); local = new Node.LocalNode(); if(MAIN_SERVER) { diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java index 6512c9c0..4daa5b78 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java @@ -20,15 +20,15 @@ package de.steamwar.velocitycore.commands; import com.velocitypowered.api.proxy.Player; -import de.steamwar.persistent.Storage; -import de.steamwar.velocitycore.VelocityCore; -import de.steamwar.velocitycore.mods.ModUtils; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; +import de.steamwar.persistent.Storage; import de.steamwar.sql.*; +import de.steamwar.velocitycore.VelocityCore; +import de.steamwar.velocitycore.mods.ModUtils; import lombok.AllArgsConstructor; import lombok.Getter; import net.kyori.adventure.text.event.ClickEvent; @@ -86,9 +86,12 @@ public class WhoisCommand extends SWCommand { if(firstJoin == null && target != null) { firstJoin = Storage.sessions.get(target); } + Timestamp lastOnline = user.getLastOnline(); if(firstJoin != null) sender.system("WHOIS_JOINED_FIRST", firstJoin.toString()); + if (lastOnline != null) + sender.system("WHOIS_LAST_ONLINE", lastOnline.toString()); sender.system("WHOIS_HOURS_PLAYED", new DecimalFormat("###.##").format(onlineTime / 3600d)); if(target != null) { diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordSchemUpload.java b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordSchemUpload.java index 037eadcd..68b8d360 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordSchemUpload.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordSchemUpload.java @@ -25,10 +25,13 @@ import de.steamwar.sql.NodeData; import de.steamwar.sql.Punishment; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; +import dev.dewy.nbt.Nbt; +import dev.dewy.nbt.tags.collection.CompoundTag; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; +import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; @@ -38,6 +41,8 @@ import java.util.logging.Level; public class DiscordSchemUpload extends ListenerAdapter { + private static final Nbt NBT = new Nbt(); + private static final List SCHEM_FILE_ENDINGS = Arrays.asList(".schem", ".schematic"); @Override @@ -79,7 +84,17 @@ public class DiscordSchemUpload extends ListenerAdapter { node = SchematicNode.createSchematic(user.getId(), name, null); try (InputStream in = attachment.getProxy().download().get()) { - NodeData.get(node).saveFromStream(in, fileName.substring(dot).equalsIgnoreCase(".schem")); + CompoundTag tags = NBT.fromStream(new DataInputStream(in)); + + NodeData.SchematicFormat version = NodeData.SchematicFormat.SPONGE_V2; + + if (tags.size() == 1) { + version = NodeData.SchematicFormat.SPONGE_V3; + } else if (tags.contains("Materials")) { + version = NodeData.SchematicFormat.MCEDIT; + } + + NodeData.get(node).saveFromStream(in, version); sender.system("DC_SCHEMUPLOAD_SUCCESS", name); } catch (InterruptedException e) { Thread.currentThread().interrupt(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java index a9592c6c..f32b4767 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java @@ -41,12 +41,12 @@ import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.utils.SplitUtil; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; import net.kyori.adventure.text.event.ClickEvent; import org.jetbrains.annotations.NotNull; import java.awt.*; import java.time.Instant; -import java.util.Collections; import java.util.LinkedList; import java.util.stream.Collectors; @@ -112,9 +112,12 @@ public class DiscordTicketHandler extends ListenerAdapter { .setTimestamp(Instant.now()) .setTitle(event.getChannel().getName()); + User user; if(channel.getTopic() != null && !channel.getTopic().isEmpty()) { - User user = event.getJDA().retrieveUserById(channel.getTopic()).complete(); + user = event.getJDA().retrieveUserById(channel.getTopic()).complete(); embedBuilder.setAuthor(user.getName(), null, user.getAvatarUrl()); + } else { + user = null; } TextChannel logChannel = event.getGuild().getTextChannelById(TICKET_LOG); @@ -124,7 +127,14 @@ public class DiscordTicketHandler extends ListenerAdapter { 2000, SplitUtil.Strategy.NEWLINE, SplitUtil.Strategy.ANYWHERE - ).stream().map(message -> new MessageCreateBuilder().setEmbeds(embedBuilder.setDescription(message).build())).forEach(builder -> logChannel.sendMessage(builder.build()).queue()); + ).stream().map(message -> new MessageCreateBuilder().setEmbeds(embedBuilder.setDescription(message).build())) + .forEach(builder -> { + MessageCreateData createData = builder.build(); + logChannel.sendMessage(createData).queue(); + if (user != null) { + user.openPrivateChannel().queue(privateChannel -> privateChannel.sendMessage(createData).queue()); + } + }); Chatter.serverteam().prefixless("DISCORD_TICKET_CLOSED", channel.getName()); channel.delete().reason("Closed").queue(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/VersionAnnouncer.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/VersionAnnouncer.java new file mode 100644 index 00000000..c28a8fee --- /dev/null +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/VersionAnnouncer.java @@ -0,0 +1,47 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.ServerConnectedEvent; +import com.velocitypowered.api.network.ProtocolVersion; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.server.ServerInfo; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.velocity.platform.VelocityViaConfig; +import de.steamwar.messages.Chatter; +import de.steamwar.persistent.Subserver; + +public class VersionAnnouncer extends BasicListener { + + @Subscribe + public void postConnect(ServerConnectedEvent e) { + ServerInfo server = e.getServer().getServerInfo(); + if(!Subserver.isBuild(Subserver.getSubserver(server))) + return; + + Player player = e.getPlayer(); + int serverVersion = ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols().get(server.getName()); + if(Via.getAPI().getPlayerVersion(player) == serverVersion) + return; + + player.sendActionBar(Chatter.of(player).parse("SERVER_VERSION", ProtocolVersion.getProtocolVersion(serverVersion).getMostRecentSupportedVersion())); + } +} diff --git a/WebsiteBackend/build.gradle.kts b/WebsiteBackend/build.gradle.kts index 2cf527a7..d58a5142 100644 --- a/WebsiteBackend/build.gradle.kts +++ b/WebsiteBackend/build.gradle.kts @@ -53,4 +53,5 @@ dependencies { implementation(libs.yamlconfig) implementation(libs.kotlinxSerializationCbor) implementation(libs.ktorRateLimit) + implementation(libs.nbt) } \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/routes/Schematic.kt b/WebsiteBackend/src/de/steamwar/routes/Schematic.kt index b873b97d..c4d76f80 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Schematic.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Schematic.kt @@ -22,10 +22,13 @@ package de.steamwar.routes import de.steamwar.plugins.SWAuthPrincipal import de.steamwar.plugins.SWPermissionCheck import de.steamwar.sql.NodeData +import de.steamwar.sql.NodeData.SchematicFormat import de.steamwar.sql.NodeDownload import de.steamwar.sql.NodeMember import de.steamwar.sql.SWException import de.steamwar.sql.SchematicNode +import dev.dewy.nbt.Nbt +import dev.dewy.nbt.tags.collection.CompoundTag import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.auth.* @@ -33,6 +36,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromByteArray import java.security.MessageDigest import java.time.Duration import java.time.Instant @@ -71,6 +75,8 @@ data class SchematicCode(val id: Int, val code: String, val expires: Long) @Serializable data class UploadSchematic(val name: String, val content: String) +val nbt = Nbt() + fun Route.configureSchematic() { route("/download/{code}") { get { @@ -88,7 +94,7 @@ fun Route.configureSchematic() { return@get } - call.response.header("Content-Disposition", "attachment; filename=\"${node.name}.${if (data.nodeFormat) "schem" else "schematic"}\"") + call.response.header("Content-Disposition", "attachment; filename=\"${node.name}${data.nodeFormat.fileEnding}\"") call.respondBytes(data.schemData().readAllBytes(), contentType = ContentType.Application.OctetStream, status = HttpStatusCode.OK) } get("/info") { @@ -112,16 +118,34 @@ fun Route.configureSchematic() { val user = call.principal()!!.user - val content = Base64.getDecoder().decode(file.content) var node = SchematicNode.getSchematicNode(user.id, schemName, 0) if (node == null) { node = SchematicNode.createSchematic(user.id, schemName, 0) } - val data = NodeData(node.id, false) - data.saveFromStream(content.inputStream(), schemType == "schem") + try { + val content = Base64.getDecoder().decode(file.content) - call.respond(ResponseSchematic(node)) + var schem = nbt.fromByteArray(content) + + if (schem.size() == 1) schem = schem.first() as CompoundTag + + val version = schem.let { + if (it.contains("Materials")) + return@let SchematicFormat.MCEDIT + else if (it.contains("Blocks")) + return@let SchematicFormat.SPONGE_V3 + else + return@let SchematicFormat.SPONGE_V2 + } + + val data = NodeData(node.id, version) + data.saveFromStream(content.inputStream(), version) + + call.respond(ResponseSchematic(node)) + } catch (e: Exception) { + call.respond(HttpStatusCode.BadRequest) + } } } } diff --git a/settings.gradle.kts b/settings.gradle.kts index a29c0412..b0fb3f72 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -116,7 +116,6 @@ dependencyResolutionManagement { library("authlib", "com.mojang:authlib:1.5.25") library("datafixer", "com.mojang:datafixerupper:4.0.26") library("brigadier", "com.mojang:brigadier:1.0.18") - library("viaapi", "com.viaversion:viaversion-api:4.3.1") library("anvilgui", "net.wesjd:anvilgui:1.10.3-SNAPSHOT") library("nms8", "de.steamwar:spigot:1.8") @@ -138,6 +137,8 @@ dependencyResolutionManagement { library("velocity", "de.steamwar:velocity:RELEASE") library("velocityapi", "com.velocitypowered:velocity-api:3.3.0-SNAPSHOT") + library("viaapi", "com.viaversion:viaversion-api:4.3.1") + library("viavelocity", "com.viaversion:viaversion-velocity:4.3.1") library("jda", "net.dv8tion:JDA:5.2.0") library("msgpack", "org.msgpack:msgpack-core:0.9.8") library("apolloprotos", "com.lunarclient:apollo-protos:1.0-SNAPSHOT") @@ -164,6 +165,8 @@ dependencyResolutionManagement { library("yamlconfig", "org.bspfsystems:yamlconfiguration:1.3.0") library("kotlinxSerializationCbor", "org.jetbrains.kotlinx:kotlinx-serialization-cbor:1.4.1") library("ktorRateLimit", "io.ktor:ktor-server-rate-limit:$ktorVersion") + + library("nbt", "dev.dewy:nbt:1.5.1") } } }