Merge branch 'main' into 1.21.1/rplayer-fix

This commit is contained in:
2025-12-03 09:59:33 +01:00
227 changed files with 5606 additions and 6155 deletions
@@ -107,7 +107,8 @@ public class ChunkHider21 implements ChunkHider {
int value = ProtocolUtils.readVarInt(section.getIn());
ProtocolUtils.writeVarInt(section.getOut(), !section.isSkipSection() && section.getObfuscate().contains(value) ? section.getTarget() : value);
return;
} else {
} else if (section.getBitsPerBlock() < 9) {
// Indirect (paletted) storage only present when bitsPerBlock < 9 in 1.21+
section.processPalette();
}
@@ -152,6 +153,9 @@ public class ChunkHider21 implements ChunkHider {
} else if(section.getBitsPerBlock() < 6) {
section.skipPalette();
section.skipNewDataArray(64);
} else {
// Direct (global) biome IDs no palette present
section.skipNewDataArray(64);
}
}
}
@@ -67,7 +67,7 @@ public class TypeUtils {
Player player = (Player) commandSender;
return BauweltMember.getMembers(player.getUniqueId())
.stream()
.filter(member -> SteamwarUser.get(member.getMemberID()).getUserName().equalsIgnoreCase(s))
.filter(member -> SteamwarUser.byId(member.getMemberID()).getUserName().equalsIgnoreCase(s))
.findAny()
.orElse(null);
}
@@ -80,7 +80,7 @@ public class TypeUtils {
Player player = (Player) sender;
return BauweltMember.getMembers(player.getUniqueId())
.stream()
.map(m -> SteamwarUser.get(m.getMemberID()).getUserName())
.map(m -> SteamwarUser.byId(m.getMemberID()).getUserName())
.collect(Collectors.toList());
}
});
@@ -0,0 +1,181 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.core;
import de.steamwar.message.Message;
import lombok.NonNull;
import lombok.experimental.Delegate;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.ClickEvent;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class SWPlayer {
private static final Map<Player, SWPlayer> players = new HashMap<>();
private static class SWPlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent event) {
SWPlayer.of(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerQuit(PlayerQuitEvent event) {
SWPlayer swPlayer = players.remove(event.getPlayer());
swPlayer.components.forEach((aClass, component) -> {
component.onUnmount(swPlayer);
});
}
@EventHandler
public void onCRIUSleep(CRIUSleepEvent event) {
for (SWPlayer value : players.values()) {
value.components.forEach((aClass, component) -> {
component.onUnmount(value);
});
}
players.clear();
}
}
public interface Component {
default void onMount(SWPlayer player) {
}
default void onUnmount(SWPlayer player) {
}
}
static {
Bukkit.getPluginManager().registerEvents(new SWPlayerListener(), Core.getInstance());
}
public static @NonNull SWPlayer of(@NonNull Player player) {
return players.computeIfAbsent(player, SWPlayer::new);
}
public static @NonNull Stream<SWPlayer> all() {
return players.values().stream();
}
public static <T extends Component> @NonNull Stream<Pair<SWPlayer, T>> allWithSingleComponent(Class<T> component) {
return players.values().stream()
.filter(player -> player.components.containsKey(component))
.map(player -> Pair.of(player, (T) player.components.get(component)));
}
@Delegate
private final Player player;
private final Map<Class<? extends Component>, Component> components = new HashMap<>();
private SWPlayer(@NonNull Player player) {
this.player = player;
}
public boolean hasComponent(@NonNull Class<? extends Component> component) {
return components.containsKey(component);
}
public <T extends Component> @NonNull Optional<T> getComponent(@NonNull Class<T> clazz) {
return Optional.ofNullable((T) components.get(clazz));
}
public <T extends Component> @NonNull Optional<T> getComponentAndFilter(@NonNull Class<T> clazz, Predicate<T> filter) {
return Optional.ofNullable((T) components.get(clazz)).filter(filter);
}
public <T extends Component> @NonNull T getComponentOrDefault(@NonNull Class<T> clazz, @NonNull Supplier<T> defaultValue) {
T value = (T) components.get(clazz);
if (value != null) return value;
value = defaultValue.get();
setComponent(value);
return value;
}
public <T extends Component> SWPlayer setComponent(@NonNull T value) {
Component component = components.put(value.getClass(), value);
if (component != null) component.onUnmount(this);
value.onMount(this);
return this;
}
public <T extends Component> SWPlayer removeComponent(@NonNull Class<T> clazz) {
Component component = components.remove(clazz);
if (component != null) component.onUnmount(this);
return this;
}
private ThreadLocal<Message> messageThreadLocal = ThreadLocal.withInitial(() -> null);
public SWPlayer using(Message message) {
this.messageThreadLocal.set(message);
return this;
}
private Message getMessage() {
Message message = this.messageThreadLocal.get();
if (message == null) throw new IllegalStateException("Use #using(Message) before sending or parsing a message!");
return message;
}
public void sendMessage(String message, Object... params) {
getMessage().send(message, player, ChatMessageType.SYSTEM, params);
}
public void sendMessagePrefixless(String message, Object... params) {
getMessage().sendPrefixless(message, player, ChatMessageType.SYSTEM, params);
}
public void sendActionBar(String message, Object... params) {
getMessage().sendPrefixless(message, player, ChatMessageType.ACTION_BAR, params);
}
public void sendMessage(String message, String onHover, ClickEvent onClick, Object... params) {
getMessage().send(message, true, player, ChatMessageType.SYSTEM, onHover, onClick, params);
}
public void sendMessagePrefixless(String message, String onHover, ClickEvent onClick, Object... params) {
getMessage().send(message, false, player, ChatMessageType.SYSTEM, onHover, onClick, params);
}
public String parsePrefixed(String message, Object... params) {
return getMessage().parsePrefixed(message, player, params);
}
public String parse(String message, Object... params) {
return getMessage().parse(message, player, params);
}
}
@@ -84,7 +84,7 @@ public class SchematicSelector {
public void open() {
injectable.onSelectorCreate(this);
if(publicMode == PublicMode.PUBLIC_ONLY) {
this.user = SteamwarUser.get(0);
this.user = SteamwarUser.byId(0);
}
openList(null);
injectable.onSelectorOpen(this, SchematicSelectorInjectable.OpenFrom.FRESH);
@@ -122,7 +122,7 @@ public class SchematicSelector {
list.add(renderItem(node));
}
SWListInv<SchematicNode> inv = new SWListInv<>(player, MessageFormat.format(injectable.createTitle(player), target.target.getName(player), (filter == null || filter.getName() == null)?(parent == null?"/":parent.generateBreadcrumbs()):filter.getName()), false, list, (clickType, node) -> handleClick(node, parent));
SWListInv<SchematicNode> inv = new SWListInv<>(player, MessageFormat.format(injectable.createTitle(player), target.target.getName(player), (filter == null || filter.getName() == null)?(parent == null?"/":parent.generateBreadcrumbs(user)):filter.getName()), false, list, (clickType, node) -> handleClick(node, parent));
if(publicMode == PublicMode.ALL) {
if(user.getId() == 0) {
inv.setItem(48, new SWItem(Material.BUCKET, Core.MESSAGE.parse("SCHEM_SELECTOR_OWN", player), clickType -> {
@@ -131,7 +131,7 @@ public class SchematicSelector {
}).setCustomModelData(CMDs.Schematic.OWN_SCHEMS));
} else {
inv.setItem(48, new SWItem(Material.GLASS, Core.MESSAGE.parse("SCHEM_SELECTOR_PUB", player), clickType -> {
this.user = SteamwarUser.get(0);
this.user = SteamwarUser.byId(0);
openList(null);
}).setCustomModelData(CMDs.Schematic.PUBLIC_SCHEMS));
}
@@ -178,7 +178,7 @@ public class SchematicSelector {
Optional<SchematicNode> currentParent = Optional.of(parent);
do {
sdoTrigger = false;
currentParent = currentParent.flatMap(SchematicSelector::getParent);
currentParent = currentParent.flatMap(this::getParent);
if(!currentParent.isPresent()) {
break;
}
@@ -326,7 +326,7 @@ public class SchematicSelector {
if(filter.getOwner() == null) {
inv.setItem(1, SWItem.getMaterial("SKULL_ITEM"), (byte) 3, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_OWNER", player), ownerCallback);
} else {
SteamwarUser tUser = SteamwarUser.get(filter.getOwner());
SteamwarUser tUser = SteamwarUser.byId(filter.getOwner());
SWItem item = SWItem.getPlayerSkull(tUser.getUserName());
item.setName(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_OWNER", player));
item.setEnchanted(true);
@@ -484,8 +484,8 @@ public class SchematicSelector {
return nodes;
}
private static Optional<SchematicNode> getParent(SchematicNode node) {
return node.getOptionalParent().map(integer -> SchematicNode.byIdAndUser(SteamwarUser.get(node.getEffectiveOwner()), integer));
private Optional<SchematicNode> getParent(SchematicNode node) {
return node.getOptionalParent().map(integer -> SchematicNode.byIdAndUser(user, integer));
}
public static SelectorTarget selectSchematic() {
@@ -585,7 +585,7 @@ public class SchematicSelector {
lore.add(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_NAME_SEARCH", player, name));
}
if(owner != null) {
lore.add(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_OWNER_SEARCH", player, SteamwarUser.get(owner).getUserName()));
lore.add(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_OWNER_SEARCH", player, SteamwarUser.byId(owner).getUserName()));
}
if(type != null) {
lore.add(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_TYPE_SEARCH", player, type.name()));
@@ -606,7 +606,7 @@ public class SchematicSelector {
if (name != null) {
return new SWItem(Material.NAME_TAG, itemName, lore, false, click -> {});
} else if (owner != null) {
SWItem playerSkull = SWItem.getPlayerSkull(SteamwarUser.get(owner).getUserName());
SWItem playerSkull = SWItem.getPlayerSkull(SteamwarUser.byId(owner).getUserName());
playerSkull.setName(itemName);
playerSkull.setLore(lore);
return playerSkull;
@@ -40,7 +40,7 @@ public class UtilGui {
public static void openMaterialSelector(Player player, String title, Consumer<Material> callback) {
List<SWListInv.SWListEntry<Material>> materials = new LinkedList<>();
for(Material material : Material.values()){
if(material.name().startsWith(Material.LEGACY_PREFIX))
if(material.name().startsWith(Material.LEGACY_PREFIX) || !material.isItem())
continue;
SWItem item = new SWItem(material, "§7" + material.name());
if(item.getItemMeta() != null && material.isItem()) {
@@ -48,7 +48,7 @@ public class CoreNetworkHandler extends PacketHandler {
@Handler
public void handleCloseInventoryPacket(CloseInventoryPacket packet) {
Player player = Bukkit.getPlayer(SteamwarUser.get(packet.getPlayerId()).getUUID());
Player player = Bukkit.getPlayer(SteamwarUser.byId(packet.getPlayerId()).getUUID());
if (player != null) {
player.closeInventory();
}
@@ -66,7 +66,7 @@ public class CoreNetworkHandler extends PacketHandler {
@Handler
public void handlePingPacket(PingPacket packet) {
UUID uuid = SteamwarUser.get(packet.getId()).getUUID();
UUID uuid = SteamwarUser.byId(packet.getId()).getUUID();
if(Bukkit.getPlayer(uuid) != null) {
Player player = Bukkit.getPlayer(uuid);
BountifulWrapper.impl.playPling(player);
@@ -24,7 +24,6 @@ import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.NetworkPacket;
import de.steamwar.network.packets.PacketHandler;
import de.steamwar.network.packets.client.AnvilAnswerPacket;
import de.steamwar.network.packets.client.InventoryCallbackPacket;
@@ -42,7 +41,7 @@ public class InventoryHandler extends PacketHandler {
@Handler
public static void handleInventoryPacket(InventoryPacket packet) {
Player player = Bukkit.getPlayer(SteamwarUser.get(packet.getPlayer()).getUUID());
Player player = Bukkit.getPlayer(SteamwarUser.byId(packet.getPlayer()).getUUID());
Map<Integer, SWItem> items = new HashMap<>();
packet.getItems().forEach((i, item) -> {
@SuppressWarnings("deprecation") SWItem it = SWItem.getItemFromJson(new JsonParser().parse(item).getAsJsonObject());
@@ -60,7 +59,7 @@ public class InventoryHandler extends PacketHandler {
@Handler
public static void handleAnvilInventoryPacket(AnvilInventoryPacket packet) {
Player player = Bukkit.getPlayer(SteamwarUser.get(packet.getPlayerId()).getUUID());
Player player = Bukkit.getPlayer(SteamwarUser.byId(packet.getPlayerId()).getUUID());
SWAnvilInv inv = new SWAnvilInv(player, packet.getTitle(), packet.getDefaultText());
if (packet.getMaterial() != null && !packet.getMaterial().isEmpty()) {
@@ -41,6 +41,6 @@ public class BauServerInfo {
public static SteamwarUser getOwnerUser() {
if (bauOwner == null) return null;
return SteamwarUser.get(bauOwner);
return SteamwarUser.byId(bauOwner);
}
}
@@ -19,119 +19,87 @@
package de.steamwar.sql;
import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import java.io.StringReader;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@AllArgsConstructor
public class PersonalKit {
private final InternalKit kit;
private static final Table<PersonalKit> table = new Table<>(PersonalKit.class);
private static final SelectStatement<PersonalKit> getKits = table.selectFields("UserID", "GameMode");
private static final SelectStatement<PersonalKit> getKit = table.select(Table.PRIMARY);
private static final SelectStatement<PersonalKit> getKitInUse = table.selectFields("UserID", "GameMode", "InUse");
private static final Statement update = table.insertAll();
private static final Statement delete = table.delete(Table.PRIMARY);
public String getName() {
return kit.getName();
}
@Getter
@Field(keys = {Table.PRIMARY})
private final int userID;
@Getter
@Field(keys = {Table.PRIMARY})
private final String gamemode;
@Getter
@Field(keys = {Table.PRIMARY})
private final String name;
@Field
private String inventory;
@Field
private String armor;
@Getter
@Field(def = "1")
private boolean inUse;
public boolean isInUse() {
return kit.getInUse();
}
public String getRawInventory() {
return inventory;
return kit.getRawInventory();
}
public String getRawArmor() {
return armor;
return kit.getRawArmor();
}
public ItemStack[] getInventory(){
YamlConfiguration config = YamlConfiguration.loadConfiguration(new StringReader(inventory));
YamlConfiguration config = YamlConfiguration.loadConfiguration(new StringReader(getRawInventory()));
return Objects.requireNonNull(config.getList("Inventory")).toArray(new ItemStack[0]);
}
public ItemStack[] getArmor(){
YamlConfiguration config = YamlConfiguration.loadConfiguration(new StringReader(armor));
YamlConfiguration config = YamlConfiguration.loadConfiguration(new StringReader(getRawArmor()));
return Objects.requireNonNull(config.getList("Armor")).toArray(new ItemStack[0]);
}
public void setInUse() {
PersonalKit kit = getKitInUse(userID, gamemode);
if(kit != null)
kit.setUse(false);
setUse(true);
}
private void setUse(boolean inUse) {
this.inUse = inUse;
update();
kit.setDefault();
}
public void setInventory(ItemStack[] inventory) {
this.inventory = saveInvConfig("Inventory", inventory);
update();
kit.setInventory(saveInvConfig("Inventory", inventory));
}
public void setArmor(ItemStack[] armor) {
this.armor = saveInvConfig("Armor", armor);
update();
kit.setArmor(saveInvConfig("Armor", armor));
}
public void setContainer(ItemStack[] inventory, ItemStack[] armor) {
this.armor = saveInvConfig("Armor", armor);
this.inventory = saveInvConfig("Inventory", inventory);
update();
setInventory(inventory);
setArmor(armor);
}
public void delete() {
delete.update(userID, gamemode, name);
}
private void update() {
update.update(userID, gamemode, name, inventory, armor, inUse);
kit.delete();
}
public static List<PersonalKit> get(int userID, String gamemode){
return getKits.listSelect(userID, gamemode);
return InternalKit.get(userID, gamemode).stream().map(PersonalKit::new).collect(Collectors.toList());
}
public static PersonalKit get(int userID, String gamemode, String name) {
return getKit.select(userID, gamemode, name);
InternalKit kit = InternalKit.get(userID, gamemode, name);
if(kit == null)
return null;
return new PersonalKit(kit);
}
public static PersonalKit create(int userID, String gamemode, String name, ItemStack[] inventory, ItemStack[] armor){
if(armor == null) {
armor = new ItemStack[]{null, null, null, null};
}
PersonalKit kit = new PersonalKit(userID, gamemode, name, saveInvConfig("Inventory", inventory), saveInvConfig("Armor", armor), true);
kit.update();
return kit;
InternalKit kit = InternalKit.create(userID, gamemode, name, saveInvConfig("Inventory", inventory), saveInvConfig("Armor", armor));
return new PersonalKit(kit);
}
public static PersonalKit getKitInUse(int userID, String gamemode) {
return getKitInUse.select(userID, gamemode, true);
InternalKit kit = InternalKit.getKitInUse(userID, gamemode);
if(kit == null)
return null;
return new PersonalKit(kit);
}
private static String saveInvConfig(String name, ItemStack[] inv) {
@@ -27,6 +27,10 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SQLWrapperImpl implements SQLWrapper<Material> {
@@ -40,6 +44,17 @@ public class SQLWrapperImpl implements SQLWrapper<Material> {
return new GameModeConfig<>(file, GameModeConfigUtils.ToMaterial, GameModeConfig.ToString, GameModeConfig.ToStaticWarGear, true);
}
@Override
public List<Material> getMaterialWithGreaterBlastResistance(double maxBlastResistance) {
Stream<Material> stream = Arrays.stream(Material.values());
if (Core.getVersion() > 12) {
stream = stream.filter(material -> !material.isLegacy());
}
return stream.filter(Material::isBlock)
.filter(material -> material.getBlastResistance() > maxBlastResistance)
.collect(Collectors.toList());
}
private static final String SERVER_VERSION = Bukkit.getServer().getVersion();
@Override
@@ -20,19 +20,12 @@
package de.steamwar.sql;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.core.Core;
import de.steamwar.core.WorldEditWrapper;
import de.steamwar.sql.internal.SqlTypeMapper;
import de.steamwar.sql.internal.Statement;
import org.bukkit.entity.Player;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.sql.Blob;
import java.sql.PreparedStatement;
import java.util.zip.GZIPInputStream;
public class SchematicData {
@@ -3,6 +3,10 @@ version: "2.0"
author: Lixfel
api-version: "1.13"
load: STARTUP
depend:
- KotlinCore
softdepend:
- WorldEdit