Merge branch 'master' into SimulatorPreview
Dieser Commit ist enthalten in:
Commit
a2cdcc0b47
@ -509,6 +509,16 @@ SCRIPT_GUI_CONSTANT_TPS_LORE = §etps§7 of the server
|
|||||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit
|
SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit
|
||||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 of the server
|
SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 of the server
|
||||||
|
|
||||||
|
# Shield Printing
|
||||||
|
SHIELD_PRINTING_NO_REGION = §cYou are not in a region.
|
||||||
|
SHIELD_PRINTING_NOT_RUNNING = §cThe shield printing is not running.
|
||||||
|
SHIELD_PRINTING_DISALLOWED = §cYou are not allowed to use shield printing here.
|
||||||
|
|
||||||
|
SHIELD_PRINTING_START = §aThe shield printing has been started.
|
||||||
|
SHIELD_PRINTING_COPY = §aThe shield has been copied.
|
||||||
|
SHIELD_PRINTING_APPLY = §aThe shield has been applied.
|
||||||
|
SHIELD_PRINTING_STOP = §aThe shield printing has been stopped.
|
||||||
|
|
||||||
# Unsign Book
|
# Unsign Book
|
||||||
UNSIGN_HELP=§8/§eunsign §8- §7Make a signed book writable again
|
UNSIGN_HELP=§8/§eunsign §8- §7Make a signed book writable again
|
||||||
|
|
||||||
|
@ -502,6 +502,16 @@ SCRIPT_GUI_CONSTANT_TPS_LORE = §etps§7 vom Server
|
|||||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit
|
SCRIPT_GUI_CONSTANT_TPS_LIMIT_NAME = §7Constant §etps_limit
|
||||||
SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 vom Server
|
SCRIPT_GUI_CONSTANT_TPS_LIMIT_LORE = §etps_limit§7 vom Server
|
||||||
|
|
||||||
|
# Shield Printing
|
||||||
|
SHIELD_PRINTING_NO_REGION = §cDu bist in keiner Region.
|
||||||
|
SHIELD_PRINTING_NOT_RUNNING = §cShield printing ist nicht aktiv.
|
||||||
|
SHIELD_PRINTING_DISALLOWED = §cDu darfst Shield printing nicht benutzen.
|
||||||
|
|
||||||
|
SHIELD_PRINTING_START = §aShield printing wurde gestartet.
|
||||||
|
SHIELD_PRINTING_COPY = §aSchilde wurden kopiert.
|
||||||
|
SHIELD_PRINTING_APPLY = §aSchilde wurden angewendet.
|
||||||
|
SHIELD_PRINTING_STOP = §aShield printing wurde gestoppt.
|
||||||
|
|
||||||
# Unsign Book
|
# Unsign Book
|
||||||
UNSIGN_HELP=§8/§eunsign §8- §7Mache ein Buch beschreibbar
|
UNSIGN_HELP=§8/§eunsign §8- §7Mache ein Buch beschreibbar
|
||||||
|
|
||||||
|
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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.shieldprinting;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.bausystem.region.Region;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||||
|
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ShieldPrinting implements Listener {
|
||||||
|
|
||||||
|
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vector of current position, Vector of origin
|
||||||
|
*/
|
||||||
|
private Map<Vector, Vector> shieldMap = new HashMap<>();
|
||||||
|
private Map<Vector, BlockData> shieldData = new HashMap<>();
|
||||||
|
|
||||||
|
private final Region region;
|
||||||
|
|
||||||
|
public ShieldPrinting(Region region) {
|
||||||
|
this.region = region;
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copy() {
|
||||||
|
for (Map.Entry<Vector, Vector> entry : shieldMap.entrySet()) {
|
||||||
|
shieldData.put(entry.getValue(), entry.getKey().toLocation(WORLD).getBlock().getBlockData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void apply() {
|
||||||
|
for (Map.Entry<Vector, BlockData> entry : shieldData.entrySet()) {
|
||||||
|
entry.getKey().toLocation(WORLD).getBlock().setBlockData(entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disable() {
|
||||||
|
BlockPistonExtendEvent.getHandlerList().unregister(this);
|
||||||
|
BlockPistonRetractEvent.getHandlerList().unregister(this);
|
||||||
|
shieldMap.clear();
|
||||||
|
shieldData.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
|
||||||
|
update(event.getDirection(), event.getBlocks());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
|
||||||
|
update(event.getDirection(), event.getBlocks());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update(BlockFace direction, List<Block> blockList) {
|
||||||
|
Set<Vector> toRemove = new HashSet<>();
|
||||||
|
Map<Vector, Vector> temp = new HashMap<>();
|
||||||
|
for (Block block : blockList) {
|
||||||
|
if (Region.getRegion(block.getLocation()) != region) continue;
|
||||||
|
Vector vector = block.getLocation().toVector();
|
||||||
|
Vector origin = vector.clone();
|
||||||
|
vector = vector.add(direction.getDirection());
|
||||||
|
if (shieldMap.containsKey(origin)) {
|
||||||
|
toRemove.add(origin);
|
||||||
|
temp.put(vector, shieldMap.get(origin));
|
||||||
|
} else {
|
||||||
|
temp.put(vector, origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shieldMap.keySet().removeAll(toRemove);
|
||||||
|
shieldMap.putAll(temp);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.shieldprinting;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.bausystem.Permission;
|
||||||
|
import de.steamwar.bausystem.region.Region;
|
||||||
|
import de.steamwar.command.SWCommand;
|
||||||
|
import de.steamwar.command.TypeValidator;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class ShieldPrintingCommand extends SWCommand {
|
||||||
|
|
||||||
|
public ShieldPrintingCommand() {
|
||||||
|
super("shieldprinting");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Region, ShieldPrinting> shieldMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Register
|
||||||
|
public void genericCommand(@Validator Player player, ShieldPrintingState shieldPrintingState) {
|
||||||
|
Region region = Region.getRegion(player.getLocation());
|
||||||
|
if (region.isGlobal()) {
|
||||||
|
// BauSystem.MESSAGE.send("SHIELD_PRINTING_NO_REGION", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ShieldPrinting shieldPrinting;
|
||||||
|
switch (shieldPrintingState) {
|
||||||
|
case START:
|
||||||
|
shieldPrinting = shieldMap.put(region, new ShieldPrinting(region));
|
||||||
|
if (shieldPrinting != null) {
|
||||||
|
shieldPrinting.disable();
|
||||||
|
}
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_START", player);
|
||||||
|
break;
|
||||||
|
case COPY:
|
||||||
|
shieldPrinting = shieldMap.get(region);
|
||||||
|
if (shieldPrinting == null) {
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
shieldPrinting.copy();
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_COPY", player);
|
||||||
|
break;
|
||||||
|
case APPLY:
|
||||||
|
shieldPrinting = shieldMap.get(region);
|
||||||
|
if (shieldPrinting == null) {
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
shieldPrinting.apply();
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_APPLY", player);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register("stop")
|
||||||
|
public void stopCommand(@Validator Player player) {
|
||||||
|
Region region = Region.getRegion(player.getLocation());
|
||||||
|
if (region.isGlobal()) {
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_NO_REGION", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ShieldPrinting shieldPrinting = shieldMap.remove(region);
|
||||||
|
if (shieldPrinting == null) {
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_NOT_RUNNING", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
shieldPrinting.disable();
|
||||||
|
BauSystem.MESSAGE.send("SHIELD_PRINTING_STOP", player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ClassValidator(value = Player.class, local = true)
|
||||||
|
public TypeValidator<Player> validator() {
|
||||||
|
return (commandSender, player, messageSender) -> {
|
||||||
|
if (!Permission.hasPermission(player, Permission.WORLD)) {
|
||||||
|
messageSender.send("SHIELD_PRINTING_DISALLOWED", player);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Region region = Region.getRegion(player.getLocation());
|
||||||
|
if (region.isGlobal()) {
|
||||||
|
messageSender.send("SHIELD_PRINTING_NO_REGION", player);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.shieldprinting;
|
||||||
|
|
||||||
|
public enum ShieldPrintingState {
|
||||||
|
|
||||||
|
START,
|
||||||
|
COPY,
|
||||||
|
APPLY
|
||||||
|
}
|
@ -20,13 +20,27 @@
|
|||||||
package de.steamwar.bausystem.features.tpslimit;
|
package de.steamwar.bausystem.features.tpslimit;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.core.BountifulWrapper;
|
||||||
|
import de.steamwar.core.ChatWrapper;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.TNTPrimed;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
import yapion.utils.ReflectionsUtils;
|
import yapion.utils.ReflectionsUtils;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class FreezeUtils {
|
public class FreezeUtils {
|
||||||
@ -64,10 +78,89 @@ public class FreezeUtils {
|
|||||||
if (freezeEnabled) {
|
if (freezeEnabled) {
|
||||||
try {
|
try {
|
||||||
field.set(getWorldHandle.invoke(world), state);
|
field.set(getWorldHandle.invoke(world), state);
|
||||||
|
cacheEntityPackets(state);
|
||||||
frozen = state;
|
frozen = state;
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
// Ignored;
|
// Ignored;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Object> packets = new ArrayList<>();
|
||||||
|
private Set<Entity> entities = new HashSet<>();
|
||||||
|
private BukkitTask task = null;
|
||||||
|
|
||||||
|
private Class<?> vec3dClass = Reflection.getClass("{nms.world.phys}.Vec3D");
|
||||||
|
private Reflection.FieldAccessor<Object> zeroVec3d = (Reflection.FieldAccessor<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
|
||||||
|
private Object ZERO_VEC3D = zeroVec3d.get(null);
|
||||||
|
private Class<?> velocityPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity");
|
||||||
|
private Reflection.ConstructorInvoker velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
|
||||||
|
|
||||||
|
private Class<?> teleportPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
|
||||||
|
private Class<?> entityClass = Reflection.getClass("{nms.world.entity}.Entity");
|
||||||
|
private Reflection.ConstructorInvoker teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
|
||||||
|
|
||||||
|
private Class<?> craftEntityClass = Reflection.getClass("{obc}.entity.CraftEntity");
|
||||||
|
private Reflection.MethodInvoker getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
|
||||||
|
|
||||||
|
private Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class);
|
||||||
|
private Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
|
||||||
|
|
||||||
|
private void cacheEntityPackets(boolean state) {
|
||||||
|
if (state) {
|
||||||
|
createPackets();
|
||||||
|
|
||||||
|
if (task == null) {
|
||||||
|
task = new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
createPackets();
|
||||||
|
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
for (Object packet : packets) {
|
||||||
|
TinyProtocol.instance.sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskTimer(BauSystem.getInstance(), 1, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
packets.clear();
|
||||||
|
entities.clear();
|
||||||
|
|
||||||
|
if (task != null) {
|
||||||
|
task.cancel();
|
||||||
|
task = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPackets() {
|
||||||
|
if (FreezeUtils.entities.stream().anyMatch(Entity::isDead)) {
|
||||||
|
entities.clear();
|
||||||
|
packets.clear();
|
||||||
|
}
|
||||||
|
List<Entity> entities = Bukkit.getWorlds().get(0).getEntities().stream()
|
||||||
|
.filter(e -> !(e instanceof Player))
|
||||||
|
.filter(e -> !FreezeUtils.entities.contains(e))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
packets.add(teleportPacketConstructor.invoke(getHandle.invoke(entity)));
|
||||||
|
}
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
packets.add(velocityPacketConstructor.invoke(entity.getEntityId(), ZERO_VEC3D));
|
||||||
|
}
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), noGravityDataWatcher, true));
|
||||||
|
}
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
if (!(entity instanceof TNTPrimed)) continue;
|
||||||
|
TNTPrimed tnt = (TNTPrimed) entity;
|
||||||
|
int fuse = tnt.getFuseTicks();
|
||||||
|
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
FreezeUtils.entities.addAll(entities);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,6 @@ public class Recorder implements Listener {
|
|||||||
TraceRecorder traceRecorder = get((TNTPrimed) entity);
|
TraceRecorder traceRecorder = get((TNTPrimed) entity);
|
||||||
Region region = tntTraceRecorderMap.get((TNTPrimed) entity);
|
Region region = tntTraceRecorderMap.get((TNTPrimed) entity);
|
||||||
boolean inBuildRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
|
boolean inBuildRegion = event.blockList().stream().anyMatch(block -> region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION));
|
||||||
System.out.println(event.blockList() + " " + inBuildRegion);
|
|
||||||
traceRecorder.explode((TNTPrimed) entity, inBuildRegion);
|
traceRecorder.explode((TNTPrimed) entity, inBuildRegion);
|
||||||
tntTraceRecorderMap.remove(entity);
|
tntTraceRecorderMap.remove(entity);
|
||||||
tick();
|
tick();
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren