13
0

Implement player inventory, schematic pasting and scoreboard

Dieser Commit ist enthalten in:
Lixfel 2020-09-01 06:35:25 +02:00
Ursprung 69df058018
Commit 28903eebe3
15 geänderte Dateien mit 312 neuen und 56 gelöschten Zeilen

Datei anzeigen

@ -55,5 +55,11 @@
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>steamwar</groupId>
<artifactId>WorldEdit</artifactId>
<version>1.15</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

Datei anzeigen

@ -44,6 +44,10 @@ public class Config {
public static final int ArenaMinZ;
public static final int ArenaMaxX;
public static final int ArenaMaxZ;
public static final boolean AlignWater;
public static final int WaterDepth;
public static final boolean TeamRedRotate;
public static final boolean TeamBlueRotate;
//tech hider parameter
public static final boolean TechhiderActive;
@ -64,6 +68,12 @@ public class Config {
}
FileConfiguration worldconfig = YamlConfiguration.loadConfiguration(worldConfigFile);
if(!new File(SpectateSystem.get().getDataFolder(), "config.yml").exists()) {
Bukkit.getLogger().log(Level.SEVERE, "Arenaconfig fehlt!");
Bukkit.shutdown();
}
FileConfiguration config = SpectateSystem.get().getConfig();
int schemsizeX = worldconfig.getInt("Arena.Schemsize.x");
int schemsizeY = worldconfig.getInt("Arena.Schemsize.y");
int schemsizeZ = worldconfig.getInt("Arena.Schemsize.z");
@ -77,6 +87,9 @@ public class Config {
Schem2BorderZ = worldconfig.getInt("Arena.Schem2Border.z");
underArenaBorder = worldconfig.getInt("Arena.underArenaBorder");
BorderFromSchematic = worldconfig.getInt("Arena.BorderFromSchematic");
AlignWater = worldconfig.getBoolean("Arena.AlignWater");
WaterDepth = worldconfig.getInt("Arena.WaterDepth");
boolean rotate = config.getBoolean("Schematic.Rotate");
if(schemsizeX < 0){
SchemsizeX = -schemsizeX;
@ -116,26 +129,38 @@ public class Config {
TeamBlueCornerY + TeamBluetoReddistanceY/2.0 + SchemsizeY/2.0,
TeamBluePasteZ + TeamBluetoReddistanceZ/2.0);
boolean teamRedRotate;
boolean teamBlueRotate;
if(TeamBluetoReddistanceX > 0){
ArenaMinX = TeamBlueCornerX - Schem2BorderX;
ArenaMaxX = TeamRedCornerX + SchemsizeX + Schem2BorderX;
teamRedRotate = true;
teamBlueRotate = false;
}else{
ArenaMinX = TeamRedCornerX - Schem2BorderX;
ArenaMaxX = TeamBlueCornerX + SchemsizeX + Schem2BorderX;
teamRedRotate = false;
teamBlueRotate = true;
}
if(TeamBluetoReddistanceZ > 0){
ArenaMinZ = TeamBlueCornerZ - Schem2BorderZ;
ArenaMaxZ = TeamRedCornerZ + SchemsizeZ + Schem2BorderZ;
teamRedRotate = true;
teamBlueRotate = false;
}else{
ArenaMinZ = TeamRedCornerZ - Schem2BorderZ;
ArenaMaxZ = TeamBlueCornerZ + SchemsizeZ + Schem2BorderZ;
if(TeamBluetoReddistanceZ != 0){
teamRedRotate = false;
teamBlueRotate = true;
}
}
if(!new File(SpectateSystem.get().getDataFolder(), "config.yml").exists()) {
Bukkit.getLogger().log(Level.SEVERE, "Arenaconfig fehlt!");
Bukkit.shutdown();
if(!rotate){
teamRedRotate = false;
teamBlueRotate = false;
}
FileConfiguration config = SpectateSystem.get().getConfig();
TeamRedRotate = teamRedRotate;
TeamBlueRotate = teamBlueRotate;
ConfigurationSection techhiderConfig = config.getConfigurationSection("Techhider.HiddenBlocks");
Set<Integer> blocks = new HashSet<>();

Datei anzeigen

@ -3,6 +3,8 @@ package de.steamwar.spectatesystem;
import de.steamwar.spectatesystem.elements.REntity;
import de.steamwar.spectatesystem.elements.RPlayer;
import de.steamwar.spectatesystem.elements.RTnT;
import de.steamwar.sql.NoClipboardException;
import de.steamwar.sql.Schematic;
import de.steamwar.sql.SteamwarUser;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.BaseComponent;
@ -17,6 +19,8 @@ import java.util.logging.Level;
class PacketProcessor {
private static final World world = Bukkit.getWorlds().get(0);
private final PacketSource source;
public PacketProcessor(PacketSource source){
@ -95,8 +99,6 @@ class PacketProcessor {
Bukkit.getOnlinePlayers().forEach(p -> p.spigot().sendMessage(type, text));
}
private static final World world = Bukkit.getWorlds().get(0);
private void block() throws IOException {
int x = source.rInt();
byte y = source.rByte();
@ -125,6 +127,19 @@ class PacketProcessor {
});
}
private void scoreboardTitle() throws IOException {
String title = source.rString();
SpectateSystem.getScoreboard().setTitle(title);
}
private void scoreboardData() throws IOException {
String key = source.rString();
int value = source.rInt();
SpectateSystem.getScoreboard().addValue(key, value);
}
private void sound() throws IOException {
int x = source.rInt();
int y = source.rInt();
@ -144,6 +159,28 @@ class PacketProcessor {
});
}
private void pasteSchem(int cornerX, int cornerY, int cornerZ, boolean rotate) throws IOException {
int schemId = source.rInt();
Schematic schem = Schematic.getSchemFromDB(schemId);
//DyeColor c = ColorConverter.chat2dye(color);
try {
Paster.pasteSchematic(schem, cornerX, cornerY, cornerZ, rotate);
} catch (NoClipboardException e) {
throw new IOException("Could not load Clipboard", e);
}
//Paster.replaceTeamColor(e, c, cornerX, cornerY, cornerZ);
}
private void playerItem() throws IOException {
int entityId = source.rInt();
String item = source.rString();
boolean enchanted = source.rBoolean();
String slot = source.rString();
((RPlayer)REntity.getEntity(entityId)).setItem(item, enchanted, slot);
}
private void process(){
try{
while(!source.isClosed()){
@ -169,6 +206,9 @@ class PacketProcessor {
case 0x06:
entityVelocity();
break;
case 0x07:
playerItem();
break;
case 0x30:
block();
break;
@ -184,10 +224,23 @@ class PacketProcessor {
case (byte) 0xA1:
send(ChatMessageType.ACTION_BAR);
break;
case (byte) 0xa2:
case (byte) 0xA2:
send(ChatMessageType.SYSTEM);
break;
case (byte) 0xB0:
pasteSchem(Config.TeamBlueCornerX, Config.TeamBlueCornerY, Config.TeamBlueCornerZ, Config.TeamBlueRotate);
break;
case (byte) 0xB1:
pasteSchem(Config.TeamRedCornerX, Config.TeamRedCornerY, Config.TeamRedCornerZ, Config.TeamRedRotate);
break;
case (byte) 0xC0:
scoreboardTitle();
break;
case (byte) 0xC1:
scoreboardData();
break;
case (byte) 0xFF:
//Tick
break;
default:
Bukkit.getLogger().log(Level.SEVERE, "Unknown packet recieved, closing");
@ -197,6 +250,7 @@ class PacketProcessor {
} catch (EOFException e) {
Bukkit.getLogger().log(Level.INFO, "The FightServer is offline");
source.close();
WorldLoader.reloadWorld();
} catch(IOException e){
Bukkit.getLogger().log(Level.WARNING, "Could not recieve packet", e);
source.close();

Datei anzeigen

@ -0,0 +1,88 @@
package de.steamwar.spectatesystem;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.sql.NoClipboardException;
import de.steamwar.sql.Schematic;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import java.io.IOException;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
public class Paster {
private Paster(){}
private static final Set<BaseBlock> WOOL_SET = Collections.singleton(Objects.requireNonNull(BlockTypes.PINK_WOOL).getDefaultState().toBaseBlock());
private static final Set<BaseBlock> CLAY_SET = Collections.singleton(Objects.requireNonNull(BlockTypes.PINK_TERRACOTTA).getDefaultState().toBaseBlock());
private static final Set<BaseBlock> GLASS_SET = Collections.singleton(Objects.requireNonNull(BlockTypes.PINK_STAINED_GLASS).getDefaultState().toBaseBlock());
private static final Set<BaseBlock> GLASS_PANE_SET = Collections.singleton(Objects.requireNonNull(BlockTypes.PINK_STAINED_GLASS_PANE).getDefaultState().toBaseBlock());
private static final Set<BaseBlock> CONCRETE_SET = Collections.singleton(Objects.requireNonNull(BlockTypes.PINK_CONCRETE).getDefaultState().toBaseBlock());
private static final Set<BaseBlock> CONCRETE_POWDER_SET = Collections.singleton(Objects.requireNonNull(BlockTypes.PINK_CONCRETE_POWDER).getDefaultState().toBaseBlock());
private static final Set<BaseBlock> CARPET_SET = Collections.singleton(Objects.requireNonNull(BlockTypes.PINK_CARPET).getDefaultState().toBaseBlock());
public static void replaceTeamColor(EditSession e, DyeColor c, int cornerX, int cornerY, int cornerZ){
BlockVector3 corner3 = BlockVector3.at(cornerX, cornerY, cornerZ);
BlockVector3 schemsize3 = BlockVector3.at(Config.SchemsizeX, Config.SchemsizeY, Config.SchemsizeZ);
CuboidRegion region = new CuboidRegion(corner3, corner3.add(schemsize3));
try {
e.replaceBlocks(region, WOOL_SET, Objects.requireNonNull(BlockTypes.get(c.name().toLowerCase() + "_wool")).getDefaultState().toBaseBlock());
e.replaceBlocks(region, CARPET_SET, Objects.requireNonNull(BlockTypes.get(c.name().toLowerCase() + "_carpet")).getDefaultState().toBaseBlock());
e.replaceBlocks(region, CLAY_SET, Objects.requireNonNull(BlockTypes.get(c.name().toLowerCase() + "_terracotta")).getDefaultState().toBaseBlock());
e.replaceBlocks(region, GLASS_SET, Objects.requireNonNull(BlockTypes.get(c.name().toLowerCase() + "_stained_glass")).getDefaultState().toBaseBlock());
e.replaceBlocks(region, GLASS_PANE_SET, Objects.requireNonNull(BlockTypes.get(c.name().toLowerCase() + "_stained_glass_pane")).getDefaultState().toBaseBlock());
e.replaceBlocks(region, CONCRETE_SET, Objects.requireNonNull(BlockTypes.get(c.name().toLowerCase() + "_concrete")).getDefaultState().toBaseBlock());
e.replaceBlocks(region, CONCRETE_POWDER_SET, Objects.requireNonNull(BlockTypes.get(c.name().toLowerCase() + "_concrete_powder")).getDefaultState().toBaseBlock());
} catch (MaxChangedBlocksException ex) {
//ignored
}
e.flushSession();
}
public static EditSession pasteSchematic(Schematic schematic, int pX, int pY, int pZ, boolean rotate) throws IOException, NoClipboardException {
BlockVector3 paste = BlockVector3.at(pX, pY, pZ);
Clipboard clipboard = schematic.load();
World w = new BukkitWorld(Bukkit.getWorlds().get(0));
BlockVector3 dimensions = clipboard.getDimensions();
BlockVector3 v;
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
AffineTransform aT = new AffineTransform();
if(rotate){
aT = aT.rotateY(180);
v = paste.add(dimensions.getX()/2 + dimensions.getX()%2, 0, dimensions.getZ()/2 + dimensions.getZ()%2).subtract(offset.multiply(-1, 1, -1)).subtract(1, 0, 1);
}else{
v = paste.subtract(dimensions.getX()/2, 0, dimensions.getZ()/2 - dimensions.getZ()%2).subtract(offset);
}
if(Config.AlignWater){
BlockVector3 it = clipboard.getMinimumPoint();
int depth = 0;
while(!clipboard.getBlock(it).getBlockType().getMaterial().isAir()){
depth++;
it = it.add(0, 1, 0);
}
v = v.add(0, Config.WaterDepth - depth, 0);
}
EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(w, -1);
ClipboardHolder ch = new ClipboardHolder(clipboard);
ch.setTransform(aT);
Operations.completeBlindly(ch.createPaste(e).to(v).build());
e.flushSession();
return e;
}
}

Datei anzeigen

@ -1,5 +1,6 @@
package de.steamwar.spectatesystem;
import de.steamwar.spectatesystem.elements.RScoreboard;
import de.steamwar.spectatesystem.listener.ArenaListener;
import de.steamwar.spectatesystem.listener.CancelListener;
import de.steamwar.spectatesystem.listener.JoinListener;
@ -12,11 +13,13 @@ import java.util.logging.Level;
public class SpectateSystem extends JavaPlugin {
private static SpectateSystem instance;
private static RScoreboard scoreboard;
private ConnectionAcceptor acceptor;
@Override
public void onEnable() {
instance = this;
scoreboard = new RScoreboard();
new JoinListener();
new ArenaListener();
new CancelListener();
@ -35,4 +38,8 @@ public class SpectateSystem extends JavaPlugin {
public static SpectateSystem get(){
return instance;
}
public static RScoreboard getScoreboard(){
return scoreboard;
}
}

Datei anzeigen

@ -0,0 +1,20 @@
package de.steamwar.spectatesystem;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
public class WorldLoader {
private WorldLoader(){}
private static final World world = Bukkit.getWorlds().get(0);
public static void reloadWorld(){
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> {
for(Chunk chunk: world.getLoadedChunks()){
world.unloadChunk(chunk.getX(), chunk.getZ(), false);
world.getChunkAt(chunk.getX(), chunk.getZ());
}
});
}
}

Datei anzeigen

@ -1,23 +0,0 @@
package de.steamwar.spectatesystem.elements;
import de.steamwar.spectatesystem.Config;
import net.minecraft.server.v1_15_R1.Block;
import net.minecraft.server.v1_15_R1.BlockPosition;
import net.minecraft.server.v1_15_R1.IBlockData;
import net.minecraft.server.v1_15_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
public class RBlockchange {
private static final WorldServer WORLD = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
public RBlockchange(int x, int y, int z, int stateId){
if(Config.TechhiderActive && Config.HiddenBlocks.contains(stateId))
stateId = Config.ObfuscateWith;
IBlockData blockData = Block.REGISTRY_ID.fromId(stateId);
BlockPosition pos = new BlockPosition(x, y, z);
WORLD.setTypeAndData(pos, blockData, 1042);
WORLD.getChunkProvider().flagDirty(pos);
}
}

Datei anzeigen

@ -1,8 +0,0 @@
package de.steamwar.spectatesystem.elements;
public class RChatmessage {
public RChatmessage(){
}
}

Datei anzeigen

@ -1,9 +0,0 @@
package de.steamwar.spectatesystem.elements;
public class RParticle {
public RParticle() {
}
}

Datei anzeigen

@ -6,6 +6,9 @@ import net.minecraft.server.v1_15_R1.*;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_15_R1.CraftServer;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_15_R1.enchantments.CraftEnchantment;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
@ -21,8 +24,6 @@ public class RPlayer extends REntity {
public RPlayer(UUID uuid, String name, int internalId){
super(internalId, createPlayer(uuid, name));
//TODO Item in Hand
//TODO Armor
//TODO Damage
}
@ -30,6 +31,12 @@ public class RPlayer extends REntity {
protected void spawnEntity(PlayerConnection connection) {
connection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, (EntityPlayer) entity)); // "Adds the player data for the client to use when spawning a player" - https://wiki.vg/Protocol#Spawn_Player
connection.sendPacket(new PacketPlayOutNamedEntitySpawn((EntityPlayer) entity)); // Spawns the NPC for the player client.
connection.sendPacket(new PacketPlayOutEntityEquipment(entity.getId(), EnumItemSlot.MAINHAND, ((EntityPlayer) entity).inventory.getItemInHand()));
connection.sendPacket(new PacketPlayOutEntityEquipment(entity.getId(), EnumItemSlot.OFFHAND, ((EntityPlayer) entity).inventory.extraSlots.get(0)));
connection.sendPacket(new PacketPlayOutEntityEquipment(entity.getId(), EnumItemSlot.HEAD, ((EntityPlayer) entity).inventory.armor.get(0)));
connection.sendPacket(new PacketPlayOutEntityEquipment(entity.getId(), EnumItemSlot.CHEST, ((EntityPlayer) entity).inventory.armor.get(1)));
connection.sendPacket(new PacketPlayOutEntityEquipment(entity.getId(), EnumItemSlot.LEGS, ((EntityPlayer) entity).inventory.armor.get(2)));
connection.sendPacket(new PacketPlayOutEntityEquipment(entity.getId(), EnumItemSlot.FEET, ((EntityPlayer) entity).inventory.armor.get(3)));
}
private static EntityPlayer createPlayer(UUID uuid, String name){
@ -61,4 +68,40 @@ public class RPlayer extends REntity {
npc.getDataWatcher().set(new DataWatcherObject<>(15, DataWatcherRegistry.a), (byte)127);
return npc;
}
public void setItem(String item, boolean enchanted, String slot) {
ItemStack stack = new ItemStack(IRegistry.ITEM.get(new MinecraftKey(item)), 1);
if(enchanted)
stack.addEnchantment(((CraftEnchantment)org.bukkit.enchantments.Enchantment.KNOCKBACK).getHandle(), 1);
PlayerInventory inventory = ((EntityPlayer)entity).inventory;
switch(slot){
case "MAINHAND":
inventory.setItem(inventory.itemInHandIndex, stack);
break;
case "OFFHAND":
inventory.setItem(40, stack);
break;
case "HEAD":
inventory.setItem(36, stack);
break;
case "CHEST":
inventory.setItem(37, stack);
break;
case "LEGS":
inventory.setItem(38, stack);
break;
case "FEET":
default:
inventory.setItem(39, stack);
}
PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment(entity.getId(), EnumItemSlot.valueOf(slot), stack);
for(Player player : Bukkit.getOnlinePlayers()){
PlayerConnection connection = ((CraftPlayer)player).getHandle().playerConnection;
connection.sendPacket(packet);
}
}
}

Datei anzeigen

@ -0,0 +1,30 @@
package de.steamwar.spectatesystem.elements;
import de.steamwar.scoreboard.ScoreboardCallback;
import java.util.HashMap;
public class RScoreboard implements ScoreboardCallback {
private String title = "§f";
private HashMap<String, Integer> data = new HashMap<>();
@Override
public synchronized String getTitle() {
return title;
}
@Override
public synchronized HashMap<String, Integer> getData() {
return data;
}
public synchronized void setTitle(String title){
this.title = title;
data.clear();
}
public synchronized void addValue(String key, int value){
data.put(key, value);
}
}

Datei anzeigen

@ -1,4 +0,0 @@
package de.steamwar.spectatesystem.elements;
public class RSound {
}

Datei anzeigen

@ -11,6 +11,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
public class ArenaListener extends BasicListener {
@ -49,4 +51,14 @@ public class ArenaListener extends BasicListener {
Bukkit.getScheduler().runTaskLater(SpectateSystem.get(), () -> e.getPlayer().teleport(e.getFrom()), 2);
}
}
@EventHandler
public void onChunkSave(ChunkUnloadEvent e){
e.setSaveChunk(false);
}
@EventHandler
public void onWorldLoad(WorldLoadEvent e){
e.getWorld().setAutoSave(false);
}
}

Datei anzeigen

@ -1,10 +1,14 @@
package de.steamwar.spectatesystem.listener;
import de.steamwar.scoreboard.SWScoreboard;
import de.steamwar.spectatesystem.Config;
import de.steamwar.spectatesystem.SpectateSystem;
import de.steamwar.spectatesystem.elements.REntity;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class JoinListener extends BasicListener {
@ -13,5 +17,13 @@ public class JoinListener extends BasicListener {
Player player = e.getPlayer();
REntity.playerJoins(player);
player.setGameMode(GameMode.SPECTATOR);
player.getInventory().clear();
player.teleport(Config.SpecSpawn);
SWScoreboard.createScoreboard(player, SpectateSystem.getScoreboard());
}
@EventHandler
public void onLeave(PlayerQuitEvent e){
SWScoreboard.removeScoreboard(e.getPlayer());
}
}

Datei anzeigen

@ -1,7 +1,10 @@
authors:
- Lixfel
name: SpectateSystem
version: 1.0
version: "1.0"
api-version: "1.13"
main: de.steamwar.spectatesystem.SpectateSystem
load: STARTUP
depends:
- SpigotCore
- WorldEdit