diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java
index 265d2e3..17260c3 100644
--- a/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java
+++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java
@@ -37,4 +37,24 @@ class WaterRemover_14 {
return ((Waterlogged) data).isWaterlogged();
}
+
+ static boolean removeWater(Block block){
+ if(block.getType() == Material.WATER){
+ block.setType(Material.AIR);
+ return true;
+ }
+
+ BlockData data = block.getBlockData();
+ if(!(data instanceof Waterlogged))
+ return false;
+
+ Waterlogged waterlogged = (Waterlogged) data;
+ if(waterlogged.isWaterlogged()){
+ waterlogged.setWaterlogged(false);
+ block.setBlockData(waterlogged);
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/FightSystem_15/src/de/steamwar/fightsystem/record/RecordSystem_15.java b/FightSystem_15/src/de/steamwar/fightsystem/record/RecordSystem_15.java
new file mode 100644
index 0000000..6d1a1e3
--- /dev/null
+++ b/FightSystem_15/src/de/steamwar/fightsystem/record/RecordSystem_15.java
@@ -0,0 +1,31 @@
+/*
+ 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 .
+*/
+
+package de.steamwar.fightsystem.record;
+
+import org.bukkit.block.Block;
+import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
+
+class RecordSystem_15 {
+ private RecordSystem_15(){}
+
+ static int blockToId(Block block){
+ return net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS());
+ }
+}
diff --git a/FightSystem_8/src/de/steamwar/fightsystem/record/RecordSystem_8.java b/FightSystem_8/src/de/steamwar/fightsystem/record/RecordSystem_8.java
new file mode 100644
index 0000000..207a3fd
--- /dev/null
+++ b/FightSystem_8/src/de/steamwar/fightsystem/record/RecordSystem_8.java
@@ -0,0 +1,31 @@
+/*
+ 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 .
+*/
+
+package de.steamwar.fightsystem.record;
+
+import org.bukkit.block.Block;
+
+class RecordSystem_8 {
+ private RecordSystem_8(){}
+
+ @SuppressWarnings("deprecation")
+ static int blockToId(Block block){
+ return block.getTypeId() << 4 + block.getData();
+ }
+}
diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java
index 0a544df..a510557 100644
--- a/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java
+++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java
@@ -29,4 +29,12 @@ public class WaterRemover_8 {
Material type = block.getType();
return type == Material.WATER || type == Material.STATIONARY_WATER;
}
+
+ static boolean removeWater(Block block){
+ if(isWater(block)){
+ block.setType(Material.AIR);
+ return true;
+ }
+ return false;
+ }
}
diff --git a/FightSystem_API/src/de/steamwar/fightsystem/Config.java b/FightSystem_API/src/de/steamwar/fightsystem/Config.java
index 43db7ba..524da67 100644
--- a/FightSystem_API/src/de/steamwar/fightsystem/Config.java
+++ b/FightSystem_API/src/de/steamwar/fightsystem/Config.java
@@ -140,10 +140,15 @@ public class Config {
public static final int EventTeamRedID;
public static final boolean BothTeamsPublic;
public static final int MaximumTeamMembers;
+ public static final boolean SpectateSystem;
//check parameter
public static final int CheckSchemID;
+ //live recorder parameter
+ public static final String spectateIP = "127.0.0.1";
+ public static final int spectatePort = 2222;
+
static{
File worldConfigFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "config.yml");
if(!worldConfigFile.exists()) {
@@ -370,6 +375,7 @@ public class Config {
OnlyPublicSchematics = event.publicSchemsOnly();
MaximumTeamMembers = event.getMaximumTeamMembers();
}
+ SpectateSystem = event.spectateSystem();
}else{
//No event
TeamRedName = config.getString("Output.TeamRedName");
@@ -379,6 +385,7 @@ public class Config {
EventTeamRedID = 0;
BothTeamsPublic = true;
MaximumTeamMembers = Integer.MAX_VALUE;
+ SpectateSystem = false;
}
String blueLeader = System.getProperty("blueLeader", null);
@@ -405,4 +412,7 @@ public class Config {
public static boolean check(){
return CheckSchemID != 0;
}
+ public static boolean recording(){
+ return event();
+ }
}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java
index 4c7e65f..8ad4146 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java
@@ -28,9 +28,14 @@ import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.kit.KitManager;
import de.steamwar.fightsystem.listener.*;
+import de.steamwar.fightsystem.record.RecordSystem;
+import de.steamwar.fightsystem.record.Recorder;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
-import de.steamwar.fightsystem.utils.*;
+import de.steamwar.fightsystem.utils.EnterHandler;
+import de.steamwar.fightsystem.utils.FightScoreboard;
+import de.steamwar.fightsystem.utils.FightStatistics;
+import de.steamwar.fightsystem.utils.TechHider;
import de.steamwar.fightsystem.winconditions.*;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.Schematic;
@@ -66,6 +71,7 @@ public class FightSystem extends JavaPlugin {
KitManager.loadAllKits();
TechHider.init();
FightScoreboard.init();
+ RecordSystem.init();
try {
CommandRemover.removeAll("gamemode");
@@ -89,6 +95,7 @@ public class FightSystem extends JavaPlugin {
new InFightInventoryListener();
new FreezeWorldStateListener();
new EventJoinListener();
+ new EventRecordListener();
new CheckListener();
new TestListener();
new NormalJoinListener();
@@ -144,6 +151,12 @@ public class FightSystem extends JavaPlugin {
}
}
+ @Override
+ public void onDisable() {
+
+ Recorder.closeAll();
+ }
+
public static void setPreSchemState() {
if(fightState != FightState.PRE_LEADER_SETUP)
throw new SecurityException(fightState.name());
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/commands/GUI.java b/FightSystem_Main/src/de/steamwar/fightsystem/commands/GUI.java
index 7d598ba..fe567c3 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/commands/GUI.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/commands/GUI.java
@@ -153,7 +153,8 @@ public class GUI {
FightTeam fightTeam = Fight.getPlayerTeam(p);
if(fightTeam == null)
return;
- fightTeam.setSchematic(s);
+ if(FightSystem.getFightState() != FightState.POST_SCHEM_SETUP)
+ fightTeam.setSchematic(s);
p.closeInventory();
});
inv.setCallback(-999, (ClickType click) -> p.closeInventory());
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/Countdown.java b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/Countdown.java
index 7b1c2fe..6618edd 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/Countdown.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/Countdown.java
@@ -20,9 +20,11 @@
package de.steamwar.fightsystem.countdown;
import de.steamwar.core.Core;
+import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.listener.BasicListener;
+import de.steamwar.fightsystem.record.RecordSystem;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
@@ -71,6 +73,8 @@ public abstract class Countdown {
}
private void broadcast(String message){
+ if(Config.recording())
+ RecordSystem.actionBar(message);
BaseComponent[] msg = TextComponent.fromLegacyText(message);
for(Player p : Bukkit.getOnlinePlayers())
BasicListener.toActionbar(p, msg);
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/Fight.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/Fight.java
index 4f4d4ca..e060c46 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/Fight.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/Fight.java
@@ -19,15 +19,24 @@
package de.steamwar.fightsystem.fight;
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.events.PacketContainer;
+import com.comphenix.protocol.wrappers.EnumWrappers;
+import com.comphenix.protocol.wrappers.PlayerInfoData;
+import com.comphenix.protocol.wrappers.WrappedChatComponent;
+import com.comphenix.protocol.wrappers.WrappedGameProfile;
import de.steamwar.fightsystem.Config;
+import de.steamwar.fightsystem.record.RecordSystem;
+import de.steamwar.fightsystem.FightSystem;
import de.steamwar.sql.Schematic;
-import org.bukkit.Bukkit;
-import org.bukkit.GameMode;
-import org.bukkit.Material;
-import org.bukkit.Sound;
+import org.bukkit.*;
import org.bukkit.entity.Player;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Level;
public class Fight {
private Fight(){}
@@ -84,6 +93,8 @@ public class Fight {
}
public static void playSound(Sound sound, float volume, float pitch) {
+ if(Config.recording())
+ RecordSystem.soundAtPlayer(sound.name(), volume, pitch);
//volume: max. 100, pitch: max. 2
Bukkit.getServer().getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), sound, volume, pitch));
}
@@ -114,17 +125,33 @@ public class Fight {
if(gameMode == GameMode.SPECTATOR) {
for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) {
if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) {
- currentPlayer.hidePlayer(player);
- player.hidePlayer(currentPlayer);
+ currentPlayer.hidePlayer(FightSystem.getPlugin(), player);
+ player.hidePlayer(FightSystem.getPlugin(), currentPlayer);
}
}
- }
- if(gameMode == GameMode.SURVIVAL) {
+ if(FightSystem.getEventLeiter() == player || Config.test())
+ return;
+
+ Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
+ if(!player.isOnline())
+ return;
+ PacketContainer gm1packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO);
+ gm1packet.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
+ List playerInfoActions = new ArrayList<>();
+ playerInfoActions.add(new PlayerInfoData(WrappedGameProfile.fromPlayer(player), 1, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(player.getDisplayName())));
+ gm1packet.getPlayerInfoDataLists().write(0, playerInfoActions);
+ try {
+ ProtocolLibrary.getProtocolManager().sendServerPacket(player, gm1packet);
+ } catch (InvocationTargetException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Invocation target exception", e);
+ }
+ }, 2);
+ }else if(gameMode == GameMode.SURVIVAL) {
for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) {
if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) {
- currentPlayer.showPlayer(player);
- player.showPlayer(currentPlayer);
+ currentPlayer.showPlayer(FightSystem.getPlugin(), player);
+ player.showPlayer(FightSystem.getPlugin(), currentPlayer);
}
}
}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java
index 6bd4a93..57380a2 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java
@@ -20,13 +20,19 @@
package de.steamwar.fightsystem.fight;
import com.sk89q.worldedit.EditSession;
+import de.steamwar.comms.packets.TablistNamePacket;
import de.steamwar.core.Core;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.IFightSystem;
import de.steamwar.fightsystem.kit.KitManager;
+import de.steamwar.fightsystem.listener.PersonalKitCreator;
+import de.steamwar.fightsystem.record.RecordSystem;
import de.steamwar.fightsystem.states.FightState;
-import de.steamwar.fightsystem.utils.*;
+import de.steamwar.fightsystem.utils.ColorConverter;
+import de.steamwar.fightsystem.utils.FightScoreboard;
+import de.steamwar.fightsystem.utils.ItemBuilder;
+import de.steamwar.fightsystem.utils.TechHider;
import de.steamwar.fightsystem.winconditions.RankedPlayerLeftWincondition;
import de.steamwar.inventory.SWItem;
import de.steamwar.sql.NoClipboardException;
@@ -177,6 +183,10 @@ public class FightTeam implements IFightTeam{
if(KitManager.getKits(false).size() > 1 || Config.PersonalKits)
player.getInventory().setItem(1, new ItemBuilder(Material.LEATHER_CHESTPLATE).removeAllAttributs().addEnchantment(Enchantment.DURABILITY, 1).setDisplayName("§eKit wählen").build());
player.getInventory().setItem(7, new ItemBuilder(Material.BEACON).removeAllAttributs().setDisplayName("§eRespawn").build());
+ if(!Config.test())
+ Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> new TablistNamePacket(SteamwarUser.get(player.getUniqueId()).getId(), prefix + player.getName()).send(player), 5);
+ if(Config.recording())
+ RecordSystem.playerJoins(player);
TechHider.reloadChunks(player, chunksToReload);
return fightPlayer;
}
@@ -194,6 +204,10 @@ public class FightTeam implements IFightTeam{
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
player.teleport(Config.SpecSpawn);
+ if(!Config.test())
+ new TablistNamePacket(SteamwarUser.get(player.getUniqueId()).getId(), "§7§o" + player.getName()).send(player);
+ if(Config.recording())
+ RecordSystem.entityDespawns(player);
TechHider.reloadChunks(player, chunksToReload);
}
@@ -222,6 +236,9 @@ public class FightTeam implements IFightTeam{
}
return;
}
+ if (!PersonalKitCreator.notInKitCreator(leader.getPlayer()))
+ leader.getPlayer().closeInventory();
+
this.leader = leader;
if(ready)
setReady(false);
@@ -255,6 +272,13 @@ public class FightTeam implements IFightTeam{
}
public void pasteSchematic(){
+ if(Config.recording()){
+ if(blue)
+ RecordSystem.blueSchem(schematic);
+ else
+ RecordSystem.redSchem(schematic);
+ }
+
FreezeWorld freezer = new FreezeWorld();
DyeColor c = ColorConverter.chat2dye(color);
Schematic schem;
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/EventJoinListener.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/EventJoinListener.java
index 23a4a31..6e60e5c 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/EventJoinListener.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/EventJoinListener.java
@@ -29,6 +29,7 @@ import de.steamwar.sql.SteamwarUser;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.EnumSet;
@@ -39,6 +40,21 @@ public class EventJoinListener extends BasicListener {
super(Config.event() ? EnumSet.of(FightState.PRE_LEADER_SETUP, FightState.PRE_SCHEM_SETUP, FightState.POST_SCHEM_SETUP) : EnumSet.noneOf(FightState.class));
}
+ @EventHandler
+ public void playerLogin(PlayerLoginEvent event) {
+ if(!Config.SpectateSystem)
+ return;
+
+ Player player = event.getPlayer();
+ SteamwarUser user = SteamwarUser.get(player.getUniqueId());
+ if(user.getTeam() == Config.EventTeamBlueID ||
+ user.getTeam() == Config.EventTeamRedID ||
+ user.getId() == FightSystem.getEventFight().getKampfleiter())
+ return;
+
+ event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "§cDu bist kein Kampfteilnehmer");
+ }
+
@EventHandler
public void handlePlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
@@ -66,10 +82,15 @@ public class EventJoinListener extends BasicListener {
FightPlayer fp = team.addMember(player);
if(!team.hasTeamLeader())
team.setLeader(fp);
+ return;
}
- if(user.getId() == FightSystem.getEventFight().getKampfleiter())
+ if(user.getId() == FightSystem.getEventFight().getKampfleiter()){
FightSystem.setEventLeiter(player);
+ return;
+ }
+ if(Config.SpectateSystem)
+ player.kickPlayer("§cDu bist kein Kampfteilnehmer");
}
@EventHandler
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/EventRecordListener.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/EventRecordListener.java
new file mode 100644
index 0000000..7b690a1
--- /dev/null
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/EventRecordListener.java
@@ -0,0 +1,227 @@
+/*
+ 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 .
+*/
+
+package de.steamwar.fightsystem.listener;
+
+import de.steamwar.fightsystem.Config;
+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.record.RecordSystem;
+import de.steamwar.fightsystem.states.FightState;
+import org.bukkit.*;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.TNTPrimed;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.BlockPhysicsEvent;
+import org.bukkit.event.entity.EntityExplodeEvent;
+import org.bukkit.event.entity.EntitySpawnEvent;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.entity.ProjectileLaunchEvent;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.player.*;
+import org.bukkit.event.server.BroadcastMessageEvent;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.EnumSet;
+import java.util.Random;
+
+public class EventRecordListener extends BasicListener {
+
+ private static final int AIR = 0;
+ private static final Random random = new Random();
+
+ public EventRecordListener() {
+ super(Config.recording() ? EnumSet.allOf(FightState.class) : EnumSet.noneOf(FightState.class));
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onPlayerMove(PlayerMoveEvent e){
+ if(isNotSent(e.getPlayer()))
+ return;
+
+ RecordSystem.entityMoves(e.getPlayer());
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onPlayerDeath(PlayerDeathEvent e){
+ if(isNotSent(e.getEntity()))
+ return;
+
+ RecordSystem.entityDespawns(e.getEntity());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onBroadcast(BroadcastMessageEvent e){
+ RecordSystem.systemChat(e.getMessage());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onSneak(PlayerToggleSneakEvent e){
+ if(isNotSent(e.getPlayer()))
+ return;
+
+ RecordSystem.playerSneak(e.getPlayer(), e.isSneaking());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onAnimation(PlayerAnimationEvent e){
+ if(isNotSent(e.getPlayer()))
+ return;
+
+ if(e.getAnimationType() == PlayerAnimationType.ARM_SWING)
+ RecordSystem.entityAnimation(e.getPlayer(), AIR);
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onTNTSpawn(EntitySpawnEvent e){
+ //TODO: Falling block
+ if(e.getEntityType() != EntityType.PRIMED_TNT)
+ return;
+
+ RecordSystem.tntSpawn(e.getEntity());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onBlockPhysics(BlockPhysicsEvent e){
+ if(e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR)
+ RecordSystem.blockChange(e.getBlock());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onExplosion(EntityExplodeEvent e){
+ if(e.getEntityType() != EntityType.PRIMED_TNT)
+ return;
+
+ Location loc = e.getLocation();
+ RecordSystem.entityDespawns(e.getEntity());
+ RecordSystem.particle(loc.getX(), loc.getY(), loc.getZ(), Particle.EXPLOSION_HUGE.name());
+ RecordSystem.sound(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), Sound.ENTITY_GENERIC_EXPLODE.name(), SoundCategory.BLOCKS.name(), 4.0F, (1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F) * 0.7F);
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onItem(PlayerItemHeldEvent e){
+ if(isNotSent(e.getPlayer()))
+ return;
+
+ RecordSystem.item(e.getPlayer(), disarmNull(e.getPlayer().getInventory().getItem(e.getNewSlot())), "MAINHAND");
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onItemSwap(PlayerSwapHandItemsEvent e){
+ if(isNotSent(e.getPlayer()))
+ return;
+
+ Player player = e.getPlayer();
+ RecordSystem.item(player, disarmNull(e.getMainHandItem()), "MAINHAND");
+ RecordSystem.item(player, disarmNull(e.getOffHandItem()), "OFFHAND");
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onProjectileSpawn(ProjectileLaunchEvent e){
+ if(e.getEntityType() == EntityType.FIREBALL)
+ RecordSystem.fireballSpawn(e.getEntity());
+ else if(e.getEntityType() == EntityType.ARROW)
+ RecordSystem.arrowSpawn(e.getEntity());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onInventoryClick(InventoryClickEvent e){
+ Player player = (Player) e.getWhoClicked();
+ if(isNotSent(player))
+ return;
+
+ if(e.getSlotType() != InventoryType.SlotType.ARMOR)
+ return;
+
+ switch(e.getSlot()){
+ case 103:
+ RecordSystem.item(player, disarmNull(e.getCurrentItem()), "HEAD");
+ break;
+ case 102:
+ RecordSystem.item(player, disarmNull(e.getCurrentItem()), "CHEST");
+ break;
+ case 101:
+ RecordSystem.item(player, disarmNull(e.getCurrentItem()), "LEGS");
+ break;
+ case 100:
+ default:
+ RecordSystem.item(player, disarmNull(e.getCurrentItem()), "FEET");
+ }
+ }
+
+ @Override
+ public void stateChange(FightState state) {
+ if(state == FightState.PRE_RUNNING) {
+ Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
+ setKitItems(Fight.getBlueTeam());
+ setKitItems(Fight.getRedTeam());
+ }, 1);
+ }else if(state == FightState.SPECTATE){
+ despawnTeam(Fight.getRedTeam());
+ despawnTeam(Fight.getBlueTeam());
+ despawnTNT();
+ }
+ }
+
+ private void setKitItems(FightTeam team){
+ if(FightSystem.getFightState() != FightState.PRE_RUNNING)
+ return;
+
+ for(FightPlayer fp : team.getPlayers()){
+ if(!fp.isLiving())
+ continue;
+
+ Player player = fp.getPlayer();
+ RecordSystem.item(player, disarmNull(player.getInventory().getItemInMainHand()), "MAINHAND");
+ RecordSystem.item(player, disarmNull(player.getInventory().getItemInOffHand()), "OFFHAND");
+ RecordSystem.item(player, disarmNull(player.getInventory().getHelmet()), "HEAD");
+ RecordSystem.item(player, disarmNull(player.getInventory().getChestplate()), "CHEST");
+ RecordSystem.item(player, disarmNull(player.getInventory().getLeggings()), "LEGS");
+ RecordSystem.item(player, disarmNull(player.getInventory().getBoots()), "FEET");
+ }
+ }
+
+ private ItemStack disarmNull(ItemStack stack){
+ if(stack == null)
+ return new ItemStack(Material.AIR);
+ return stack;
+ }
+
+ private void despawnTeam(FightTeam team){
+ for(FightPlayer player : team.getPlayers()){
+ if(player.isLiving())
+ RecordSystem.entityDespawns(player.getPlayer());
+ }
+ }
+
+ private void despawnTNT(){
+ for(TNTPrimed tnt : Bukkit.getWorlds().get(0).getEntitiesByClass(TNTPrimed.class))
+ RecordSystem.entityDespawns(tnt);
+ }
+
+ private boolean isNotSent(Player p){
+ FightPlayer fp = Fight.getFightPlayer(p);
+ return fp == null || !fp.isLiving() || FightSystem.getFightState() == FightState.SPECTATE;
+ }
+}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java
index c593dae..104fa81 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java
@@ -78,7 +78,7 @@ public class PersonalKitCreator extends BasicListener {
player.setGameMode(GameMode.CREATIVE);
}
- static boolean notInKitCreator(HumanEntity player){
+ public static boolean notInKitCreator(HumanEntity player){
return !openKitCreators.containsKey(player);
}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerChatListener.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerChatListener.java
index c627ad0..394f109 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerChatListener.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerChatListener.java
@@ -23,6 +23,7 @@ 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.record.RecordSystem;
import de.steamwar.fightsystem.states.FightState;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
@@ -61,7 +62,9 @@ public class PlayerChatListener extends BasicListener {
event.setCancelled(true);
}
- private void broadcastChat(String message){
+ private void broadcastChat(String message) {
+ if (Config.recording())
+ RecordSystem.chat(message);
BaseComponent[] msg = TextComponent.fromLegacyText(message);
for(Player p : Bukkit.getOnlinePlayers())
toChat(p, msg);
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerMoveListener.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerMoveListener.java
index d6b678e..bec0121 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerMoveListener.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerMoveListener.java
@@ -26,6 +26,7 @@ import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.utils.Region;
import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@@ -33,6 +34,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.EnumSet;
+import java.util.logging.Level;
public class PlayerMoveListener extends BasicListener {
@@ -64,15 +66,30 @@ public class PlayerMoveListener extends BasicListener {
reset(event, DENY_TEAM);
else if(fightTeam == Fight.getRedTeam() && player.getGameMode() == GameMode.SPECTATOR)
reset(event, DENY_ENTERN);
+ else
+ return; // Is allowed in area
+ checkInInnerArea(event.getPlayer(), to, Config.TeamBlueCornerX, Config.TeamBlueCornerZ);
}else if(inRedArea){
if(fightTeam == null)
reset(event, DENY_TEAM);
else if(fightTeam == Fight.getBlueTeam() && player.getGameMode() == GameMode.SPECTATOR)
reset(event, DENY_ENTERN);
+ else
+ return; // Is allowed in area
+ checkInInnerArea(event.getPlayer(), to, Config.TeamRedCornerX, Config.TeamRedCornerZ);
}else if(fightTeam != null && player.getGameMode() != GameMode.SPECTATOR && !fightTeam.canPlayerEntern(player))
reset(event, DENY_ENTERN);
}
+ private void checkInInnerArea(Player player, Location to, int teamCornerX, int teamCornerZ){
+ boolean inArenaY = to.getY() + 1.8 <= Config.TeamBlueCornerY + Config.SchemsizeY;
+ boolean inArea = inArenaY && Region.isIn2DRange(to, teamCornerX, teamCornerZ, Config.SchemsizeX, Config.SchemsizeZ, 0);
+ if(inArea){
+ player.kickPlayer(null);
+ Bukkit.getLogger().log(Level.SEVERE, player.getName() + " ist in einen Teambereich eingedrungen.");
+ }
+ }
+
@EventHandler
public void arenaBorder(PlayerMoveEvent event){
Player player = event.getPlayer();
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerStateListener.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerStateListener.java
index 8f179e6..3830c12 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerStateListener.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/PlayerStateListener.java
@@ -19,6 +19,7 @@
package de.steamwar.fightsystem.listener;
+import de.steamwar.comms.packets.TablistNamePacket;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.countdown.Countdown;
@@ -26,7 +27,9 @@ import de.steamwar.fightsystem.countdown.SWSound;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
+import de.steamwar.fightsystem.record.RecordSystem;
import de.steamwar.fightsystem.states.FightState;
+import de.steamwar.sql.SteamwarUser;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
@@ -61,6 +64,8 @@ public class PlayerStateListener extends BasicListener{
if (fightTeam == null) {
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
player.teleport(Config.SpecSpawn);
+ if(!Config.test())
+ Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> new TablistNamePacket(SteamwarUser.get(player.getUniqueId()).getId(), "§7" + player.getName()).send(player), 5);
} else {
player.teleport(fightTeam.getSpawn());
if(FightSystem.getFightState().setup())
@@ -85,6 +90,8 @@ public class PlayerStateListener extends BasicListener{
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
player.teleport(fightTeam.getSpawn());
Fight.playSound(Countdown.getSound(SWSound.ENTITY_WITHER_DEATH), 100.0F, 1.0F);
+ if(Config.recording())
+ RecordSystem.entityDespawns(player);
}
@EventHandler(priority = EventPriority.HIGH)
@@ -99,11 +106,17 @@ public class PlayerStateListener extends BasicListener{
FightState fightState = FightSystem.getFightState();
if(fightState.setup()){
fightTeam.removePlayer(player);
+
+ if(Config.recording())
+ RecordSystem.entityDespawns(player);
}else if(fightState.ingame()){
FightPlayer fightPlayer = fightTeam.getFightPlayer(player);
if(fightPlayer.isLiving()) {
Bukkit.broadcastMessage(FightSystem.PREFIX + "§cDer Spieler " + fightTeam.getPrefix() + player.getName() + " §chat den Kampf verlassen!");
fightTeam.getFightPlayer(player).setOut();
+
+ if(Config.recording())
+ RecordSystem.entityDespawns(player);
}
}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/FileRecorder.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/FileRecorder.java
new file mode 100644
index 0000000..3a0c616
--- /dev/null
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/FileRecorder.java
@@ -0,0 +1,146 @@
+/*
+ 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 .
+*/
+
+package de.steamwar.fightsystem.record;
+
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.zip.GZIPOutputStream;
+
+public class FileRecorder extends Recorder {
+
+ private final DataOutputStream outputStream;
+
+ public FileRecorder(){
+ super();
+ World world = Bukkit.getWorlds().get(0);
+ File file = new File(world.getWorldFolder(), world.getName() + ".recording");
+ try{
+ file.createNewFile();
+ outputStream = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(file), 4096));
+ }catch(IOException e){
+ throw new SecurityException("Could not open file", e);
+ }
+ }
+
+ @Override
+ protected void writeBoolean(boolean b) {
+ try {
+ outputStream.writeBoolean(b);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeByte(int b) {
+ try {
+ outputStream.writeByte(b);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeShort(short s) {
+ try {
+ outputStream.writeShort(s);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeInt(int i) {
+ try {
+ outputStream.writeInt(i);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeLong(long l) {
+ try {
+ outputStream.writeLong(l);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeFloat(float f) {
+ try {
+ outputStream.writeFloat(f);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeDouble(double d) {
+ try {
+ outputStream.writeDouble(d);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeString(String s) {
+ try {
+ outputStream.writeUTF(s);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void doFlush() {
+ try {
+ outputStream.flush();
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not flush", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void closeRecorder() {
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Could not close OutputStream", e);
+ }
+ }
+}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/RecordSystem.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/RecordSystem.java
new file mode 100644
index 0000000..84660b4
--- /dev/null
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/RecordSystem.java
@@ -0,0 +1,303 @@
+/*
+ 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 .
+*/
+
+package de.steamwar.fightsystem.record;
+
+import de.steamwar.core.Core;
+import de.steamwar.fightsystem.Config;
+import de.steamwar.fightsystem.FightSystem;
+import de.steamwar.fightsystem.states.FightState;
+import de.steamwar.sql.SteamwarUser;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.TNTPrimed;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
+
+public class RecordSystem {
+ private RecordSystem(){}
+
+ private static final World WORLD = Bukkit.getWorlds().get(0);
+
+ public static void init(){
+ if(!Config.recording())
+ return;
+
+ Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), RecordSystem::checkWorldState, 1, 1);
+ new SpectateConnection();
+ new FileRecorder();
+ if(Config.event())
+ teamIds(Config.EventTeamBlueID, Config.EventTeamRedID);
+ }
+
+ /*
+ * PlayerJoinPacket (0x00) + int EntityId + int SWUserId
+ * EntityMovePacket (0x01) + int EntityId + double x, y, z + float pitch, yaw + byte headyaw
+ * EntityDespawnsPacket (0x02) + int EntityId
+ * PlayerSneakPacket (0x03) + int EntityId + boolean sneaks
+ * EntityAnimationPacket (0x04) + int EntityId + byte animation
+ * TNTSpawnPacket (0x05) + int EntityId
+ * EntitySpeedPacket (0x06) + int EntityId + double dx, dy, dz
+ * PlayerItemPacket (0x07) + int EntityId + String item + boolean enchanted + String slot
+ * ArrowSpawnPacket (0x08) + int EntityId
+ * FireballSpawnPacket (0x09) + int EntityId
+ * TODO Bow spanning
+ *
+ *
+ *
+ * BlockPacket (0x30) + pos int, byte, int + int BlockState
+ * ParticlePacket (0x31) + double x, y, z + string particleType
+ * SoundPacket (0x32) + int x, y, z + string soundType + string soundCategory + float volume, pitch
+ * ShortBlockPacket (0x33) + pos relative to ArenaMinX,ArenaMinZ byte, byte, byte + short BlockState
+ * SoundAtPlayerPacket (0x34) + string (soundType, soundCategory) + float volume, pitch
+ *
+ *
+ * ChatPacket (0xA0) + String message
+ * ActionBarPacket (0xA1) + String message
+ * SystemPacket (0xA2) + String message
+ * BlueSchemPacket (0xB0) + int blueSchemId
+ * RedSchemPacket (0xB1) + int redSchemId
+ * TeamIDPacket (0xB2) + int blueTeamId, redTeamId
+ * ScoreboardTitlePacket (0xC0) + String scoreboardTitle
+ * ScoreboardDataPacket (0xC1) + String key + int value
+ *
+ * CommentPacket (0xfe) + String comment
+ * TickPacket (0xff)
+ * */
+
+ public static synchronized void playerJoins(Player p){
+ SteamwarUser user = SteamwarUser.get(p.getUniqueId());
+
+ Recorder.rByte(0x00);
+ Recorder.rInt(p.getEntityId());
+ Recorder.rInt(user.getId());
+ entityMoves(p);
+ }
+
+ public static synchronized void entityMoves(Entity e){
+ Location location = e.getLocation();
+
+ Recorder.rByte(0x01);
+ Recorder.rInt(e.getEntityId());
+ Recorder.rDouble(location.getX());
+ Recorder.rDouble(location.getY());
+ Recorder.rDouble(location.getZ());
+ Recorder.rFloat(location.getPitch());
+ Recorder.rFloat(location.getYaw());
+ Recorder.rByte((int)(((CraftEntity)e).getHandle().getHeadRotation() * 256 / 360));
+ Recorder.flush();
+ }
+
+ public static synchronized void entityDespawns(Entity e){
+ Recorder.rByte(0x02);
+ Recorder.rInt(e.getEntityId());
+ Recorder.flush();
+ }
+
+ public static synchronized void playerSneak(Player p, boolean sneaks){
+ Recorder.rByte(0x03);
+ Recorder.rInt(p.getEntityId());
+ Recorder.rBoolean(sneaks);
+ Recorder.flush();
+ }
+
+ public static synchronized void entityAnimation(Entity e, int animation){
+ Recorder.rByte(0x04);
+ Recorder.rInt(e.getEntityId());
+ Recorder.rByte(animation);
+ Recorder.flush();
+ }
+
+ public static synchronized void tntSpawn(Entity e){
+ Recorder.rByte(0x05);
+ spawnEntity(e);
+ }
+
+ public static synchronized void entitySpeed(Entity e){
+ Vector velocity = e.getVelocity();
+ Recorder.rByte(0x06);
+ Recorder.rInt(e.getEntityId());
+ Recorder.rDouble(velocity.getX());
+ Recorder.rDouble(velocity.getY());
+ Recorder.rDouble(velocity.getZ());
+ Recorder.flush();
+ }
+
+ public static synchronized void item(Player p, ItemStack item, String slot){
+ Recorder.rByte(0x07);
+ Recorder.rInt(p.getEntityId());
+ Recorder.rString(item.getType().getKey().toString());
+ Recorder.rBoolean(!item.getEnchantments().isEmpty());
+ Recorder.rString(slot);
+ Recorder.flush();
+ }
+
+ public static synchronized void arrowSpawn(Entity e){
+ Recorder.rByte(0x08);
+ spawnEntity(e);
+ }
+
+ public static synchronized void fireballSpawn(Entity e){
+ Recorder.rByte(0x09);
+ spawnEntity(e);
+ }
+
+ public static synchronized void blockChange(Block block){
+ int blockState = blockToId(block);
+
+ int shortX = block.getX() - Config.ArenaMinX;
+ int shortZ = block.getZ() - Config.ArenaMinZ;
+ if((short)blockState == blockState && shortX > 0 && shortX < 256 && shortZ > 0 && shortZ < 256){
+ //Short block packet
+ Recorder.rByte(0x33);
+ Recorder.rByte(shortX);
+ Recorder.rByte(block.getY());
+ Recorder.rByte(shortZ);
+ Recorder.rShort((short)blockState);
+ }else{
+ //Block packet
+ Recorder.rByte(0x30);
+ Recorder.rInt(block.getX());
+ Recorder.rByte(block.getY());
+ Recorder.rInt(block.getZ());
+ Recorder.rInt(blockState);
+ }
+ Recorder.flush();
+ }
+
+ public static synchronized void particle(double x, double y, double z, String particleType){
+ Recorder.rByte(0x31);
+ Recorder.rDouble(x);
+ Recorder.rDouble(y);
+ Recorder.rDouble(z);
+ Recorder.rString(particleType);
+ Recorder.flush();
+ }
+
+ public static synchronized void sound(int x, int y, int z, String soundType, String soundCategory, float volume, float pitch){
+ Recorder.rByte(0x32);
+ Recorder.rInt(x);
+ Recorder.rInt(y);
+ Recorder.rInt(z);
+ Recorder.rString(soundType);
+ Recorder.rString(soundCategory);
+ Recorder.rFloat(volume);
+ Recorder.rFloat(pitch);
+ Recorder.flush();
+ }
+
+ public static synchronized void soundAtPlayer(String soundType, float volume, float pitch){
+ Recorder.rByte(0x34);
+ Recorder.rString(soundType);
+ Recorder.rFloat(volume);
+ Recorder.rFloat(pitch);
+ Recorder.flush();
+ }
+
+ public static synchronized void chat(String s) {
+ Recorder.rByte(0xA0);
+ Recorder.rString(s);
+ Recorder.flush();
+ }
+
+ public static synchronized void actionBar(String s) {
+ Recorder.rByte(0xA1);
+ Recorder.rString(s);
+ Recorder.flush();
+ }
+
+ public static synchronized void systemChat(String s) {
+ Recorder.rByte(0xA2);
+ Recorder.rString(s);
+ Recorder.flush();
+ }
+
+ public static synchronized void blueSchem(int schemId) {
+ Recorder.rByte(0xB0);
+ Recorder.rInt(schemId);
+ Recorder.flush();
+ }
+
+ public static synchronized void redSchem(int schemId) {
+ Recorder.rByte(0xB1);
+ Recorder.rInt(schemId);
+ Recorder.flush();
+ }
+
+ public static synchronized void teamIds(int blueTeamId, int redTeamId) {
+ Recorder.rByte(0xB2);
+ Recorder.rInt(blueTeamId);
+ Recorder.rInt(redTeamId);
+ Recorder.flush();
+ }
+
+ public static synchronized void scoreboardTitle(String title){
+ Recorder.rByte(0xC0);
+ Recorder.rString(title);
+ Recorder.flush();
+ }
+
+ public static synchronized void scoreboardData(String key, int value){
+ Recorder.rByte(0xC1);
+ Recorder.rString(key);
+ Recorder.rInt(value);
+ Recorder.flush();
+ }
+
+ public static synchronized void tick(){
+ Recorder.rByte(0xff);
+ Recorder.flush();
+ }
+
+ private static void checkWorldState(){
+ tick();
+
+ if(FightSystem.getFightState() == FightState.SPECTATE)
+ return;
+
+ for(TNTPrimed tnt : WORLD.getEntitiesByClass(TNTPrimed.class)){
+ entityMoves(tnt);
+ entitySpeed(tnt);
+ }
+ }
+
+ private static void spawnEntity(Entity e){
+ Recorder.rInt(e.getEntityId());
+ entityMoves(e);
+ entitySpeed(e);
+ }
+
+ private static int blockToId(Block block){
+ switch(Core.getVersion()){
+ case 8:
+ case 9:
+ case 10:
+ case 12:
+ return RecordSystem_8.blockToId(block);
+ case 15:
+ default:
+ return RecordSystem_15.blockToId(block);
+ }
+ }
+}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/Recorder.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/Recorder.java
new file mode 100644
index 0000000..a332331
--- /dev/null
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/Recorder.java
@@ -0,0 +1,90 @@
+/*
+ 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 .
+*/
+
+package de.steamwar.fightsystem.record;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class Recorder {
+
+ private static final List recorders = new ArrayList<>();
+
+ public static void rBoolean(boolean b){
+ recorders.forEach((recorder) -> recorder.writeBoolean(b));
+ }
+
+ public static void rByte(int b){
+ recorders.forEach((recorder) -> recorder.writeByte(b));
+ }
+
+ public static void rShort(short s){
+ recorders.forEach((recorder) -> recorder.writeShort(s));
+ }
+
+ public static void rInt(int i){
+ recorders.forEach((recorder) -> recorder.writeInt(i));
+ }
+
+ public static void rLong(long l){
+ recorders.forEach((recorder) -> recorder.writeLong(l));
+ }
+
+ public static void rFloat(float f){
+ recorders.forEach((recorder) -> recorder.writeFloat(f));
+ }
+
+ public static void rDouble(double d){
+ recorders.forEach((recorder) -> recorder.writeDouble(d));
+ }
+
+ public static void rString(String s){
+ recorders.forEach((recorder) -> recorder.writeString(s));
+ }
+
+ public static void flush(){
+ recorders.forEach(Recorder::doFlush);
+ }
+
+ public static void closeAll(){
+ while(!recorders.isEmpty())
+ recorders.get(0).close();
+ }
+
+ protected Recorder(){
+ recorders.add(this);
+ }
+
+ protected void close(){
+ closeRecorder();
+ recorders.remove(this);
+ }
+
+ protected abstract void writeBoolean(boolean b);
+ protected abstract void writeByte(int b);
+ protected abstract void writeShort(short s);
+ protected abstract void writeInt(int i);
+ protected abstract void writeLong(long l);
+ protected abstract void writeFloat(float f);
+ protected abstract void writeDouble(double d);
+ protected abstract void writeString(String s);
+ protected abstract void doFlush();
+
+ protected abstract void closeRecorder();
+}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/SpectateConnection.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/SpectateConnection.java
new file mode 100644
index 0000000..9951321
--- /dev/null
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/SpectateConnection.java
@@ -0,0 +1,147 @@
+/*
+ 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 .
+*/
+
+package de.steamwar.fightsystem.record;
+
+import de.steamwar.fightsystem.Config;
+import org.bukkit.Bukkit;
+
+import java.io.*;
+import java.net.Socket;
+import java.util.logging.Level;
+
+public class SpectateConnection extends Recorder{
+
+ private Socket socket;
+ private DataOutputStream outputStream;
+
+ SpectateConnection(){
+ super();
+ try {
+ this.socket = new Socket(Config.spectateIP, Config.spectatePort);
+ socket.setSoTimeout(1); // Wait a maximum of 1ms on a blocking operation (flush)
+ socket.setSoLinger(true, 1); // Wait a maximum of 1ms on close
+ socket.setTcpNoDelay(true); // Don't wait always on ack
+ this.outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.WARNING, "Could not init connection to spectate server", e);
+ close();
+ }
+ }
+
+ @Override
+ protected void writeBoolean(boolean b) {
+ try{
+ outputStream.writeBoolean(b);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void writeByte(int b) {
+ try{
+ outputStream.writeByte(b);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void writeShort(short s) {
+ try{
+ outputStream.writeShort(s);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void writeInt(int i) {
+ try{
+ outputStream.writeInt(i);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void writeLong(long l) {
+ try{
+ outputStream.writeLong(l);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void writeFloat(float f) {
+ try{
+ outputStream.writeFloat(f);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void writeDouble(double d) {
+ try{
+ outputStream.writeDouble(d);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void writeString(String s) {
+ try{
+ outputStream.writeUTF(s);
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not send", e);
+ }
+ }
+
+ @Override
+ protected void doFlush() {
+ try{
+ outputStream.flush();
+ } catch (IOException e) {
+ close();
+ Bukkit.getLogger().log(Level.SEVERE, "Could not flush", e);
+ }
+ }
+
+ @Override
+ protected void closeRecorder() {
+ try {
+ socket.close();
+ outputStream.close();
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.WARNING, "IOException on socket close", e);
+ }
+ }
+}
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightScoreboard.java b/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightScoreboard.java
index 3cf6766..7f628ae 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightScoreboard.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightScoreboard.java
@@ -19,10 +19,12 @@
package de.steamwar.fightsystem.utils;
+import de.steamwar.core.TPSWatcher;
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.record.RecordSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.winconditions.*;
import de.steamwar.scoreboard.SWScoreboard;
@@ -91,6 +93,8 @@ public class FightScoreboard implements Listener {
objective.addScore("§7Zeit: §a" + fightTime + "s", 3);
}
+ setScore("§7TPS: §e" + TPSWatcher.getTPS(), 3);
+
if(fullScoreboard.contains(FightSystem.getFightState())){
if (Config.PercentSystem){
objective.addScore(Fight.getRedTeam().getPrefix() + "Schaden: " + (Math.round(100.0 * WinconditionPercentSystem.getRedPercent()) / 100.0) + "%", 1);
@@ -112,6 +116,12 @@ public class FightScoreboard implements Listener {
return objective;
}
+ private static void setScore(String key, int value){
+ objective.getScore(key).setScore(value);
+ if(Config.recording())
+ RecordSystem.scoreboardData(key, value);
+ }
+
private static FightTeam getIndexDisplay() {
if(index == 1)
return Fight.redTeam;
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightStatistics.java b/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightStatistics.java
index 0b948b3..23fcdf4 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightStatistics.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/utils/FightStatistics.java
@@ -47,6 +47,8 @@ public class FightStatistics {
public static void saveStats(FightTeam winner, String windescription){
String gameMode = Config.SchematicType.toDB();
+ if(!Fight.getBlueTeam().hasTeamLeader() || !Fight.getRedTeam().hasTeamLeader())
+ return;
SteamwarUser blueLeader = SteamwarUser.get(Fight.getBlueTeam().getLeader().getPlayer().getUniqueId());
SteamwarUser redLeader = SteamwarUser.get(Fight.getRedTeam().getLeader().getPlayer().getUniqueId());
int win = 0;
diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java b/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java
index 8506394..fcff47a 100644
--- a/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java
+++ b/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java
@@ -49,14 +49,15 @@ public class WaterRemover {
}
private static void checkBlock(Block b, int startX, int startY, int startZ) throws IsAnOcean {
- if(!isWater(b))
+ if(!removeWater(b))
return;
// If distance to original block is greater than 20
- if(Math.abs(startX - b.getX()) + Math.abs(startY - b.getY() + Math.abs(startZ - b.getZ())) >= 20)
+ if(Math.abs(startX - b.getX()) + Math.abs(startY - b.getY() + Math.abs(startZ - b.getZ())) >= 20){
+ b.setType(Material.WATER);
throw new IsAnOcean();
+ }
- b.setType(Material.AIR);
try{
checkBlock(b.getRelative(BlockFace.EAST), startX, startY, startZ);
checkBlock(b.getRelative(BlockFace.WEST), startX, startY, startZ);
@@ -84,4 +85,19 @@ public class WaterRemover {
return WaterRemover_14.isWater(block);
}
}
+
+ public static boolean removeWater(Block block){
+ //checks for water and removes it, if present
+ switch(Core.getVersion()){
+ case 8:
+ case 9:
+ case 10:
+ case 12:
+ return WaterRemover_8.removeWater(block);
+ case 14:
+ case 15:
+ default:
+ return WaterRemover_14.removeWater(block);
+ }
+ }
}