Merge branch 'master' into joinAnytime
# Conflicts: # FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties # FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties # FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java # FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java # FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java
Dieser Commit ist enthalten in:
Commit
c91f22658b
@ -25,14 +25,8 @@ import net.minecraft.server.v1_10_R1.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
|
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_10_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class CraftbukkitWrapper10 implements CraftbukkitWrapper {
|
public class CraftbukkitWrapper10 implements CraftbukkitWrapper {
|
||||||
@ -52,24 +46,11 @@ public class CraftbukkitWrapper10 implements CraftbukkitWrapper {
|
|||||||
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
|
||||||
((CraftPlayer)player).getHandle().setResourcePack(pack, sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().getHeadRotation();
|
return ((CraftEntity)e).getHandle().getHeadRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<?> entityIterator() {
|
public Stream<?> entityIterator() {
|
||||||
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
||||||
|
@ -25,14 +25,8 @@ import net.minecraft.server.v1_12_R1.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class CraftbukkitWrapper12 implements CraftbukkitWrapper {
|
public class CraftbukkitWrapper12 implements CraftbukkitWrapper {
|
||||||
@ -52,24 +46,11 @@ public class CraftbukkitWrapper12 implements CraftbukkitWrapper {
|
|||||||
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
|
||||||
((CraftPlayer)player).getHandle().setResourcePack(pack, sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().getHeadRotation();
|
return ((CraftEntity)e).getHandle().getHeadRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<?> entityIterator() {
|
public Stream<?> entityIterator() {
|
||||||
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class ProtocolWrapper12 extends ProtocolWrapper8 {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket){
|
|
||||||
UnaryOperator<Object> blockBreakCloner = ProtocolAPI.shallowCloneGenerator(blockBreakPacket);
|
|
||||||
Reflection.FieldAccessor<?> blockBreakPosition = Reflection.getField(blockBreakPacket, TechHider.blockPosition, 0);
|
|
||||||
Reflection.FieldAccessor<?> blockBreakBlockData = Reflection.getField(blockBreakPacket, TechHider.iBlockData, 0);
|
|
||||||
|
|
||||||
return (p, packet) -> {
|
|
||||||
Object pos = blockBreakPosition.get(packet);
|
|
||||||
if(TechHider.bypass(p, TechHider.posToChunk(TechHider.blockPositionX.get(pos)), TechHider.posToChunk(TechHider.blockPositionZ.get(pos))))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
if(ProtocolWrapper.impl.iBlockDataHidden(blockBreakBlockData.get(packet))){
|
|
||||||
packet = blockBreakCloner.apply(packet);
|
|
||||||
blockBreakBlockData.set(packet, TechHider.obfuscateIBlockData);
|
|
||||||
}
|
|
||||||
return packet;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,61 +19,41 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
import de.steamwar.core.Core;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class BlockIdWrapper14 implements BlockIdWrapper {
|
public class BlockIdWrapper14 implements BlockIdWrapper {
|
||||||
|
|
||||||
|
private static final Class<?> worldServer = Reflection.getClass("{nms.server.level}.WorldServer");
|
||||||
|
private static final Class<?> chunkProviderServer = Reflection.getClass("{nms.server.level}.ChunkProviderServer");
|
||||||
|
private static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
|
||||||
|
private static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
|
||||||
|
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
||||||
|
|
||||||
|
private static final Reflection.MethodInvoker getCombinedId = Reflection.getTypedMethod(block, null, int.class, iBlockData);
|
||||||
|
private static final Reflection.MethodInvoker getNMS = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.CraftBlock"), "getNMS", iBlockData);
|
||||||
@Override
|
@Override
|
||||||
public int blockToId(Block block) {
|
public int blockToId(Block block) {
|
||||||
return net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS());
|
return (int) getCombinedId.invoke(null, getNMS.invoke(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Reflection.MethodInvoker getByCombinedId = Reflection.getTypedMethod(block, null, iBlockData, int.class);
|
||||||
|
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", worldServer);
|
||||||
|
private static final Reflection.ConstructorInvoker newBlockPosition = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
|
||||||
|
private static final Reflection.MethodInvoker getTypeAndData = Reflection.getMethod(worldServer, null, blockPosition, iBlockData, int.class);
|
||||||
|
private static final Reflection.MethodInvoker removeTileEntity = Reflection.getMethod(worldServer, Core.getVersion() > 15 ? "m" : "removeTileEntity", blockPosition);
|
||||||
|
private static final Reflection.MethodInvoker getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer);
|
||||||
|
private static final Reflection.MethodInvoker flagDirty = Reflection.getMethod(chunkProviderServer, null, blockPosition);
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(World world, int x, int y, int z, int blockState) {
|
public void setBlock(World world, int x, int y, int z, int blockState) {
|
||||||
IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.fromId(blockState));
|
Object blockData = getByCombinedId.invoke(null, blockState);
|
||||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
Object nworld = getWorldHandle.invoke(world);
|
||||||
BlockPosition pos = new BlockPosition(x, y, z);
|
Object pos = newBlockPosition.invoke(x, y, z);
|
||||||
cworld.removeTileEntity(pos);
|
|
||||||
cworld.setTypeAndData(pos, blockData, 1042);
|
|
||||||
cworld.getChunkProvider().flagDirty(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
removeTileEntity.invoke(nworld, pos);
|
||||||
public Set<Integer> getHiddenBlockIds() {
|
getTypeAndData.invoke(nworld, pos, blockData, 1042);
|
||||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
flagDirty.invoke(getChunkProvider.invoke(nworld), pos);
|
||||||
for(String tag : Config.HiddenBlocks){
|
|
||||||
for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(tag)).getStates().a()){
|
|
||||||
hiddenBlockIds.add(net.minecraft.server.v1_14_R1.Block.getCombinedId(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Config.HiddenBlocks.contains("water")){
|
|
||||||
Fluid water = FluidTypes.WATER.a(false);
|
|
||||||
for(IBlockData data : net.minecraft.server.v1_14_R1.Block.REGISTRY_ID){
|
|
||||||
if(data.p() == water){
|
|
||||||
hiddenBlockIds.add(net.minecraft.server.v1_14_R1.Block.getCombinedId(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hiddenBlockIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getObfuscateWith() {
|
|
||||||
return net.minecraft.server.v1_14_R1.Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(Config.ObfuscateWith)).getBlockData());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getPose(boolean sneaking) {
|
|
||||||
return sneaking ? EntityPose.SNEAKING : EntityPose.STANDING;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,8 @@ import net.minecraft.server.v1_14_R1.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class CraftbukkitWrapper14 implements CraftbukkitWrapper {
|
public class CraftbukkitWrapper14 implements CraftbukkitWrapper {
|
||||||
@ -53,24 +47,11 @@ public class CraftbukkitWrapper14 implements CraftbukkitWrapper {
|
|||||||
chunk.heightMap.putAll(backupChunk.heightMap);
|
chunk.heightMap.putAll(backupChunk.heightMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
|
||||||
((CraftPlayer)player).getHandle().setResourcePack(pack, sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().getHeadRotation();
|
return ((CraftEntity)e).getHandle().getHeadRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().getKeys());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<?> entityIterator() {
|
public Stream<?> entityIterator() {
|
||||||
return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream();
|
return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream();
|
||||||
|
@ -25,6 +25,9 @@ import org.bukkit.World;
|
|||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.Waterlogged;
|
import org.bukkit.block.data.Waterlogged;
|
||||||
|
import org.bukkit.block.data.type.Dispenser;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.Pose;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BlockDataMeta;
|
import org.bukkit.inventory.meta.BlockDataMeta;
|
||||||
@ -52,7 +55,8 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeWater(Block block) {
|
public boolean removeWater(Block block) {
|
||||||
if(block.getType() == Material.WATER){
|
Material type = block.getType();
|
||||||
|
if(type == Material.WATER || type == Material.LAVA){
|
||||||
block.setType(Material.AIR);
|
block.setType(Material.AIR);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -80,23 +84,6 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
|
|||||||
return stack.hasItemMeta() && Objects.requireNonNull(stack.getItemMeta()).hasAttributeModifiers();
|
return stack.hasItemMeta() && Objects.requireNonNull(stack.getItemMeta()).hasAttributeModifiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack onBreak(Block block) {
|
|
||||||
Material type = block.getType();
|
|
||||||
switch(type){
|
|
||||||
case REDSTONE_WIRE:
|
|
||||||
type = Material.REDSTONE;
|
|
||||||
break;
|
|
||||||
case PISTON_HEAD:
|
|
||||||
type = Material.PISTON;
|
|
||||||
break;
|
|
||||||
case ICE:
|
|
||||||
type = Material.AIR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return new ItemStack(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doRecord(BlockPhysicsEvent e) {
|
public boolean doRecord(BlockPhysicsEvent e) {
|
||||||
return e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR;
|
return e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR;
|
||||||
@ -113,7 +100,12 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNamedSpawnPacketDataWatcher(Object packet) {
|
public boolean isFacingWater(Block dispenser) {
|
||||||
// field not present
|
return dispenser.getRelative(((Dispenser) dispenser.getBlockData()).getFacing()).isLiquid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCrouching(Player player) {
|
||||||
|
return player.getPose() == Pose.SWIMMING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,140 +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.utils;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.LongBuffer;
|
|
||||||
|
|
||||||
public class TechHider14 extends TechHider9 {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected byte[] dataHider(byte[] data, Integer primaryBitMask) {
|
|
||||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while(primaryBitMask != 0){
|
|
||||||
while((primaryBitMask & 1) == 0){
|
|
||||||
primaryBitMask >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.writeBytes(data, i, 2); // Block count
|
|
||||||
i += 2;
|
|
||||||
byte bitsPerBlock = data[i++];
|
|
||||||
buffer.writeByte(bitsPerBlock);
|
|
||||||
|
|
||||||
if(bitsPerBlock < 9){
|
|
||||||
int paletteLength = TechHider.readVarInt(data, i);
|
|
||||||
int paletteLengthLength = TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(data, i, paletteLengthLength);
|
|
||||||
i += paletteLengthLength;
|
|
||||||
for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++){
|
|
||||||
int blockId = TechHider.readVarInt(data, i);
|
|
||||||
int actPaletteLength = TechHider.readVarIntLength(data, i);
|
|
||||||
|
|
||||||
if(hiddenBlockIds.contains(blockId)){
|
|
||||||
buffer.writeBytes(TechHider.writeVarInt(obfuscateWith));
|
|
||||||
}else{
|
|
||||||
buffer.writeBytes(data, i, actPaletteLength);
|
|
||||||
}
|
|
||||||
i += actPaletteLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
//We modify only the chunk palette for performance reasons
|
|
||||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
|
||||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(data, i, dataArrayLength * 8 + dataArrayLengthLength);
|
|
||||||
i += dataArrayLengthLength;
|
|
||||||
i += dataArrayLength * 8;
|
|
||||||
}else{
|
|
||||||
//Full Chunk/no palette, so the chunk has to be crawled through
|
|
||||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
|
||||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(data, i, dataArrayLengthLength);
|
|
||||||
i += dataArrayLengthLength;
|
|
||||||
|
|
||||||
ByteBuffer source = ByteBuffer.wrap(data, i, dataArrayLength * 8);
|
|
||||||
VariableValueArray values = new VariableValueArray(bitsPerBlock, dataArrayLength, source.asLongBuffer());
|
|
||||||
|
|
||||||
for(int pos = 0; pos < 4096; pos++){
|
|
||||||
if(hiddenBlockIds.contains(values.get(pos))){
|
|
||||||
values.set(pos, obfuscateWith);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(long l : values.backing)
|
|
||||||
buffer.writeLong(l);
|
|
||||||
|
|
||||||
i += dataArrayLength * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
primaryBitMask >>= 1;
|
|
||||||
}
|
|
||||||
buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why
|
|
||||||
|
|
||||||
data = new byte[buffer.readableBytes()];
|
|
||||||
buffer.readBytes(data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class VariableValueArray {
|
|
||||||
private final long[] backing;
|
|
||||||
private final int bitsPerValue;
|
|
||||||
private final long valueMask;
|
|
||||||
|
|
||||||
public VariableValueArray(int bitsPerEntry, int dataArrayLength, LongBuffer buffer) {
|
|
||||||
this.bitsPerValue = bitsPerEntry;
|
|
||||||
this.backing = new long[dataArrayLength];
|
|
||||||
buffer.get(backing);
|
|
||||||
this.valueMask = (1L << this.bitsPerValue) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int get(int index) {
|
|
||||||
index *= bitsPerValue;
|
|
||||||
int i0 = index >> 6;
|
|
||||||
int i1 = index & 0x3f;
|
|
||||||
|
|
||||||
long value = backing[i0] >>> i1;
|
|
||||||
|
|
||||||
// The value is divided over two long values
|
|
||||||
if (i1 + bitsPerValue > 64) {
|
|
||||||
value |= backing[++i0] << 64 - i1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int) (value & valueMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(int index, int value) {
|
|
||||||
index *= bitsPerValue;
|
|
||||||
int i0 = index >> 6;
|
|
||||||
int i1 = index & 0x3f;
|
|
||||||
|
|
||||||
backing[i0] = this.backing[i0] & ~(this.valueMask << i1) | (value & valueMask) << i1;
|
|
||||||
int i2 = i1 + bitsPerValue;
|
|
||||||
// The value is divided over two long values
|
|
||||||
if (i2 > 64) {
|
|
||||||
i0++;
|
|
||||||
backing[i0] = backing[i0] & -(1L << i2 - 64) | value >> 64 - i1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -42,6 +42,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
|
import de.steamwar.sql.SchematicData;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -143,6 +144,6 @@ public class WorldeditWrapper14 implements WorldeditWrapper {
|
|||||||
throw new SecurityException(e);
|
throw new SecurityException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
schem.saveFromBytes(outputStream.toByteArray(), true);
|
new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import net.minecraft.server.v1_15_R1.*;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class BlockIdWrapper15 implements BlockIdWrapper {
|
|
||||||
@Override
|
|
||||||
public int blockToId(Block block) {
|
|
||||||
return net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlock(World world, int x, int y, int z, int blockState) {
|
|
||||||
IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.fromId(blockState));
|
|
||||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
|
||||||
BlockPosition pos = new BlockPosition(x, y, z);
|
|
||||||
cworld.removeTileEntity(pos);
|
|
||||||
cworld.setTypeAndData(pos, blockData, 1042);
|
|
||||||
cworld.getChunkProvider().flagDirty(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Integer> getHiddenBlockIds() {
|
|
||||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
|
||||||
for(String tag : Config.HiddenBlocks){
|
|
||||||
for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(tag)).getStates().a()){
|
|
||||||
hiddenBlockIds.add(net.minecraft.server.v1_15_R1.Block.getCombinedId(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Config.HiddenBlocks.contains("water")){
|
|
||||||
Fluid water = FluidTypes.WATER.a(false);
|
|
||||||
for(IBlockData data : net.minecraft.server.v1_15_R1.Block.REGISTRY_ID){
|
|
||||||
if(data.getFluid() == water){
|
|
||||||
hiddenBlockIds.add(net.minecraft.server.v1_15_R1.Block.getCombinedId(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hiddenBlockIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getObfuscateWith() {
|
|
||||||
return net.minecraft.server.v1_15_R1.Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(Config.ObfuscateWith)).getBlockData());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getPose(boolean sneaking) {
|
|
||||||
return sneaking ? EntityPose.CROUCHING : EntityPose.STANDING;
|
|
||||||
}
|
|
||||||
}
|
|
@ -25,14 +25,8 @@ import net.minecraft.server.v1_15_R1.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class CraftbukkitWrapper15 implements CraftbukkitWrapper {
|
public class CraftbukkitWrapper15 implements CraftbukkitWrapper {
|
||||||
@ -53,24 +47,11 @@ public class CraftbukkitWrapper15 implements CraftbukkitWrapper {
|
|||||||
chunk.heightMap.putAll(backupChunk.heightMap);
|
chunk.heightMap.putAll(backupChunk.heightMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
|
||||||
((CraftPlayer)player).getHandle().setResourcePack(pack, sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().getHeadRotation();
|
return ((CraftEntity)e).getHandle().getHeadRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().getKeys());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<?> entityIterator() {
|
public Stream<?> entityIterator() {
|
||||||
return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream();
|
return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream();
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import net.minecraft.core.BlockPosition;
|
|
||||||
import net.minecraft.core.IRegistry;
|
|
||||||
import net.minecraft.resources.MinecraftKey;
|
|
||||||
import net.minecraft.server.level.WorldServer;
|
|
||||||
import net.minecraft.world.entity.EntityPose;
|
|
||||||
import net.minecraft.world.level.block.state.IBlockData;
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import net.minecraft.world.level.material.FluidTypes;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class BlockIdWrapper18 implements BlockIdWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int blockToId(Block block) {
|
|
||||||
return net.minecraft.world.level.block.Block.i(((CraftBlock)block).getNMS());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlock(World world, int x, int y, int z, int blockState) {
|
|
||||||
IBlockData blockData = Objects.requireNonNull(net.minecraft.world.level.block.Block.a(blockState));
|
|
||||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
|
||||||
BlockPosition pos = new BlockPosition(x, y, z);
|
|
||||||
cworld.m(pos);
|
|
||||||
cworld.a(pos, blockData, 1042);
|
|
||||||
cworld.k().a(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Integer> getHiddenBlockIds() {
|
|
||||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
|
||||||
for(String tag : Config.HiddenBlocks){
|
|
||||||
for(IBlockData data : IRegistry.U.a(new MinecraftKey(tag)).m().a()){
|
|
||||||
hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Config.HiddenBlocks.contains("water")){
|
|
||||||
Fluid water = FluidTypes.c.h();
|
|
||||||
for(IBlockData data : net.minecraft.world.level.block.Block.o) {
|
|
||||||
if(data.o() == water) {
|
|
||||||
hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hiddenBlockIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getObfuscateWith() { //ResourceLocation, DefaultedRegistry
|
|
||||||
return net.minecraft.world.level.block.Block.i(IRegistry.U.a(new MinecraftKey(Config.ObfuscateWith)).n());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getPose(boolean sneaking) {
|
|
||||||
return sneaking ? EntityPose.f : EntityPose.a;
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,53 +19,47 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
|
import net.minecraft.server.level.WorldServer;
|
||||||
import net.minecraft.world.level.chunk.Chunk;
|
import net.minecraft.world.level.chunk.Chunk;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkSection;
|
||||||
|
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
public class CraftbukkitWrapper18 implements CraftbukkitWrapper {
|
public class CraftbukkitWrapper18 implements CraftbukkitWrapper {
|
||||||
|
|
||||||
@Override
|
private static final Reflection.MethodInvoker getWorld = Reflection.getMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle");
|
||||||
public void resetChunk(World world, World backup, int x, int z) {
|
private static final Reflection.MethodInvoker getChunk = Reflection.getTypedMethod(net.minecraft.world.level.World.class, null, Chunk.class, int.class, int.class);
|
||||||
net.minecraft.world.level.World w = ((CraftWorld) world).getHandle();
|
private static final Reflection.MethodInvoker getChunkSections = Reflection.getTypedMethod(Chunk.class, null, ChunkSection[].class);
|
||||||
Chunk chunk = w.d(x, z);
|
private ChunkSection[] getChunkSections(World world, int x, int z) {
|
||||||
Chunk backupChunk = ((CraftWorld) backup).getHandle().d(x, z);
|
return (ChunkSection[]) getChunkSections.invoke(getChunk.invoke(getWorld.invoke(world), x, z));
|
||||||
|
|
||||||
System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
public void resetChunk(World world, World backup, int x, int z) {
|
||||||
((CraftPlayer)player).getHandle().a(pack, sha1, true, null);
|
ChunkSection[] sections = getChunkSections(world, x, z);
|
||||||
|
System.arraycopy(getChunkSections(backup, x, z), 0, sections, 0, sections.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.MethodInvoker getEntity = Reflection.getTypedMethod(Reflection.getClass("{obc}.entity.CraftEntity"), "getHandle", net.minecraft.world.entity.Entity.class);
|
||||||
|
protected net.minecraft.world.entity.Entity getEntity(Entity e) {
|
||||||
|
return (net.minecraft.world.entity.Entity) getEntity.invoke(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().ce();
|
return getEntity(e).ce();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).t().d());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Reflection.MethodInvoker getWorldEntities = Reflection.getTypedMethod(WorldServer.class, null, LevelEntityGetter.class);
|
||||||
|
private static final Reflection.MethodInvoker getIterable = Reflection.getTypedMethod(LevelEntityGetter.class, null, Iterable.class);
|
||||||
@Override
|
@Override
|
||||||
public Stream<?> entityIterator() {
|
public Stream<?> entityIterator() {
|
||||||
return StreamSupport.stream(((CraftWorld) Config.world).getHandle().H().a().spliterator(), false);
|
return StreamSupport.stream(((Iterable<?>) getIterable.invoke(getWorldEntities.invoke(getWorld.invoke(Config.world)))).spliterator(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
|
||||||
import de.steamwar.fightsystem.record.REntity;
|
|
||||||
import net.minecraft.core.IRegistry;
|
|
||||||
import net.minecraft.core.SectionPosition;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayOutBlockBreak;
|
|
||||||
import net.minecraft.world.entity.EntityTypes;
|
|
||||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
|
||||||
import net.minecraft.world.level.block.state.IBlockData;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class ProtocolWrapper18 implements ProtocolWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<List> equipmentStack = Reflection.getField(REntity.equipmentPacket, List.class, 0);
|
|
||||||
@Override
|
|
||||||
public void setEquipmentPacketStack(Object packet, String slot, Object stack) {
|
|
||||||
equipmentStack.set(packet, Collections.singletonList(new Pair<>(getSlot(slot), stack)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<?> spawnType = Reflection.getField(REntity.spawnPacket, EntityTypes.class, 0);
|
|
||||||
@Override
|
|
||||||
public void setSpawnPacketType(Object packet, EntityType type) {
|
|
||||||
switch(type) {
|
|
||||||
case PRIMED_TNT:
|
|
||||||
spawnType.set(packet, EntityTypes.as);
|
|
||||||
break;
|
|
||||||
case ARROW:
|
|
||||||
spawnType.set(packet, EntityTypes.d);
|
|
||||||
break;
|
|
||||||
case FIREBALL:
|
|
||||||
spawnType.set(packet, EntityTypes.S);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> enumItemSlot = Reflection.getClass("{nms.world.entity}.EnumItemSlot");
|
|
||||||
private static final Object[] itemSlots = enumItemSlot.getEnumConstants();
|
|
||||||
private static Object getSlot(String slot) {
|
|
||||||
switch(slot){
|
|
||||||
case "HEAD":
|
|
||||||
return itemSlots[5];
|
|
||||||
case "CHEST":
|
|
||||||
return itemSlots[4];
|
|
||||||
case "LEGS":
|
|
||||||
return itemSlots[3];
|
|
||||||
case "FEET":
|
|
||||||
return itemSlots[2];
|
|
||||||
case "OFFHAND":
|
|
||||||
return itemSlots[1];
|
|
||||||
case "MAINHAND":
|
|
||||||
default:
|
|
||||||
return itemSlots[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<SectionPosition> multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, SectionPosition.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<IBlockData[]> multiBlockChangeBlocks = Reflection.getField(TechHider.multiBlockChangePacket, IBlockData[].class, 0);
|
|
||||||
private static final BiFunction<Object, UnaryOperator<Object>, Object> iBlockDataArrayCloner = ProtocolAPI.arrayCloneGenerator(TechHider.iBlockData);
|
|
||||||
@Override
|
|
||||||
public Object multiBlockChangeHider(Player p, Object packet) {
|
|
||||||
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
|
||||||
if(TechHider.bypass(p, TechHider.blockPositionX.get(chunkCoords), TechHider.blockPositionZ.get(chunkCoords)))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
packet = TechHider.multiBlockChangeCloner.apply(packet);
|
|
||||||
multiBlockChangeBlocks.set(packet, iBlockDataArrayCloner.apply(multiBlockChangeBlocks.get(packet), block -> ProtocolWrapper.impl.iBlockDataHidden(block) ? TechHider.obfuscateIBlockData : block));
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<TileEntityTypes> tileEntityType = Reflection.getField(TechHider.tileEntityDataPacket, TileEntityTypes.class, 0);
|
|
||||||
@Override
|
|
||||||
public boolean unfilteredTileEntityDataAction(Object packet) {
|
|
||||||
return tileEntityType.get(packet) != TileEntityTypes.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket) {
|
|
||||||
return (p, packet) -> {
|
|
||||||
PacketPlayOutBlockBreak breakPacket = (PacketPlayOutBlockBreak) packet;
|
|
||||||
if(TechHider.bypass(p, TechHider.posToChunk(TechHider.blockPositionX.get(breakPacket.b())), TechHider.posToChunk(TechHider.blockPositionZ.get(breakPacket.b()))))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
if(!ProtocolWrapper.impl.iBlockDataHidden(breakPacket.c()))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
return new PacketPlayOutBlockBreak(breakPacket.b(), (IBlockData) TechHider.obfuscateIBlockData, breakPacket.d(), breakPacket.a());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent);
|
|
||||||
@Override
|
|
||||||
public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) {
|
|
||||||
return playerInfoDataConstructor.invoke(profile, 0, mode, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean iBlockDataHidden(Object iBlockData) {
|
|
||||||
return Config.HiddenBlocks.contains(IRegistry.U.b(((IBlockData) iBlockData).b()).a());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
|
||||||
import net.minecraft.core.IRegistry;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
|
||||||
import net.minecraft.util.SimpleBitStorage;
|
|
||||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.IntFunction;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class TechHider18 implements TechHider.ChunkHider {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> mapChunkPacket() {
|
|
||||||
return ClientboundLevelChunkWithLightPacket.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final UnaryOperator<Object> chunkPacketCloner = ProtocolAPI.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class);
|
|
||||||
private static final UnaryOperator<Object> chunkDataCloner = ProtocolAPI.shallowCloneGenerator(ClientboundLevelChunkPacketData.class);
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<Integer> chunkX = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> chunkZ = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 1);
|
|
||||||
private static final Reflection.FieldAccessor<ClientboundLevelChunkPacketData> chunkData = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, ClientboundLevelChunkPacketData.class, 0);
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<byte[]> dataField = Reflection.getField(ClientboundLevelChunkPacketData.class, byte[].class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<List> tileEntities = Reflection.getField(ClientboundLevelChunkPacketData.class, List.class, 0);
|
|
||||||
public static final Class<?> tileEntity = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData$a");
|
|
||||||
protected static final Reflection.FieldAccessor<TileEntityTypes> entityType = Reflection.getField(tileEntity, TileEntityTypes.class, 0);
|
|
||||||
|
|
||||||
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
|
||||||
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object mapChunkHider(Player p, Object packet) {
|
|
||||||
if(TechHider.bypass(p, chunkX.get(packet), chunkZ.get(packet)))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
packet = chunkPacketCloner.apply(packet);
|
|
||||||
Object data = chunkDataCloner.apply(chunkData.get(packet));
|
|
||||||
|
|
||||||
tileEntities.set(data, ((List<?>)tileEntities.get(data)).stream().filter(this::tileEntityVisible).collect(Collectors.toList()));
|
|
||||||
|
|
||||||
World world = p.getWorld();
|
|
||||||
int sections = (world.getMaxHeight() - world.getMinHeight()) / 16;
|
|
||||||
dataField.set(data, dataHider(dataField.get(data), sections));
|
|
||||||
|
|
||||||
chunkData.set(packet, data);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean tileEntityVisible(Object tile) {
|
|
||||||
return !Config.HiddenBlockEntities.contains(IRegistry.aa.b(entityType.get(tile)).a());
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] dataHider(byte[] data, int sections) {
|
|
||||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while(sections-- > 0) {
|
|
||||||
buffer.writeBytes(data, i, 2); // Block count
|
|
||||||
i += 2;
|
|
||||||
|
|
||||||
i = containerWalker(data, buffer, i, 15, blockId -> hiddenBlockIds.contains(blockId) ? obfuscateWith : blockId, (curI, dataArrayLength, bitsPerBlock) -> {
|
|
||||||
if(bitsPerBlock < 15) {
|
|
||||||
buffer.writeBytes(data, curI, dataArrayLength * 8);
|
|
||||||
} else {
|
|
||||||
ByteBuffer source = ByteBuffer.wrap(data, curI, dataArrayLength * 8);
|
|
||||||
long[] array = new long[dataArrayLength];
|
|
||||||
source.asLongBuffer().get(array);
|
|
||||||
SimpleBitStorage values = new SimpleBitStorage(bitsPerBlock, 4096, array);
|
|
||||||
|
|
||||||
for (int pos = 0; pos < 4096; pos++) {
|
|
||||||
if (hiddenBlockIds.contains(values.a(pos))) {
|
|
||||||
values.b(pos, obfuscateWith);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (long l : values.a())
|
|
||||||
buffer.writeLong(l);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
i = containerWalker(data, buffer, i, 6, value -> value, (curI, dataArrayLength, bitsPerBlock) -> buffer.writeBytes(data, curI, dataArrayLength * 8));
|
|
||||||
}
|
|
||||||
buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why
|
|
||||||
|
|
||||||
byte[] outdata = new byte[buffer.readableBytes()];
|
|
||||||
buffer.readBytes(outdata);
|
|
||||||
return outdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int containerWalker(byte[] data, ByteBuf buffer, int i, int globalPalette, IntFunction<Integer> palette, Region.TriConsumer<Integer, Integer, Byte> dataArray) {
|
|
||||||
byte bitsPerBlock = data[i++];
|
|
||||||
buffer.writeByte(bitsPerBlock);
|
|
||||||
|
|
||||||
if(bitsPerBlock == 0) {
|
|
||||||
int paletteValue = TechHider.readVarInt(data, i);
|
|
||||||
i += TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(TechHider.writeVarInt(palette.apply(paletteValue)));
|
|
||||||
}else if(bitsPerBlock < globalPalette) {
|
|
||||||
int paletteLength = TechHider.readVarInt(data, i);
|
|
||||||
int paletteLengthLength = TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(data, i, paletteLengthLength);
|
|
||||||
i += paletteLengthLength;
|
|
||||||
|
|
||||||
for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++) {
|
|
||||||
int paletteValue = TechHider.readVarInt(data, i);
|
|
||||||
i += TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(TechHider.writeVarInt(palette.apply(paletteValue)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
|
||||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(data, i, dataArrayLengthLength);
|
|
||||||
i += dataArrayLengthLength;
|
|
||||||
|
|
||||||
dataArray.accept(i, dataArrayLength, bitsPerBlock);
|
|
||||||
i += dataArrayLength * 8;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import net.minecraft.core.BlockPosition;
|
|
||||||
import net.minecraft.core.IRegistry;
|
|
||||||
import net.minecraft.resources.MinecraftKey;
|
|
||||||
import net.minecraft.server.level.WorldServer;
|
|
||||||
import net.minecraft.world.entity.EntityPose;
|
|
||||||
import net.minecraft.world.level.block.state.IBlockData;
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import net.minecraft.world.level.material.FluidTypes;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class BlockIdWrapper19 implements BlockIdWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int blockToId(Block block) {
|
|
||||||
return net.minecraft.world.level.block.Block.i(((CraftBlock)block).getNMS());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlock(World world, int x, int y, int z, int blockState) {
|
|
||||||
IBlockData blockData = Objects.requireNonNull(net.minecraft.world.level.block.Block.a(blockState));
|
|
||||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
|
||||||
BlockPosition pos = new BlockPosition(x, y, z);
|
|
||||||
cworld.m(pos);
|
|
||||||
cworld.a(pos, blockData, 1042);
|
|
||||||
cworld.k().a(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Integer> getHiddenBlockIds() {
|
|
||||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
|
||||||
for(String tag : Config.HiddenBlocks){
|
|
||||||
for(IBlockData data : IRegistry.V.a(new MinecraftKey(tag)).k().a()){
|
|
||||||
hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Config.HiddenBlocks.contains("water")){
|
|
||||||
Fluid water = FluidTypes.c.h();
|
|
||||||
for(IBlockData data : net.minecraft.world.level.block.Block.o) {
|
|
||||||
if(data.p() == water) {
|
|
||||||
hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hiddenBlockIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getObfuscateWith() { //ResourceLocation, DefaultedRegistry
|
|
||||||
return net.minecraft.world.level.block.Block.i(IRegistry.V.a(new MinecraftKey(Config.ObfuscateWith)).m());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getPose(boolean sneaking) {
|
|
||||||
return sneaking ? EntityPose.f : EntityPose.a;
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,53 +19,12 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import net.minecraft.world.level.chunk.Chunk;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
public class CraftbukkitWrapper19 extends CraftbukkitWrapper18 {
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
public class CraftbukkitWrapper19 implements CraftbukkitWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resetChunk(World world, World backup, int x, int z) {
|
|
||||||
net.minecraft.world.level.World w = ((CraftWorld) world).getHandle();
|
|
||||||
Chunk chunk = w.d(x, z);
|
|
||||||
Chunk backupChunk = ((CraftWorld) backup).getHandle().d(x, z);
|
|
||||||
|
|
||||||
System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
|
||||||
((CraftPlayer)player).getHandle().a(pack, sha1, true, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().ch();
|
return getEntity(e).ck();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).u().d());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<?> entityIterator() {
|
|
||||||
return StreamSupport.stream(((CraftWorld) Config.world).getHandle().F().a().spliterator(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
|
||||||
import de.steamwar.fightsystem.record.REntity;
|
|
||||||
import net.minecraft.core.IRegistry;
|
|
||||||
import net.minecraft.core.SectionPosition;
|
|
||||||
import net.minecraft.world.entity.EntityTypes;
|
|
||||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
|
||||||
import net.minecraft.world.level.block.state.IBlockData;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class ProtocolWrapper19 implements ProtocolWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<List> equipmentStack = Reflection.getField(REntity.equipmentPacket, List.class, 0);
|
|
||||||
@Override
|
|
||||||
public void setEquipmentPacketStack(Object packet, String slot, Object stack) {
|
|
||||||
equipmentStack.set(packet, Collections.singletonList(new Pair<>(getSlot(slot), stack)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<?> spawnType = Reflection.getField(REntity.spawnPacket, EntityTypes.class, 0);
|
|
||||||
@Override
|
|
||||||
public void setSpawnPacketType(Object packet, EntityType type) {
|
|
||||||
switch(type) {
|
|
||||||
case PRIMED_TNT:
|
|
||||||
spawnType.set(packet, EntityTypes.as);
|
|
||||||
break;
|
|
||||||
case ARROW:
|
|
||||||
spawnType.set(packet, EntityTypes.d);
|
|
||||||
break;
|
|
||||||
case FIREBALL:
|
|
||||||
spawnType.set(packet, EntityTypes.S);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> enumItemSlot = Reflection.getClass("{nms.world.entity}.EnumItemSlot");
|
|
||||||
private static final Object[] itemSlots = enumItemSlot.getEnumConstants();
|
|
||||||
private static Object getSlot(String slot) {
|
|
||||||
switch(slot){
|
|
||||||
case "HEAD":
|
|
||||||
return itemSlots[5];
|
|
||||||
case "CHEST":
|
|
||||||
return itemSlots[4];
|
|
||||||
case "LEGS":
|
|
||||||
return itemSlots[3];
|
|
||||||
case "FEET":
|
|
||||||
return itemSlots[2];
|
|
||||||
case "OFFHAND":
|
|
||||||
return itemSlots[1];
|
|
||||||
case "MAINHAND":
|
|
||||||
default:
|
|
||||||
return itemSlots[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<SectionPosition> multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, SectionPosition.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<IBlockData[]> multiBlockChangeBlocks = Reflection.getField(TechHider.multiBlockChangePacket, IBlockData[].class, 0);
|
|
||||||
private static final BiFunction<Object, UnaryOperator<Object>, Object> iBlockDataArrayCloner = ProtocolAPI.arrayCloneGenerator(TechHider.iBlockData);
|
|
||||||
@Override
|
|
||||||
public Object multiBlockChangeHider(Player p, Object packet) {
|
|
||||||
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
|
||||||
if(TechHider.bypass(p, TechHider.blockPositionX.get(chunkCoords), TechHider.blockPositionZ.get(chunkCoords)))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
packet = TechHider.multiBlockChangeCloner.apply(packet);
|
|
||||||
multiBlockChangeBlocks.set(packet, iBlockDataArrayCloner.apply(multiBlockChangeBlocks.get(packet), block -> ProtocolWrapper.impl.iBlockDataHidden(block) ? TechHider.obfuscateIBlockData : block));
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<TileEntityTypes> tileEntityType = Reflection.getField(TechHider.tileEntityDataPacket, TileEntityTypes.class, 0);
|
|
||||||
@Override
|
|
||||||
public boolean unfilteredTileEntityDataAction(Object packet) {
|
|
||||||
return tileEntityType.get(packet) != TileEntityTypes.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent, Reflection.getClass("net.minecraft.world.entity.player.ProfilePublicKey$a"));
|
|
||||||
@Override
|
|
||||||
public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) {
|
|
||||||
return playerInfoDataConstructor.invoke(profile, 0, mode, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean iBlockDataHidden(Object iBlockData) {
|
|
||||||
return Config.HiddenBlocks.contains(IRegistry.V.b(((IBlockData) iBlockData).b()).a());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import net.minecraft.core.IRegistry;
|
|
||||||
|
|
||||||
public class TechHider19 extends TechHider18 {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean tileEntityVisible(Object tile) {
|
|
||||||
return !Config.HiddenBlockEntities.contains(IRegistry.ab.b(entityType.get(tile)).a());
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,14 +19,9 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class BlockIdWrapper8 implements BlockIdWrapper {
|
public class BlockIdWrapper8 implements BlockIdWrapper {
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@ -37,27 +32,9 @@ public class BlockIdWrapper8 implements BlockIdWrapper {
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void setBlock(World world, int x, int y, int z, int blockState) {
|
public void setBlock(World world, int x, int y, int z, int blockState) {
|
||||||
|
if((blockState >> 4) > 256) // Illegal blockstate / corrupted replay
|
||||||
|
blockState = 0;
|
||||||
|
|
||||||
world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false);
|
world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public Set<Integer> getHiddenBlockIds() {
|
|
||||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
|
||||||
for(String tag : Config.HiddenBlocks){
|
|
||||||
hiddenBlockIds.add(Material.matchMaterial(tag).getId() << 4);
|
|
||||||
}
|
|
||||||
return hiddenBlockIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public int getObfuscateWith() {
|
|
||||||
return Material.matchMaterial(Config.ObfuscateWith).getId() << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getPose(boolean sneaking) {
|
|
||||||
return Byte.valueOf((byte)(sneaking ? 2 : 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,24 +19,25 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.fight.FightTeam;
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
import de.steamwar.fightsystem.listener.Recording;
|
import de.steamwar.fightsystem.listener.Recording;
|
||||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||||
import de.steamwar.fightsystem.record.REntity;
|
|
||||||
import net.minecraft.server.v1_8_R3.DataWatcher;
|
import net.minecraft.server.v1_8_R3.DataWatcher;
|
||||||
import net.minecraft.server.v1_8_R3.EntityEnderDragon;
|
import net.minecraft.server.v1_8_R3.EntityEnderDragon;
|
||||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
|
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
|
||||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
|
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
|
||||||
import net.royawesome.jlibnoise.MathHelper;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.*;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.scoreboard.Team;
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class BountifulWrapper8 implements BountifulWrapper {
|
public class BountifulWrapper8 implements BountifulWrapper {
|
||||||
|
|
||||||
@ -92,47 +93,6 @@ public class BountifulWrapper8 implements BountifulWrapper {
|
|||||||
world.playEffect(new Location(world, x, y, z), Effect.valueOf(particleName), 1);
|
world.playEffect(new Location(world, x, y, z), Effect.valueOf(particleName), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getDataWatcherObject(int index, Class<?> type) {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> watchableObject = Reflection.getClass("{nms}.DataWatcher$WatchableObject");
|
|
||||||
private static final Reflection.ConstructorInvoker watchableObjectConstructor = Reflection.getConstructor(watchableObject, int.class, int.class, Object.class);
|
|
||||||
private static final Map<Class<?>, Integer> watchableDatatypes = new HashMap<>();
|
|
||||||
static {
|
|
||||||
watchableDatatypes.put(byte.class, 0);
|
|
||||||
watchableDatatypes.put(short.class, 1);
|
|
||||||
watchableDatatypes.put(int.class, 2);
|
|
||||||
watchableDatatypes.put(float.class, 3);
|
|
||||||
watchableDatatypes.put(String.class, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getDataWatcherItem(Object dwo, Object value) {
|
|
||||||
return watchableObjectConstructor.invoke(watchableDatatypes.get(value.getClass()), dwo, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<Integer> teleportX = Reflection.getField(REntity.teleportPacket, int.class, 1);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> teleportY = Reflection.getField(REntity.teleportPacket, int.class, 2);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> teleportZ = Reflection.getField(REntity.teleportPacket, int.class, 3);
|
|
||||||
@Override
|
|
||||||
public void setTeleportPacketPosition(Object packet, double x, double y, double z) {
|
|
||||||
teleportX.set(packet, MathHelper.floor(x * 32));
|
|
||||||
teleportY.set(packet, MathHelper.floor(y * 32));
|
|
||||||
teleportZ.set(packet, MathHelper.floor(z * 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpawnPacketUUID(Object packet, UUID uuid) {
|
|
||||||
// field not present
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNamedSpawnPosition(Object packet, double x, double y, double z) {
|
|
||||||
//no implementation for 1.8
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Set<Player> seesDragon = new HashSet<>();
|
private final Set<Player> seesDragon = new HashSet<>();
|
||||||
private final PacketPlayOutSpawnEntityLiving spawnDragon;
|
private final PacketPlayOutSpawnEntityLiving spawnDragon;
|
||||||
private final int spawnDragonId;
|
private final int spawnDragonId;
|
||||||
|
@ -24,14 +24,8 @@ import net.minecraft.server.v1_8_R3.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class CraftbukkitWrapper8 implements CraftbukkitWrapper {
|
public class CraftbukkitWrapper8 implements CraftbukkitWrapper {
|
||||||
@ -49,24 +43,11 @@ public class CraftbukkitWrapper8 implements CraftbukkitWrapper {
|
|||||||
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
|
||||||
((CraftPlayer)player).getHandle().setResourcePack(pack, sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().getHeadRotation();
|
return ((CraftEntity)e).getHandle().getHeadRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<?> entityIterator() {
|
public Stream<?> entityIterator() {
|
||||||
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
||||||
|
@ -19,12 +19,11 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import de.steamwar.fightsystem.record.REntity;
|
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@ -38,7 +37,7 @@ public class FlatteningWrapper8 implements FlatteningWrapper {
|
|||||||
@Override
|
@Override
|
||||||
public boolean isWater(Block block) {
|
public boolean isWater(Block block) {
|
||||||
Material type = block.getType();
|
Material type = block.getType();
|
||||||
return type == Material.WATER || type == Material.STATIONARY_WATER;
|
return type == Material.WATER || type == Material.STATIONARY_WATER || type == Material.LAVA || type == Material.STATIONARY_LAVA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -60,11 +59,6 @@ public class FlatteningWrapper8 implements FlatteningWrapper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack onBreak(Block block) {
|
|
||||||
return block.getDrops().stream().findAny().orElse(new ItemStack(Material.AIR));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doRecord(BlockPhysicsEvent e) {
|
public boolean doRecord(BlockPhysicsEvent e) {
|
||||||
return e.getChangedType() != e.getBlock().getType();
|
return e.getChangedType() != e.getBlock().getType();
|
||||||
@ -80,12 +74,13 @@ public class FlatteningWrapper8 implements FlatteningWrapper {
|
|||||||
return block.getType() == Material.PISTON_MOVING_PIECE;
|
return block.getType() == Material.PISTON_MOVING_PIECE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> dataWatcher = Reflection.getClass("{nms}.DataWatcher");
|
|
||||||
private static final Reflection.FieldAccessor<?> namedSpawnDataWatcher = Reflection.getField(REntity.namedSpawnPacket, dataWatcher, 0);
|
|
||||||
private static final Class<?> entity = Reflection.getClass("{nms}.Entity");
|
|
||||||
private static final Reflection.ConstructorInvoker dataWatcherConstructor = Reflection.getConstructor(dataWatcher, entity);
|
|
||||||
@Override
|
@Override
|
||||||
public void setNamedSpawnPacketDataWatcher(Object packet) {
|
public boolean isFacingWater(Block dispenser) {
|
||||||
namedSpawnDataWatcher.set(packet, dataWatcherConstructor.invoke((Object) null));
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCrouching(Player player) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
|
||||||
import de.steamwar.fightsystem.record.REntity;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class ProtocolWrapper8 implements ProtocolWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<?> equipmentSlot;
|
|
||||||
private static final Object[] itemSlots;
|
|
||||||
static {
|
|
||||||
if(Core.getVersion() == 8) {
|
|
||||||
equipmentSlot = Reflection.getField(REntity.equipmentPacket, int.class, 1);
|
|
||||||
itemSlots = new Integer[]{0, 0, 1, 2, 3, 4};
|
|
||||||
} else {
|
|
||||||
Class<?> enumItemSlot = Reflection.getClass("{nms.world.entity}.EnumItemSlot");
|
|
||||||
equipmentSlot = Reflection.getField(REntity.equipmentPacket, enumItemSlot, 0);
|
|
||||||
itemSlots = enumItemSlot.getEnumConstants();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<?> equipmentStack = Reflection.getField(REntity.equipmentPacket, REntity.itemStack, 0);
|
|
||||||
@Override
|
|
||||||
public void setEquipmentPacketStack(Object packet, String slot, Object stack) {
|
|
||||||
switch(slot){
|
|
||||||
case "HEAD":
|
|
||||||
equipmentSlot.set(packet, itemSlots[5]);
|
|
||||||
break;
|
|
||||||
case "CHEST":
|
|
||||||
equipmentSlot.set(packet, itemSlots[4]);
|
|
||||||
break;
|
|
||||||
case "LEGS":
|
|
||||||
equipmentSlot.set(packet, itemSlots[3]);
|
|
||||||
break;
|
|
||||||
case "FEET":
|
|
||||||
equipmentSlot.set(packet, itemSlots[2]);
|
|
||||||
break;
|
|
||||||
case "OFFHAND":
|
|
||||||
equipmentSlot.set(packet, itemSlots[1]);
|
|
||||||
break;
|
|
||||||
case "MAINHAND":
|
|
||||||
default:
|
|
||||||
equipmentSlot.set(packet, itemSlots[0]);
|
|
||||||
}
|
|
||||||
equipmentStack.set(packet, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<?> spawnType;
|
|
||||||
private static final Object tnt;
|
|
||||||
private static final Object arrow;
|
|
||||||
private static final Object fireball;
|
|
||||||
static {
|
|
||||||
if(Core.getVersion() < 14) {
|
|
||||||
spawnType = Reflection.getField(REntity.spawnPacket, int.class, Core.getVersion() > 8 ? 6 : 9);
|
|
||||||
tnt = 50;
|
|
||||||
arrow = 60;
|
|
||||||
fireball = 63;
|
|
||||||
} else {
|
|
||||||
Class<?> entityTypes = Reflection.getClass("{nms.world.entity}.EntityTypes");
|
|
||||||
spawnType = Reflection.getField(REntity.spawnPacket, entityTypes, 0);
|
|
||||||
tnt = Reflection.getField(entityTypes, "TNT", entityTypes).get(null);
|
|
||||||
arrow = Reflection.getField(entityTypes, "ARROW", entityTypes).get(null);
|
|
||||||
fireball = Reflection.getField(entityTypes, "FIREBALL", entityTypes).get(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setSpawnPacketType(Object packet, EntityType type) {
|
|
||||||
switch(type) {
|
|
||||||
case PRIMED_TNT:
|
|
||||||
spawnType.set(packet, tnt);
|
|
||||||
break;
|
|
||||||
case ARROW:
|
|
||||||
spawnType.set(packet, arrow);
|
|
||||||
break;
|
|
||||||
case FIREBALL:
|
|
||||||
spawnType.set(packet, fireball);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> chunkCoordinateIntPair = Reflection.getClass("{nms}.ChunkCoordIntPair");
|
|
||||||
private static final Reflection.FieldAccessor<?> multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, chunkCoordinateIntPair, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> chunkCoordinateX = Reflection.getField(chunkCoordinateIntPair, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> chunkCoordinateZ = Reflection.getField(chunkCoordinateIntPair, int.class, 1);
|
|
||||||
private static final Class<?> multiBlockChangeInfo = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo");
|
|
||||||
private static final Reflection.ConstructorInvoker multiBlockChangeInfoConstructor = Reflection.getConstructor(multiBlockChangeInfo, TechHider.multiBlockChangePacket, short.class, TechHider.iBlockData);
|
|
||||||
private static final BiFunction<Object, UnaryOperator<Object>, Object> multiBlockChangeInfoArrayCloner = ProtocolAPI.arrayCloneGenerator(multiBlockChangeInfo);
|
|
||||||
private static final Reflection.FieldAccessor<?> multiBlockChangeInfoBlock = Reflection.getField(multiBlockChangeInfo, TechHider.iBlockData, 0);
|
|
||||||
private static final Reflection.FieldAccessor<?> multiBlockChangeInfoPos = Reflection.getField(multiBlockChangeInfo, short.class, 0);
|
|
||||||
private static final Class<?> multiBlockChangeInfoArray = Reflection.getClass("[L{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo;");
|
|
||||||
private static final Reflection.FieldAccessor<?> multiBlockChangeInfos = Reflection.getField(TechHider.multiBlockChangePacket, multiBlockChangeInfoArray, 0);
|
|
||||||
@Override
|
|
||||||
public Object multiBlockChangeHider(Player p, Object packet) {
|
|
||||||
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
|
||||||
if(TechHider.bypass(p, chunkCoordinateX.get(chunkCoords), chunkCoordinateZ.get(chunkCoords)))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
Object modpacket = TechHider.multiBlockChangeCloner.apply(packet);
|
|
||||||
multiBlockChangeInfos.set(modpacket, multiBlockChangeInfoArrayCloner.apply(multiBlockChangeInfos.get(modpacket), mbci -> {
|
|
||||||
if(ProtocolWrapper.impl.iBlockDataHidden(multiBlockChangeInfoBlock.get(mbci)))
|
|
||||||
return multiBlockChangeInfoConstructor.invoke(modpacket, multiBlockChangeInfoPos.get(mbci), TechHider.obfuscateIBlockData);
|
|
||||||
return mbci;
|
|
||||||
}));
|
|
||||||
return modpacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<Integer> tileEntityDataAction = Reflection.getField(TechHider.tileEntityDataPacket, int.class, 0);
|
|
||||||
@Override
|
|
||||||
public boolean unfilteredTileEntityDataAction(Object packet) {
|
|
||||||
return tileEntityDataAction.get(packet) != 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, Fight.playerInfoPacket, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent);
|
|
||||||
@Override
|
|
||||||
public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) {
|
|
||||||
return playerInfoDataConstructor.invoke(packet, profile, 0, mode, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(TechHider.iBlockData, null, TechHider.block);
|
|
||||||
private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(TechHider.craftMagicNumbers, "getMaterial", Material.class, TechHider.block);
|
|
||||||
@Override
|
|
||||||
public boolean iBlockDataHidden(Object iBlockData) {
|
|
||||||
return Config.HiddenBlocks.contains(((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData))).name().toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class TechHider8 implements TechHider.ChunkHider {
|
|
||||||
|
|
||||||
protected static final Class<?> mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk");
|
|
||||||
@Override
|
|
||||||
public Class<?> mapChunkPacket() {
|
|
||||||
return mapChunkPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object mapChunkHider(Player p, Object packet) {
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,6 +39,7 @@ import com.sk89q.worldedit.session.ClipboardHolder;
|
|||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
|
import de.steamwar.sql.SchematicData;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -141,6 +142,6 @@ public class WorldeditWrapper8 implements WorldeditWrapper {
|
|||||||
throw new SecurityException(e);
|
throw new SecurityException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
schem.saveFromBytes(outputStream.toByteArray(), false);
|
new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ import de.steamwar.fightsystem.fight.Fight;
|
|||||||
import de.steamwar.fightsystem.fight.FightTeam;
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
import de.steamwar.fightsystem.listener.Recording;
|
import de.steamwar.fightsystem.listener.Recording;
|
||||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||||
import de.steamwar.fightsystem.record.REntity;
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.attribute.Attribute;
|
import org.bukkit.attribute.Attribute;
|
||||||
import org.bukkit.attribute.AttributeInstance;
|
import org.bukkit.attribute.AttributeInstance;
|
||||||
@ -39,11 +38,8 @@ import org.bukkit.event.player.PlayerPickupArrowEvent;
|
|||||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||||
import org.bukkit.scoreboard.Team;
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class BountifulWrapper9 implements BountifulWrapper {
|
public class BountifulWrapper9 implements BountifulWrapper {
|
||||||
|
|
||||||
@ -120,58 +116,6 @@ public class BountifulWrapper9 implements BountifulWrapper {
|
|||||||
world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1);
|
world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final Class<?> dataWatcherObject = Reflection.getClass("{nms.network.syncher}.DataWatcherObject");
|
|
||||||
private static final Class<?> dataWatcherRegistry = Reflection.getClass("{nms.network.syncher}.DataWatcherRegistry");
|
|
||||||
private static final Class<?> dataWatcherSerializer = Reflection.getClass("{nms.network.syncher}.DataWatcherSerializer");
|
|
||||||
private static final Reflection.ConstructorInvoker dataWatcherObjectConstructor = Reflection.getConstructor(dataWatcherObject, int.class, dataWatcherSerializer);
|
|
||||||
@Override
|
|
||||||
public Object getDataWatcherObject(int index, Class<?> type) {
|
|
||||||
for(Field field : dataWatcherRegistry.getFields()) {
|
|
||||||
if(dataWatcherSerializer.isAssignableFrom(field.getType()) && type.equals(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0])) {
|
|
||||||
try {
|
|
||||||
return dataWatcherObjectConstructor.invoke(index, field.get(null));
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new SecurityException("Could not get field", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new SecurityException("Could not find Serializer for " + type.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> item = Reflection.getClass("{nms.network.syncher}.DataWatcher$Item");
|
|
||||||
private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class);
|
|
||||||
@Override
|
|
||||||
public Object getDataWatcherItem(Object dwo, Object value) {
|
|
||||||
return itemConstructor.invoke(dwo, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<Double> teleportX = Reflection.getField(REntity.teleportPacket, double.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Double> teleportY = Reflection.getField(REntity.teleportPacket, double.class, 1);
|
|
||||||
private static final Reflection.FieldAccessor<Double> teleportZ = Reflection.getField(REntity.teleportPacket, double.class, 2);
|
|
||||||
@Override
|
|
||||||
public void setTeleportPacketPosition(Object packet, double x, double y, double z) {
|
|
||||||
teleportX.set(packet, x);
|
|
||||||
teleportY.set(packet, y);
|
|
||||||
teleportZ.set(packet, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<UUID> spawnUUID = Reflection.getField(REntity.spawnPacket, UUID.class, 0);
|
|
||||||
@Override
|
|
||||||
public void setSpawnPacketUUID(Object packet, UUID uuid) {
|
|
||||||
spawnUUID.set(packet, uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<Double> namedSpawnX = Reflection.getField(REntity.namedSpawnPacket, double.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Double> namedSpawnY = Reflection.getField(REntity.namedSpawnPacket, double.class, 1);
|
|
||||||
private static final Reflection.FieldAccessor<Double> namedSpawnZ = Reflection.getField(REntity.namedSpawnPacket, double.class, 2);
|
|
||||||
@Override
|
|
||||||
public void setNamedSpawnPosition(Object packet, double x, double y, double z) {
|
|
||||||
namedSpawnX.set(packet, x);
|
|
||||||
namedSpawnY.set(packet, y);
|
|
||||||
namedSpawnZ.set(packet, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Map<Player, BossBar> barMap = new HashMap<>();
|
private final Map<Player, BossBar> barMap = new HashMap<>();
|
||||||
@Override
|
@Override
|
||||||
public void sendBar(Player player, FightTeam team, double progress, String text) {
|
public void sendBar(Player player, FightTeam team, double progress, String text) {
|
||||||
|
@ -25,14 +25,8 @@ import net.minecraft.server.v1_9_R2.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_9_R2.CraftWorld;
|
import org.bukkit.craftbukkit.v1_9_R2.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_9_R2.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class CraftbukkitWrapper9 implements CraftbukkitWrapper {
|
public class CraftbukkitWrapper9 implements CraftbukkitWrapper {
|
||||||
@ -52,24 +46,11 @@ public class CraftbukkitWrapper9 implements CraftbukkitWrapper {
|
|||||||
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendResourcePack(Player player, String pack, String sha1) {
|
|
||||||
((CraftPlayer)player).getHandle().setResourcePack(pack, sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float headRotation(Entity e) {
|
public float headRotation(Entity e) {
|
||||||
return ((CraftEntity)e).getHandle().getHeadRotation();
|
return ((CraftEntity)e).getHandle().getHeadRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasItems(ItemStack stack) {
|
|
||||||
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c());
|
|
||||||
keys.remove("Enchantments");
|
|
||||||
keys.remove("Damage");
|
|
||||||
return !keys.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<?> entityIterator() {
|
public Stream<?> entityIterator() {
|
||||||
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
return ((CraftWorld) Config.world).getHandle().entityList.stream();
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class TechHider9 extends TechHider8 {
|
|
||||||
|
|
||||||
private static final UnaryOperator<Object> mapChunkCloner = ProtocolAPI.shallowCloneGenerator(mapChunkPacket);
|
|
||||||
|
|
||||||
private static final Reflection.FieldAccessor<Integer> mapChunkX = Reflection.getField(mapChunkPacket, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> mapChunkZ = Reflection.getField(mapChunkPacket, int.class, 1);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> mapChunkBitMask = Reflection.getField(mapChunkPacket, int.class, 2);
|
|
||||||
private static final Reflection.FieldAccessor<List> mapChunkBlockEntities = Reflection.getField(mapChunkPacket, List.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<byte[]> mapChunkData = Reflection.getField(mapChunkPacket, byte[].class, 0);
|
|
||||||
|
|
||||||
private static final Class<?> nbtTagCompound = Reflection.getClass("{nms.nbt}.NBTTagCompound");
|
|
||||||
private static final Reflection.MethodInvoker nbtTagGetString = Reflection.getTypedMethod(nbtTagCompound, null, String.class, String.class);
|
|
||||||
|
|
||||||
protected final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
|
||||||
protected final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object mapChunkHider(Player p, Object packet) {
|
|
||||||
if(TechHider.bypass(p, mapChunkX.get(packet), mapChunkZ.get(packet)))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
packet = mapChunkCloner.apply(packet);
|
|
||||||
mapChunkBlockEntities.set(packet, ((List<?>)mapChunkBlockEntities.get(packet)).stream().filter(
|
|
||||||
nbttag -> !Config.HiddenBlockEntities.contains((String) nbtTagGetString.invoke(nbttag, "id"))
|
|
||||||
).collect(Collectors.toList()));
|
|
||||||
|
|
||||||
byte[] data = dataHider(mapChunkData.get(packet), mapChunkBitMask.get(packet));
|
|
||||||
mapChunkData.set(packet, data);
|
|
||||||
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected byte[] dataHider(byte[] data, Integer primaryBitMask) {
|
|
||||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while(i < data.length){
|
|
||||||
byte bitsPerBlock = data[i++];
|
|
||||||
buffer.writeByte(bitsPerBlock);
|
|
||||||
|
|
||||||
if(bitsPerBlock != 13){
|
|
||||||
int paletteLength = TechHider.readVarInt(data, i);
|
|
||||||
int paletteLengthLength = TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(data, i, paletteLengthLength);
|
|
||||||
i += paletteLengthLength;
|
|
||||||
|
|
||||||
for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++){
|
|
||||||
int entry = TechHider.readVarInt(data, i);
|
|
||||||
i += TechHider.readVarIntLength(data, i);
|
|
||||||
|
|
||||||
if(hiddenBlockIds.contains(entry)){
|
|
||||||
entry = obfuscateWith;
|
|
||||||
}
|
|
||||||
buffer.writeBytes(TechHider.writeVarInt(entry));
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
buffer.writeByte(data[++i]); //Empty palette
|
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Full chunk occured");
|
|
||||||
}
|
|
||||||
|
|
||||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
|
||||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
|
||||||
buffer.writeBytes(data, i, dataArrayLength*8 + dataArrayLengthLength);
|
|
||||||
i += dataArrayLengthLength;
|
|
||||||
i += dataArrayLength * 8;
|
|
||||||
|
|
||||||
buffer.writeBytes(data, i, 4096);
|
|
||||||
i += 4096; //Skylight (Not in Nether/End!!!) 2048 + Blocklight 2048
|
|
||||||
}
|
|
||||||
|
|
||||||
data = new byte[buffer.readableBytes()];
|
|
||||||
buffer.readBytes(data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,7 +20,7 @@ Ranks: [] # Disables ranks for this schematic type if missing
|
|||||||
|
|
||||||
Times:
|
Times:
|
||||||
# Time in seconds the server stops after starting if nobody joins
|
# Time in seconds the server stops after starting if nobody joins
|
||||||
NoPlayersOnlineDuration: 30 # defaults to 30 if missing
|
NoPlayersOnlineDuration: 300 # defaults to 300 if missing
|
||||||
# Time in seconds the team leaders have to choose their schematic
|
# Time in seconds the team leaders have to choose their schematic
|
||||||
PreSchemPasteDuration: 120 # defaults to 120 if missing
|
PreSchemPasteDuration: 120 # defaults to 120 if missing
|
||||||
# Time in seconds for preparing
|
# Time in seconds for preparing
|
||||||
@ -72,6 +72,8 @@ Schematic:
|
|||||||
ReplaceObsidianBedrock: false # defaults to false if missing
|
ReplaceObsidianBedrock: false # defaults to false if missing
|
||||||
# If the replacement should happen with block updates
|
# If the replacement should happen with block updates
|
||||||
ReplaceWithBlockupdates: false # defaults to false if missing
|
ReplaceWithBlockupdates: false # defaults to false if missing
|
||||||
|
# If the schematic perparation arena mode is time limited
|
||||||
|
UnlimitedPrepare: false # defaults to false if missing
|
||||||
# Maximal amount of blocks allowed in the schematic
|
# Maximal amount of blocks allowed in the schematic
|
||||||
MaxBlocks: 0 # defaults to 0 (ignored) if missing
|
MaxBlocks: 0 # defaults to 0 (ignored) if missing
|
||||||
# Maximal amount of items per dispenser
|
# Maximal amount of items per dispenser
|
||||||
|
@ -43,10 +43,11 @@ public enum ArenaMode {
|
|||||||
public static final Set<ArenaMode> AntiReplay = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(REPLAY)));
|
public static final Set<ArenaMode> AntiReplay = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(REPLAY)));
|
||||||
public static final Set<ArenaMode> AntiTest = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK)));
|
public static final Set<ArenaMode> AntiTest = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK)));
|
||||||
public static final Set<ArenaMode> AntiEvent = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT)));
|
public static final Set<ArenaMode> AntiEvent = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT)));
|
||||||
|
public static final Set<ArenaMode> AntiTestCheckPrepare = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE)));
|
||||||
public static final Set<ArenaMode> AntiPrepare = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PREPARE)));
|
public static final Set<ArenaMode> AntiPrepare = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PREPARE)));
|
||||||
public static final Set<ArenaMode> VariableTeams = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT, REPLAY)));
|
public static final Set<ArenaMode> VariableTeams = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT, REPLAY)));
|
||||||
public static final Set<ArenaMode> RankedEvent = Collections.unmodifiableSet(EnumSet.of(EVENT, REPLAY));
|
public static final Set<ArenaMode> RankedEvent = Collections.unmodifiableSet(EnumSet.of(EVENT, REPLAY));
|
||||||
public static final Set<ArenaMode> Restartable = Collections.unmodifiableSet(EnumSet.of(NORMAL));
|
public static final Set<ArenaMode> Restartable = Collections.unmodifiableSet(EnumSet.of(NORMAL, TEST));
|
||||||
public static final Set<ArenaMode> NotRestartable = Collections.unmodifiableSet(EnumSet.of(EVENT, REPLAY));
|
public static final Set<ArenaMode> NotRestartable = Collections.unmodifiableSet(EnumSet.of(EVENT, REPLAY));
|
||||||
public static final Set<ArenaMode> SoloLeader = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK, PREPARE));
|
public static final Set<ArenaMode> SoloLeader = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK, PREPARE));
|
||||||
public static final Set<ArenaMode> NotOnBau = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE, REPLAY)));
|
public static final Set<ArenaMode> NotOnBau = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE, REPLAY)));
|
||||||
|
@ -61,6 +61,7 @@ public class Config {
|
|||||||
public static final Region BlueExtendRegion;
|
public static final Region BlueExtendRegion;
|
||||||
public static final Region RedExtendRegion;
|
public static final Region RedExtendRegion;
|
||||||
public static final Region ArenaRegion;
|
public static final Region ArenaRegion;
|
||||||
|
public static final Region PlayerRegion;
|
||||||
|
|
||||||
public static final Location TeamBlueSpawn;
|
public static final Location TeamBlueSpawn;
|
||||||
public static final Location TeamRedSpawn;
|
public static final Location TeamRedSpawn;
|
||||||
@ -87,6 +88,7 @@ public class Config {
|
|||||||
public static final boolean PasteAligned;
|
public static final boolean PasteAligned;
|
||||||
public static final boolean ReplaceObsidianBedrock;
|
public static final boolean ReplaceObsidianBedrock;
|
||||||
public static final boolean ReplaceWithBlockupdates;
|
public static final boolean ReplaceWithBlockupdates;
|
||||||
|
public static final boolean UnlimitedPrepare;
|
||||||
|
|
||||||
//team parameter
|
//team parameter
|
||||||
public static final String TeamRedName;
|
public static final String TeamRedName;
|
||||||
@ -155,7 +157,7 @@ public class Config {
|
|||||||
}
|
}
|
||||||
FileConfiguration worldconfig = YamlConfiguration.loadConfiguration(worldConfigFile);
|
FileConfiguration worldconfig = YamlConfiguration.loadConfiguration(worldConfigFile);
|
||||||
|
|
||||||
NoPlayerOnlineDuration = config.getInt("Times.NoPlayersOnlineDuration", 30);
|
NoPlayerOnlineDuration = config.getInt("Times.NoPlayersOnlineDuration", 300);
|
||||||
PreSchemPasteDuration = config.getInt("Times.PreSchemPasteDuration", 120);
|
PreSchemPasteDuration = config.getInt("Times.PreSchemPasteDuration", 120);
|
||||||
SetupDuration = config.getInt("Times.SetupDuration", 300);
|
SetupDuration = config.getInt("Times.SetupDuration", 300);
|
||||||
PreFightDuration = config.getInt("Times.PreFightDuration", 30);
|
PreFightDuration = config.getInt("Times.PreFightDuration", 30);
|
||||||
@ -184,6 +186,7 @@ public class Config {
|
|||||||
PasteAligned = config.getBoolean("Schematic.PasteAligned", false);
|
PasteAligned = config.getBoolean("Schematic.PasteAligned", false);
|
||||||
ReplaceObsidianBedrock = config.getBoolean("Schematic.ReplaceObsidianBedrock", false);
|
ReplaceObsidianBedrock = config.getBoolean("Schematic.ReplaceObsidianBedrock", false);
|
||||||
ReplaceWithBlockupdates = config.getBoolean("Schematic.ReplaceWithBlockupdates", false);
|
ReplaceWithBlockupdates = config.getBoolean("Schematic.ReplaceWithBlockupdates", false);
|
||||||
|
UnlimitedPrepare = config.getBoolean("Schematic.UnlimitedPrepare", false);
|
||||||
|
|
||||||
GameName = config.getString("GameName", "WarGear");
|
GameName = config.getString("GameName", "WarGear");
|
||||||
TeamChatDetection = config.getString("TeamChatPrefix", "+");
|
TeamChatDetection = config.getString("TeamChatPrefix", "+");
|
||||||
@ -204,7 +207,7 @@ public class Config {
|
|||||||
ForbiddenItems = Collections.unmodifiableSet(config.getStringList("Kits.ForbiddenItems").stream().map(Material::valueOf).collect(Collectors.toSet()));
|
ForbiddenItems = Collections.unmodifiableSet(config.getStringList("Kits.ForbiddenItems").stream().map(Material::valueOf).collect(Collectors.toSet()));
|
||||||
|
|
||||||
TechhiderActive = config.getBoolean("Techhider.Active", false);
|
TechhiderActive = config.getBoolean("Techhider.Active", false);
|
||||||
ObfuscateWith = config.getString("Techhider.ObfuscateWith", "end_stone");
|
ObfuscateWith = config.getString("Techhider.ObfuscateWith", "end_stone").toUpperCase();
|
||||||
HiddenBlocks = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlocks")));
|
HiddenBlocks = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlocks")));
|
||||||
HiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities")));
|
HiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities")));
|
||||||
|
|
||||||
@ -300,14 +303,13 @@ public class Config {
|
|||||||
RedRotate = teamRedRotate;
|
RedRotate = teamRedRotate;
|
||||||
BlueRotate = teamBlueRotate;
|
BlueRotate = teamBlueRotate;
|
||||||
|
|
||||||
int arenaYSize = blueCornerY - underBorder + schemsizeY + PreperationArea;
|
|
||||||
|
|
||||||
RedPasteRegion = new Region(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ);
|
RedPasteRegion = new Region(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ);
|
||||||
BluePasteRegion = new Region(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ);
|
BluePasteRegion = new Region(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ);
|
||||||
|
|
||||||
RedExtendRegion = new Region(teamRedCornerX, underBorder, teamRedCornerZ, schemsizeX, arenaYSize, schemsizeZ, PreperationArea, PreperationArea);
|
RedExtendRegion = new Region(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea);
|
||||||
BlueExtendRegion = new Region(blueCornerX, underBorder, blueCornerZ, schemsizeX, arenaYSize, schemsizeZ, PreperationArea, PreperationArea);
|
BlueExtendRegion = new Region(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea);
|
||||||
ArenaRegion = new Region(arenaMinX, underBorder, arenaMinZ, arenaMaxX - arenaMinX, arenaYSize, arenaMaxZ - arenaMinZ);
|
ArenaRegion = new Region(arenaMinX, blueCornerY, arenaMinZ, arenaMaxX - arenaMinX, schemsizeY, arenaMaxZ - arenaMinZ, 0, PreperationArea, 0);
|
||||||
|
PlayerRegion = new Region(arenaMinX, underBorder, arenaMinZ, arenaMaxX - arenaMinX, world.getMaxHeight() - underBorder, arenaMaxZ - arenaMinZ);
|
||||||
|
|
||||||
EventKampfID = Integer.parseInt(System.getProperty("fightID", "0"));
|
EventKampfID = Integer.parseInt(System.getProperty("fightID", "0"));
|
||||||
if(EventKampfID >= 1){
|
if(EventKampfID >= 1){
|
||||||
|
@ -48,6 +48,7 @@ public class FightSystem extends JavaPlugin {
|
|||||||
private Message message;
|
private Message message;
|
||||||
private FightTeam lastWinner;
|
private FightTeam lastWinner;
|
||||||
private String lastWinreason;
|
private String lastWinreason;
|
||||||
|
private TechHiderWrapper techHider;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
@ -66,7 +67,12 @@ public class FightSystem extends JavaPlugin {
|
|||||||
new EntityDamage();
|
new EntityDamage();
|
||||||
new WaterRemover();
|
new WaterRemover();
|
||||||
new Permanent();
|
new Permanent();
|
||||||
new PistonListener();
|
new PistonListener(ArenaMode.AntiTestCheckPrepare, e -> e.setCancelled(true));
|
||||||
|
new PistonListener(ArenaMode.Test, e -> getMessage().broadcastActionbar("PISTON_PUSHED_OUTSIDE"));
|
||||||
|
new PistonListener(ArenaMode.Prepare, e -> {
|
||||||
|
getMessage().broadcast("PISTON_PUSHED_OUTSIDE");
|
||||||
|
shutdown();
|
||||||
|
});
|
||||||
new Chat();
|
new Chat();
|
||||||
new ArenaBorder();
|
new ArenaBorder();
|
||||||
new TeamArea();
|
new TeamArea();
|
||||||
@ -77,7 +83,6 @@ public class FightSystem extends JavaPlugin {
|
|||||||
new DenyInventoryMovement();
|
new DenyInventoryMovement();
|
||||||
new EventJoin();
|
new EventJoin();
|
||||||
new Recording();
|
new Recording();
|
||||||
//new ResourcePack();
|
|
||||||
new Check();
|
new Check();
|
||||||
new Shutdown();
|
new Shutdown();
|
||||||
new SetupQuit();
|
new SetupQuit();
|
||||||
@ -90,12 +95,14 @@ public class FightSystem extends JavaPlugin {
|
|||||||
new ArrowPickup();
|
new ArrowPickup();
|
||||||
new BlockFadeListener();
|
new BlockFadeListener();
|
||||||
new LeaveableArena();
|
new LeaveableArena();
|
||||||
|
new ClickAnalyzer();
|
||||||
|
new BlockPlaceCollision();
|
||||||
new HotbarKit.HotbarKitListener();
|
new HotbarKit.HotbarKitListener();
|
||||||
new JoinRequestListener();
|
new JoinRequestListener();
|
||||||
new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f));
|
new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f));
|
||||||
|
|
||||||
new EnterHandler();
|
new EnterHandler();
|
||||||
new TechHider();
|
techHider = new TechHiderWrapper();
|
||||||
new FightWorld();
|
new FightWorld();
|
||||||
new FightUI();
|
new FightUI();
|
||||||
new FightStatistics();
|
new FightStatistics();
|
||||||
@ -118,6 +125,7 @@ public class FightSystem extends JavaPlugin {
|
|||||||
|
|
||||||
new HellsBells();
|
new HellsBells();
|
||||||
new Meteor();
|
new Meteor();
|
||||||
|
new WinconditionAmongUs();
|
||||||
|
|
||||||
new NoPlayersOnlineCountdown();
|
new NoPlayersOnlineCountdown();
|
||||||
new PreSchemCountdown();
|
new PreSchemCountdown();
|
||||||
@ -146,7 +154,6 @@ public class FightSystem extends JavaPlugin {
|
|||||||
new LiveRecorder();
|
new LiveRecorder();
|
||||||
new FileRecorder();
|
new FileRecorder();
|
||||||
|
|
||||||
REntity.initWatchers();
|
|
||||||
FileSource.startReplay();
|
FileSource.startReplay();
|
||||||
|
|
||||||
if(Config.mode == ArenaMode.EVENT) {
|
if(Config.mode == ArenaMode.EVENT) {
|
||||||
@ -161,6 +168,7 @@ public class FightSystem extends JavaPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
GlobalRecorder.getInstance().close();
|
GlobalRecorder.getInstance().close();
|
||||||
|
ClickAnalyzer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setSpectateState(FightTeam winFightTeam, String winreason, String subtitle, Object... params) {
|
public static void setSpectateState(FightTeam winFightTeam, String winreason, String subtitle, Object... params) {
|
||||||
@ -192,6 +200,10 @@ public class FightSystem extends JavaPlugin {
|
|||||||
return plugin.lastWinreason;
|
return plugin.lastWinreason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TechHiderWrapper getTechHider() {
|
||||||
|
return plugin.techHider;
|
||||||
|
}
|
||||||
|
|
||||||
public static void shutdown() {
|
public static void shutdown() {
|
||||||
//Staggered kick to prevent lobby overloading
|
//Staggered kick to prevent lobby overloading
|
||||||
if(Bukkit.getOnlinePlayers().isEmpty()){
|
if(Bukkit.getOnlinePlayers().isEmpty()){
|
||||||
|
@ -145,7 +145,6 @@ NO_FRIENDLY_FIRE=§cNo friendly fire allowed
|
|||||||
NO_TNT_PLACE=§cYou are not allowed to place tnt
|
NO_TNT_PLACE=§cYou are not allowed to place tnt
|
||||||
NO_TELEPORT=§cYou are not allowed to use this teleport function
|
NO_TELEPORT=§cYou are not allowed to use this teleport function
|
||||||
OPEN_INVENTORY_TO_CUSTOMIZE=§eOpen inventory to customize your kit
|
OPEN_INVENTORY_TO_CUSTOMIZE=§eOpen inventory to customize your kit
|
||||||
RESOURCEPACK_REQUIRED=§cYou can only join on the event server with the SteamWar resourcepack\n§cPlease allow the use of server resourcepacks in the server list!
|
|
||||||
NO_ENTERN=§cYou may not board
|
NO_ENTERN=§cYou may not board
|
||||||
NO_TEAMAREA=§cYou are not allowed in the team area
|
NO_TEAMAREA=§cYou are not allowed in the team area
|
||||||
TEST_BECOME_LEADER=§7Become a team leader with §8/§eleader
|
TEST_BECOME_LEADER=§7Become a team leader with §8/§eleader
|
||||||
@ -157,6 +156,7 @@ PREPARE_SENT_IN=§aA team member will review the schematic soon
|
|||||||
PARTICIPANT_CHAT={0} {1}§8» §7{2}
|
PARTICIPANT_CHAT={0} {1}§8» §7{2}
|
||||||
FIGHTLEADER_CHAT=§e{0}§8» §e{1}
|
FIGHTLEADER_CHAT=§e{0}§8» §e{1}
|
||||||
SPECTATOR_CHAT=§7{0}§8» §7{1}
|
SPECTATOR_CHAT=§7{0}§8» §7{1}
|
||||||
|
PISTON_PUSHED_OUTSIDE=§cA piston pushed a block outside the allowed area!
|
||||||
|
|
||||||
|
|
||||||
# Replay
|
# Replay
|
||||||
@ -239,6 +239,11 @@ WIN_LESS_DAMAGE={0} §7less damaged
|
|||||||
WIN_POINTS={0} has more points
|
WIN_POINTS={0} has more points
|
||||||
WIN_POINTS_EQUAL=§7Equal points
|
WIN_POINTS_EQUAL=§7Equal points
|
||||||
WIN_TECHKO={0} §7is tech K.O.
|
WIN_TECHKO={0} §7is tech K.O.
|
||||||
|
WIN_IMPOSTER_DEAD={0} §7killed the imposter
|
||||||
|
WIN_CREWMATE_DEAD={0} §7killed all team mates
|
||||||
|
|
||||||
|
AMONG_US_IMPOSTER_MESSAGE = §4You are the Imposter§8! §7Kill all your team mates to win the game!
|
||||||
|
AMONG_US_IMPOSTER_AMONG_MESSAGE = §4There is an Imposter among us§8! §7Kill him to win the game!
|
||||||
|
|
||||||
|
|
||||||
# Invites
|
# Invites
|
||||||
|
@ -142,7 +142,6 @@ NO_FRIENDLY_FIRE=§cDu darfst deinen Teamkollegen keinen Schaden zufügen
|
|||||||
NO_TNT_PLACE=§cDu darfst kein TNT setzen
|
NO_TNT_PLACE=§cDu darfst kein TNT setzen
|
||||||
NO_TELEPORT=§cDu darfst diese Teleportfunktion nicht benutzen
|
NO_TELEPORT=§cDu darfst diese Teleportfunktion nicht benutzen
|
||||||
OPEN_INVENTORY_TO_CUSTOMIZE=§eInventar zum Anpassen des Kits öffnen
|
OPEN_INVENTORY_TO_CUSTOMIZE=§eInventar zum Anpassen des Kits öffnen
|
||||||
RESOURCEPACK_REQUIRED=§cAuf Eventserver kann nur mit dem SteamWar-Resourcepack beigetreten werden\n§cDa du abgelehnt hast, musst du nun in der Serverliste erst einmal wieder Ressourcenpakete von SteamWar aktivieren
|
|
||||||
NO_ENTERN=§cDu darfst nicht entern
|
NO_ENTERN=§cDu darfst nicht entern
|
||||||
NO_TEAMAREA=§cDu darfst nicht zu den Teams
|
NO_TEAMAREA=§cDu darfst nicht zu den Teams
|
||||||
TEST_BECOME_LEADER=§7Werde zum Teamleader mit §8/§eleader
|
TEST_BECOME_LEADER=§7Werde zum Teamleader mit §8/§eleader
|
||||||
@ -151,6 +150,7 @@ PREPARE_SCHEM_EXISTS=§cEs existiert bereits eine Schem mit Namenszusatz -prepar
|
|||||||
PREPARE_ACTIVE_PISTON=§cIm Teambereich wurden sich noch bewegende Pistons gefunden, Einsenden wird abgebrochen.
|
PREPARE_ACTIVE_PISTON=§cIm Teambereich wurden sich noch bewegende Pistons gefunden, Einsenden wird abgebrochen.
|
||||||
PREPARE_FAILED_SAVING=§cDie Schematic konnte nicht gespeichert werden, Einsenden wird abgebrochen.
|
PREPARE_FAILED_SAVING=§cDie Schematic konnte nicht gespeichert werden, Einsenden wird abgebrochen.
|
||||||
PREPARE_SENT_IN=§aDie Schematic wird nun zeitnah von einem Teammitglied überprüft
|
PREPARE_SENT_IN=§aDie Schematic wird nun zeitnah von einem Teammitglied überprüft
|
||||||
|
PISTON_PUSHED_OUTSIDE=§cEin Kolben hat einen Block aus dem erlaubten Bereich geschoben!
|
||||||
|
|
||||||
|
|
||||||
# Replay
|
# Replay
|
||||||
@ -224,7 +224,11 @@ WIN_LESS_DAMAGE={0} §7weniger beschädigt
|
|||||||
WIN_POINTS={0} hat mehr Punkte
|
WIN_POINTS={0} hat mehr Punkte
|
||||||
WIN_POINTS_EQUAL=§7Gleicher Punktestand
|
WIN_POINTS_EQUAL=§7Gleicher Punktestand
|
||||||
WIN_TECHKO={0} §7ist Tech K.O.
|
WIN_TECHKO={0} §7ist Tech K.O.
|
||||||
|
WIN_IMPOSTER_DEAD={0} §7 hat den Imposter getötet
|
||||||
|
WIN_CREWMATE_DEAD={0} §7 hat alle Kameraden getötet
|
||||||
|
|
||||||
|
AMONG_US_IMPOSTER_MESSAGE = §4Du bist ein Imposter§8! §7Du musst alle Kameraden töten, um zu gewinnen.
|
||||||
|
AMONG_US_IMPOSTER_AMONG_MESSAGE = §4Es ist ein Imposter unter uns§8! §7Tötet ihn, um das Spiel zu gewinnen!
|
||||||
|
|
||||||
# Invites
|
# Invites
|
||||||
JOIN_REQUEST=§7Teambeitritt anfragen
|
JOIN_REQUEST=§7Teambeitritt anfragen
|
||||||
|
@ -24,7 +24,7 @@ import de.steamwar.fightsystem.FightSystem;
|
|||||||
import de.steamwar.fightsystem.fight.FightPlayer;
|
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||||
import de.steamwar.fightsystem.utils.Message;
|
import de.steamwar.fightsystem.utils.Message;
|
||||||
import de.steamwar.fightsystem.utils.SWSound;
|
import de.steamwar.fightsystem.utils.SWSound;
|
||||||
import de.steamwar.fightsystem.utils.TechHider;
|
import de.steamwar.techhider.ProtocolUtils;
|
||||||
import de.steamwar.fightsystem.winconditions.Wincondition;
|
import de.steamwar.fightsystem.winconditions.Wincondition;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ public class EnternCountdown extends Countdown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final FightPlayer fightPlayer;
|
private final FightPlayer fightPlayer;
|
||||||
private List<TechHider.ChunkPos> chunkPos;
|
private List<ProtocolUtils.ChunkPos> chunkPos;
|
||||||
|
|
||||||
public EnternCountdown(FightPlayer fp) {
|
public EnternCountdown(FightPlayer fp) {
|
||||||
super(calcTime(fp), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false);
|
super(calcTime(fp), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false);
|
||||||
@ -58,12 +58,12 @@ public class EnternCountdown extends Countdown {
|
|||||||
@Override
|
@Override
|
||||||
public void countdownFinished() {
|
public void countdownFinished() {
|
||||||
FightSystem.getMessage().sendPrefixless("ENTERN_ALLOWED", fightPlayer.getPlayer(), ChatMessageType.ACTION_BAR);
|
FightSystem.getMessage().sendPrefixless("ENTERN_ALLOWED", fightPlayer.getPlayer(), ChatMessageType.ACTION_BAR);
|
||||||
TechHider.reloadChunks(fightPlayer.getPlayer(), chunkPos, false);
|
FightSystem.getTechHider().reloadChunks(fightPlayer.getPlayer(), chunkPos, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void prepareFinish() {
|
protected void prepareFinish() {
|
||||||
chunkPos = TechHider.prepareChunkReload(fightPlayer.getPlayer(), false);
|
chunkPos = FightSystem.getTechHider().prepareChunkReload(fightPlayer.getPlayer(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -23,31 +23,16 @@ import de.steamwar.fightsystem.ArenaMode;
|
|||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependentCountdown;
|
import de.steamwar.fightsystem.states.StateDependentCountdown;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
|
||||||
import de.steamwar.fightsystem.utils.Message;
|
import de.steamwar.fightsystem.utils.Message;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
|
|
||||||
public class NoPlayersOnlineCountdown extends Countdown implements Listener {
|
public class NoPlayersOnlineCountdown extends Countdown {
|
||||||
|
|
||||||
public NoPlayersOnlineCountdown() {
|
public NoPlayersOnlineCountdown() {
|
||||||
super(Config.NoPlayerOnlineDuration, new Message("SHUTDOWN_COUNTDOWN"), null, false);
|
super(Config.NoPlayerOnlineDuration, new Message("SHUTDOWN_COUNTDOWN"), null, false);
|
||||||
|
|
||||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this);
|
if (!Config.ArenaLeaveable)
|
||||||
new StateDependentCountdown(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this) {
|
new StateDependentCountdown(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this);
|
||||||
@Override
|
|
||||||
public void enable() {
|
|
||||||
if(Bukkit.getOnlinePlayers().isEmpty())
|
|
||||||
super.enable();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void handlePlayerJoin(PlayerJoinEvent event) {
|
|
||||||
disable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,6 +29,9 @@ public class PostSchemCountdown extends Countdown {
|
|||||||
|
|
||||||
public PostSchemCountdown() {
|
public PostSchemCountdown() {
|
||||||
super(Config.SetupDuration, new Message("POST_SCHEM_COUNTDOWN"), null, false);
|
super(Config.SetupDuration, new Message("POST_SCHEM_COUNTDOWN"), null, false);
|
||||||
|
if(Config.mode == ArenaMode.PREPARE && Config.UnlimitedPrepare)
|
||||||
|
return;
|
||||||
|
|
||||||
new StateDependentCountdown(ArenaMode.SeriousFight, FightState.PostSchemSetup, this);
|
new StateDependentCountdown(ArenaMode.SeriousFight, FightState.PostSchemSetup, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ import de.steamwar.fightsystem.utils.SWSound;
|
|||||||
public class SpectateOverCountdown extends Countdown {
|
public class SpectateOverCountdown extends Countdown {
|
||||||
|
|
||||||
public SpectateOverCountdown() {
|
public SpectateOverCountdown() {
|
||||||
super(Config.SpectatorDuration, new Message("SPECTATE_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false);
|
super(Config.test() ? 3600 : Config.SpectatorDuration, new Message("SPECTATE_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false);
|
||||||
new StateDependentCountdown(ArenaMode.Restartable.contains(Config.mode) || Config.replayserver(), FightState.Spectate, this);
|
new StateDependentCountdown(ArenaMode.Restartable.contains(Config.mode) || Config.replayserver(), FightState.Spectate, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,21 +19,20 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.fight;
|
package de.steamwar.fightsystem.fight;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.ProtocolWrapper;
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||||
import de.steamwar.fightsystem.utils.ProtocolWrapper;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
public class Fight {
|
public class Fight {
|
||||||
private Fight(){}
|
private Fight(){}
|
||||||
@ -135,28 +134,8 @@ public class Fight {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Class<?> playerInfoPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo");
|
|
||||||
private static final Class<?> playerInfoActionClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction");
|
|
||||||
public static final Object addPlayer = playerInfoActionClass.getEnumConstants()[0];
|
|
||||||
private static final Reflection.FieldAccessor<?> playerInfoAction = Reflection.getField(playerInfoPacket, playerInfoActionClass, 0);
|
|
||||||
private static final Object updateGamemode = playerInfoActionClass.getEnumConstants()[1];
|
|
||||||
public static final Object removePlayer = playerInfoActionClass.getEnumConstants()[4];
|
|
||||||
private static final Reflection.FieldAccessor<List> playerInfoData = Reflection.getField(playerInfoPacket, List.class, 0);
|
|
||||||
public static final Class<?> playerInfoDataClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$PlayerInfoData");
|
|
||||||
public static final Class<?> enumGamemode = Reflection.getClass(Core.getVersion() > 9 ? "{nms.world.level}.EnumGamemode" : "{nms}.WorldSettings$EnumGamemode");
|
|
||||||
public static final Object creative = enumGamemode.getEnumConstants()[Core.getVersion() > 15 ? 1 : 2];
|
|
||||||
private static final Object spectator = enumGamemode.getEnumConstants()[Core.getVersion() > 15 ? 3 : 4];
|
|
||||||
public static final Class<?> iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent");
|
|
||||||
|
|
||||||
public static void pseudoSpectator(Player player, boolean enable) {
|
public static void pseudoSpectator(Player player, boolean enable) {
|
||||||
TinyProtocol.instance.sendPacket(player, playerInfoPacket(updateGamemode, new GameProfile(player.getUniqueId(), player.getName()), enable ? creative : spectator));
|
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR));
|
||||||
}
|
|
||||||
|
|
||||||
public static Object playerInfoPacket(Object action, GameProfile profile, Object mode) {
|
|
||||||
Object packet = Reflection.newInstance(playerInfoPacket);
|
|
||||||
playerInfoAction.set(packet, action);
|
|
||||||
playerInfoData.set(packet, Collections.singletonList(ProtocolWrapper.impl.playerInfoDataConstructor(packet, profile, mode)));
|
|
||||||
return packet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMaxRank(){
|
public static int getMaxRank(){
|
||||||
|
@ -31,10 +31,13 @@ import de.steamwar.fightsystem.states.StateDependent;
|
|||||||
import de.steamwar.fightsystem.utils.ColorConverter;
|
import de.steamwar.fightsystem.utils.ColorConverter;
|
||||||
import de.steamwar.fightsystem.utils.Region;
|
import de.steamwar.fightsystem.utils.Region;
|
||||||
import de.steamwar.fightsystem.utils.WorldeditWrapper;
|
import de.steamwar.fightsystem.utils.WorldeditWrapper;
|
||||||
|
import de.steamwar.sql.SchematicData;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import org.bukkit.*;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.DyeColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -70,7 +73,7 @@ public class FightSchematic extends StateDependent {
|
|||||||
public void setSchematic(SchematicNode schem) {
|
public void setSchematic(SchematicNode schem) {
|
||||||
schematic = schem.getId();
|
schematic = schem.getId();
|
||||||
try {
|
try {
|
||||||
clipboard = schem.load();
|
clipboard = new SchematicData(schem).load();
|
||||||
|
|
||||||
if(schem.replaceColor())
|
if(schem.replaceColor())
|
||||||
replaceTeamColor(clipboard);
|
replaceTeamColor(clipboard);
|
||||||
@ -153,7 +156,7 @@ public class FightSchematic extends StateDependent {
|
|||||||
replaceSync(Material.BEDROCK, Material.SLIME_BLOCK);
|
replaceSync(Material.BEDROCK, Material.SLIME_BLOCK);
|
||||||
|
|
||||||
if(!Config.ReplaceWithBlockupdates)
|
if(!Config.ReplaceWithBlockupdates)
|
||||||
HandlerList.unregisterAll(freezer);
|
freezer.disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pasteTeamName(){
|
public void pasteTeamName(){
|
||||||
|
@ -26,15 +26,18 @@ import de.steamwar.fightsystem.FightSystem;
|
|||||||
import de.steamwar.fightsystem.commands.GUI;
|
import de.steamwar.fightsystem.commands.GUI;
|
||||||
import de.steamwar.fightsystem.countdown.Countdown;
|
import de.steamwar.fightsystem.countdown.Countdown;
|
||||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
import de.steamwar.fightsystem.listener.FightScoreboard;
|
||||||
|
import de.steamwar.fightsystem.listener.Permanent;
|
||||||
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
||||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.OneShotStateDependent;
|
import de.steamwar.fightsystem.states.OneShotStateDependent;
|
||||||
import de.steamwar.fightsystem.states.StateDependent;
|
import de.steamwar.fightsystem.states.StateDependent;
|
||||||
import de.steamwar.fightsystem.utils.*;
|
import de.steamwar.fightsystem.utils.*;
|
||||||
|
import de.steamwar.fightsystem.winconditions.Winconditions;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.techhider.ProtocolUtils;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
@ -69,7 +72,7 @@ public class FightTeam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Config.test())
|
if(Config.test())
|
||||||
notReadyKit.setItem(1, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), GUI::preSchemDialog);
|
notReadyKit.setItem(5, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), GUI::preSchemDialog);
|
||||||
|
|
||||||
notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true));
|
notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true));
|
||||||
}
|
}
|
||||||
@ -118,19 +121,17 @@ public class FightTeam {
|
|||||||
new KitLoader();
|
new KitLoader();
|
||||||
new SpectateHandler();
|
new SpectateHandler();
|
||||||
|
|
||||||
if(FightScoreboard.getBukkit().getTeam(name) == null)
|
team = FightScoreboard.getBukkitTeam(name);
|
||||||
team = FightScoreboard.getBukkit().registerNewTeam(name);
|
|
||||||
else
|
|
||||||
team = FightScoreboard.getBukkit().getTeam(name);
|
|
||||||
assert team != null;
|
|
||||||
WorldOfColorWrapper.impl.setTeamColor(team, color);
|
WorldOfColorWrapper.impl.setTeamColor(team, color);
|
||||||
BountifulWrapper.impl.setNametagVisibility(team);
|
BountifulWrapper.impl.setNametagVisibility(team);
|
||||||
team.setNameTagVisibility(NameTagVisibility.HIDE_FOR_OTHER_TEAMS);
|
team.setNameTagVisibility(NameTagVisibility.HIDE_FOR_OTHER_TEAMS);
|
||||||
team.setAllowFriendlyFire(false);
|
if (!Config.ActiveWinconditions.contains(Winconditions.AMONG_US)) {
|
||||||
|
team.setAllowFriendlyFire(false);
|
||||||
|
}
|
||||||
|
|
||||||
new OneShotStateDependent(ArenaMode.Restartable, FightState.PreLeaderSetup, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::reset));
|
new OneShotStateDependent(ArenaMode.Restartable, FightState.PreLeaderSetup, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::reset));
|
||||||
new OneShotStateDependent(Config.replayserver(), FightState.PreLeaderSetup, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::reset));
|
new OneShotStateDependent(Config.replayserver(), FightState.PreLeaderSetup, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::reset));
|
||||||
new OneShotStateDependent(ArenaMode.AntiTest, FightState.PostSchemSetup, () -> {
|
new OneShotStateDependent(ArenaMode.All, FightState.PostSchemSetup, () -> {
|
||||||
if(leader != null)
|
if(leader != null)
|
||||||
notReadyKit.loadToPlayer(leader.getPlayer());
|
notReadyKit.loadToPlayer(leader.getPlayer());
|
||||||
});
|
});
|
||||||
@ -216,7 +217,9 @@ public class FightTeam {
|
|||||||
playerSet.forEach(p -> addMember(p, true));
|
playerSet.forEach(p -> addMember(p, true));
|
||||||
|
|
||||||
if(ArenaMode.VariableTeams.contains(Config.mode) && isLeaderless()){
|
if(ArenaMode.VariableTeams.contains(Config.mode) && isLeaderless()){
|
||||||
for(Player player : Bukkit.getOnlinePlayers()){
|
List<Player> onlinePlayers = new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||||
|
Collections.shuffle(onlinePlayers);
|
||||||
|
for(Player player : onlinePlayers) {
|
||||||
if(Fight.getPlayerTeam(player) == null && canbeLeader(player)){
|
if(Fight.getPlayerTeam(player) == null && canbeLeader(player)){
|
||||||
addMember(player);
|
addMember(player);
|
||||||
break;
|
break;
|
||||||
@ -242,10 +245,11 @@ public class FightTeam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addMember(Player player, boolean silent) {
|
private void addMember(Player player, boolean silent) {
|
||||||
final List<TechHider.ChunkPos> chunksToReload = TechHider.prepareChunkReload(player, false);
|
final List<ProtocolUtils.ChunkPos> chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, false);
|
||||||
FightPlayer fightPlayer = getFightPlayer(player) != null ? getFightPlayer(player) : new FightPlayer(player, this);
|
FightPlayer fightPlayer = getFightPlayer(player) != null ? getFightPlayer(player) : new FightPlayer(player, this);
|
||||||
fightPlayer.revive();
|
fightPlayer.revive();
|
||||||
players.put(player, fightPlayer);
|
players.put(player, fightPlayer);
|
||||||
|
Permanent.getSpectatorTeam().removeEntry(player.getName());
|
||||||
team.addEntry(player.getName());
|
team.addEntry(player.getName());
|
||||||
|
|
||||||
player.setHealth(20);
|
player.setHealth(20);
|
||||||
@ -264,7 +268,7 @@ public class FightTeam {
|
|||||||
fightPlayer.startEnternCountdown();
|
fightPlayer.startEnternCountdown();
|
||||||
|
|
||||||
GlobalRecorder.getInstance().playerJoins(player);
|
GlobalRecorder.getInstance().playerJoins(player);
|
||||||
TechHider.reloadChunks(player, chunksToReload, false);
|
FightSystem.getTechHider().reloadChunks(player, chunksToReload, false);
|
||||||
|
|
||||||
if(isLeaderless())
|
if(isLeaderless())
|
||||||
setLeader(fightPlayer, silent);
|
setLeader(fightPlayer, silent);
|
||||||
@ -276,9 +280,10 @@ public class FightTeam {
|
|||||||
FightPlayer fightPlayer = getFightPlayer(player);
|
FightPlayer fightPlayer = getFightPlayer(player);
|
||||||
|
|
||||||
PersonalKitCreator.closeIfInKitCreator(player);
|
PersonalKitCreator.closeIfInKitCreator(player);
|
||||||
List<TechHider.ChunkPos> chunksToReload = TechHider.prepareChunkReload(player, true);
|
List<ProtocolUtils.ChunkPos> chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, true);
|
||||||
players.remove(player);
|
players.remove(player);
|
||||||
team.removeEntry(player.getName());
|
team.removeEntry(player.getName());
|
||||||
|
Permanent.getSpectatorTeam().addEntry(player.getName());
|
||||||
|
|
||||||
FightUI.addSubtitle("UI_PLAYER_LEAVES", prefix, player.getName());
|
FightUI.addSubtitle("UI_PLAYER_LEAVES", prefix, player.getName());
|
||||||
|
|
||||||
@ -291,7 +296,7 @@ public class FightTeam {
|
|||||||
player.getInventory().clear();
|
player.getInventory().clear();
|
||||||
|
|
||||||
if(player.isOnline()){
|
if(player.isOnline()){
|
||||||
TechHider.reloadChunks(player, chunksToReload, true);
|
FightSystem.getTechHider().reloadChunks(player, chunksToReload, true);
|
||||||
HotbarKit.spectatorKit.loadToPlayer(player);
|
HotbarKit.spectatorKit.loadToPlayer(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import org.bukkit.event.EventPriority;
|
|||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.*;
|
import org.bukkit.event.block.*;
|
||||||
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||||
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
@ -83,6 +84,10 @@ public class FreezeWorld implements Listener {
|
|||||||
public void onBlockExplosion(BlockExplodeEvent e){
|
public void onBlockExplosion(BlockExplodeEvent e){
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockExplosion(ItemSpawnEvent e){
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
public void handlePlayerInteract(PlayerInteractEvent event) {
|
public void handlePlayerInteract(PlayerInteractEvent event) {
|
||||||
|
@ -27,6 +27,7 @@ import de.steamwar.fightsystem.commands.GUI;
|
|||||||
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
|
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||||
import de.steamwar.fightsystem.utils.ItemBuilder;
|
import de.steamwar.fightsystem.utils.ItemBuilder;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -40,7 +41,9 @@ import org.bukkit.inventory.meta.ItemMeta;
|
|||||||
import org.bukkit.potion.PotionEffect;
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class HotbarKit extends Kit {
|
public class HotbarKit extends Kit {
|
||||||
@ -90,8 +93,11 @@ public class HotbarKit extends Kit {
|
|||||||
|
|
||||||
public static class HotbarKitListener implements Listener {
|
public static class HotbarKitListener implements Listener {
|
||||||
|
|
||||||
|
private static final Set<Player> clicked = new HashSet<>();
|
||||||
|
|
||||||
public HotbarKitListener() {
|
public HotbarKitListener() {
|
||||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this);
|
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this);
|
||||||
|
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, clicked::clear, 10, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -106,6 +112,9 @@ public class HotbarKit extends Kit {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
if(!clicked.add(player))
|
||||||
|
return;
|
||||||
|
|
||||||
((HotbarKit)activeKit).onClicks[slot].accept(player);
|
((HotbarKit)activeKit).onClicks[slot].accept(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.fight;
|
package de.steamwar.fightsystem.fight;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.commands.Commands;
|
import de.steamwar.fightsystem.commands.Commands;
|
||||||
import de.steamwar.fightsystem.commands.GUI;
|
import de.steamwar.fightsystem.commands.GUI;
|
||||||
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
||||||
import de.steamwar.fightsystem.utils.CraftbukkitWrapper;
|
|
||||||
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
||||||
import de.steamwar.inventory.SWInventory;
|
import de.steamwar.inventory.SWInventory;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
@ -52,6 +52,10 @@ public class Kit {
|
|||||||
|
|
||||||
protected static final Map<Player, Kit> activeKits = new HashMap<>();
|
protected static final Map<Player, Kit> activeKits = new HashMap<>();
|
||||||
|
|
||||||
|
public static Kit getActiveKit(Player player) {
|
||||||
|
return activeKits.get(player);
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if(!kits.exists()) {
|
if(!kits.exists()) {
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Kitconfig fehlend!" + kits.getAbsolutePath());
|
Bukkit.getLogger().log(Level.SEVERE, "Kitconfig fehlend!" + kits.getAbsolutePath());
|
||||||
@ -156,6 +160,18 @@ public class Kit {
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean contains(ItemStack stack) {
|
||||||
|
for(ItemStack i : inventory) {
|
||||||
|
if(similar(i, stack))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for(ItemStack i : armor) {
|
||||||
|
if(similar(i, stack))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public ItemStack[] getArmor() {
|
public ItemStack[] getArmor() {
|
||||||
return armor;
|
return armor;
|
||||||
}
|
}
|
||||||
@ -207,7 +223,7 @@ public class Kit {
|
|||||||
if(FlatteningWrapper.impl.containsBlockMeta(meta))
|
if(FlatteningWrapper.impl.containsBlockMeta(meta))
|
||||||
return true; //Blocks always upwards slabs etc.
|
return true; //Blocks always upwards slabs etc.
|
||||||
|
|
||||||
if(CraftbukkitWrapper.impl.hasItems(stack))
|
if(hasItems(stack))
|
||||||
return true; //Blocks prefilled inventories
|
return true; //Blocks prefilled inventories
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +232,18 @@ public class Kit {
|
|||||||
return !normal.isEnchantmentInKit(stack) && !stack.getEnchantments().isEmpty();
|
return !normal.isEnchantmentInKit(stack) && !stack.getEnchantments().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> itemStack = Reflection.getClass("{nms.world.item}.ItemStack");
|
||||||
|
private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStack, ItemStack.class);
|
||||||
|
private static final Class<?> nbtTagCompound = Reflection.getClass("{nms.nbt}.NBTTagCompound");
|
||||||
|
private static final Reflection.MethodInvoker getTag = Reflection.getTypedMethod(itemStack, null, nbtTagCompound);
|
||||||
|
private static final Reflection.MethodInvoker getKeys = Reflection.getTypedMethod(nbtTagCompound, null, Set.class);
|
||||||
|
public static boolean hasItems(ItemStack stack) {
|
||||||
|
Set<String> keys = new HashSet<>((Set<String>) getKeys.invoke(getTag.invoke(asNMSCopy.invoke(null, stack))));
|
||||||
|
keys.remove("Enchantments");
|
||||||
|
keys.remove("Damage");
|
||||||
|
return !keys.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isEnchantmentInKit(ItemStack stack){
|
private boolean isEnchantmentInKit(ItemStack stack){
|
||||||
for(ItemStack is : inventory){
|
for(ItemStack is : inventory){
|
||||||
if(similar(stack, is))
|
if(similar(stack, is))
|
||||||
|
@ -26,7 +26,9 @@ import de.steamwar.fightsystem.fight.Fight;
|
|||||||
import de.steamwar.fightsystem.fight.FightTeam;
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
|
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -38,40 +40,39 @@ public class ArenaBorder implements Listener {
|
|||||||
|
|
||||||
public ArenaBorder() {
|
public ArenaBorder() {
|
||||||
new StateDependentListener(ArenaMode.All, FightState.All, this);
|
new StateDependentListener(ArenaMode.All, FightState.All, this);
|
||||||
|
new StateDependentTask(ArenaMode.All, FightState.Running, this::damage, 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void arenaBorder(PlayerMoveEvent event){
|
public void arenaBorder(PlayerMoveEvent event){
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
if(Config.ArenaLeaveable && !Fight.fighting(player))
|
FightTeam team = Fight.getPlayerTeam(player);
|
||||||
|
|
||||||
|
if(Config.ArenaLeaveable && team == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Location to = event.getTo();
|
Location to = event.getTo();
|
||||||
assert to != null;
|
assert to != null;
|
||||||
|
|
||||||
if(!Config.ArenaRegion.in2dRegion(to)){
|
if(Config.PlayerRegion.inRegion(to))
|
||||||
reset(event);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
FightTeam team = Fight.getPlayerTeam(player);
|
if(to.getY() <= Config.PlayerRegion.getMinY() && player.getGameMode() != GameMode.SPECTATOR && team != null) {
|
||||||
if(team == null || player.getGameMode() == GameMode.SPECTATOR){
|
if(!Config.GroundWalkable && !FightState.infight())
|
||||||
if(to.getY() <= Config.ArenaRegion.getMinY())
|
|
||||||
reset(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(to.getY() <= Config.ArenaRegion.getMinY()) {
|
|
||||||
if(FightState.infight())
|
|
||||||
player.damage(2);
|
|
||||||
else if(!Config.GroundWalkable)
|
|
||||||
player.teleport(team.getSpawn());
|
player.teleport(team.getSpawn());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reset(PlayerMoveEvent event){
|
return;
|
||||||
Player player = event.getPlayer();
|
}
|
||||||
|
|
||||||
player.teleport(event.getFrom());
|
player.teleport(event.getFrom());
|
||||||
FightSystem.getMessage().sendPrefixless("NO_ARENA_LEAVING", player, ChatMessageType.ACTION_BAR);
|
FightSystem.getMessage().sendPrefixless("NO_ARENA_LEAVING", player, ChatMessageType.ACTION_BAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void damage() {
|
||||||
|
for(Player player : Bukkit.getServer().getOnlinePlayers()) {
|
||||||
|
FightTeam team = Fight.getPlayerTeam(player);
|
||||||
|
if(team != null && player.getLocation().getY() <= Config.PlayerRegion.getMinY())
|
||||||
|
player.damage(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
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.fightsystem.listener;
|
||||||
|
|
||||||
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
|
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
|
||||||
|
public class BlockPlaceCollision implements Listener {
|
||||||
|
|
||||||
|
public BlockPlaceCollision() {
|
||||||
|
new StateDependentListener(ArenaMode.All, FightState.All, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockPlace(BlockPlaceEvent event) {
|
||||||
|
Block block = event.getBlock();
|
||||||
|
if(!block.getType().isSolid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Hitbox size: 0.6xz, 1.8y, 1.5y when sneaking
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Location min = player.getLocation().add(-0.3, 0, -0.3);
|
||||||
|
Location max = player.getLocation().add(0.3, FlatteningWrapper.impl.isCrouching(player) ? 0.6 : (player.isSneaking() ? 1.5 : 1.8), 0.3);
|
||||||
|
|
||||||
|
Location blockmin = block.getLocation();
|
||||||
|
Location blockmax = block.getLocation().add(1.0, 1.0, 1.0);
|
||||||
|
if(
|
||||||
|
max.getX() <= blockmin.getX() || min.getX() >= blockmax.getX() ||
|
||||||
|
max.getY() <= blockmin.getY() || min.getY() >= blockmax.getY() ||
|
||||||
|
max.getZ() <= blockmin.getZ() || min.getZ() >= blockmax.getZ()
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.listener;
|
package de.steamwar.fightsystem.listener;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.utils.CraftbukkitWrapper;
|
import de.steamwar.fightsystem.utils.CraftbukkitWrapper;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -26,7 +29,6 @@ import org.bukkit.entity.Player;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
public class ClickAnalyzer {
|
public class ClickAnalyzer {
|
||||||
private ClickAnalyzer() {}
|
|
||||||
|
|
||||||
private static final PrintStream output;
|
private static final PrintStream output;
|
||||||
|
|
||||||
@ -38,7 +40,20 @@ public class ClickAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onBlockPlace(Player player) {
|
public ClickAnalyzer() {
|
||||||
output.println(player.getName() + "," + System.nanoTime() + "," + CraftbukkitWrapper.impl.headRotation(player) + "," + player.getLocation().getPitch());
|
TinyProtocol.instance.addFilter(Recording.blockPlacePacket, this::onBlockPlace);
|
||||||
|
if(Core.getVersion() > 8)
|
||||||
|
TinyProtocol.instance.addFilter(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"), this::onBlockPlace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object onBlockPlace(Player player, Object packet) {
|
||||||
|
synchronized(output) {
|
||||||
|
output.println(player.getName() + "," + System.nanoTime() + "," + CraftbukkitWrapper.impl.headRotation(player) + "," + player.getLocation().getPitch());
|
||||||
|
}
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close() {
|
||||||
|
output.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,12 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockIgniteEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||||
import org.bukkit.event.hanging.HangingBreakEvent;
|
import org.bukkit.event.hanging.HangingBreakEvent;
|
||||||
|
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||||
import org.bukkit.event.player.PlayerKickEvent;
|
import org.bukkit.event.player.PlayerKickEvent;
|
||||||
|
|
||||||
public class DenyWorldInteraction implements Listener {
|
public class DenyWorldInteraction implements Listener {
|
||||||
@ -52,6 +54,14 @@ public class DenyWorldInteraction implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void handleItemDrop(PlayerDropItemEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if(Fight.fighting(player)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void handleHangingBreak(HangingBreakEvent event) {
|
public void handleHangingBreak(HangingBreakEvent event) {
|
||||||
if(Config.ArenaRegion.inRegion(event.getEntity().getLocation())) {
|
if(Config.ArenaRegion.inRegion(event.getEntity().getLocation())) {
|
||||||
@ -74,6 +84,12 @@ public class DenyWorldInteraction implements Listener {
|
|||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void handleBlockBurn(BlockIgniteEvent event) {
|
||||||
|
if(!Config.ArenaLeaveable || Config.ArenaRegion.inRegion(event.getBlock()))
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void handlePlayerKickEvent(PlayerKickEvent e){
|
public void handlePlayerKickEvent(PlayerKickEvent e){
|
||||||
if(e.getReason().contains("Flying is not enabled"))
|
if(e.getReason().contains("Flying is not enabled"))
|
||||||
|
@ -30,14 +30,20 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.scoreboard.Scoreboard;
|
import org.bukkit.scoreboard.Scoreboard;
|
||||||
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class FightScoreboard implements Listener, ScoreboardCallback {
|
public class FightScoreboard implements Listener, ScoreboardCallback {
|
||||||
|
|
||||||
public static Scoreboard getBukkit() {
|
public static Team getBukkitTeam(String name) {
|
||||||
return Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard();
|
Scoreboard scoreboard = Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard();
|
||||||
|
Team team = scoreboard.getTeam(name);
|
||||||
|
if(team != null)
|
||||||
|
return team;
|
||||||
|
|
||||||
|
return scoreboard.registerNewTeam(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FightScoreboard scoreboard;
|
private static FightScoreboard scoreboard;
|
||||||
|
@ -20,10 +20,12 @@
|
|||||||
package de.steamwar.fightsystem.listener;
|
package de.steamwar.fightsystem.listener;
|
||||||
|
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
import de.steamwar.fightsystem.fight.Fight;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
|
import de.steamwar.fightsystem.winconditions.Winconditions;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import org.bukkit.entity.Arrow;
|
import org.bukkit.entity.Arrow;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -36,7 +38,7 @@ import java.util.Objects;
|
|||||||
public class InFightDamage implements Listener {
|
public class InFightDamage implements Listener {
|
||||||
|
|
||||||
public InFightDamage() {
|
public InFightDamage() {
|
||||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this);
|
new StateDependentListener(!Config.ActiveWinconditions.contains(Winconditions.AMONG_US), FightState.Running, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
package de.steamwar.fightsystem.listener;
|
package de.steamwar.fightsystem.listener;
|
||||||
|
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
import de.steamwar.fightsystem.fight.Fight;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
@ -28,7 +27,6 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockDispenseEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
@ -74,10 +72,4 @@ public class InFightInventory implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onBlockDispense(BlockDispenseEvent e) {
|
|
||||||
if(Config.ArenaRegion.inRegion(e.getBlock()) && e.getItem().getType() == Material.TNT)
|
|
||||||
e.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,30 +23,47 @@ import de.steamwar.fightsystem.ArenaMode;
|
|||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
import de.steamwar.fightsystem.fight.Fight;
|
||||||
|
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||||
import de.steamwar.fightsystem.fight.FightTeam;
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
import de.steamwar.fightsystem.record.REntity;
|
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
|
import de.steamwar.fightsystem.utils.BountifulWrapper;
|
||||||
|
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockDispenseEvent;
|
||||||
import org.bukkit.event.block.BlockFromToEvent;
|
import org.bukkit.event.block.BlockFromToEvent;
|
||||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
import org.bukkit.event.entity.SpawnerSpawnEvent;
|
import org.bukkit.event.entity.SpawnerSpawnEvent;
|
||||||
import org.bukkit.event.inventory.CraftItemEvent;
|
import org.bukkit.event.inventory.CraftItemEvent;
|
||||||
import org.bukkit.event.inventory.FurnaceSmeltEvent;
|
import org.bukkit.event.inventory.FurnaceSmeltEvent;
|
||||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
|
||||||
import org.bukkit.event.player.*;
|
import org.bukkit.event.player.*;
|
||||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||||
import org.bukkit.event.world.WorldLoadEvent;
|
import org.bukkit.event.world.WorldLoadEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.scoreboard.NameTagVisibility;
|
||||||
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
public class Permanent implements Listener {
|
public class Permanent implements Listener {
|
||||||
|
|
||||||
|
private static final Team spectatorTeam = FightScoreboard.getBukkitTeam("Spectator");
|
||||||
|
static {
|
||||||
|
BountifulWrapper.impl.setNametagVisibility(spectatorTeam);
|
||||||
|
spectatorTeam.setNameTagVisibility(NameTagVisibility.NEVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Team getSpectatorTeam() {
|
||||||
|
return spectatorTeam;
|
||||||
|
}
|
||||||
|
|
||||||
public Permanent() {
|
public Permanent() {
|
||||||
new StateDependentListener(ArenaMode.All, FightState.All, this);
|
new StateDependentListener(ArenaMode.All, FightState.All, this);
|
||||||
}
|
}
|
||||||
@ -79,10 +96,9 @@ public class Permanent implements Listener {
|
|||||||
|
|
||||||
if (!Config.ArenaLeaveable && !Fight.fighting(player)) {
|
if (!Config.ArenaLeaveable && !Fight.fighting(player)) {
|
||||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||||
|
spectatorTeam.addEntry(player.getName());
|
||||||
player.teleport(Config.SpecSpawn);
|
player.teleport(Config.SpecSpawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
REntity.playerJoins(player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
@ -121,7 +137,7 @@ public class Permanent implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onCrafting(CraftItemEvent e){
|
public void onCrafting(CraftItemEvent e) {
|
||||||
if(Fight.fighting((Player) e.getWhoClicked()))
|
if(Fight.fighting((Player) e.getWhoClicked()))
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
@ -132,16 +148,34 @@ public class Permanent implements Listener {
|
|||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@SuppressWarnings("deprecation")
|
||||||
public void onDropPickup(InventoryPickupItemEvent e){
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
if(Config.ArenaRegion.inRegion(e.getItem().getLocation()))
|
public void onBlockBreak(BlockBreakEvent e) {
|
||||||
e.setCancelled(true);
|
Block block = e.getBlock();
|
||||||
|
for(ItemStack stack : block.getDrops(e.getPlayer().getItemInHand()))
|
||||||
|
Config.world.dropItemNaturally(block.getLocation(), stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onDropping(PlayerDropItemEvent e){
|
public void onDropPickup(PlayerPickupItemEvent e) {
|
||||||
if(Fight.fighting(e.getPlayer()))
|
if(!(Config.ArenaRegion.inRegion(e.getItem().getLocation())))
|
||||||
e.setCancelled(true);
|
return;
|
||||||
|
Player player = e.getPlayer();
|
||||||
|
|
||||||
|
ItemStack stack = e.getItem().getItemStack();
|
||||||
|
if(Config.PersonalKits) {
|
||||||
|
if(Config.ForbiddenItems.contains(stack.getType())) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FightPlayer fp = Fight.getFightPlayer(player);
|
||||||
|
if(fp == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!fp.getKit().contains(stack)) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -164,4 +198,15 @@ public class Permanent implements Listener {
|
|||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockDispense(BlockDispenseEvent e) {
|
||||||
|
Block block = e.getBlock();
|
||||||
|
|
||||||
|
if(!Config.ArenaRegion.inRegion(block))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(e.getItem().getType() == Material.TNT || FlatteningWrapper.impl.isFacingWater(block))
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.inventory.InventoryAction;
|
import org.bukkit.event.inventory.InventoryAction;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -108,6 +109,15 @@ public class PersonalKitCreator implements Listener {
|
|||||||
backup.close();
|
backup.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onOpenEvent(InventoryOpenEvent e){
|
||||||
|
InventoryBackup backup = openKitCreators.get(e.getPlayer());
|
||||||
|
if(backup == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
backup.close();
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onInventoryClose(InventoryCloseEvent e) {
|
public void onInventoryClose(InventoryCloseEvent e) {
|
||||||
InventoryBackup backup = openKitCreators.get(e.getPlayer());
|
InventoryBackup backup = openKitCreators.get(e.getPlayer());
|
||||||
@ -134,7 +144,7 @@ public class PersonalKitCreator implements Listener {
|
|||||||
private InventoryBackup(Player player, PersonalKit kit){
|
private InventoryBackup(Player player, PersonalKit kit){
|
||||||
openKitCreators.put(player, this);
|
openKitCreators.put(player, this);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.backup = new Kit("backup", player);
|
this.backup = Kit.getActiveKit(player);
|
||||||
this.kit = kit;
|
this.kit = kit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,17 +28,25 @@ import org.bukkit.block.BlockFace;
|
|||||||
import org.bukkit.block.PistonMoveReaction;
|
import org.bukkit.block.PistonMoveReaction;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockPistonEvent;
|
||||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class PistonListener implements Listener {
|
public class PistonListener implements Listener {
|
||||||
|
|
||||||
public PistonListener() {
|
private final Consumer<BlockPistonEvent> leftAreaHandler;
|
||||||
|
|
||||||
|
public PistonListener(Set<ArenaMode> condition, Consumer<BlockPistonEvent> leftAreaHandler) {
|
||||||
|
this.leftAreaHandler = leftAreaHandler;
|
||||||
|
if(!condition.contains(Config.mode))
|
||||||
|
return;
|
||||||
|
|
||||||
//Wenn Entern aktiv ist, sollen Raketen etc. entern können
|
//Wenn Entern aktiv ist, sollen Raketen etc. entern können
|
||||||
if(!ArenaMode.Check.contains(Config.mode)) {
|
new StateDependentListener(!Config.AllowMissiles, FightState.All, this);
|
||||||
new StateDependentListener(!Config.AllowMissiles, FightState.All, this);
|
new StateDependentListener(Config.AllowMissiles, FightState.Setup, this);
|
||||||
new StateDependentListener(Config.AllowMissiles, FightState.Setup, this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -50,7 +58,7 @@ public class PistonListener implements Listener {
|
|||||||
for(Block block : e.getBlocks()){
|
for(Block block : e.getBlocks()){
|
||||||
Block target = block.getRelative(face);
|
Block target = block.getRelative(face);
|
||||||
if(!Config.BlueExtendRegion.inRegion(target) && !Config.RedExtendRegion.inRegion(target) && block.getPistonMoveReaction() != PistonMoveReaction.BREAK) {
|
if(!Config.BlueExtendRegion.inRegion(target) && !Config.RedExtendRegion.inRegion(target) && block.getPistonMoveReaction() != PistonMoveReaction.BREAK) {
|
||||||
e.setCancelled(true);
|
leftAreaHandler.accept(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,7 +71,7 @@ public class PistonListener implements Listener {
|
|||||||
|
|
||||||
for(Block block : e.getBlocks()){
|
for(Block block : e.getBlocks()){
|
||||||
if(!Config.BlueExtendRegion.inRegion(block) && !Config.RedExtendRegion.inRegion(block)) {
|
if(!Config.BlueExtendRegion.inRegion(block) && !Config.RedExtendRegion.inRegion(block)) {
|
||||||
e.setCancelled(true);
|
leftAreaHandler.accept(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.fightsystem.listener;
|
package de.steamwar.fightsystem.listener;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
import de.steamwar.fightsystem.fight.Fight;
|
||||||
@ -48,6 +49,7 @@ import org.bukkit.event.player.*;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@ -89,16 +91,19 @@ public class Recording implements Listener {
|
|||||||
}
|
}
|
||||||
}.register();
|
}.register();
|
||||||
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
|
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
|
||||||
|
private final BiFunction<Player, Object, Object> place = Recording.this::blockPlace;
|
||||||
|
private final BiFunction<Player, Object, Object> dig = Recording.this::blockDig;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
ProtocolAPI.setIncomingHandler(blockPlacePacket, Recording.this::blockPlace);
|
TinyProtocol.instance.addFilter(blockPlacePacket, place);
|
||||||
ProtocolAPI.setIncomingHandler(blockDigPacket, Recording.this::blockDig);
|
TinyProtocol.instance.addFilter(blockDigPacket, dig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
ProtocolAPI.removeIncomingHandler(blockPlacePacket);
|
TinyProtocol.instance.removeFilter(blockPlacePacket, place);
|
||||||
ProtocolAPI.removeIncomingHandler(blockDigPacket);
|
TinyProtocol.instance.removeFilter(blockDigPacket, dig);
|
||||||
}
|
}
|
||||||
}.register();
|
}.register();
|
||||||
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
|
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
|
||||||
@ -128,8 +133,6 @@ public class Recording implements Listener {
|
|||||||
|
|
||||||
public static final Class<?> blockPlacePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockPlace");
|
public static final Class<?> blockPlacePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockPlace");
|
||||||
private Object blockPlace(Player p, Object packet) {
|
private Object blockPlace(Player p, Object packet) {
|
||||||
ClickAnalyzer.onBlockPlace(p);
|
|
||||||
|
|
||||||
boolean mainHand = BountifulWrapper.impl.mainHand(packet);
|
boolean mainHand = BountifulWrapper.impl.mainHand(packet);
|
||||||
if(!isNotSent(p) && BountifulWrapper.impl.bowInHand(mainHand, p))
|
if(!isNotSent(p) && BountifulWrapper.impl.bowInHand(mainHand, p))
|
||||||
GlobalRecorder.getInstance().bowSpan(p, true, !mainHand);
|
GlobalRecorder.getInstance().bowSpan(p, true, !mainHand);
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
package de.steamwar.fightsystem.listener;
|
|
||||||
|
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
|
||||||
import de.steamwar.fightsystem.utils.CraftbukkitWrapper;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerResourcePackStatusEvent;
|
|
||||||
|
|
||||||
public class ResourcePack implements Listener {
|
|
||||||
|
|
||||||
public ResourcePack(){
|
|
||||||
new StateDependentListener(ArenaMode.Event, FightState.All, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void handlePlayerJoin(PlayerJoinEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
CraftbukkitWrapper.impl.sendResourcePack(player, "https://steamwar.de/antixray.zip", "3e94f5abeb07cc95067b27705615ec14666abe7b");
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onResourcepack(PlayerResourcePackStatusEvent e){
|
|
||||||
if(e.getStatus() == PlayerResourcePackStatusEvent.Status.ACCEPTED || e.getStatus() == PlayerResourcePackStatusEvent.Status.SUCCESSFULLY_LOADED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Player player = e.getPlayer();
|
|
||||||
FightSystem.getMessage().sendPrefixless("RESOURCEPACK_REQUIRED", player);
|
|
||||||
player.kickPlayer(null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -25,15 +25,11 @@ import de.steamwar.fightsystem.fight.Fight;
|
|||||||
import de.steamwar.fightsystem.fight.FightPlayer;
|
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
public class RunningWorldInteraction implements Listener {
|
public class RunningWorldInteraction implements Listener {
|
||||||
|
|
||||||
@ -41,35 +37,6 @@ public class RunningWorldInteraction implements Listener {
|
|||||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this);
|
new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onBlockBreak(BlockBreakEvent event) {
|
|
||||||
if(!Fight.fighting(event.getPlayer()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Inventory inventory = event.getPlayer().getInventory();
|
|
||||||
|
|
||||||
ItemStack stack = FlatteningWrapper.impl.onBreak(event.getBlock());
|
|
||||||
|
|
||||||
for (int i = 0; i <= 35; i++) { //35 is the last normal inventory slot
|
|
||||||
ItemStack itemStack = inventory.getItem(i);
|
|
||||||
if (itemStack != null && itemStack.isSimilar(stack) && itemStack.getAmount() != itemStack.getMaxStackSize()) {
|
|
||||||
itemStack.setAmount(itemStack.getAmount() + 1);
|
|
||||||
inventory.setItem(i, itemStack);
|
|
||||||
event.getPlayer().updateInventory();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i <= 35; i++) { //35 is the last normal inventory slot
|
|
||||||
ItemStack itemStack = inventory.getItem(i);
|
|
||||||
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
|
|
||||||
inventory.setItem(i, stack);
|
|
||||||
event.getPlayer().updateInventory();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockPlace(BlockPlaceEvent e) {
|
public void onBlockPlace(BlockPlaceEvent e) {
|
||||||
FightPlayer fp = Fight.getFightPlayer(e.getPlayer());
|
FightPlayer fp = Fight.getFightPlayer(e.getPlayer());
|
||||||
|
@ -80,7 +80,7 @@ public class TeamArea implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void blockBreak(BlockBreakEvent event) {
|
public void blockBreak(BlockBreakEvent event) {
|
||||||
Block block = event.getBlock();
|
Block block = event.getBlock();
|
||||||
if(Config.BluePasteRegion.getMinY() <= block.getY())
|
if(Config.BlueExtendRegion.getMinY() <= block.getY())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
@ -20,10 +20,11 @@
|
|||||||
package de.steamwar.fightsystem.record;
|
package de.steamwar.fightsystem.record;
|
||||||
|
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
|
import de.steamwar.sql.Replay;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.nio.file.Files;
|
import java.io.FileInputStream;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.io.IOException;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
public class FileSource extends PacketSource {
|
public class FileSource extends PacketSource {
|
||||||
@ -39,19 +40,8 @@ public class FileSource extends PacketSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Config.ReplayID > 0) {
|
if(Config.ReplayID > 0) {
|
||||||
de.steamwar.sql.Fight.getReplay(Config.ReplayID, input -> {
|
|
||||||
try {
|
|
||||||
Files.copy(
|
|
||||||
input,
|
|
||||||
FileRecorder.getFile().toPath(),
|
|
||||||
StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new SecurityException("Could not start replay", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new FileSource(FileRecorder.getFile());
|
new FileSource(Replay.get(Config.ReplayID).getReplay());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SecurityException("Could not start replay", e);
|
throw new SecurityException("Could not start replay", e);
|
||||||
}
|
}
|
||||||
@ -60,6 +50,7 @@ public class FileSource extends PacketSource {
|
|||||||
|
|
||||||
public FileSource(File fightFile) throws IOException {
|
public FileSource(File fightFile) throws IOException {
|
||||||
super(new GZIPInputStream(new FileInputStream(fightFile)));
|
super(new GZIPInputStream(new FileInputStream(fightFile)));
|
||||||
|
new PacketProcessor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -31,6 +31,7 @@ public class LiveSource extends PacketSource {
|
|||||||
protected LiveSource(Socket socket) throws IOException {
|
protected LiveSource(Socket socket) throws IOException {
|
||||||
super(socket.getInputStream());
|
super(socket.getInputStream());
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
|
new PacketProcessor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,6 +21,9 @@ package de.steamwar.fightsystem.record;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
|
import de.steamwar.entity.REntity;
|
||||||
|
import de.steamwar.entity.REntityServer;
|
||||||
|
import de.steamwar.entity.RPlayer;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.countdown.Countdown;
|
import de.steamwar.fightsystem.countdown.Countdown;
|
||||||
@ -31,23 +34,44 @@ import de.steamwar.fightsystem.fight.FreezeWorld;
|
|||||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
import de.steamwar.fightsystem.listener.FightScoreboard;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.utils.*;
|
import de.steamwar.fightsystem.utils.*;
|
||||||
|
import de.steamwar.sql.SchematicData;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.Team;
|
import de.steamwar.sql.Team;
|
||||||
|
import de.steamwar.techhider.BlockIds;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
import org.bukkit.scoreboard.NameTagVisibility;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
|
import java.io.FilterInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PacketProcessor {
|
public class PacketProcessor implements Listener {
|
||||||
|
|
||||||
|
private static final org.bukkit.scoreboard.Team team = FightScoreboard.getBukkitTeam("Replay");
|
||||||
|
static {
|
||||||
|
BountifulWrapper.impl.setNametagVisibility(team);
|
||||||
|
team.setNameTagVisibility(NameTagVisibility.NEVER);
|
||||||
|
}
|
||||||
|
|
||||||
private static PacketProcessor currentProcessor = null;
|
private static PacketProcessor currentProcessor = null;
|
||||||
|
|
||||||
@ -64,9 +88,11 @@ public class PacketProcessor {
|
|||||||
private final PacketSource source;
|
private final PacketSource source;
|
||||||
private final BukkitTask task;
|
private final BukkitTask task;
|
||||||
private final LinkedList<Runnable> syncList = new LinkedList<>();
|
private final LinkedList<Runnable> syncList = new LinkedList<>();
|
||||||
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
private final Set<Integer> hiddenBlockIds = Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet());
|
||||||
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
private final int obfuscateWith = BlockIds.impl.materialToId(Material.getMaterial(Config.ObfuscateWith.toUpperCase()));
|
||||||
private final FreezeWorld freezer = new FreezeWorld();
|
private final FreezeWorld freezer = new FreezeWorld();
|
||||||
|
private final REntityServer entityServer = new REntityServer();
|
||||||
|
private final Map<Integer, REntity> entities = new HashMap<>();
|
||||||
|
|
||||||
private boolean rotateZ = false;
|
private boolean rotateZ = false;
|
||||||
private int arenaMinX = Config.ArenaRegion.getMinX();
|
private int arenaMinX = Config.ArenaRegion.getMinX();
|
||||||
@ -78,7 +104,7 @@ public class PacketProcessor {
|
|||||||
private boolean tickFinished = false;
|
private boolean tickFinished = false;
|
||||||
private final List<Integer> lastPackets = new LinkedList<>();
|
private final List<Integer> lastPackets = new LinkedList<>();
|
||||||
|
|
||||||
public PacketProcessor(PacketSource source){
|
public PacketProcessor(PacketSource source) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
currentProcessor = this;
|
currentProcessor = this;
|
||||||
|
|
||||||
@ -95,13 +121,15 @@ public class PacketProcessor {
|
|||||||
packetDecoder[0x0a] = this::bow;
|
packetDecoder[0x0a] = this::bow;
|
||||||
packetDecoder[0x0b] = this::damage;
|
packetDecoder[0x0b] = this::damage;
|
||||||
packetDecoder[0x0c] = this::fireTick;
|
packetDecoder[0x0c] = this::fireTick;
|
||||||
packetDecoder[0x20] = this::arenaInfo;
|
packetDecoder[0x20] = this::oldArenaInfo;
|
||||||
packetDecoder[0x30] = this::block;
|
packetDecoder[0x21] = this::arenaInfo;
|
||||||
|
packetDecoder[0x30] = this::byteWorldHeightBlock;
|
||||||
packetDecoder[0x31] = this::particle;
|
packetDecoder[0x31] = this::particle;
|
||||||
packetDecoder[0x32] = this::sound;
|
packetDecoder[0x32] = this::sound;
|
||||||
packetDecoder[0x33] = this::shortBlock;
|
packetDecoder[0x33] = this::shortBlock;
|
||||||
packetDecoder[0x34] = this::soundAtPlayer;
|
packetDecoder[0x34] = this::soundAtPlayer;
|
||||||
packetDecoder[0x35] = this::shortRelativeBlock;
|
packetDecoder[0x35] = this::shortRelativeBlock;
|
||||||
|
packetDecoder[0x36] = this::block;
|
||||||
packetDecoder[0xa0] = () -> send(ChatMessageType.CHAT);
|
packetDecoder[0xa0] = () -> send(ChatMessageType.CHAT);
|
||||||
packetDecoder[0xa1] = () -> send(ChatMessageType.ACTION_BAR);
|
packetDecoder[0xa1] = () -> send(ChatMessageType.ACTION_BAR);
|
||||||
packetDecoder[0xa2] = () -> send(ChatMessageType.SYSTEM);
|
packetDecoder[0xa2] = () -> send(ChatMessageType.SYSTEM);
|
||||||
@ -131,6 +159,15 @@ public class PacketProcessor {
|
|||||||
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::runSync, 1, 1);
|
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::runSync, 1, 1);
|
||||||
}else
|
}else
|
||||||
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::process, 1, 1);
|
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::process, 1, 1);
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, FightSystem.getPlugin());
|
||||||
|
for(Player player : Bukkit.getOnlinePlayers())
|
||||||
|
entityServer.addPlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||||
|
entityServer.addPlayer(e.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void skipToSubtitle() {
|
public void skipToSubtitle() {
|
||||||
@ -196,7 +233,11 @@ public class PacketProcessor {
|
|||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
int userId = source.readInt();
|
int userId = source.readInt();
|
||||||
|
|
||||||
execSync(() -> new REntity(entityId, userId));
|
execSync(() -> {
|
||||||
|
SteamwarUser user = SteamwarUser.get(userId);
|
||||||
|
entities.put(entityId, new RPlayer(entityServer, user.getUUID(), user.getUserName(), Config.SpecSpawn));
|
||||||
|
team.addEntry(user.getUserName());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityMoves() throws IOException {
|
private void entityMoves() throws IOException {
|
||||||
@ -214,14 +255,18 @@ public class PacketProcessor {
|
|||||||
float yaw = source.readFloat() + (rotateZ ? 180 : 0);
|
float yaw = source.readFloat() + (rotateZ ? 180 : 0);
|
||||||
byte headYaw = (byte)((source.readByte() + (rotateZ ? 128 : 0)) % 256);
|
byte headYaw = (byte)((source.readByte() + (rotateZ ? 128 : 0)) % 256);
|
||||||
|
|
||||||
execSync(() -> REntity.getEntity(entityId).move(locX, locY, locZ, pitch, yaw, headYaw));
|
execSync(() -> {
|
||||||
|
REntity entity = entities.get(entityId);
|
||||||
|
if(entity != null)
|
||||||
|
entity.move(locX, locY, locZ, pitch, yaw, headYaw);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityDespawns() throws IOException {
|
private void entityDespawns() throws IOException {
|
||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
|
|
||||||
execSync(() -> {
|
execSync(() -> {
|
||||||
REntity entity = REntity.getEntity(entityId);
|
REntity entity = entities.remove(entityId);
|
||||||
if(entity != null)
|
if(entity != null)
|
||||||
entity.die();
|
entity.die();
|
||||||
});
|
});
|
||||||
@ -231,20 +276,20 @@ public class PacketProcessor {
|
|||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
boolean sneaking = source.readBoolean();
|
boolean sneaking = source.readBoolean();
|
||||||
|
|
||||||
execSync(() -> REntity.getEntity(entityId).sneak(sneaking));
|
execSync(() -> entities.get(entityId).setPose(sneaking ? de.steamwar.core.FlatteningWrapper.EntityPose.SNEAKING : de.steamwar.core.FlatteningWrapper.EntityPose.NORMAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityAnimation() throws IOException {
|
private void entityAnimation() throws IOException {
|
||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
byte animation = source.readByte();
|
byte animation = source.readByte();
|
||||||
|
|
||||||
execSync(() -> REntity.getEntity(entityId).animation(animation));
|
execSync(() -> entities.get(entityId).showAnimation(animation));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tntSpawn() throws IOException {
|
private void tntSpawn() throws IOException {
|
||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
|
|
||||||
execSync(() -> new REntity(entityId, EntityType.PRIMED_TNT));
|
execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.PRIMED_TNT, Config.SpecSpawn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityVelocity() throws IOException {
|
private void entityVelocity() throws IOException {
|
||||||
@ -255,7 +300,7 @@ public class PacketProcessor {
|
|||||||
double dZ = rotateZ ? -source.readDouble() : source.readDouble();
|
double dZ = rotateZ ? -source.readDouble() : source.readDouble();
|
||||||
|
|
||||||
execSync(() -> {
|
execSync(() -> {
|
||||||
REntity entity = REntity.getEntity(entityId);
|
REntity entity = entities.get(entityId);
|
||||||
if(entity != null)
|
if(entity != null)
|
||||||
entity.setVelocity(dX, dY, dZ);
|
entity.setVelocity(dX, dY, dZ);
|
||||||
});
|
});
|
||||||
@ -265,21 +310,47 @@ public class PacketProcessor {
|
|||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
String item = source.readUTF();
|
String item = source.readUTF();
|
||||||
boolean enchanted = source.readBoolean();
|
boolean enchanted = source.readBoolean();
|
||||||
String slot = source.readUTF();
|
String slotName = source.readUTF();
|
||||||
|
|
||||||
execSync(() -> REntity.getEntity(entityId).setItem(item, enchanted, slot));
|
ItemStack stack = new ItemStack(Material.valueOf(item.replace("minecraft:", "").toUpperCase()), 1);
|
||||||
|
if(enchanted)
|
||||||
|
stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
||||||
|
|
||||||
|
Object slot;
|
||||||
|
switch(slotName){
|
||||||
|
case "HEAD":
|
||||||
|
slot = de.steamwar.core.ProtocolWrapper.itemSlots[5];
|
||||||
|
break;
|
||||||
|
case "CHEST":
|
||||||
|
slot = de.steamwar.core.ProtocolWrapper.itemSlots[4];
|
||||||
|
break;
|
||||||
|
case "LEGS":
|
||||||
|
slot = de.steamwar.core.ProtocolWrapper.itemSlots[3];
|
||||||
|
break;
|
||||||
|
case "FEET":
|
||||||
|
slot = de.steamwar.core.ProtocolWrapper.itemSlots[2];
|
||||||
|
break;
|
||||||
|
case "OFFHAND":
|
||||||
|
slot = de.steamwar.core.ProtocolWrapper.itemSlots[1];
|
||||||
|
break;
|
||||||
|
case "MAINHAND":
|
||||||
|
default:
|
||||||
|
slot = de.steamwar.core.ProtocolWrapper.itemSlots[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
execSync(() -> entities.get(entityId).setItem(slot, stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void arrowSpawn() throws IOException {
|
private void arrowSpawn() throws IOException {
|
||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
|
|
||||||
execSync(() -> new REntity(entityId, EntityType.ARROW));
|
execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.ARROW, Config.SpecSpawn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireballSpawn() throws IOException {
|
private void fireballSpawn() throws IOException {
|
||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
|
|
||||||
execSync(() -> new REntity(entityId, EntityType.FIREBALL));
|
execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.FIREBALL, Config.SpecSpawn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send(ChatMessageType type) throws IOException {
|
private void send(ChatMessageType type) throws IOException {
|
||||||
@ -297,13 +368,20 @@ public class PacketProcessor {
|
|||||||
Bukkit.getOnlinePlayers().forEach(p -> Countdown.sendCountdownMessage(p, message, displaytime, appendix));
|
Bukkit.getOnlinePlayers().forEach(p -> Countdown.sendCountdownMessage(p, message, displaytime, appendix));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void arenaInfo() throws IOException {
|
private void oldArenaInfo() throws IOException {
|
||||||
rotateZ = source.readBoolean() != Config.blueNegZ();
|
rotateZ = source.readBoolean() != Config.blueNegZ();
|
||||||
arenaMinY = Byte.toUnsignedInt(source.readByte());
|
arenaMinY = Byte.toUnsignedInt(source.readByte());
|
||||||
arenaMinX = source.readInt();
|
arenaMinX = source.readInt();
|
||||||
arenaMinZ = source.readInt();
|
arenaMinZ = source.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void arenaInfo() throws IOException {
|
||||||
|
rotateZ = source.readBoolean() != Config.blueNegZ();
|
||||||
|
arenaMinX = source.readInt();
|
||||||
|
arenaMinY = source.readInt();
|
||||||
|
arenaMinZ = source.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
private void shortBlock() throws IOException {
|
private void shortBlock() throws IOException {
|
||||||
int x = Byte.toUnsignedInt(source.readByte()) + Config.ArenaRegion.getMinX();
|
int x = Byte.toUnsignedInt(source.readByte()) + Config.ArenaRegion.getMinX();
|
||||||
int y = Byte.toUnsignedInt(source.readByte());
|
int y = Byte.toUnsignedInt(source.readByte());
|
||||||
@ -327,7 +405,7 @@ public class PacketProcessor {
|
|||||||
setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState);
|
setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void block() throws IOException {
|
private void byteWorldHeightBlock() throws IOException {
|
||||||
int x = source.readInt() - arenaMinX;
|
int x = source.readInt() - arenaMinX;
|
||||||
int y = Byte.toUnsignedInt(source.readByte()) - arenaMinY;
|
int y = Byte.toUnsignedInt(source.readByte()) - arenaMinY;
|
||||||
int z = source.readInt() - arenaMinZ;
|
int z = source.readInt() - arenaMinZ;
|
||||||
@ -341,11 +419,25 @@ public class PacketProcessor {
|
|||||||
setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState);
|
setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void block() throws IOException {
|
||||||
|
int x = source.readInt() - arenaMinX;
|
||||||
|
int y = source.readShort() - arenaMinY;
|
||||||
|
int z = source.readInt() - arenaMinZ;
|
||||||
|
int blockState = source.readInt();
|
||||||
|
|
||||||
|
if(rotateZ) {
|
||||||
|
x = Config.ArenaRegion.getSizeX() - x;
|
||||||
|
z = Config.ArenaRegion.getSizeZ() - z;
|
||||||
|
}
|
||||||
|
|
||||||
|
setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState);
|
||||||
|
}
|
||||||
|
|
||||||
private void setBlock(int x, int y, int z, int blockState){
|
private void setBlock(int x, int y, int z, int blockState){
|
||||||
if(!Config.ArenaRegion.in2dRegion(x, z))
|
if(!Config.ArenaRegion.in2dRegion(x, z))
|
||||||
return; //Outside of the arena
|
return; //Outside of the arena
|
||||||
|
|
||||||
execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHider.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState));
|
execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void particle() throws IOException {
|
private void particle() throws IOException {
|
||||||
@ -401,13 +493,20 @@ public class PacketProcessor {
|
|||||||
|
|
||||||
private void pasteSchem(FightTeam team) throws IOException {
|
private void pasteSchem(FightTeam team) throws IOException {
|
||||||
int schemId = source.readInt();
|
int schemId = source.readInt();
|
||||||
|
if(schemId == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
execSync(() -> team.pasteSchem(SchematicNode.getSchematicNode(schemId)));
|
execSync(() -> team.pasteSchem(SchematicNode.getSchematicNode(schemId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pasteEmbeddedSchem(FightTeam team) throws IOException {
|
private void pasteEmbeddedSchem(FightTeam team) throws IOException {
|
||||||
int schemId = source.readInt();
|
int schemId = source.readInt();
|
||||||
Clipboard clipboard = SchematicNode.clipboardFromStream(source, Core.getVersion() > 12);
|
Clipboard clipboard = SchematicData.clipboardFromStream(new FilterInputStream(source) {
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
// FAWE 1.12 calls close...
|
||||||
|
}
|
||||||
|
}, Core.getVersion() > 12);
|
||||||
|
|
||||||
execSync(() -> team.pasteSchem(schemId, clipboard));
|
execSync(() -> team.pasteSchem(schemId, clipboard));
|
||||||
}
|
}
|
||||||
@ -477,7 +576,10 @@ public class PacketProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void endReplay() {
|
private void endReplay() {
|
||||||
REntity.dieAll();
|
HandlerList.unregisterAll(this);
|
||||||
|
entityServer.close();
|
||||||
|
entities.clear();
|
||||||
|
|
||||||
freezer.disable();
|
freezer.disable();
|
||||||
if(!Config.replayserver()) {
|
if(!Config.replayserver()) {
|
||||||
FightSystem.getMessage().broadcast("REPLAY_ENDS");
|
FightSystem.getMessage().broadcast("REPLAY_ENDS");
|
||||||
@ -493,6 +595,7 @@ public class PacketProcessor {
|
|||||||
}
|
}
|
||||||
FightState.setFightState(FightState.SPECTATE);
|
FightState.setFightState(FightState.SPECTATE);
|
||||||
currentProcessor = null;
|
currentProcessor = null;
|
||||||
|
task.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bow() throws IOException {
|
private void bow() throws IOException {
|
||||||
@ -500,24 +603,25 @@ public class PacketProcessor {
|
|||||||
boolean drawn = source.readBoolean();
|
boolean drawn = source.readBoolean();
|
||||||
boolean offHand = source.readBoolean();
|
boolean offHand = source.readBoolean();
|
||||||
|
|
||||||
execSync(() -> REntity.getEntity(entityId).setBowDrawn(drawn, offHand));
|
execSync(() -> entities.get(entityId).setBowDrawn(drawn, offHand));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void damage() throws IOException {
|
private void damage() throws IOException {
|
||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
|
|
||||||
execSync(() -> REntity.getEntity(entityId).damage());
|
execSync(() -> entities.get(entityId).showDamage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireTick() throws IOException {
|
private void fireTick() throws IOException {
|
||||||
int entityId = source.readInt();
|
int entityId = source.readInt();
|
||||||
boolean perma = source.readBoolean();
|
boolean perma = source.readBoolean();
|
||||||
|
|
||||||
execSync(() -> REntity.getEntity(entityId).setOnFire(perma));
|
execSync(() -> entities.get(entityId).setOnFire(perma));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tick(){
|
private void tick(){
|
||||||
execSync(REntity::tickFire);
|
execSync(entityServer::tick);
|
||||||
|
|
||||||
if(!source.async() && !skipToSubtitle)
|
if(!source.async() && !skipToSubtitle)
|
||||||
tickFinished = true;
|
tickFinished = true;
|
||||||
}
|
}
|
||||||
@ -527,6 +631,11 @@ public class PacketProcessor {
|
|||||||
try{
|
try{
|
||||||
while(!source.isClosed() && !tickFinished){
|
while(!source.isClosed() && !tickFinished){
|
||||||
int packetType = Byte.toUnsignedInt(source.readByte());
|
int packetType = Byte.toUnsignedInt(source.readByte());
|
||||||
|
|
||||||
|
lastPackets.add(packetType);
|
||||||
|
if (lastPackets.size() > 10)
|
||||||
|
lastPackets.remove(0);
|
||||||
|
|
||||||
PacketParser parser = packetDecoder[packetType];
|
PacketParser parser = packetDecoder[packetType];
|
||||||
if(parser != null){
|
if(parser != null){
|
||||||
parser.process();
|
parser.process();
|
||||||
@ -534,9 +643,6 @@ public class PacketProcessor {
|
|||||||
Bukkit.getLogger().log(Level.SEVERE, "Unknown packet " + packetType + " recieved, closing. LastPacket: " + Arrays.toString(lastPackets.toArray()));
|
Bukkit.getLogger().log(Level.SEVERE, "Unknown packet " + packetType + " recieved, closing. LastPacket: " + Arrays.toString(lastPackets.toArray()));
|
||||||
source.close();
|
source.close();
|
||||||
}
|
}
|
||||||
lastPackets.add(packetType);
|
|
||||||
if (lastPackets.size() > 10)
|
|
||||||
lastPackets.remove(0);
|
|
||||||
}
|
}
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
Bukkit.getLogger().log(Level.INFO, "The FightServer is offline");
|
Bukkit.getLogger().log(Level.INFO, "The FightServer is offline");
|
||||||
@ -547,10 +653,7 @@ public class PacketProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(source.isClosed()){
|
if(source.isClosed()){
|
||||||
execSync(() -> {
|
execSync(() -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay));
|
||||||
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay);
|
|
||||||
task.cancel();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ public abstract class PacketSource extends DataInputStream {
|
|||||||
|
|
||||||
protected PacketSource(InputStream inputStream){
|
protected PacketSource(InputStream inputStream){
|
||||||
super(inputStream);
|
super(inputStream);
|
||||||
new PacketProcessor(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,348 +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.record;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
|
||||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
|
||||||
import de.steamwar.fightsystem.utils.*;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.scoreboard.NameTagVisibility;
|
|
||||||
import org.bukkit.scoreboard.Team;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class REntity {
|
|
||||||
|
|
||||||
private static final Map<Integer, REntity> entities = new HashMap<>();
|
|
||||||
|
|
||||||
public static REntity getEntity(int internalId){
|
|
||||||
return entities.get(internalId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object entityStatusWatcher;
|
|
||||||
private static Object sneakingDataWatcher;
|
|
||||||
private static Object bowDrawnWatcher;
|
|
||||||
public static void initWatchers() {
|
|
||||||
// not during <clinit> to prevent cyclic class init.
|
|
||||||
entityStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(0, Byte.class);
|
|
||||||
sneakingDataWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 6 : 0, BlockIdWrapper.impl.getPose(true).getClass());
|
|
||||||
bowDrawnWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 7 : 6, Byte.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void tickFire() {
|
|
||||||
entities.forEach((integer, entity) -> {
|
|
||||||
if(entity.fireTick > 0) {
|
|
||||||
entity.fireTick--;
|
|
||||||
if(entity.fireTick == 0) {
|
|
||||||
ProtocolAPI.broadcastPacket(entity.getDataWatcherPacket(entityStatusWatcher, (byte)0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void playerJoins(Player player) {
|
|
||||||
for(REntity entity : entities.values()){
|
|
||||||
if(entity.entityType == EntityType.PLAYER){
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getPlayerInfoPacket());
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getNamedSpawnPacket());
|
|
||||||
for (Map.Entry<String, ItemStack> entry : entity.itemSlots.entrySet()) {
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getEquipmentPacket(entry.getKey(), entry.getValue()));
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getSpawnEntityPacket());
|
|
||||||
}
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getTeleportPacket());
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getHeadRotationPacket());
|
|
||||||
|
|
||||||
if(entity.fireTick != 0) {
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getDataWatcherPacket(entityStatusWatcher, (byte) 1));
|
|
||||||
}
|
|
||||||
if(entity.sneaks) {
|
|
||||||
TinyProtocol.instance.sendPacket(player, entity.getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(true)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dieAll(){
|
|
||||||
entities.forEach((id, entity) -> entity.broadcastDeath());
|
|
||||||
entities.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String SCOREBOARD_TEAMNAME = "Replay";
|
|
||||||
private static final Team team;
|
|
||||||
|
|
||||||
static {
|
|
||||||
if(FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME) == null)
|
|
||||||
team = FightScoreboard.getBukkit().registerNewTeam(SCOREBOARD_TEAMNAME);
|
|
||||||
else
|
|
||||||
team = FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME);
|
|
||||||
team.setNameTagVisibility(NameTagVisibility.NEVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int entityCount = Integer.MAX_VALUE;
|
|
||||||
private static final Random random = new Random();
|
|
||||||
|
|
||||||
private final int internalId;
|
|
||||||
private final int entityId;
|
|
||||||
private final UUID uuid;
|
|
||||||
private final EntityType entityType;
|
|
||||||
private final String name;
|
|
||||||
private final Map<String, ItemStack> itemSlots = new HashMap<>();
|
|
||||||
|
|
||||||
private double locX;
|
|
||||||
private double locY;
|
|
||||||
private double locZ;
|
|
||||||
private byte yaw;
|
|
||||||
private byte pitch;
|
|
||||||
private byte headYaw;
|
|
||||||
private int fireTick;
|
|
||||||
private boolean sneaks;
|
|
||||||
|
|
||||||
private boolean playerSpawned = false;
|
|
||||||
|
|
||||||
public REntity(int internalId, int userId){
|
|
||||||
this.internalId = internalId;
|
|
||||||
this.entityType = EntityType.PLAYER;
|
|
||||||
this.entityId = entityCount--;
|
|
||||||
|
|
||||||
SteamwarUser user;
|
|
||||||
try {
|
|
||||||
user = SteamwarUser.get(userId);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
FightSystem.getPlugin().getLogger().log(Level.SEVERE, "Could not load user " + userId);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.uuid = user.getUUID();
|
|
||||||
this.name = user.getUserName();
|
|
||||||
entities.put(internalId, this);
|
|
||||||
|
|
||||||
ProtocolAPI.broadcastPacket(getPlayerInfoPacket());
|
|
||||||
team.addEntry(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public REntity(int internalId, EntityType entityType){
|
|
||||||
this.internalId = internalId;
|
|
||||||
this.entityType = entityType;
|
|
||||||
this.entityId = entityCount--;
|
|
||||||
this.name = null;
|
|
||||||
this.uuid = new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L);
|
|
||||||
entities.put(internalId, this);
|
|
||||||
|
|
||||||
ProtocolAPI.broadcastPacket(getSpawnEntityPacket());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw){
|
|
||||||
this.locX = locX;
|
|
||||||
this.locY = locY;
|
|
||||||
this.locZ = locZ;
|
|
||||||
if(entityType == EntityType.PLAYER && !playerSpawned) {
|
|
||||||
ProtocolAPI.broadcastPacket(getNamedSpawnPacket());
|
|
||||||
playerSpawned = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.yaw = (byte)((int)(yaw * 256.0F / 360.0F));
|
|
||||||
this.pitch = (byte)((int)(pitch * 256.0F / 360.0F));
|
|
||||||
this.headYaw = headYaw;
|
|
||||||
ProtocolAPI.broadcastPacket(getTeleportPacket());
|
|
||||||
ProtocolAPI.broadcastPacket(getHeadRotationPacket());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> animationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutAnimation");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> animationEntity = Reflection.getField(animationPacket, int.class, Core.getVersion() > 15 ? 6 : 0);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> animationAnimation = Reflection.getField(animationPacket, int.class, Core.getVersion() > 15 ? 7 : 1);
|
|
||||||
public void animation(byte animation) {
|
|
||||||
Object packet = Reflection.newInstance(animationPacket);
|
|
||||||
animationEntity.set(packet, entityId);
|
|
||||||
animationAnimation.set(packet, (int) animation);
|
|
||||||
ProtocolAPI.broadcastPacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> velocityPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> velocityEntity = Reflection.getField(velocityPacket, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> velocityX = Reflection.getField(velocityPacket, int.class, 1);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> velocityY = Reflection.getField(velocityPacket, int.class, 2);
|
|
||||||
private static final Reflection.FieldAccessor<Integer> velocityZ = Reflection.getField(velocityPacket, int.class, 3);
|
|
||||||
public void setVelocity(double dX, double dY, double dZ) {
|
|
||||||
Object packet = Reflection.newInstance(velocityPacket);
|
|
||||||
velocityEntity.set(packet, entityId);
|
|
||||||
velocityX.set(packet, calcVelocity(dX));
|
|
||||||
velocityY.set(packet, calcVelocity(dY));
|
|
||||||
velocityZ.set(packet, calcVelocity(dZ));
|
|
||||||
ProtocolAPI.broadcastPacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> statusPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityStatus");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> statusEntity = Reflection.getField(statusPacket, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Byte> statusStatus = Reflection.getField(statusPacket, byte.class, 0);
|
|
||||||
public void damage() {
|
|
||||||
Object packet = Reflection.newInstance(statusPacket);
|
|
||||||
statusEntity.set(packet, entityId);
|
|
||||||
statusStatus.set(packet, (byte) 2);
|
|
||||||
ProtocolAPI.broadcastPacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sneak(boolean sneaking) {
|
|
||||||
sneaks = sneaking;
|
|
||||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(sneaking)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnFire(boolean perma) {
|
|
||||||
if(!perma) {
|
|
||||||
fireTick = 21;
|
|
||||||
} else {
|
|
||||||
fireTick = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte) 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBowDrawn(boolean drawn, boolean offHand) {
|
|
||||||
if(Core.getVersion() > 8){
|
|
||||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(bowDrawnWatcher, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))));
|
|
||||||
}else{
|
|
||||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte)0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setItem(String item, boolean enchanted, String slot) {
|
|
||||||
ItemStack stack = new ItemStack(Material.valueOf(item.replace("minecraft:", "").toUpperCase()), 1);
|
|
||||||
if(enchanted)
|
|
||||||
stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
|
||||||
itemSlots.put(slot, stack);
|
|
||||||
|
|
||||||
ProtocolAPI.broadcastPacket(getEquipmentPacket(slot, stack));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void die(){
|
|
||||||
broadcastDeath();
|
|
||||||
entities.remove(internalId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> destroyPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityDestroy");
|
|
||||||
private static final Reflection.FieldAccessor<?> destroyEntities;
|
|
||||||
static {
|
|
||||||
if(Core.getVersion() > 15)
|
|
||||||
destroyEntities = Reflection.getField(destroyPacket, IntList.class, 0);
|
|
||||||
else
|
|
||||||
destroyEntities = Reflection.getField(destroyPacket, int[].class, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void broadcastDeath(){
|
|
||||||
if(entityType == EntityType.PLAYER){
|
|
||||||
ProtocolAPI.broadcastPacket(Fight.playerInfoPacket(Fight.removePlayer, new GameProfile(uuid, name), Fight.creative));
|
|
||||||
team.removeEntry(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object packet = Reflection.newInstance(destroyPacket);
|
|
||||||
destroyEntities.set(packet, Core.getVersion() > 15 ? new IntArrayList(new int[]{entityId}) : new int[]{entityId});
|
|
||||||
ProtocolAPI.broadcastPacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int calcVelocity(double value) {
|
|
||||||
return (int)(Math.max(-3.9, Math.min(value, 3.9)) * 8000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> metadataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityMetadata");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> metadataEntity = Reflection.getField(metadataPacket, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<List> metadataMetadata = Reflection.getField(metadataPacket, List.class, 0);
|
|
||||||
private Object getDataWatcherPacket(Object dataWatcherObject, Object value) {
|
|
||||||
Object packet = Reflection.newInstance(metadataPacket);
|
|
||||||
metadataEntity.set(packet, entityId);
|
|
||||||
metadataMetadata.set(packet, Collections.singletonList(BountifulWrapper.impl.getDataWatcherItem(dataWatcherObject, value)));
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Class<?> teleportPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> teleportEntity = Reflection.getField(teleportPacket, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Byte> teleportYaw = Reflection.getField(teleportPacket, byte.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Byte> teleportPitch = Reflection.getField(teleportPacket, byte.class, 1);
|
|
||||||
private Object getTeleportPacket(){
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, entityId);
|
|
||||||
BountifulWrapper.impl.setTeleportPacketPosition(packet, locX, locY, locZ);
|
|
||||||
teleportYaw.set(packet, yaw);
|
|
||||||
teleportPitch.set(packet, pitch);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> headRotationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityHeadRotation");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> headRotationEntity = Reflection.getField(headRotationPacket, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<Byte> headRotationYaw = Reflection.getField(headRotationPacket, byte.class, 0);
|
|
||||||
private Object getHeadRotationPacket(){
|
|
||||||
Object packet = Reflection.newInstance(headRotationPacket);
|
|
||||||
headRotationEntity.set(packet, entityId);
|
|
||||||
headRotationYaw.set(packet, headYaw);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Class<?> spawnPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutSpawnEntity");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> spawnEntity = Reflection.getField(spawnPacket, int.class, 0);
|
|
||||||
private Object getSpawnEntityPacket(){
|
|
||||||
Object packet = Reflection.newInstance(spawnPacket);
|
|
||||||
spawnEntity.set(packet, entityId);
|
|
||||||
BountifulWrapper.impl.setSpawnPacketUUID(packet, uuid);
|
|
||||||
ProtocolWrapper.impl.setSpawnPacketType(packet, entityType);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Class<?> equipmentPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityEquipment");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> equipmentEntity = Reflection.getField(equipmentPacket, int.class, 0);
|
|
||||||
|
|
||||||
public static final Class<?> itemStack = Reflection.getClass("{nms.world.item}.ItemStack");
|
|
||||||
private static final Class<?> craftItemStack = Reflection.getClass("{obc}.inventory.CraftItemStack");
|
|
||||||
private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", REntity.itemStack, ItemStack.class);
|
|
||||||
private Object getEquipmentPacket(String slot, ItemStack stack){
|
|
||||||
Object packet = Reflection.newInstance(equipmentPacket);
|
|
||||||
equipmentEntity.set(packet, entityId);
|
|
||||||
ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, asNMSCopy.invoke(null, stack));
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object getPlayerInfoPacket(){
|
|
||||||
return Fight.playerInfoPacket(Fight.addPlayer, new GameProfile(uuid, name), Fight.creative);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Class<?> namedSpawnPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutNamedEntitySpawn");
|
|
||||||
private static final Reflection.FieldAccessor<Integer> namedSpawnEntity = Reflection.getField(namedSpawnPacket, int.class, 0);
|
|
||||||
private static final Reflection.FieldAccessor<UUID> namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0);
|
|
||||||
private Object getNamedSpawnPacket(){
|
|
||||||
Object packet = Reflection.newInstance(namedSpawnPacket);
|
|
||||||
namedSpawnEntity.set(packet, entityId);
|
|
||||||
namedSpawnUUID.set(packet, uuid);
|
|
||||||
BountifulWrapper.impl.setNamedSpawnPosition(packet, locX, locY, locZ);
|
|
||||||
FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,6 +29,7 @@ import de.steamwar.fightsystem.utils.BlockIdWrapper;
|
|||||||
import de.steamwar.fightsystem.utils.CraftbukkitWrapper;
|
import de.steamwar.fightsystem.utils.CraftbukkitWrapper;
|
||||||
import de.steamwar.fightsystem.utils.Message;
|
import de.steamwar.fightsystem.utils.Message;
|
||||||
import de.steamwar.fightsystem.utils.SWSound;
|
import de.steamwar.fightsystem.utils.SWSound;
|
||||||
|
import de.steamwar.sql.NodeData;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -97,14 +98,16 @@ public interface Recorder {
|
|||||||
* PlayerDamagePacket (0x0b) + int EntityId
|
* PlayerDamagePacket (0x0b) + int EntityId
|
||||||
* SetOnFire (0x0c) + int EntityId + boolean perma
|
* SetOnFire (0x0c) + int EntityId + boolean perma
|
||||||
*
|
*
|
||||||
* ArenaInfo (0x20) + bool blueNegZ + byte arenaY + int arenaMinX + int arenaMinZ
|
* DEPRECATED ArenaInfo (0x20) + bool blueNegZ + byte arenaY + int arenaMinX + int arenaMinZ
|
||||||
|
* ArenaInfo (0x21) + bool blueNegZ + int arenaMinX + int arenaMinY + int arenaMinZ
|
||||||
*
|
*
|
||||||
* BlockPacket (0x30) + pos int, byte, int + int BlockState
|
* DEPRECATED BlockPacket (0x30) + pos int, byte, int + int BlockState
|
||||||
* ParticlePacket (0x31) + double x, y, z + string particleType
|
* ParticlePacket (0x31) + double x, y, z + string particleType
|
||||||
* SoundPacket (0x32) + int x, y, z + string soundType + string soundCategory + float volume, pitch
|
* SoundPacket (0x32) + int x, y, z + string soundType + string soundCategory + float volume, pitch
|
||||||
* DEPRECATED ShortBlockPacket (0x33) + pos relative to ArenaMinX,ArenaMinZ byte, byte, byte + short BlockState
|
* DEPRECATED ShortBlockPacket (0x33) + pos relative to ArenaMinX,ArenaMinZ byte, byte, byte + short BlockState
|
||||||
* SoundAtPlayerPacket (0x34) + string (soundType, soundCategory) + float volume, pitch
|
* SoundAtPlayerPacket (0x34) + string (soundType, soundCategory) + float volume, pitch
|
||||||
* ShortBlockPacket (0x35) + pos relative to ArenaMinX,BluePasteY,ArenaMinZ byte, byte, byte + short BlockState
|
* ShortBlockPacket (0x35) + pos relative to ArenaMinX,BluePasteY,ArenaMinZ byte, byte, byte + short BlockState
|
||||||
|
* BlockPacket (0x36) + pos int, short, int + int BlockState
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* DEPRECATED ChatPacket (0xa0) + String message
|
* DEPRECATED ChatPacket (0xa0) + String message
|
||||||
@ -211,8 +214,7 @@ public interface Recorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default void arenaInfo(){
|
default void arenaInfo(){
|
||||||
write(0x20, Config.blueNegZ(), (byte)Config.BluePasteRegion.getMinY(),
|
write(0x21, Config.blueNegZ(), Config.ArenaRegion.getMinX(), Config.BluePasteRegion.getMinY(), Config.ArenaRegion.getMinZ());
|
||||||
Config.ArenaRegion.getMinX(), Config.ArenaRegion.getMinZ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void blockChange(Block block){
|
default void blockChange(Block block){
|
||||||
@ -226,7 +228,7 @@ public interface Recorder {
|
|||||||
write(0x35, (byte)shortX, (byte)shortY, (byte)shortZ, (short)blockState);
|
write(0x35, (byte)shortX, (byte)shortY, (byte)shortZ, (short)blockState);
|
||||||
}else{
|
}else{
|
||||||
//Block packet
|
//Block packet
|
||||||
write(0x30, block.getX(), (byte)block.getY(), block.getZ(), blockState);
|
write(0x36, block.getX(), (short)block.getY(), block.getZ(), blockState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +276,7 @@ public interface Recorder {
|
|||||||
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
try{
|
try{
|
||||||
copy(SchematicNode.getSchematicNode(schemId).schemData(), buffer);
|
copy(NodeData.get(SchematicNode.getSchematicNode(schemId)).schemData(), buffer);
|
||||||
}catch (EOFException e) {
|
}catch (EOFException e) {
|
||||||
Bukkit.getLogger().log(Level.INFO, "EOFException ignored");
|
Bukkit.getLogger().log(Level.INFO, "EOFException ignored");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -24,16 +24,9 @@ import de.steamwar.fightsystem.FightSystem;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public interface BlockIdWrapper {
|
public interface BlockIdWrapper {
|
||||||
BlockIdWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
BlockIdWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||||
|
|
||||||
int blockToId(Block block);
|
int blockToId(Block block);
|
||||||
void setBlock(World world, int x, int y, int z, int blockState);
|
void setBlock(World world, int x, int y, int z, int blockState);
|
||||||
|
|
||||||
Set<Integer> getHiddenBlockIds();
|
|
||||||
int getObfuscateWith();
|
|
||||||
|
|
||||||
Object getPose(boolean sneaking);
|
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,6 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.scoreboard.Team;
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface BountifulWrapper {
|
public interface BountifulWrapper {
|
||||||
BountifulWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
BountifulWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||||
|
|
||||||
@ -47,11 +45,5 @@ public interface BountifulWrapper {
|
|||||||
|
|
||||||
void spawnParticle(World world, String particleName, double x, double y, double z);
|
void spawnParticle(World world, String particleName, double x, double y, double z);
|
||||||
|
|
||||||
Object getDataWatcherObject(int index, Class<?> type);
|
|
||||||
Object getDataWatcherItem(Object dataWatcherObject, Object value);
|
|
||||||
void setTeleportPacketPosition(Object packet, double x, double y, double z);
|
|
||||||
void setSpawnPacketUUID(Object packet, UUID uuid);
|
|
||||||
void setNamedSpawnPosition(Object packet, double x, double y, double z);
|
|
||||||
|
|
||||||
void sendBar(Player player, FightTeam team, double progress, String text);
|
void sendBar(Player player, FightTeam team, double progress, String text);
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,6 @@ import de.steamwar.core.VersionDependent;
|
|||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -32,9 +30,7 @@ public interface CraftbukkitWrapper {
|
|||||||
CraftbukkitWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
CraftbukkitWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||||
|
|
||||||
void resetChunk(World world, World backup, int x, int z);
|
void resetChunk(World world, World backup, int x, int z);
|
||||||
void sendResourcePack(Player player, String pack, String sha1);
|
|
||||||
float headRotation(Entity e);
|
float headRotation(Entity e);
|
||||||
boolean hasItems(ItemStack stack);
|
|
||||||
|
|
||||||
Stream<?> entityIterator();
|
Stream<?> entityIterator();
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,17 @@ import de.steamwar.fightsystem.states.OneShotStateDependent;
|
|||||||
import de.steamwar.fightsystem.winconditions.Wincondition;
|
import de.steamwar.fightsystem.winconditions.Wincondition;
|
||||||
import de.steamwar.network.NetworkSender;
|
import de.steamwar.network.NetworkSender;
|
||||||
import de.steamwar.network.packets.common.FightEndsPacket;
|
import de.steamwar.network.packets.common.FightEndsPacket;
|
||||||
|
import de.steamwar.sql.Replay;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static de.steamwar.sql.Fight.create;
|
import static de.steamwar.sql.Fight.create;
|
||||||
import static de.steamwar.sql.Fight.setReplay;
|
|
||||||
|
|
||||||
public class FightStatistics {
|
public class FightStatistics {
|
||||||
|
|
||||||
@ -79,6 +78,7 @@ public class FightStatistics {
|
|||||||
FightTeam winner = FightSystem.getLastWinner();
|
FightTeam winner = FightSystem.getLastWinner();
|
||||||
String windescription = FightSystem.getLastWinreason();
|
String windescription = FightSystem.getLastWinreason();
|
||||||
String gameMode = Config.SchematicType.toDB();
|
String gameMode = Config.SchematicType.toDB();
|
||||||
|
Instant endTime = Instant.now();
|
||||||
|
|
||||||
int blueLeader = getLeader(Fight.getBlueTeam());
|
int blueLeader = getLeader(Fight.getBlueTeam());
|
||||||
int redLeader = getLeader(Fight.getRedTeam());
|
int redLeader = getLeader(Fight.getRedTeam());
|
||||||
@ -123,7 +123,7 @@ public class FightStatistics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setReplay(fightId, new FileInputStream(FileRecorder.getFile()));
|
Replay.save(fightId, FileRecorder.getFile());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Bukkit.getLogger().log(Level.INFO, "Failed to save replay", e);
|
Bukkit.getLogger().log(Level.INFO, "Failed to save replay", e);
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ public class FightStatistics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Bukkit.getOnlinePlayers().isEmpty() && !unranked) {
|
if (!Bukkit.getOnlinePlayers().isEmpty() && !unranked) {
|
||||||
NetworkSender.send(new FightEndsPacket((byte) win, blueSchem == null ? 0 : blueSchem, redSchem == null ? 0 : redSchem, Fight.getBlueTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(SteamwarUser::get).map(SteamwarUser::getId).collect(Collectors.toList()), Fight.getRedTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(SteamwarUser::get).map(SteamwarUser::getId).collect(Collectors.toList()), gameMode));
|
NetworkSender.send(new FightEndsPacket((byte) win, blueSchem == null ? 0 : blueSchem, redSchem == null ? 0 : redSchem, Fight.getBlueTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(p -> SteamwarUser.get(p.getUniqueId())).map(SteamwarUser::getId).collect(Collectors.toList()), Fight.getRedTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(p -> SteamwarUser.get(p.getUniqueId())).map(SteamwarUser::getId).collect(Collectors.toList()), gameMode, (int)(endTime.getEpochSecond() - starttime.toInstant().getEpochSecond())));
|
||||||
}
|
}
|
||||||
|
|
||||||
unranked = false;
|
unranked = false;
|
||||||
|
@ -24,6 +24,7 @@ import de.steamwar.fightsystem.FightSystem;
|
|||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@ -39,13 +40,13 @@ public interface FlatteningWrapper {
|
|||||||
boolean containsBlockMeta(ItemMeta meta);
|
boolean containsBlockMeta(ItemMeta meta);
|
||||||
boolean hasAttributeModifier(ItemStack stack);
|
boolean hasAttributeModifier(ItemStack stack);
|
||||||
|
|
||||||
ItemStack onBreak(Block type);
|
|
||||||
|
|
||||||
boolean doRecord(BlockPhysicsEvent e);
|
boolean doRecord(BlockPhysicsEvent e);
|
||||||
|
|
||||||
void forceLoadChunk(World world, int cX, int cZ);
|
void forceLoadChunk(World world, int cX, int cZ);
|
||||||
|
|
||||||
boolean checkPistonMoving(Block block);
|
boolean checkPistonMoving(Block block);
|
||||||
|
|
||||||
void setNamedSpawnPacketDataWatcher(Object packet);
|
boolean isFacingWater(Block dispenser);
|
||||||
|
|
||||||
|
boolean isCrouching(Player player);
|
||||||
}
|
}
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class ProtocolAPI {
|
|
||||||
private ProtocolAPI() {}
|
|
||||||
|
|
||||||
private static final Map<Class<?>, BiFunction<Player, Object, Object>> outgoingHandler = new HashMap<>();
|
|
||||||
private static final Map<Class<?>, BiFunction<Player, Object, Object>> incomingHandler = new HashMap<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
TinyProtocol.instance.setOutFilter((receiver, channel, packet) -> {
|
|
||||||
BiFunction<Player, Object, Object> handler = outgoingHandler.get(packet.getClass());
|
|
||||||
if(handler == null)
|
|
||||||
return packet;
|
|
||||||
return handler.apply(receiver, packet);
|
|
||||||
});
|
|
||||||
TinyProtocol.instance.setInFilter((sender, channel, packet) -> {
|
|
||||||
BiFunction<Player, Object, Object> handler = incomingHandler.get(packet.getClass());
|
|
||||||
if(handler == null)
|
|
||||||
return packet;
|
|
||||||
return handler.apply(sender, packet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setOutgoingHandler(Class<?> packetClass, BiFunction<Player, Object, Object> handler) {
|
|
||||||
outgoingHandler.put(packetClass, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeOutgoingHandler(Class<?> packetClass) {
|
|
||||||
outgoingHandler.remove(packetClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setIncomingHandler(Class<?> packetClass, BiFunction<Player, Object, Object> handler) {
|
|
||||||
incomingHandler.put(packetClass, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeIncomingHandler(Class<?> packetClass) {
|
|
||||||
incomingHandler.remove(packetClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void broadcastPacket(Object packet) {
|
|
||||||
Bukkit.getOnlinePlayers().stream().map(TinyProtocol.instance::getChannel).filter(TinyProtocol.instance::hasInjected).forEach(channel -> TinyProtocol.instance.sendPacket(channel, packet));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BiFunction<Object, UnaryOperator<Object>, Object> arrayCloneGenerator(Class<?> elementClass) {
|
|
||||||
return (array, worker) -> {
|
|
||||||
int length = Array.getLength(array);
|
|
||||||
Object result = Array.newInstance(elementClass, length);
|
|
||||||
|
|
||||||
for(int i = 0; i < length; i++)
|
|
||||||
Array.set(result, i, worker.apply(Array.get(array, i)));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnaryOperator<Object> shallowCloneGenerator(Class<?> clazz) {
|
|
||||||
BiConsumer<Object, Object> filler = shallowFill(clazz);
|
|
||||||
|
|
||||||
return source -> {
|
|
||||||
Object clone = Reflection.newInstance(clazz);
|
|
||||||
filler.accept(source, clone);
|
|
||||||
return clone;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BiConsumer<Object, Object> shallowFill(Class<?> clazz) {
|
|
||||||
if(clazz == null)
|
|
||||||
return (source, clone) -> {};
|
|
||||||
|
|
||||||
BiConsumer<Object, Object> superFiller = shallowFill(clazz.getSuperclass());
|
|
||||||
|
|
||||||
Field[] fds = clazz.getDeclaredFields();
|
|
||||||
List<Field> fields = new ArrayList<>();
|
|
||||||
for(Field field : fds) {
|
|
||||||
if (Modifier.isStatic(field.getModifiers()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
field.setAccessible(true);
|
|
||||||
fields.add(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (source, clone) -> {
|
|
||||||
superFiller.accept(source, clone);
|
|
||||||
try {
|
|
||||||
for(Field field : fields) {
|
|
||||||
field.set(clone, field.get(source));
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new IllegalStateException("Could not set field", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2021 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.utils;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
public interface ProtocolWrapper {
|
|
||||||
ProtocolWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
|
||||||
|
|
||||||
void setEquipmentPacketStack(Object packet, String slot, Object stack);
|
|
||||||
|
|
||||||
void setSpawnPacketType(Object packet, EntityType type);
|
|
||||||
|
|
||||||
Object multiBlockChangeHider(Player p, Object packet);
|
|
||||||
|
|
||||||
boolean unfilteredTileEntityDataAction(Object packet);
|
|
||||||
|
|
||||||
BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket);
|
|
||||||
|
|
||||||
Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode);
|
|
||||||
|
|
||||||
boolean iBlockDataHidden(Object iBlockData);
|
|
||||||
}
|
|
@ -33,9 +33,9 @@ public class Region {
|
|||||||
private final int maxY;
|
private final int maxY;
|
||||||
private final int maxZ;
|
private final int maxZ;
|
||||||
|
|
||||||
public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ, int extendX, int extendZ) {
|
public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ, int extendX, int extendY, int extendZ) {
|
||||||
this(minX - extendX, minY, minZ - extendZ,
|
this(minX - extendX, minY - extendY, minZ - extendZ,
|
||||||
sizeX + extendX * 2, sizeY, sizeZ + extendZ * 2);
|
sizeX + extendX * 2, sizeY + extendY * 2, sizeZ + extendZ * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) {
|
public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) {
|
||||||
|
@ -1,247 +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.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
|
||||||
import com.google.common.primitives.Bytes;
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.core.CraftbukkitWrapper;
|
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
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.StateDependent;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class TechHider extends StateDependent {
|
|
||||||
|
|
||||||
public static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
|
||||||
private static final Class<?> baseBlockPosition = Reflection.getClass("{nms.core}.BaseBlockPosition");
|
|
||||||
public static final Reflection.FieldAccessor<Integer> blockPositionX = Reflection.getField(baseBlockPosition, int.class, 0);
|
|
||||||
public static final Reflection.FieldAccessor<Integer> blockPositionZ = Reflection.getField(baseBlockPosition, int.class, 2);
|
|
||||||
|
|
||||||
public static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
|
|
||||||
public static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
|
|
||||||
private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, null, iBlockData);
|
|
||||||
|
|
||||||
public static final Class<?> craftMagicNumbers = Reflection.getClass("{obc}.util.CraftMagicNumbers");
|
|
||||||
private static final Reflection.MethodInvoker getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class);
|
|
||||||
|
|
||||||
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
|
||||||
|
|
||||||
public static final Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase())));
|
|
||||||
private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>();
|
|
||||||
|
|
||||||
public interface ChunkHider {
|
|
||||||
Class<?> mapChunkPacket();
|
|
||||||
Object mapChunkHider(Player p, Object packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TechHider(){
|
|
||||||
super(ENABLED, FightState.Schem);
|
|
||||||
|
|
||||||
techhiders.put(blockActionPacket, this::blockActionHider);
|
|
||||||
techhiders.put(blockChangePacket, this::blockChangeHider);
|
|
||||||
techhiders.put(tileEntityDataPacket, this::tileEntityDataHider);
|
|
||||||
techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl::multiBlockChangeHider);
|
|
||||||
|
|
||||||
ChunkHider chunkHider = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
|
||||||
techhiders.put(chunkHider.mapChunkPacket(), chunkHider::mapChunkHider);
|
|
||||||
|
|
||||||
if(Core.getVersion() > 12 && Core.getVersion() < 19) {
|
|
||||||
Class<?> blockBreakClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockBreak");
|
|
||||||
techhiders.put(blockBreakClass, ProtocolWrapper.impl.blockBreakHiderGenerator(blockBreakClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Core.getVersion() > 8){
|
|
||||||
ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
|
|
||||||
}
|
|
||||||
ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseEntity"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
|
|
||||||
|
|
||||||
register();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enable() {
|
|
||||||
techhiders.forEach(ProtocolAPI::setOutgoingHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disable() {
|
|
||||||
techhiders.keySet().forEach(ProtocolAPI::removeOutgoingHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Class<?> multiBlockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutMultiBlockChange");
|
|
||||||
public static final UnaryOperator<Object> multiBlockChangeCloner = ProtocolAPI.shallowCloneGenerator(TechHider.multiBlockChangePacket);
|
|
||||||
|
|
||||||
private static final Class<?> blockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockChange");
|
|
||||||
private static final Function<Object, Object> blockChangeCloner = ProtocolAPI.shallowCloneGenerator(blockChangePacket);
|
|
||||||
private static final Reflection.FieldAccessor<?> blockChangePosition = Reflection.getField(blockChangePacket, blockPosition, 0);
|
|
||||||
private static final Reflection.FieldAccessor<?> blockChangeBlockData = Reflection.getField(blockChangePacket, iBlockData, 0);
|
|
||||||
private Object blockChangeHider(Player p, Object packet) {
|
|
||||||
Object pos = blockChangePosition.get(packet);
|
|
||||||
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
if(ProtocolWrapper.impl.iBlockDataHidden(blockChangeBlockData.get(packet))) {
|
|
||||||
packet = blockChangeCloner.apply(packet);
|
|
||||||
blockChangeBlockData.set(packet, obfuscateIBlockData);
|
|
||||||
}
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?> blockActionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockAction");
|
|
||||||
private static final Reflection.FieldAccessor<?> blockActionPosition = Reflection.getField(blockActionPacket, blockPosition, 0);
|
|
||||||
private Object blockActionHider(Player p, Object packet) {
|
|
||||||
Object pos = blockActionPosition.get(packet);
|
|
||||||
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
|
||||||
return packet;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Class<?> tileEntityDataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutTileEntityData");
|
|
||||||
private static final Reflection.FieldAccessor<?> tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 0);
|
|
||||||
private Object tileEntityDataHider(Player p, Object packet) {
|
|
||||||
Object pos = tileEntityDataPosition.get(packet);
|
|
||||||
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
|
||||||
return packet;
|
|
||||||
|
|
||||||
if(ProtocolWrapper.impl.unfilteredTileEntityDataAction(packet))
|
|
||||||
return packet;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ChunkPos> prepareChunkReload(Player p, boolean hide){
|
|
||||||
if(!ENABLED)
|
|
||||||
return Collections.emptyList();
|
|
||||||
List<ChunkPos> chunksToReload = new ArrayList<>();
|
|
||||||
Config.ArenaRegion.forEachChunk((x, z) -> {
|
|
||||||
if(bypass(p, x, z) == hide)
|
|
||||||
chunksToReload.add(new ChunkPos(x, z));
|
|
||||||
});
|
|
||||||
return chunksToReload;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reloadChunks(Player p, List<ChunkPos> chunksToReload, boolean hide){
|
|
||||||
if(!ENABLED || !FightState.Schem.contains(FightState.getFightState()))
|
|
||||||
return;
|
|
||||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
|
||||||
for(ChunkPos chunk : chunksToReload){
|
|
||||||
if(bypass(p, chunk.x(), chunk.z()) != hide)
|
|
||||||
CraftbukkitWrapper.impl.sendChunk(p, chunk.x(), chunk.z());
|
|
||||||
}
|
|
||||||
}, 40);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean bypass(Player p, int chunkX, int chunkZ){
|
|
||||||
if(Config.isReferee(p))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
FightTeam ft = Fight.getPlayerTeam(p);
|
|
||||||
if(ft == null){
|
|
||||||
return Config.ArenaRegion.chunkOutside(chunkX, chunkZ);
|
|
||||||
}else if(ft.isBlue()){
|
|
||||||
return ft.canPlayerEntern(p) || Config.RedExtendRegion.chunkOutside(chunkX, chunkZ);
|
|
||||||
}else{
|
|
||||||
return ft.canPlayerEntern(p) || Config.BlueExtendRegion.chunkOutside(chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int posToChunk(int c){
|
|
||||||
int chunk = c / 16;
|
|
||||||
if(c<0)
|
|
||||||
chunk--;
|
|
||||||
return chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int readVarInt(byte[] array, int startPos) {
|
|
||||||
int numRead = 0;
|
|
||||||
int result = 0;
|
|
||||||
byte read;
|
|
||||||
do {
|
|
||||||
read = array[startPos + numRead];
|
|
||||||
int value = (read & 0b01111111);
|
|
||||||
result |= (value << (7 * numRead));
|
|
||||||
|
|
||||||
numRead++;
|
|
||||||
if (numRead > 5) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ((read & 0b10000000) != 0);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int readVarIntLength(byte[] array, int startPos) {
|
|
||||||
int numRead = 0;
|
|
||||||
byte read;
|
|
||||||
do {
|
|
||||||
read = array[startPos + numRead];
|
|
||||||
numRead++;
|
|
||||||
if (numRead > 5) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ((read & 0b10000000) != 0);
|
|
||||||
|
|
||||||
return numRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
static byte[] writeVarInt(int value) {
|
|
||||||
List<Byte> buffer = new ArrayList<>(5);
|
|
||||||
do {
|
|
||||||
byte temp = (byte)(value & 0b01111111);
|
|
||||||
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
|
||||||
value >>>= 7;
|
|
||||||
if (value != 0) {
|
|
||||||
temp |= 0b10000000;
|
|
||||||
}
|
|
||||||
buffer.add(temp);
|
|
||||||
} while (value != 0);
|
|
||||||
return Bytes.toArray(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ChunkPos{
|
|
||||||
final int x;
|
|
||||||
final int z;
|
|
||||||
|
|
||||||
ChunkPos(int x, int z){
|
|
||||||
this.x = x;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int x(){
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int z(){
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2021 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.utils;
|
||||||
|
|
||||||
|
import de.steamwar.core.CraftbukkitWrapper;
|
||||||
|
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.StateDependent;
|
||||||
|
import de.steamwar.techhider.ProtocolUtils;
|
||||||
|
import de.steamwar.techhider.TechHider;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class TechHiderWrapper extends StateDependent {
|
||||||
|
|
||||||
|
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
||||||
|
private final TechHider techHider;
|
||||||
|
|
||||||
|
public TechHiderWrapper() {
|
||||||
|
super(ENABLED, FightState.Schem);
|
||||||
|
techHider = new TechHider(this::bypass, Material.getMaterial(Config.ObfuscateWith), Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).collect(Collectors.toSet()), Config.HiddenBlockEntities);
|
||||||
|
register();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
techHider.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
techHider.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProtocolUtils.ChunkPos> prepareChunkReload(Player p, boolean hide) {
|
||||||
|
if(!ENABLED)
|
||||||
|
return Collections.emptyList();
|
||||||
|
|
||||||
|
List<ProtocolUtils.ChunkPos> chunksToReload = new ArrayList<>();
|
||||||
|
Config.ArenaRegion.forEachChunk((x, z) -> {
|
||||||
|
if(bypass(p, x, z) == hide)
|
||||||
|
chunksToReload.add(new ProtocolUtils.ChunkPos(x, z));
|
||||||
|
});
|
||||||
|
return chunksToReload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reloadChunks(Player p, List<ProtocolUtils.ChunkPos> chunksToReload, boolean hide) {
|
||||||
|
if(!ENABLED || !FightState.Schem.contains(FightState.getFightState()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||||
|
for(ProtocolUtils.ChunkPos chunk : chunksToReload){
|
||||||
|
if(bypass(p, chunk.x(), chunk.z()) != hide)
|
||||||
|
CraftbukkitWrapper.impl.sendChunk(p, chunk.x(), chunk.z());
|
||||||
|
}
|
||||||
|
}, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean bypass(Player p, int chunkX, int chunkZ){
|
||||||
|
if(Config.isReferee(p))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
FightTeam ft = Fight.getPlayerTeam(p);
|
||||||
|
if(ft == null){
|
||||||
|
return Config.ArenaRegion.chunkOutside(chunkX, chunkZ);
|
||||||
|
}else if(ft.isBlue()){
|
||||||
|
return ft.canPlayerEntern(p) || Config.RedExtendRegion.chunkOutside(chunkX, chunkZ);
|
||||||
|
}else{
|
||||||
|
return ft.canPlayerEntern(p) || Config.BlueExtendRegion.chunkOutside(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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.winconditions;
|
||||||
|
|
||||||
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
|
import de.steamwar.fightsystem.fight.Fight;
|
||||||
|
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||||
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
|
import de.steamwar.fightsystem.states.OneShotStateDependent;
|
||||||
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class WinconditionAmongUs extends Wincondition implements Listener {
|
||||||
|
|
||||||
|
private Map<FightTeam, FightPlayer> imposter = new HashMap<>();
|
||||||
|
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
|
public WinconditionAmongUs() {
|
||||||
|
super("AmongUs");
|
||||||
|
new OneShotStateDependent(Winconditions.AMONG_US, FightState.Ingame, () -> {
|
||||||
|
imposter.put(Fight.getRedTeam(), sendMessageAndReturnImposter(Fight.getRedTeam().getPlayers()));
|
||||||
|
imposter.put(Fight.getBlueTeam(), sendMessageAndReturnImposter(Fight.getBlueTeam().getPlayers()));
|
||||||
|
});
|
||||||
|
new StateDependentListener(Winconditions.AMONG_US, FightState.Ingame, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FightPlayer sendMessageAndReturnImposter(Collection<FightPlayer> fightPlayers) {
|
||||||
|
List<FightPlayer> fightPlayerList = new ArrayList<>(fightPlayers);
|
||||||
|
FightPlayer imposter = fightPlayerList.get(random.nextInt(fightPlayerList.size()));
|
||||||
|
for (FightPlayer fightPlayer : fightPlayerList) {
|
||||||
|
if (fightPlayer == imposter) {
|
||||||
|
FightSystem.getMessage().send("AMONG_US_IMPOSTER_MESSAGE", fightPlayer.getPlayer());
|
||||||
|
} else {
|
||||||
|
FightSystem.getMessage().send("AMONG_US_IMPOSTER_AMONG_MESSAGE", fightPlayer.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return imposter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void handlePlayerDeath(PlayerDeathEvent event) {
|
||||||
|
handleDeath(event.getEntity().getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void handlePlayerQuit(PlayerQuitEvent event) {
|
||||||
|
handleDeath(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDeath(Player player){
|
||||||
|
FightTeam team = isTarget(player);
|
||||||
|
if(team == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FightPlayer current = team.getFightPlayer(player);
|
||||||
|
if (current == imposter.get(team)) {
|
||||||
|
win(team, "WIN_IMPOSTER_DEAD", team.getPrefix());
|
||||||
|
} else if (team.getAlivePlayers() <= 2 && imposter.get(team).isLiving()) {
|
||||||
|
win(Fight.getOpposite(team), "WIN_CREWMATE_DEAD", Fight.getOpposite(team).getPrefix());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -38,5 +38,6 @@ public enum Winconditions {
|
|||||||
PUMPKIN_TECH_KO,
|
PUMPKIN_TECH_KO,
|
||||||
|
|
||||||
HELLS_BELLS,
|
HELLS_BELLS,
|
||||||
METEOR
|
METEOR,
|
||||||
|
AMONG_US
|
||||||
}
|
}
|
||||||
|
193
build.gradle
193
build.gradle
@ -17,10 +17,6 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
// Adding the base plugin fixes the following gradle warnings in IntelliJ:
|
// Adding the base plugin fixes the following gradle warnings in IntelliJ:
|
||||||
//
|
//
|
||||||
@ -33,43 +29,12 @@ plugins {
|
|||||||
id 'application'
|
id 'application'
|
||||||
|
|
||||||
id 'com.github.johnrengelman.shadow' version '5.0.0'
|
id 'com.github.johnrengelman.shadow' version '5.0.0'
|
||||||
}
|
id 'de.steamwar.gradle' version 'RELEASE'
|
||||||
|
|
||||||
ext.swdep = { s ->
|
|
||||||
if (file("${rootDir}/lib/${s}.jar").exists()) {
|
|
||||||
return files("${rootDir}/lib/${s}.jar")
|
|
||||||
} else {
|
|
||||||
if (s.contains("-")) {
|
|
||||||
return "de.steamwar:${s.toLowerCase().replace('-', ':')}"
|
|
||||||
} else {
|
|
||||||
return "de.steamwar:${s.toLowerCase()}:RELEASE"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'de.steamwar'
|
group 'de.steamwar'
|
||||||
version ''
|
version ''
|
||||||
|
|
||||||
Properties steamwarProperties = new Properties()
|
|
||||||
if (file("steamwar.properties").exists()) {
|
|
||||||
steamwarProperties.load(file("steamwar.properties").newDataInputStream())
|
|
||||||
}
|
|
||||||
|
|
||||||
ext {
|
|
||||||
buildName = 'FightSystem'
|
|
||||||
artifactName = 'fightsystem'
|
|
||||||
|
|
||||||
uberJarName = "${buildName}-all.jar"
|
|
||||||
jarName = "${artifactName}.jar"
|
|
||||||
libs = "${buildDir}/libs"
|
|
||||||
|
|
||||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
||||||
operatingSystem = "windows"
|
|
||||||
} else {
|
|
||||||
operatingSystem = "unix"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
compileJava.options.encoding = 'UTF-8'
|
||||||
compileJava.options.compilerArgs << '-parameter'
|
compileJava.options.compilerArgs << '-parameter'
|
||||||
|
|
||||||
@ -94,14 +59,6 @@ allprojects {
|
|||||||
maven {
|
maven {
|
||||||
url = uri('https://libraries.minecraft.net')
|
url = uri('https://libraries.minecraft.net')
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
|
||||||
url = uri('https://steamwar.de/maven')
|
|
||||||
credentials {
|
|
||||||
username = steamwarProperties.getProperty("maven.username")
|
|
||||||
password = steamwarProperties.getProperty("maven.password")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,151 +72,3 @@ dependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task buildProject {
|
|
||||||
description 'Build this project'
|
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
dependsOn build, tasks.getByPath(':FightSystem_Standalone:shadowJar')
|
|
||||||
}
|
|
||||||
|
|
||||||
task finalizeProject {
|
|
||||||
description 'Finalize this project'
|
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
if ("${buildDir}" == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delete fileTree("${libs}").matching {
|
|
||||||
exclude("${uberJarName}")
|
|
||||||
}
|
|
||||||
file(libs + "/" + uberJarName).renameTo(file(libs + "/" + jarName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build.finalizedBy(finalizeProject)
|
|
||||||
|
|
||||||
if (steamwarProperties.containsKey("hostname")) {
|
|
||||||
String hostname = steamwarProperties.get("hostname")
|
|
||||||
String uploadPath = steamwarProperties.getOrDefault("uploadPath", "~")
|
|
||||||
|
|
||||||
String server = steamwarProperties.getOrDefault("server", "Dev1.15")
|
|
||||||
String serverStartFlags = steamwarProperties.getOrDefault("serverStartFlags", "")
|
|
||||||
|
|
||||||
task uploadProject {
|
|
||||||
description 'Upload this project'
|
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
await(shell("scp ${libs}/${jarName} ${hostname}:${uploadPath}/${server}/plugins"))
|
|
||||||
if (steamwarProperties.getOrDefault("directStart", "false") == "false" && !answer("Start ${server} server?")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
serverStart(server, serverStartFlags, hostname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uploadProject.dependsOn(buildProject)
|
|
||||||
|
|
||||||
task startDevServer {
|
|
||||||
description 'Start the DevServer'
|
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
serverStart(server, serverStartFlags, hostname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def await(Process proc) {
|
|
||||||
def out = new StringBuilder()
|
|
||||||
def err = new StringBuilder()
|
|
||||||
proc.waitForProcessOutput(out, err)
|
|
||||||
return [out, err, proc.exitValue()]
|
|
||||||
}
|
|
||||||
|
|
||||||
private def shell(String command) {
|
|
||||||
if (operatingSystem == "unix") {
|
|
||||||
return ['bash', '-c', command].execute()
|
|
||||||
} else {
|
|
||||||
return ["cmd", "/c", command].execute()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def serverStart(String serverName, String serverFlags, String hostname) {
|
|
||||||
def proc = shell("ssh -t ${hostname} \"./mc ${serverFlags} ${serverName}\"")
|
|
||||||
|
|
||||||
Set<String> strings = new HashSet<>()
|
|
||||||
File file = new File("${projectDir}/ignoredlog");
|
|
||||||
if (file.exists()) {
|
|
||||||
new BufferedReader(new InputStreamReader(new FileInputStream(file))).readLines().forEach({ s ->
|
|
||||||
strings.add(s)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread outputThread = new Thread({
|
|
||||||
Reader reader = proc.getInputStream().newReader();
|
|
||||||
Writer writer = System.out.newWriter();
|
|
||||||
try {
|
|
||||||
while (proc.alive) {
|
|
||||||
String s = reader.readLine()
|
|
||||||
if (s == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (strings.stream().anyMatch({check -> s.contains(check)})) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
writer.write(s + "\n")
|
|
||||||
writer.flush()
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Ignored
|
|
||||||
}
|
|
||||||
})
|
|
||||||
outputThread.setName("${serverName} - OutputThread")
|
|
||||||
outputThread.start()
|
|
||||||
|
|
||||||
Writer writer
|
|
||||||
Thread inputThread = new Thread({
|
|
||||||
Reader reader = System.in.newReader()
|
|
||||||
writer = proc.getOutputStream().newWriter()
|
|
||||||
try {
|
|
||||||
while (proc.alive) {
|
|
||||||
String s = reader.readLine()
|
|
||||||
writer.write(s + "\n")
|
|
||||||
writer.flush()
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Ignored
|
|
||||||
}
|
|
||||||
})
|
|
||||||
inputThread.setName("${serverName} - InputThread")
|
|
||||||
inputThread.start()
|
|
||||||
|
|
||||||
gradle.buildFinished { buildResult ->
|
|
||||||
if (!proc.alive) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
writer = proc.getOutputStream().newWriter()
|
|
||||||
writer.write("stop\n")
|
|
||||||
writer.flush()
|
|
||||||
awaitClose(proc, outputThread, inputThread)
|
|
||||||
}
|
|
||||||
awaitClose(proc, outputThread, inputThread)
|
|
||||||
};
|
|
||||||
|
|
||||||
private static def awaitClose(Process proc, Thread outputThread, Thread inputThread) {
|
|
||||||
while (proc.alive) {
|
|
||||||
Thread.sleep(10)
|
|
||||||
}
|
|
||||||
proc.closeStreams()
|
|
||||||
outputThread.interrupt()
|
|
||||||
inputThread.interrupt()
|
|
||||||
}
|
|
||||||
|
|
||||||
private def answer(String question) {
|
|
||||||
while (System.in.available() > 0) System.in.read()
|
|
||||||
println(question)
|
|
||||||
boolean valid = "Yy".contains(((char) System.in.read()).toString())
|
|
||||||
while (System.in.available() > 0) System.in.read()
|
|
||||||
return valid
|
|
||||||
}
|
|
@ -17,6 +17,15 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven {
|
||||||
|
url = uri("https://steamwar.de/maven/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rootProject.name = 'FightSystem'
|
rootProject.name = 'FightSystem'
|
||||||
|
|
||||||
file('.').listFiles().each {
|
file('.').listFiles().each {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
build:
|
setup:
|
||||||
- "ln -s /home/gitea/lib"
|
- "ln -s /home/gitea/lib"
|
||||||
- "cp ~/gradle.properties ."
|
|
||||||
|
build:
|
||||||
- "./gradlew buildProject"
|
- "./gradlew buildProject"
|
||||||
|
- "./gradlew --stop"
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
"/binarys/fightsystem.jar": "build/libs/fightsystem.jar"
|
"/binarys/fightsystem.jar": "build/libs/fightsystem.jar"
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren