diff --git a/CommonCore b/CommonCore index 1237a69..d000b86 160000 --- a/CommonCore +++ b/CommonCore @@ -1 +1 @@ -Subproject commit 1237a699ba244ecfac65478df34e714afbe2366e +Subproject commit d000b8687d93eb43520bbf6685281099055eab9f diff --git a/SpigotCore_21/build.gradle b/SpigotCore_21/build.gradle new file mode 100644 index 0000000..cdcd092 --- /dev/null +++ b/SpigotCore_21/build.gradle @@ -0,0 +1,51 @@ +/* + * 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 . + */ + +plugins { + id 'base' + id 'java' +} + +group 'steamwar' +version '1.0' + +compileJava.options.encoding = 'UTF-8' + +sourceSets { + main { + java { + srcDirs = ['src/'] + } + resources { + srcDirs = ['src/'] + exclude '**/*.java', '**/*.kt' + } + } +} + +dependencies { + compileOnly project(":SpigotCore_Main") + + compileOnly 'io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT' +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} diff --git a/SpigotCore_21/src/de/steamwar/scoreboard/SWScoreboard21.java b/SpigotCore_21/src/de/steamwar/scoreboard/SWScoreboard21.java new file mode 100644 index 0000000..bc89850 --- /dev/null +++ b/SpigotCore_21/src/de/steamwar/scoreboard/SWScoreboard21.java @@ -0,0 +1,75 @@ +/* + * 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.scoreboard; + +import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.core.Core; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; + +import java.util.HashMap; +import java.util.Map; + +public class SWScoreboard21 implements SWScoreboard.ISWScoreboard { + + private static final HashMap playerBoards = new HashMap<>(); + private static final String SIDEBAR = "sw-sidebar"; + + static { + Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { + for(Map.Entry scoreboard : playerBoards.entrySet()) { + render(scoreboard.getKey(), scoreboard.getValue()); + } + }, 5, 10); + } + + private static void render(Player player, ScoreboardCallback callback) { + if (player.getScoreboard().getObjective(SIDEBAR) != null) { + player.getScoreboard().getObjective(SIDEBAR).unregister(); + } + + Objective objective = player.getScoreboard().registerNewObjective(SIDEBAR, "dummy", Component.text(callback.getTitle())); + objective.setAutoUpdateDisplay(true); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + + callback.getData().forEach((text, score) -> objective.getScore(text).setScore(score)); + } + + @Override + public boolean createScoreboard(Player player, ScoreboardCallback callback) { + Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + player.setScoreboard(scoreboard); + + render(player, callback); + + playerBoards.put(player, callback); + return true; + } + + @Override + public void removeScoreboard(Player player) { + player.getScoreboard().getObjective(SIDEBAR).unregister(); + playerBoards.remove(player); + } +} diff --git a/SpigotCore_8/src/de/steamwar/scoreboard/SWScoreboard8.java b/SpigotCore_8/src/de/steamwar/scoreboard/SWScoreboard8.java new file mode 100644 index 0000000..3af0fc9 --- /dev/null +++ b/SpigotCore_8/src/de/steamwar/scoreboard/SWScoreboard8.java @@ -0,0 +1,115 @@ +/* + * 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.scoreboard; + +import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.core.Core; +import de.steamwar.core.FlatteningWrapper; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +public class SWScoreboard8 implements SWScoreboard.ISWScoreboard { + private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(FlatteningWrapper.scoreboardObjective, String.class, 0); + private static final Reflection.FieldAccessor scoreboardAction = Reflection.getField(FlatteningWrapper.scoreboardObjective, int.class, Core.getVersion() > 15 ? 3 : 0); + private static final Class scoreboardDisplayEnum = Reflection.getClass("{nms.world.scores.criteria}.IScoreboardCriteria$EnumScoreboardHealthDisplay"); + private static final Reflection.FieldAccessor scoreboardDisplayType = Reflection.getField(FlatteningWrapper.scoreboardObjective, scoreboardDisplayEnum, 0); + private static final Object displayTypeIntegers = scoreboardDisplayEnum.getEnumConstants()[0]; + + private static final Reflection.FieldAccessor scoreName = Reflection.getField(FlatteningWrapper.scoreboardScore, String.class, 0); + private static final Reflection.FieldAccessor scoreScoreboardName = Reflection.getField(FlatteningWrapper.scoreboardScore, String.class, 1); + private static final Reflection.FieldAccessor scoreValue = Reflection.getField(FlatteningWrapper.scoreboardScore, int.class, 0); + + private static final HashMap playerBoards = new HashMap<>(); //Object -> Scoreboard | Alle Versionen in der Map! + private static int toggle = 0; // Scoreboard 0 updates while scoreboard 1 is presenting. toggle marks the current active scoreboard + + private static final String SIDEBAR = "Sidebar"; + private static final Object[] DELETE_SCOREBOARD = new Object[2]; + private static final Object[] DISPLAY_SIDEBAR = new Object[2]; + + static { + Class scoreboardDisplayObjective = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutScoreboardDisplayObjective"); + Reflection.FieldAccessor scoreboardDisplayName = Reflection.getField(scoreboardDisplayObjective, String.class, 0); + Reflection.FieldAccessor scoreboardDisplaySlot = Reflection.getField(scoreboardDisplayObjective, int.class, 0); + for(int id = 0; id < 2; id++) { + DELETE_SCOREBOARD[id] = Reflection.newInstance(FlatteningWrapper.scoreboardObjective); + scoreboardName.set(DELETE_SCOREBOARD[id], SIDEBAR + id); + scoreboardAction.set(DELETE_SCOREBOARD[id], 1); //1 to remove + + DISPLAY_SIDEBAR[id] = Reflection.newInstance(scoreboardDisplayObjective); + scoreboardDisplayName.set(DISPLAY_SIDEBAR[id], SIDEBAR + id); + scoreboardDisplaySlot.set(DISPLAY_SIDEBAR[id], 1); // 1 = Sidebar + } + + Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { + toggle ^= 1; // Toggle between 0 and 1 + + for(Map.Entry scoreboard : playerBoards.entrySet()) { + Player player = scoreboard.getKey(); + ScoreboardCallback callback = scoreboard.getValue(); + + TinyProtocol.instance.sendPacket(player, DELETE_SCOREBOARD[toggle]); + TinyProtocol.instance.sendPacket(player, createSidebarPacket(callback.getTitle())); + for(Map.Entry score : callback.getData().entrySet()){ + TinyProtocol.instance.sendPacket(player, createScorePacket(score.getKey(), score.getValue())); + } + + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + if(!player.isOnline()) + return; + TinyProtocol.instance.sendPacket(player, DISPLAY_SIDEBAR[toggle]); + }, 2); + } + }, 10, 5); + } + + public boolean createScoreboard(Player player, ScoreboardCallback callback) { + playerBoards.put(player, callback); + return true; + } + + public void removeScoreboard(Player player) { + if(playerBoards.remove(player) == null || !player.isOnline()) + return; + + TinyProtocol.instance.sendPacket(player, DELETE_SCOREBOARD[toggle]); + } + + private static Object createSidebarPacket(String name){ + Object packet = Reflection.newInstance(FlatteningWrapper.scoreboardObjective); + scoreboardName.set(packet, SIDEBAR + toggle); + scoreboardAction.set(packet, 0); //0 to create + FlatteningWrapper.impl.setScoreboardTitle(packet, name); + scoreboardDisplayType.set(packet, displayTypeIntegers); + return packet; + } + + private static Object createScorePacket(String name, int value){ + Object packet = Reflection.newInstance(FlatteningWrapper.scoreboardScore); + scoreName.set(packet, name); + scoreScoreboardName.set(packet, SIDEBAR + toggle); + scoreValue.set(packet, value); + FlatteningWrapper.impl.setScoreAction(packet); + return packet; + } +} diff --git a/SpigotCore_Main/build.gradle b/SpigotCore_Main/build.gradle index 0db32c5..01a8882 100644 --- a/SpigotCore_Main/build.gradle +++ b/SpigotCore_Main/build.gradle @@ -44,16 +44,16 @@ sourceSets { dependencies { compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT' - compileOnly 'io.netty:netty-all:4.1.68.Final' + compileOnly 'io.netty:netty-all:4.1.107.Final' compileOnly 'com.mojang:authlib:1.5.25' - compileOnly 'mysql:mysql-connector-java:5.1.49' + compileOnly 'com.mysql:mysql-connector-j:8.3.0' compileOnly 'com.viaversion:viaversion-api:4.3.1' compileOnly 'it.unimi.dsi:fastutil:8.5.6' compileOnly swdep("WorldEdit-1.12") implementation 'net.wesjd:anvilgui:1.7.0-SNAPSHOT' - compileOnly 'org.projectlombok:lombok:1.18.22' - annotationProcessor 'org.projectlombok:lombok:1.18.22' + compileOnly 'org.projectlombok:lombok:1.18.34' + annotationProcessor 'org.projectlombok:lombok:1.18.34' compileOnly project(":CommonCore") } diff --git a/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore_Main/src/de/steamwar/core/Core.java index 7e0b371..658eeb7 100644 --- a/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -44,7 +44,8 @@ public class Core extends JavaPlugin{ public static final Message MESSAGE = new Message("SpigotCore", Core.class.getClassLoader()); - private static final int VERSION = Integer.parseInt(Bukkit.getServer().getClass().getPackage().getName().split("_", 3)[1]); + private static final String[] version = Bukkit.getServer().getBukkitVersion().split("-")[0].split("\\."); + private static final int VERSION = Integer.parseInt(version[1]); public static int getVersion(){ return VERSION; diff --git a/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java b/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java index 440e29a..5fd8808 100644 --- a/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java +++ b/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java @@ -19,99 +19,25 @@ package de.steamwar.scoreboard; -import com.comphenix.tinyprotocol.Reflection; -import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.core.Core; -import de.steamwar.core.FlatteningWrapper; -import org.bukkit.Bukkit; +import de.steamwar.core.VersionDependent; import org.bukkit.entity.Player; -import java.util.HashMap; -import java.util.Map; - public class SWScoreboard { private SWScoreboard() {} - private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(FlatteningWrapper.scoreboardObjective, String.class, 0); - private static final Reflection.FieldAccessor scoreboardAction = Reflection.getField(FlatteningWrapper.scoreboardObjective, int.class, Core.getVersion() > 15 ? 3 : 0); - private static final Class scoreboardDisplayEnum = Reflection.getClass("{nms.world.scores.criteria}.IScoreboardCriteria$EnumScoreboardHealthDisplay"); - private static final Reflection.FieldAccessor scoreboardDisplayType = Reflection.getField(FlatteningWrapper.scoreboardObjective, scoreboardDisplayEnum, 0); - private static final Object displayTypeIntegers = scoreboardDisplayEnum.getEnumConstants()[0]; - - private static final Reflection.FieldAccessor scoreName = Reflection.getField(FlatteningWrapper.scoreboardScore, String.class, 0); - private static final Reflection.FieldAccessor scoreScoreboardName = Reflection.getField(FlatteningWrapper.scoreboardScore, String.class, 1); - private static final Reflection.FieldAccessor scoreValue = Reflection.getField(FlatteningWrapper.scoreboardScore, int.class, 0); - - private static final HashMap playerBoards = new HashMap<>(); //Object -> Scoreboard | Alle Versionen in der Map! - private static int toggle = 0; // Scoreboard 0 updates while scoreboard 1 is presenting. toggle marks the current active scoreboard - - private static final String SIDEBAR = "Sidebar"; - private static final Object[] DELETE_SCOREBOARD = new Object[2]; - private static final Object[] DISPLAY_SIDEBAR = new Object[2]; - - static { - Class scoreboardDisplayObjective = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutScoreboardDisplayObjective"); - Reflection.FieldAccessor scoreboardDisplayName = Reflection.getField(scoreboardDisplayObjective, String.class, 0); - Reflection.FieldAccessor scoreboardDisplaySlot = Reflection.getField(scoreboardDisplayObjective, int.class, 0); - for(int id = 0; id < 2; id++) { - DELETE_SCOREBOARD[id] = Reflection.newInstance(FlatteningWrapper.scoreboardObjective); - scoreboardName.set(DELETE_SCOREBOARD[id], SIDEBAR + id); - scoreboardAction.set(DELETE_SCOREBOARD[id], 1); //1 to remove - - DISPLAY_SIDEBAR[id] = Reflection.newInstance(scoreboardDisplayObjective); - scoreboardDisplayName.set(DISPLAY_SIDEBAR[id], SIDEBAR + id); - scoreboardDisplaySlot.set(DISPLAY_SIDEBAR[id], 1); // 1 = Sidebar - } - - Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { - toggle ^= 1; // Toggle between 0 and 1 - - for(Map.Entry scoreboard : playerBoards.entrySet()) { - Player player = scoreboard.getKey(); - ScoreboardCallback callback = scoreboard.getValue(); - - TinyProtocol.instance.sendPacket(player, DELETE_SCOREBOARD[toggle]); - TinyProtocol.instance.sendPacket(player, createSidebarPacket(callback.getTitle())); - for(Map.Entry score : callback.getData().entrySet()){ - TinyProtocol.instance.sendPacket(player, createScorePacket(score.getKey(), score.getValue())); - } - - Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { - if(!player.isOnline()) - return; - TinyProtocol.instance.sendPacket(player, DISPLAY_SIDEBAR[toggle]); - }, 2); - } - }, 10, 5); - } + private static final ISWScoreboard impl = VersionDependent.getVersionImpl(Core.getInstance()); public static boolean createScoreboard(Player player, ScoreboardCallback callback) { - playerBoards.put(player, callback); - return true; + return impl.createScoreboard(player, callback); } public static void removeScoreboard(Player player) { - if(playerBoards.remove(player) == null || !player.isOnline()) - return; - - TinyProtocol.instance.sendPacket(player, DELETE_SCOREBOARD[toggle]); + impl.removeScoreboard(player); } - private static Object createSidebarPacket(String name){ - Object packet = Reflection.newInstance(FlatteningWrapper.scoreboardObjective); - scoreboardName.set(packet, SIDEBAR + toggle); - scoreboardAction.set(packet, 0); //0 to create - FlatteningWrapper.impl.setScoreboardTitle(packet, name); - scoreboardDisplayType.set(packet, displayTypeIntegers); - return packet; - } - - private static Object createScorePacket(String name, int value){ - Object packet = Reflection.newInstance(FlatteningWrapper.scoreboardScore); - scoreName.set(packet, name); - scoreScoreboardName.set(packet, SIDEBAR + toggle); - scoreValue.set(packet, value); - FlatteningWrapper.impl.setScoreAction(packet); - return packet; + public interface ISWScoreboard { + boolean createScoreboard(Player player, ScoreboardCallback callback); + void removeScoreboard(Player player); } } diff --git a/build.gradle b/build.gradle index 6f4c1d0..4467bde 100755 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ plugins { id 'base' id 'application' - id 'com.github.johnrengelman.shadow' version '5.0.0' + id 'com.github.johnrengelman.shadow' version '8.0.0' id 'de.steamwar.gradle' version 'RELEASE' } @@ -37,11 +37,6 @@ version '' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -mainClassName = '' - allprojects { repositories { mavenCentral() @@ -70,6 +65,10 @@ allprojects { includeGroup('com.viaversion') } } + + maven { + url = uri("https://repo.papermc.io/repository/maven-public/") + } } } @@ -84,6 +83,7 @@ dependencies { implementation project(":SpigotCore_18") implementation project(":SpigotCore_19") implementation project(":SpigotCore_20") + implementation project(":SpigotCore_21") implementation project(":CommonCore") } @@ -91,3 +91,12 @@ dependencies { steamwar { publishing = true } + +java { + targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_1_8 +} + +shadowJar { + mainClassName = '' +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 086800c..b0c2826 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ #Wed May 05 10:45:33 CEST 2021 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index ff43518..ef364dc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,6 +29,7 @@ pluginManagement { rootProject.name = 'SpigotCore' include 'SpigotCore_Main' +include 'SpigotCore_21' include 'SpigotCore_20' include 'SpigotCore_19' include 'SpigotCore_18'