RecordSystem (Beta) #199
@ -128,7 +128,6 @@ public class Config {
|
||||
//live recorder parameter
|
||||
public static final String spectateIP = "127.0.0.1";
|
||||
public static final int spectatePort = 2222;
|
||||
public static final boolean recording;
|
||||
|
||||
static{
|
||||
File worldConfigFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "config.yml");
|
||||
@ -380,8 +379,6 @@ public class Config {
|
||||
|
||||
CheckSchemID = Integer.parseInt(System.getProperty("checkSchemID", "0"));
|
||||
Ranked = Boolean.parseBoolean(System.getProperty("ranked", "false"));
|
||||
|
||||
recording = event();
|
||||
}
|
||||
|
||||
public static boolean event(){
|
||||
@ -393,4 +390,7 @@ public class Config {
|
||||
public static boolean check(){
|
||||
return CheckSchemID != 0;
|
||||
}
|
||||
public static boolean recording(){
|
||||
return event();
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ 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.*;
|
||||
@ -128,6 +129,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());
|
||||
|
@ -1,9 +1,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;
|
||||
@ -54,6 +56,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);
|
||||
|
@ -1,35 +1,40 @@
|
||||
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.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
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.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.server.BroadcastMessageEvent;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class EventRecordListener extends BasicListener {
|
||||
|
||||
private static final int AIR = 0;
|
||||
|
||||
public EventRecordListener() {
|
||||
super(Config.event() ? EnumSet.allOf(FightState.class) : EnumSet.noneOf(FightState.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
RecordSystem.init();
|
||||
super.enable();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerJoin(PlayerJoinEvent e){
|
||||
FightPlayer fp = Fight.getFightPlayer(e.getPlayer());
|
||||
if(fp == null || !fp.isLiving())
|
||||
if(isNotSent(e.getPlayer()))
|
||||
return;
|
||||
|
||||
RecordSystem.playerJoins(e.getPlayer());
|
||||
@ -37,21 +42,84 @@ public class EventRecordListener extends BasicListener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerMove(PlayerMoveEvent e){
|
||||
FightPlayer fp = Fight.getFightPlayer(e.getPlayer());
|
||||
if(fp == null || !fp.isLiving())
|
||||
if(isNotSent(e.getPlayer()))
|
||||
return;
|
||||
|
||||
RecordSystem.entityMoves(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerDeath(PlayerDeathEvent e){
|
||||
FightPlayer fp = Fight.getFightPlayer(e.getEntity());
|
||||
if(fp == null || fp.isLiving())
|
||||
if(isNotSent(e.getEntity()))
|
||||
return;
|
||||
|
||||
RecordSystem.entityDespawns(e.getEntity());
|
||||
}
|
||||
|
||||
//TODO: Listener, if player gets out (leaves, dies or starts to spectate), alternatively: track sent players
|
||||
@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){
|
||||
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_LARGE.name());
|
||||
RecordSystem.sound(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), Sound.ENTITY_GENERIC_EXPLODE.name(), SoundCategory.BLOCKS.name(), 255.0f, 1.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChange(FightState state) {
|
||||
if(state == FightState.SPECTATE){
|
||||
despawnTeam(Fight.getRedTeam());
|
||||
despawnTeam(Fight.getBlueTeam());
|
||||
}
|
||||
}
|
||||
|
||||
private void despawnTeam(FightTeam team){
|
||||
for(FightPlayer player : team.getPlayers()){
|
||||
if(player.isLiving())
|
||||
RecordSystem.entityDespawns(player.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNotSent(Player p){
|
||||
FightPlayer fp = Fight.getFightPlayer(p);
|
||||
return fp == null || !fp.isLiving() || FightSystem.getFightState() == FightState.SPECTATE;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class PlayerChatListener extends BasicListener {
|
||||
}
|
||||
|
||||
private void broadcastChat(String message) {
|
||||
if (Config.recording)
|
||||
if (Config.recording())
|
||||
RecordSystem.chat(message);
|
||||
BaseComponent[] msg = TextComponent.fromLegacyText(message);
|
||||
for(Player p : Bukkit.getOnlinePlayers())
|
||||
|
126
FightSystem_Main/src/de/steamwar/fightsystem/record/FileRecorder.java
Normale Datei
126
FightSystem_Main/src/de/steamwar/fightsystem/record/FileRecorder.java
Normale Datei
@ -0,0 +1,126 @@
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
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();
|
||||
File file = new File(FightSystem.getPlugin().getDataFolder(), "recording");
|
||||
try{
|
||||
file.createNewFile();
|
||||
outputStream = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(file)));
|
||||
}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);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,41 +3,57 @@ package de.steamwar.fightsystem.record;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import net.minecraft.server.v1_15_R1.BlockPosition;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
|
||||
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.util.Vector;
|
||||
|
||||
public class RecordSystem {
|
||||
private RecordSystem(){}
|
||||
|
||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||
|
||||
public static void init(){
|
||||
if(!Config.event())
|
||||
if(!Config.recording())
|
||||
return;
|
||||
|
||||
Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), RecordSystem::checkWorldState, 1, 1);
|
||||
new SpectateConnection();
|
||||
new FileRecorder();
|
||||
}
|
||||
|
||||
/*
|
||||
* PlayerJoinPacket (0x00) + int EntityId + int SWUserId
|
||||
* EntityMovePacket (0x01) + int EntityId + double x, y, z + float pitch, yaw
|
||||
* 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
|
||||
*
|
||||
* TODO (Player-Oriented):
|
||||
* ItemInHandPacket (0x03) + int EntityId
|
||||
* LeftClickPacket (0x04) + int EntityId
|
||||
* RightClickPacket (0x05) + int EntityId TODO Bow spanning
|
||||
*
|
||||
* TODO: Block Change Recordings
|
||||
*
|
||||
*
|
||||
*
|
||||
* 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 soundType + float volume, pitch
|
||||
*
|
||||
*
|
||||
* ChatPacket (0xa0) + String message
|
||||
* ActionBarPacket (0xa1) + String message
|
||||
* SystemPacket (0xa2) + String message
|
||||
*
|
||||
* TickPacket (0xff)
|
||||
* */
|
||||
|
||||
public static synchronized void playerJoins(Player p){
|
||||
@ -59,6 +75,7 @@ public class RecordSystem {
|
||||
Recorder.rDouble(location.getZ());
|
||||
Recorder.rFloat(location.getPitch());
|
||||
Recorder.rFloat(location.getYaw());
|
||||
Recorder.rByte((int)(((CraftEntity)e).getHandle().getHeadRotation() * 256 / 360));
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
@ -68,25 +85,99 @@ public class RecordSystem {
|
||||
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);
|
||||
Recorder.rInt(e.getEntityId());
|
||||
entityMoves(e);
|
||||
entitySpeed(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 blockChange(BlockPosition pos, int blockState){
|
||||
Recorder.rByte(0x30);
|
||||
Recorder.rInt(pos.getX());
|
||||
Recorder.rByte(pos.getY());
|
||||
Recorder.rInt(pos.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 chat(String s) {
|
||||
Recorder.rByte(0xA0);
|
||||
Recorder.rByte(0xa0);
|
||||
Recorder.rString(s);
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
public static synchronized void actionBar(String s) {
|
||||
Recorder.rByte(0xA1);
|
||||
Recorder.rByte(0xa1);
|
||||
Recorder.rString(s);
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
public static synchronized void systemChat(String s) {
|
||||
Recorder.rByte(0xA2);
|
||||
Recorder.rByte(0xa2);
|
||||
Recorder.rString(s);
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
public static synchronized void tick(){
|
||||
Recorder.rByte(0xff);
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
public static synchronized void blockChange(Block block){
|
||||
blockChange(((CraftBlock)block).getPosition(), net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS()));
|
||||
}
|
||||
|
||||
private static void checkWorldState(){
|
||||
//TODO: Entity position transmissions
|
||||
tick();
|
||||
for(TNTPrimed tnt : WORLD.getEntitiesByClass(TNTPrimed.class)){
|
||||
entityMoves(tnt);
|
||||
entitySpeed(tnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,10 @@ public abstract class Recorder {
|
||||
|
||||
private static List<Recorder> 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));
|
||||
}
|
||||
@ -52,6 +56,7 @@ public abstract class Recorder {
|
||||
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);
|
||||
|
@ -24,6 +24,16 @@ public class SpectateConnection extends Recorder{
|
||||
}
|
||||
}
|
||||
|
||||
@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{
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren