Merge branch 'main' into MojMapReflections

# Conflicts:
#	SpigotCore/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java
#	SpigotCore/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java
#	SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java
This commit is contained in:
Lixfel
2025-01-06 10:06:28 +01:00
61 changed files with 426 additions and 467 deletions
@@ -38,7 +38,6 @@ dependencies {
compileOnly(libs.spigotapi)
compileOnly(libs.axiom)
compileOnly(libs.authlib)
compileOnly(libs.viaapi)
compileOnly(libs.fawe18)
@@ -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}
SCHEMATIC_GUI_ITEM=§eSchematics
@@ -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}
SCHEMATIC_GUI_ITEM=§eSchematics
@@ -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)
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Player> 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);
}
}
-2
View File
@@ -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"
@@ -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<NodeData> 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;
}
}
@@ -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() {
@@ -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<Integer, SteamwarUser> usersById = new HashMap<>();
private static final Map<UUID, SteamwarUser> 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);
@@ -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);
}
}
@@ -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);
}
}
@@ -153,7 +153,6 @@ public class FightSystem extends JavaPlugin {
new GamemodeCommand();
new ReadyCommand();
new AkCommand();
new LeaderCommand();
new LockschemCommand();
new StateCommand();
new SkipCommand();
@@ -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.
@@ -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.
@@ -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<SWListInv.SWListEntry<UUID>> 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<UUID> 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<UUID> 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());
@@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}
}
@@ -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;
@@ -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){
@@ -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));
}
@@ -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(),
@@ -19,7 +19,6 @@ commands:
ready:
kit:
remove:
leader:
lockschem:
state:
skip:
@@ -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
@@ -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
@@ -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
@@ -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));
@@ -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<String, Tag> applyDataFixer(DataFixer fixer, int dataVersion, Map<String, Tag> 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<String, Tag> 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<String, Tag> 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<String, Tag> blockContainer = null;
boolean v3Mode = false;
if (schematicVersion == 3) {
blockContainer = requireTag(schematic, "Blocks", CompoundTag.class).getValue();
v3Mode = true;
}
Map<String, Tag> paletteObject = requireTag(v3Mode ? blockContainer: schematic, "Palette", CompoundTag.class).getValue();
Map<Integer, BlockState> 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<BlockVector3, Map<String, Tag>> 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<Map<String, Tag>> 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;
}
@@ -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<String, Tag> applyDataFixer(DataFixer fixer, int dataVersion, Map<String, Tag> values) {
return ((CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, new CompoundTag(values).asBinaryTag(), dataVersion))).getValue();
}
}
+8 -12
View File
@@ -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)
}
@@ -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);
@@ -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;
}
}
@@ -70,15 +70,15 @@ public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper {
Reflection.Field<Integer> posX = Reflection.getField(packetClass, int.class, fieldOffset);
Reflection.Field<Integer> posY = Reflection.getField(packetClass, int.class, fieldOffset +1);
Reflection.Field<Integer> posZ = Reflection.getField(packetClass, int.class, fieldOffset +2);
Reflection.Field<Byte> lookPitch = Reflection.getField(packetClass, byte.class, 0);
Reflection.Field<Byte> lookYaw = Reflection.getField(packetClass, byte.class, 1);
Reflection.Field<Byte> lookYaw = Reflection.getField(packetClass, byte.class, 0);
Reflection.Field<Byte> 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));
};
}
@@ -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<String, Tag> 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<String, Tag> 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<String, Tag> blockContainer = null;
if (v3Mode) {
blockContainer = getTag(schematic, "Blocks", CompoundTag.class).getValue();
}
Map<String, Tag> paletteObject = requireTag(v3Mode ? blockContainer : schematic, "Palette", CompoundTag.class).getValue();
Map<Integer, BaseBlock> 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<BlockVector, Map<String, Tag>> 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) {
-2
View File
@@ -26,6 +26,4 @@ dependencies {
compileOnly(project(":SpigotCore:SpigotCore_8", "default"))
compileOnly(libs.nms9)
compileOnly(libs.viaapi)
}
@@ -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<Double> 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<Byte> movePitch = Reflection.getField(packetClass, "e", byte.class);
Reflection.Field<Byte> moveYaw = Reflection.getField(packetClass, "f", byte.class);
Reflection.Field<Byte> moveYaw = Reflection.getField(packetClass, "e", byte.class);
Reflection.Field<Byte> 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));
};
}
@@ -35,7 +35,6 @@ dependencies {
compileOnly(libs.spigotapi)
compileOnly(libs.netty)
compileOnly(libs.authlib)
compileOnly(libs.viaapi)
compileOnly(libs.fastutil)
implementation(libs.anvilgui)
@@ -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");
@@ -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();
@@ -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;
}
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Boolean> fullChunkFlag = Reflection.getField(mapChunk, boolean.class, 0);
private static final Reflection.Field<Integer> chunkX = Reflection.getField(mapChunk, int.class, 0);
private static final Reflection.Field<Integer> chunkZ = Reflection.getField(mapChunk, int.class, 1);
private final ViaAPI<Player> via = Via.getAPI();
private final List<ResendChunk> 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;
}
}
}
@@ -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);
@@ -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);
}
}
@@ -4,7 +4,6 @@ author: Lixfel
api-version: "1.13"
load: STARTUP
softdepend:
- ViaVersion
- WorldEdit
main: de.steamwar.core.Core
+6 -1
View File
@@ -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)
}
}
}
@@ -46,7 +46,6 @@ object GlobalListener: Listener {
with(e.player) {
teleport(TNTLeagueWorldConfig.lobby)
inventory.clear()
isOp = false
gameMode = GameMode.SPECTATOR
respawnLocation = TNTLeagueWorldConfig.lobby
}
@@ -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)) {
@@ -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);
+4 -1
View File
@@ -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)
}
@@ -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
@@ -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
@@ -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 <T extends GameModeConfig> void loadAll(Class<T> config, BiConsumer<File, T> 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<String> ChatNames = Collections.emptyList();
private List<String> 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() {
@@ -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<String> cmd, String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams) {
protected void constructServerstart(File directory, List<String> 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<String> 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<String> 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);
}
@@ -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<Integer, String> 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));
}
@@ -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<String, ServerVersion> 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 + "/";
@@ -152,6 +152,7 @@ public class VelocityCore implements ReloadablePlugin {
new BanListener();
new CheckListener();
new IPSanitizer();
new VersionAnnouncer();
local = new Node.LocalNode();
if(MAIN_SERVER) {
@@ -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) {
@@ -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<String> 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();
@@ -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();
@@ -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 <https://www.gnu.org/licenses/>.
*/
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()));
}
}
+1
View File
@@ -53,4 +53,5 @@ dependencies {
implementation(libs.yamlconfig)
implementation(libs.kotlinxSerializationCbor)
implementation(libs.ktorRateLimit)
implementation(libs.nbt)
}
@@ -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<SWAuthPrincipal>()!!.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)
}
}
}
}
+4 -1
View File
@@ -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")
}
}
}