QOL #203
@ -54,12 +54,11 @@ dependencies {
|
|||||||
implementation project(":BauSystem_Linkage")
|
implementation project(":BauSystem_Linkage")
|
||||||
annotationProcessor project(":BauSystem_Linkage")
|
annotationProcessor project(":BauSystem_Linkage")
|
||||||
|
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT'
|
||||||
compileOnly 'com.mojang:authlib:1.5.25'
|
compileOnly 'com.mojang:authlib:1.5.25'
|
||||||
compileOnly 'io.netty:netty-all:4.1.68.Final'
|
compileOnly 'io.netty:netty-all:4.1.68.Final'
|
||||||
|
|
||||||
compileOnly swdep('Spigot-1.19')
|
compileOnly swdep('Spigot-1.20')
|
||||||
// compileOnly swdep('WorldEdit-1.15')
|
|
||||||
compileOnly swdep('SpigotCore')
|
compileOnly swdep('SpigotCore')
|
||||||
annotationProcessor swdep('SpigotCore')
|
annotationProcessor swdep('SpigotCore')
|
||||||
|
|
||||||
|
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 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.features.world;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.Sign;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.block.data.Rotatable;
|
||||||
|
import org.bukkit.block.sign.Side;
|
||||||
|
import org.bukkit.block.sign.SignSide;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
@MinVersion(20)
|
||||||
|
public class SignEditFrom20 implements Listener {
|
||||||
|
|
||||||
|
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
||||||
|
private static final Class<?> craftBlock = Reflection.getClass("{obc}.block.CraftBlock");
|
||||||
|
private static final Class<?> craftWorld = Reflection.getClass("{obc}.CraftWorld");
|
||||||
|
private static final Class<?> generatorAccess = Reflection.getClass("{nms.world.level}.GeneratorAccess");
|
||||||
|
private static final Reflection.MethodInvoker getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
|
||||||
|
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
|
||||||
|
private static final Reflection.MethodInvoker at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
|
||||||
|
|
||||||
|
private static final Class<?> openSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutOpenSignEditor");
|
||||||
|
private static final Reflection.FieldAccessor<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
|
||||||
|
private static final Reflection.FieldAccessor<?> sideFieldAccessor = Reflection.getField(openSign, boolean.class, 0);
|
||||||
|
|
||||||
|
private static final Class<?> updateSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUpdateSign");
|
||||||
|
private static final Reflection.FieldAccessor<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
|
||||||
|
private static final Reflection.FieldAccessor<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void editSign(PlayerInteractEvent event) {
|
||||||
|
if (event.getClickedBlock() == null || !event.getClickedBlock().getType().name().contains("SIGN")) return;
|
||||||
|
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) event.setCancelled(true);
|
||||||
|
if (!event.getPlayer().isSneaking()) return;
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && (event.getItem() == null || event.getItem().getType() == Material.AIR) || event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||||
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
|
edit(event.getPlayer(), event.getClickedBlock());
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void edit(Player player, Block block) {
|
||||||
|
Sign sign = (Sign) block.getState();
|
||||||
|
Side side = signSide(player, block);
|
||||||
|
SignSide signSide = sign.getSide(side);
|
||||||
|
String[] lines = signSide.getLines();
|
||||||
|
for (int i = 0; i < lines.length; i++) {
|
||||||
|
signSide.setLine(i, lines[i].replace('§', '&'));
|
||||||
|
}
|
||||||
|
sign.update(true);
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
|
Object openSignObject = Reflection.newInstance(openSign);
|
||||||
|
blockPositionFieldAccessor.set(openSignObject, getPosition.invoke(block));
|
||||||
|
sideFieldAccessor.set(openSignObject, side == Side.FRONT);
|
||||||
|
TinyProtocol.instance.sendPacket(player, openSignObject);
|
||||||
|
}, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Side signSide(Player entity, Block sign) {
|
||||||
|
Vector vector = entity.getEyeLocation().toVector().subtract(sign.getLocation().add(0.5, 0.5, 0.5).toVector());
|
||||||
|
BlockFace blockFace = ((org.bukkit.block.data.type.Sign) sign.getBlockData()).getRotation();
|
||||||
|
Vector signDirection = new Vector(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ());
|
||||||
|
return vector.dot(signDirection) > 0 ? Side.FRONT : Side.BACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TinyProtocol.instance.addFilter(updateSign, (player, o) -> {
|
||||||
|
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
|
||||||
|
String[] lines = stringFieldAccessor.get(o);
|
||||||
|
|
||||||
|
Block signLoc = (Block) at.invoke(null, getWorldHandle.invoke(player.getWorld()), getBlockPositionFieldAccessor.get(o));
|
||||||
|
if (!signLoc.getType().name().contains("SIGN"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Sign sign = ((Sign) signLoc.getState());
|
||||||
|
SignSide signSide = sign.getSide(signSide(player, signLoc));
|
||||||
|
for (int i = 0; i < lines.length; i++) {
|
||||||
|
signSide.setLine(i, ChatColor.translateAlternateColorCodes('&', lines[i]));
|
||||||
|
}
|
||||||
|
sign.update(true);
|
||||||
|
});
|
||||||
|
return o;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ import com.comphenix.tinyprotocol.Reflection;
|
|||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MaxVersion;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -35,7 +36,8 @@ import org.bukkit.event.block.Action;
|
|||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class SignEdit implements Listener {
|
@MaxVersion(19)
|
||||||
|
public class SignEditUntil19 implements Listener {
|
||||||
|
|
||||||
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
||||||
private static final Class<?> craftBlock = Reflection.getClass("{obc}.block.CraftBlock");
|
private static final Class<?> craftBlock = Reflection.getClass("{obc}.block.CraftBlock");
|
In neuem Issue referenzieren
Einen Benutzer sperren