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_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_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_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_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;
|
||||
|
||||
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.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
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 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
|
||||
public class FreezeUtils {
|
||||
@ -64,10 +78,89 @@ public class FreezeUtils {
|
||||
if (freezeEnabled) {
|
||||
try {
|
||||
field.set(getWorldHandle.invoke(world), state);
|
||||
cacheEntityPackets(state);
|
||||
frozen = state;
|
||||
} catch (IllegalAccessException e) {
|
||||
// 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);
|
||||
Region region = tntTraceRecorderMap.get((TNTPrimed) entity);
|
||||
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);
|
||||
tntTraceRecorderMap.remove(entity);
|
||||
tick();
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren