Merge pull request 'Omni-Replay' (#280) from spectate2.0 into master
Reviewed-on: #280 Reviewed-by: YoyoNow <jwsteam@nidido.de>
Dieser Commit ist enthalten in:
Commit
67296c29c2
@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.fightsystem.fight;
|
||||
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -27,6 +28,7 @@ import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -38,7 +40,6 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.utils.Region;
|
||||
import de.steamwar.sql.NoClipboardException;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@ -102,7 +103,7 @@ public class FightTeam_14 {
|
||||
}
|
||||
}
|
||||
|
||||
static void pasteSchematic(Clipboard clipboard, Region region, boolean rotate) throws NoClipboardException {
|
||||
static void pasteSchematic(Clipboard clipboard, Region region, boolean rotate) {
|
||||
BlockVector3 paste = BlockVector3.at(region.centerX(), region.getMinY(), region.centerZ());
|
||||
|
||||
World w = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||
@ -134,6 +135,23 @@ public class FightTeam_14 {
|
||||
e.flushSession();
|
||||
}
|
||||
|
||||
static void pasteChar(Clipboard character, int charOffset, int length, int x, int y, int z, AffineTransform aT){
|
||||
BlockVector3 offset = character.getRegion().getMinimumPoint().subtract(character.getOrigin());
|
||||
BlockVector3 v = BlockVector3.ZERO.subtract(- charOffset + length / 2, 0, 0).subtract(offset);
|
||||
v = aT.apply(v.toVector3()).toBlockPoint();
|
||||
v = v.add(x, y, z);
|
||||
|
||||
EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1);
|
||||
ClipboardHolder ch = new ClipboardHolder(character);
|
||||
ch.setTransform(aT);
|
||||
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(true).build());
|
||||
e.flushSession();
|
||||
}
|
||||
|
||||
static Clipboard loadSchem(NBTInputStream stream) throws IOException {
|
||||
return new SpongeSchematicReader(stream).read();
|
||||
}
|
||||
|
||||
public static boolean checkPistonMoving(Block block){
|
||||
return block.getType() == Material.MOVING_PISTON;
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import net.minecraft.server.v1_14_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_14_R1.EntityPose;
|
||||
import net.minecraft.server.v1_14_R1.IBlockData;
|
||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class RecordSystem_14 {
|
||||
private RecordSystem_14(){}
|
||||
|
||||
static int blockToId(Block block){
|
||||
return net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS());
|
||||
}
|
||||
|
||||
static Object getPose(boolean sneaking){
|
||||
return sneaking ? EntityPose.SNEAKING : EntityPose.STANDING;
|
||||
}
|
||||
|
||||
static void setBlock(World world, int x, int y, int z, int blockState){
|
||||
IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.fromId(blockState));
|
||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
||||
BlockPosition pos = new BlockPosition(x, y, z);
|
||||
cworld.removeTileEntity(pos);
|
||||
cworld.setTypeAndData(pos, blockData, 1042);
|
||||
cworld.getChunkProvider().flagDirty(pos);
|
||||
}
|
||||
}
|
@ -19,13 +19,34 @@
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import net.minecraft.server.v1_15_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_15_R1.EntityPose;
|
||||
import net.minecraft.server.v1_15_R1.IBlockData;
|
||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
static Object getPose(boolean sneaking){
|
||||
return sneaking ? EntityPose.CROUCHING : EntityPose.STANDING;
|
||||
}
|
||||
|
||||
static void setBlock(World world, int x, int y, int z, int blockState){
|
||||
IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.fromId(blockState));
|
||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
||||
BlockPosition pos = new BlockPosition(x, y, z);
|
||||
cworld.removeTileEntity(pos);
|
||||
cworld.setTypeAndData(pos, blockData, 1042);
|
||||
cworld.getChunkProvider().flagDirty(pos);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.fightsystem.fight;
|
||||
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
@ -29,6 +30,7 @@ import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.SchematicReader;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
@ -37,7 +39,6 @@ import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.utils.Region;
|
||||
import de.steamwar.sql.NoClipboardException;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@ -99,7 +100,7 @@ public class FightTeam_8 {
|
||||
}
|
||||
}
|
||||
|
||||
static void pasteSchematic(Clipboard clipboard, Region paste, boolean rotate) throws NoClipboardException {
|
||||
static void pasteSchematic(Clipboard clipboard, Region paste, boolean rotate) {
|
||||
World w = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||
Vector dimensions = clipboard.getDimensions();
|
||||
Vector v = new Vector(paste.centerX(), paste.getMinY(), paste.centerZ());
|
||||
@ -129,6 +130,24 @@ public class FightTeam_8 {
|
||||
e.flushQueue();
|
||||
}
|
||||
|
||||
static void pasteChar(Clipboard character, int charOffset, int length, int x, int y, int z, AffineTransform aT){
|
||||
World w = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||
Vector offset = character.getRegion().getMinimumPoint().subtract(character.getOrigin());
|
||||
Vector v = Vector.ZERO.subtract(- charOffset + length / 2, 0, 0).subtract(offset);
|
||||
v = aT.apply(v).toBlockPoint();
|
||||
v = v.add(x, y, z);
|
||||
|
||||
EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(w, -1);
|
||||
ClipboardHolder ch = new ClipboardHolder(character, w.getWorldData());
|
||||
ch.setTransform(aT);
|
||||
Operations.completeBlindly(ch.createPaste(e, w.getWorldData()).to(v).build());
|
||||
e.flushQueue();
|
||||
}
|
||||
|
||||
static Clipboard loadSchem(NBTInputStream stream) throws IOException {
|
||||
return new SchematicReader(stream).read(new BukkitWorld(Bukkit.getWorlds().get(0)).getWorldData());
|
||||
}
|
||||
|
||||
public static boolean checkPistonMoving(Block block){
|
||||
return block.getType() == Material.PISTON_MOVING_PIECE;
|
||||
}
|
||||
|
@ -19,13 +19,18 @@
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
class RecordSystem_8 {
|
||||
private RecordSystem_8(){}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static int blockToId(Block block){
|
||||
return block.getTypeId() << 4 + block.getData();
|
||||
}
|
||||
|
||||
static void setBlock(World world, int x, int y, int z, int blockState){
|
||||
world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ public enum ArenaMode {
|
||||
EVENT,
|
||||
TEST,
|
||||
CHECK,
|
||||
PREPARE;
|
||||
PREPARE,
|
||||
REPLAY;
|
||||
|
||||
public static final Set<ArenaMode> All = Collections.unmodifiableSet(EnumSet.allOf(ArenaMode.class));
|
||||
|
||||
@ -39,14 +40,16 @@ public enum ArenaMode {
|
||||
public static final Set<ArenaMode> Test = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK));
|
||||
public static final Set<ArenaMode> Ranked = Collections.unmodifiableSet(EnumSet.of(RANKED));
|
||||
public static final Set<ArenaMode> Prepare = Collections.unmodifiableSet(EnumSet.of(PREPARE));
|
||||
public static final Set<ArenaMode> Replay = Collections.unmodifiableSet(EnumSet.of(REPLAY));
|
||||
|
||||
public static final Set<ArenaMode> AntiReplay = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(REPLAY)));
|
||||
public static final Set<ArenaMode> Replayable = Collections.unmodifiableSet(EnumSet.of(REPLAY, TEST));
|
||||
public static final Set<ArenaMode> AntiTest = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK)));
|
||||
public static final Set<ArenaMode> AntiEvent = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT)));
|
||||
public static final Set<ArenaMode> AntiPrepare = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PREPARE)));
|
||||
public static final Set<ArenaMode> VariableTeams = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(RANKED, EVENT)));
|
||||
public static final Set<ArenaMode> RankedEvent = Collections.unmodifiableSet(EnumSet.of(RANKED, EVENT));
|
||||
public static final Set<ArenaMode> Restartable = Collections.unmodifiableSet(EnumSet.of(NORMAL, RANKED));
|
||||
public static final Set<ArenaMode> Fight = Collections.unmodifiableSet(EnumSet.of(NORMAL, RANKED, EVENT));
|
||||
public static final Set<ArenaMode> VariableTeams = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(RANKED, EVENT, REPLAY)));
|
||||
public static final Set<ArenaMode> RankedEvent = Collections.unmodifiableSet(EnumSet.of(RANKED, EVENT, REPLAY));
|
||||
public static final Set<ArenaMode> Restartable = Collections.unmodifiableSet(EnumSet.of(NORMAL, RANKED, REPLAY));
|
||||
public static final Set<ArenaMode> SoloLeader = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK, PREPARE));
|
||||
public static final Set<ArenaMode> NotOnBau = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE)));
|
||||
public static final Set<ArenaMode> NotOnBau = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE, REPLAY)));
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class Config {
|
||||
|
||||
private static final int BlueToRedX;
|
||||
private static final int BlueToRedY;
|
||||
public static final int BlueToRedZ;
|
||||
private static final int BlueToRedZ;
|
||||
|
||||
public static final int PreperationArea;
|
||||
public static final int WaterDepth;
|
||||
@ -118,7 +118,7 @@ public class Config {
|
||||
public static final int EventTeamRedID;
|
||||
public static final boolean BothTeamsPublic;
|
||||
public static final int MaximumTeamMembers;
|
||||
public static final boolean SpectateSystem;
|
||||
public static final boolean LiveReplay;
|
||||
|
||||
//check parameter
|
||||
public static final int CheckSchemID;
|
||||
@ -126,9 +126,10 @@ public class Config {
|
||||
|
||||
public static final ArenaMode mode;
|
||||
|
||||
//live recorder parameter
|
||||
//replay system parameter
|
||||
public static final String spectateIP = "127.0.0.1";
|
||||
public static final int spectatePort = 2222;
|
||||
public static final int ReplayID;
|
||||
|
||||
static{
|
||||
if(!new File(IFightSystem.getPlugin().getDataFolder(), System.getProperty("config", "config.yml")).exists()) {
|
||||
@ -335,7 +336,7 @@ public class Config {
|
||||
OnlyPublicSchematics = event.publicSchemsOnly();
|
||||
MaximumTeamMembers = event.getMaximumTeamMembers();
|
||||
}
|
||||
SpectateSystem = event.spectateSystem();
|
||||
LiveReplay = event.spectateSystem();
|
||||
}else{
|
||||
//No event
|
||||
TeamRedColor = config.getString("Output.TeamRedPrefix");
|
||||
@ -347,7 +348,7 @@ public class Config {
|
||||
EventTeamRedID = 0;
|
||||
BothTeamsPublic = true;
|
||||
MaximumTeamMembers = Integer.MAX_VALUE;
|
||||
SpectateSystem = false;
|
||||
LiveReplay = false;
|
||||
}
|
||||
|
||||
String blueLeader = System.getProperty("blueLeader", null);
|
||||
@ -364,6 +365,7 @@ public class Config {
|
||||
CheckSchemID = Integer.parseInt(System.getProperty("checkSchemID", "0"));
|
||||
PrepareSchemID = Integer.parseInt(System.getProperty("prepareSchemID", "0"));
|
||||
Ranked = Boolean.parseBoolean(System.getProperty("ranked", "false"));
|
||||
ReplayID = Integer.parseInt(System.getProperty("replay", "0"));
|
||||
|
||||
if(Ranked){
|
||||
mode = ArenaMode.RANKED;
|
||||
@ -375,6 +377,8 @@ public class Config {
|
||||
mode = ArenaMode.EVENT;
|
||||
}else if(EventKampfID == -1){
|
||||
mode = ArenaMode.TEST;
|
||||
}else if(ReplayID != 0){
|
||||
mode = ArenaMode.REPLAY;
|
||||
}else{
|
||||
mode = ArenaMode.NORMAL;
|
||||
}
|
||||
@ -383,7 +387,10 @@ public class Config {
|
||||
public static boolean test(){
|
||||
return ArenaMode.Test.contains(mode);
|
||||
}
|
||||
public static boolean recording(){
|
||||
return mode == ArenaMode.EVENT;
|
||||
public static boolean replayserver(){
|
||||
return ReplayID == -1;
|
||||
}
|
||||
public static boolean blueNegZ(){
|
||||
return BlueToRedZ > 0;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class IFight {
|
||||
private static IFightTeam redTeam;
|
||||
private static IFightTeam blueTeam;
|
||||
|
||||
static void init(IFightTeam redTeam, IFightTeam blueTeam){
|
||||
public static void init(IFightTeam redTeam, IFightTeam blueTeam){
|
||||
IFight.redTeam = redTeam;
|
||||
IFight.blueTeam = blueTeam;
|
||||
}
|
||||
|
@ -71,6 +71,10 @@ public class Region {
|
||||
return maxZ;
|
||||
}
|
||||
|
||||
public int getSizeZ() {
|
||||
return maxZ - minZ;
|
||||
}
|
||||
|
||||
public double posToChunk(int pos){
|
||||
return pos / 16.0;
|
||||
}
|
||||
@ -137,7 +141,11 @@ public class Region {
|
||||
}
|
||||
|
||||
public boolean in2dRegion(Block block){
|
||||
return minX <= block.getX() && block.getX() < maxX && minZ <= block.getZ() && block.getZ() <= maxZ;
|
||||
return in2dRegion(block.getX(), block.getZ());
|
||||
}
|
||||
|
||||
public boolean in2dRegion(int x, int z) {
|
||||
return minX <= x && x < maxX && minZ <= z && z <= maxZ;
|
||||
}
|
||||
|
||||
public boolean inRegion(Block block){
|
||||
|
@ -27,10 +27,10 @@ import de.steamwar.fightsystem.event.HellsBells;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.fight.FightWorld;
|
||||
import de.steamwar.fightsystem.fight.IFight;
|
||||
import de.steamwar.fightsystem.listener.Shutdown;
|
||||
import de.steamwar.fightsystem.listener.*;
|
||||
import de.steamwar.fightsystem.record.RecordSystem;
|
||||
import de.steamwar.fightsystem.record.Recorder;
|
||||
import de.steamwar.fightsystem.record.*;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.OneShotStateDependent;
|
||||
import de.steamwar.fightsystem.utils.EnterHandler;
|
||||
@ -58,8 +58,7 @@ public class FightSystem extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
Fight.init();
|
||||
RecordSystem.init();
|
||||
IFight.init(Fight.getRedTeam(), Fight.getBlueTeam());
|
||||
|
||||
new EntityDamage();
|
||||
new WaterRemover();
|
||||
@ -107,7 +106,6 @@ public class FightSystem extends JavaPlugin {
|
||||
new RankedPlayerLeftWincondition();
|
||||
new WinconditionPercentTimeout();
|
||||
|
||||
//noinspection InstantiationOfUtilityClass
|
||||
new HellsBells();
|
||||
|
||||
new NoPlayersOnlineCountdown();
|
||||
@ -127,12 +125,16 @@ public class FightSystem extends JavaPlugin {
|
||||
new AkCommand();
|
||||
new LeaderCommand();
|
||||
new LockschemCommand();
|
||||
new ReplayCommand();
|
||||
new StateCommand();
|
||||
new SkipCommand();
|
||||
new WinCommand();
|
||||
|
||||
new OneShotStateDependent(ArenaMode.All, FightState.PreRunning, () -> Bukkit.broadcastMessage(PREFIX + "§aDer Kampf beginnt!"));
|
||||
new OneShotStateDependent(ArenaMode.All, FightState.Running, () -> Bukkit.broadcastMessage(PREFIX + "§aArena freigegeben!"));
|
||||
new LiveRecorder();
|
||||
new FileRecorder();
|
||||
|
||||
new OneShotStateDependent(ArenaMode.AntiReplay, FightState.PreRunning, () -> Bukkit.broadcastMessage(PREFIX + "§aDer Kampf beginnt!"));
|
||||
new OneShotStateDependent(ArenaMode.AntiReplay, FightState.Running, () -> Bukkit.broadcastMessage(PREFIX + "§aArena freigegeben!"));
|
||||
new OneShotStateDependent(ArenaMode.AntiTest, FightState.Running, FightStatistics::start);
|
||||
|
||||
try {
|
||||
@ -152,12 +154,15 @@ public class FightSystem extends JavaPlugin {
|
||||
}else{
|
||||
Fight.getBlueTeam().setSchem(Schematic.getSchemFromDB(Config.PrepareSchemID));
|
||||
}
|
||||
}else if(Config.mode == ArenaMode.REPLAY) {
|
||||
FightWorld.forceLoad();
|
||||
FileSource.startReplay();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
Recorder.closeAll();
|
||||
GlobalRecorder.getInstance().close();
|
||||
}
|
||||
|
||||
public static void setPreLeaderState() {
|
||||
@ -184,24 +189,26 @@ public class FightSystem extends JavaPlugin {
|
||||
}
|
||||
|
||||
public static void setSpectateState(FightTeam winFightTeam, String windescription) {
|
||||
if(!PacketProcessor.isReplaying()){
|
||||
if(winFightTeam != null) {
|
||||
Bukkit.broadcastMessage(PREFIX + "§aDas Team " + winFightTeam.getColoredName() + " §ahat gewonnen!");
|
||||
} else {
|
||||
Bukkit.broadcastMessage(PREFIX + "§aKein Team hat gewonnen!");
|
||||
}
|
||||
}
|
||||
|
||||
FightState.setFightState(FightState.SPECTATE);
|
||||
|
||||
if(winFightTeam != null) {
|
||||
Bukkit.broadcastMessage(PREFIX + "§aDas Team " + winFightTeam.getColoredName() + " §ahat gewonnen!");
|
||||
} else {
|
||||
Bukkit.broadcastMessage(PREFIX + "§aKein Team hat gewonnen!");
|
||||
}
|
||||
if(!Config.test() && !PacketProcessor.isReplaying()){
|
||||
if(Config.mode == ArenaMode.EVENT) {
|
||||
if (winFightTeam == null)
|
||||
getEventFight().setErgebnis(0);
|
||||
else if (winFightTeam.isBlue())
|
||||
getEventFight().setErgebnis(1);
|
||||
else
|
||||
getEventFight().setErgebnis(2);
|
||||
}
|
||||
|
||||
if(Config.mode == ArenaMode.EVENT) {
|
||||
if (winFightTeam == null)
|
||||
getEventFight().setErgebnis(0);
|
||||
else if (winFightTeam.isBlue())
|
||||
getEventFight().setErgebnis(1);
|
||||
else
|
||||
getEventFight().setErgebnis(2);
|
||||
}
|
||||
|
||||
if(!Config.test()){
|
||||
FightStatistics.saveStats(winFightTeam, windescription);
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import org.bukkit.entity.Player;
|
||||
public class KitCommand implements CommandExecutor {
|
||||
|
||||
public KitCommand() {
|
||||
new StateDependentCommand(ArenaMode.All, FightState.Setup, "kit", this);
|
||||
new StateDependentCommand(ArenaMode.AntiReplay, FightState.Setup, "kit", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,7 +30,7 @@ import org.bukkit.entity.Player;
|
||||
public class LeaveCommand implements CommandExecutor {
|
||||
|
||||
public LeaveCommand() {
|
||||
new StateDependentCommand(ArenaMode.All, FightState.Setup, "leave", this);
|
||||
new StateDependentCommand(ArenaMode.AntiReplay, FightState.Setup, "leave", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,7 +37,7 @@ import org.bukkit.entity.Player;
|
||||
public class LockschemCommand implements CommandExecutor {
|
||||
|
||||
public LockschemCommand() {
|
||||
new StateDependentCommand(ArenaMode.All, FightState.All, "lockschem", this);
|
||||
new StateDependentCommand(ArenaMode.AntiReplay, FightState.All, "lockschem", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.commands;
|
||||
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.record.FileRecorder;
|
||||
import de.steamwar.fightsystem.record.FileSource;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentCommand;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ReplayCommand implements CommandExecutor {
|
||||
|
||||
public ReplayCommand() {
|
||||
new StateDependentCommand(ArenaMode.Replayable, FightState.All, "replay", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if(!(sender instanceof Player)) {
|
||||
return false;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
|
||||
if(!Config.test()){
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
if(!user.getUserGroup().isTeamGroup()){
|
||||
sender.sendMessage(FightSystem.PREFIX + "§cDieser Befehl ist zu diesem Kampfzeitpunkt nicht verfügbar.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!FileRecorder.getFile().exists()){
|
||||
sender.sendMessage(FightSystem.PREFIX + "§cKein Replay vorhanden.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
new FileSource(FileRecorder.getFile());
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(FightSystem.PREFIX + "§cDas Replay konnte nicht gestartet werden.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import de.steamwar.core.Core;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.listener.BasicListener;
|
||||
import de.steamwar.fightsystem.record.RecordSystem;
|
||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -108,7 +108,7 @@ public abstract class Countdown {
|
||||
}
|
||||
|
||||
private void broadcast(String message){
|
||||
RecordSystem.actionBar(message);
|
||||
GlobalRecorder.getInstance().actionBar(message);
|
||||
BaseComponent[] msg = TextComponent.fromLegacyText(message);
|
||||
for(Player p : Bukkit.getOnlinePlayers())
|
||||
BasicListener.toActionbar(p, msg);
|
||||
|
@ -34,8 +34,8 @@ public class NoPlayersOnlineCountdown extends Countdown implements Listener {
|
||||
public NoPlayersOnlineCountdown() {
|
||||
super(Config.NoPlayerOnlineDuration, null, false);
|
||||
|
||||
new StateDependentListener(ArenaMode.All, FightState.PreLeaderSetup, this);
|
||||
new StateDependentCountdown(ArenaMode.All, FightState.PreLeaderSetup, this){
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this);
|
||||
new StateDependentCountdown(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this){
|
||||
@Override
|
||||
public void enable() {
|
||||
if(Bukkit.getOnlinePlayers().isEmpty())
|
||||
|
@ -29,7 +29,7 @@ public class PreRunningCountdown extends Countdown {
|
||||
|
||||
public PreRunningCountdown() {
|
||||
super(Config.PreFightDuration, SWSound.BLOCK_NOTE_PLING, true);
|
||||
new StateDependentCountdown(ArenaMode.All, FightState.PreRunning, this);
|
||||
new StateDependentCountdown(ArenaMode.AntiReplay, FightState.PreRunning, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -29,7 +29,7 @@ public class PreSchemCountdown extends Countdown {
|
||||
|
||||
public PreSchemCountdown() {
|
||||
super(Config.PreSchemPasteDuration, SWSound.BLOCK_NOTE_PLING, false);
|
||||
new StateDependentCountdown(ArenaMode.All, FightState.PreSchemSetup, this);
|
||||
new StateDependentCountdown(ArenaMode.AntiReplay, FightState.PreSchemSetup, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,10 +28,12 @@ import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.record.RecordSystem;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -45,10 +47,6 @@ public class Fight {
|
||||
private static final FightTeam redTeam = new FightTeam(Config.TeamRedName, Config.TeamRedColor, Config.TeamRedSpawn, Config.RedPasteRegion, Config.RedExtendRegion, Config.RedRotate, false, Config.RedLeader);
|
||||
private static final FightTeam blueTeam = new FightTeam(Config.TeamBlueName, Config.TeamBlueColor, Config.TeamBlueSpawn, Config.BluePasteRegion, Config.BlueExtendRegion, Config.BlueRotate, true, Config.BlueLeader);
|
||||
|
||||
public static void init(){
|
||||
IFight.init(redTeam, blueTeam);
|
||||
}
|
||||
|
||||
public static FightTeam getPlayerTeam(Player player) {
|
||||
if(redTeam.isPlayerInTeam(player))
|
||||
return redTeam;
|
||||
@ -91,7 +89,7 @@ public class Fight {
|
||||
}
|
||||
|
||||
public static void playSound(Sound sound, float volume, float pitch) {
|
||||
RecordSystem.soundAtPlayer(sound.name(), volume, pitch);
|
||||
GlobalRecorder.getInstance().soundAtPlayer(sound.name(), volume, pitch);
|
||||
//volume: max. 100, pitch: max. 2
|
||||
Bukkit.getServer().getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), sound, volume, pitch));
|
||||
}
|
||||
|
@ -19,35 +19,36 @@
|
||||
|
||||
package de.steamwar.fightsystem.fight;
|
||||
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import de.steamwar.core.VersionedCallable;
|
||||
import de.steamwar.core.VersionedRunnable;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.IFightSystem;
|
||||
import de.steamwar.fightsystem.record.RecordSystem;
|
||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.fightsystem.utils.ColorConverter;
|
||||
import de.steamwar.fightsystem.utils.Region;
|
||||
import de.steamwar.sql.NoClipboardException;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.*;
|
||||
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class FightSchematic extends StateDependent {
|
||||
|
||||
@ -80,10 +81,15 @@ public class FightSchematic extends StateDependent {
|
||||
clipboard = schem.load();
|
||||
} catch (IOException e) {
|
||||
team.broadcast(FightSystem.PREFIX + "§cKonnte die Schematic nicht laden!");
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Couldn't load Schematic " + schem.getSchemName(), e);
|
||||
Bukkit.getLogger().log(Level.SEVERE, e, () -> "Couldn't load Schematic " + schem.getSchemName());
|
||||
}
|
||||
}
|
||||
|
||||
public void setSchematic(int schemId, Clipboard clipboard) {
|
||||
this.schematic = schemId;
|
||||
this.clipboard = clipboard;
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
schematic = 0;
|
||||
clipboard = null;
|
||||
@ -109,50 +115,111 @@ public class FightSchematic extends StateDependent {
|
||||
}
|
||||
|
||||
if(team.isBlue())
|
||||
RecordSystem.blueSchem(schematic);
|
||||
GlobalRecorder.getInstance().blueSchem(schematic);
|
||||
else
|
||||
RecordSystem.redSchem(schematic);
|
||||
GlobalRecorder.getInstance().redSchem(schematic);
|
||||
|
||||
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::paste);
|
||||
}
|
||||
|
||||
private void replaceTeamColor(Clipboard clipboard){
|
||||
DyeColor c = ArenaMode.AntiPrepare.contains(Config.mode) ? ColorConverter.chat2dye(team.getColor()) : DyeColor.PINK;
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> {
|
||||
try {
|
||||
FightTeam_8.replaceTeamColor(clipboard, c);
|
||||
} catch (WorldEditException ex) {
|
||||
throw new SecurityException("Error recoloring schematic", ex);
|
||||
}
|
||||
}, 8),
|
||||
new VersionedRunnable(() -> {
|
||||
try {
|
||||
FightTeam_12.replaceTeamColor(clipboard, c);
|
||||
} catch (WorldEditException ex) {
|
||||
throw new SecurityException("Error recoloring schematic", ex);
|
||||
}
|
||||
}, 12),
|
||||
new VersionedRunnable(() -> {
|
||||
try {
|
||||
FightTeam_14.replaceTeamColor(clipboard, c);
|
||||
} catch (WorldEditException ex) {
|
||||
throw new SecurityException("Error recoloring schematic", ex);
|
||||
}
|
||||
}, 14));
|
||||
}
|
||||
|
||||
private void paste(){
|
||||
FreezeWorld freezer = new FreezeWorld();
|
||||
DyeColor c = ArenaMode.AntiPrepare.contains(Config.mode) ? ColorConverter.chat2dye(team.getColor()) : DyeColor.PINK;
|
||||
|
||||
try {
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> {
|
||||
try {
|
||||
FightTeam_8.replaceTeamColor(clipboard, c);
|
||||
FightTeam_8.pasteSchematic(clipboard, region, rotate);
|
||||
} catch (NoClipboardException | WorldEditException ex) {
|
||||
throw new SecurityException("Error pasting schematic", ex);
|
||||
}
|
||||
}, 8), new VersionedRunnable(() -> {
|
||||
try {
|
||||
FightTeam_12.replaceTeamColor(clipboard, c);
|
||||
FightTeam_8.pasteSchematic(clipboard, region, rotate);
|
||||
} catch (NoClipboardException | WorldEditException ex) {
|
||||
throw new SecurityException("Error pasting schematic", ex);
|
||||
}
|
||||
}, 12), new VersionedRunnable(() -> {
|
||||
try {
|
||||
FightTeam_14.replaceTeamColor(clipboard, c);
|
||||
FightTeam_14.pasteSchematic(clipboard, region, rotate);
|
||||
} catch (NoClipboardException | WorldEditException ex) {
|
||||
throw new SecurityException("Error pasting schematic", ex);
|
||||
}
|
||||
}, 14));
|
||||
replaceTeamColor(clipboard);
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> FightTeam_8.pasteSchematic(clipboard, region, rotate), 8),
|
||||
new VersionedRunnable(() -> FightTeam_14.pasteSchematic(clipboard, region, rotate), 14));
|
||||
} catch (SecurityException securityException) {
|
||||
Bukkit.broadcastMessage(FightSystem.PREFIX + "§cFehler beim Pasten der Schematic");
|
||||
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), FightSystem::setPreSchemState);
|
||||
throw securityException;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> HandlerList.unregisterAll(freezer), 3);
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), freezer::disable, 3);
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), team::teleportToSpawn, 40);
|
||||
}
|
||||
|
||||
private Clipboard loadTextSchem(String schemName){
|
||||
return VersionedCallable.call(new VersionedCallable<>(() -> FightTeam_8.loadSchem(new NBTInputStream(new GZIPInputStream(new FileInputStream(new File(FightSystem.getPlugin().getDataFolder(), "text/" + schemName + ".schematic"))))), 8),
|
||||
new VersionedCallable<>(() -> FightTeam_14.loadSchem(new NBTInputStream(new GZIPInputStream(new FileInputStream(new File(FightSystem.getPlugin().getDataFolder(), "text/" + schemName + ".schem"))))), 14));
|
||||
}
|
||||
|
||||
public void pasteTeamName(){
|
||||
List<Clipboard> characters = new ArrayList<>();
|
||||
for(char c : team.getName().toCharArray()){
|
||||
try {
|
||||
try {
|
||||
characters.add(loadTextSchem(c == '/' ? "slash" : String.valueOf(c)));
|
||||
} catch (RuntimeException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not display character {} due to missing file!", c);
|
||||
characters.add(loadTextSchem(""));
|
||||
}
|
||||
}catch (RuntimeException e) {
|
||||
throw new SecurityException("Could not load text", e);
|
||||
}
|
||||
}
|
||||
|
||||
//Calc character sizes
|
||||
int[] lengthes = new int[characters.size()];
|
||||
for(int i = 0; i < lengthes.length; i++)
|
||||
lengthes[i] = characters.get(i).getDimensions().getBlockX();
|
||||
|
||||
//Calc character offsets
|
||||
int[] offsets = new int[lengthes.length];
|
||||
int previousOffset = 0;
|
||||
for(int i = 0; i < offsets.length; i++){
|
||||
offsets[i] = previousOffset;
|
||||
previousOffset += lengthes[i] + 1; // 1 is the distance between characters
|
||||
}
|
||||
|
||||
int length = lengthes.length == 0 ? 0 : lengthes[lengthes.length - 1] + offsets[offsets.length - 1];
|
||||
|
||||
int z = team.getSchemRegion().centerZ();
|
||||
AffineTransform aT = new AffineTransform();
|
||||
|
||||
if(rotate){
|
||||
aT = aT.rotateY(180);
|
||||
z += team.getSchemRegion().getSizeZ() / 2;
|
||||
}else{
|
||||
z -= team.getSchemRegion().getSizeZ() / 2;
|
||||
}
|
||||
|
||||
for(int i = 0; i < characters.size(); i++){
|
||||
replaceTeamColor(characters.get(i));
|
||||
pasteChar(characters.get(i), offsets[i], length, team.getSchemRegion().centerX(), team.getExtendRegion().getMaxY(), z, aT);
|
||||
}
|
||||
}
|
||||
|
||||
private void pasteChar(Clipboard character, int charOffset, int length, int x, int y, int z, AffineTransform aT){
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> FightTeam_8.pasteChar(character, charOffset, length, x, y, z, aT), 8),
|
||||
new VersionedRunnable(() -> FightTeam_14.pasteChar(character, charOffset, length, x, y, z, aT), 14));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
if(!Config.ReplaceObsidianBedrock)
|
||||
@ -178,45 +245,4 @@ public class FightSchematic extends StateDependent {
|
||||
block.setType(replacement);
|
||||
});
|
||||
}
|
||||
|
||||
private static class FreezeWorld implements Listener {
|
||||
private FreezeWorld(){
|
||||
Bukkit.getPluginManager().registerEvents(this, IFightSystem.getPlugin());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPhysicsEvent(BlockPhysicsEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPistonExtend(BlockPistonExtendEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPistonRetract(BlockPistonRetractEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockGrow(BlockGrowEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRedstoneEvent(BlockRedstoneEvent e){
|
||||
e.setNewCurrent(e.getOldCurrent());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockDispense(BlockDispenseEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryMoveEvent(InventoryMoveItemEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.fightsystem.fight;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.comms.packets.TablistNamePacket;
|
||||
import de.steamwar.core.VersionedRunnable;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
@ -26,10 +27,10 @@ import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.countdown.Countdown;
|
||||
import de.steamwar.fightsystem.listener.BasicListener;
|
||||
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
||||
import de.steamwar.fightsystem.record.RecordSystem;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
||||
import de.steamwar.fightsystem.listener.PersonalKitCreator;
|
||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.fightsystem.utils.ItemBuilder;
|
||||
import de.steamwar.fightsystem.utils.Region;
|
||||
@ -54,9 +55,9 @@ public class FightTeam implements IFightTeam{
|
||||
private final Map<Player, FightPlayer> players = new HashMap<>();
|
||||
private final Set<Player> invited = new HashSet<>();
|
||||
|
||||
private final String name;
|
||||
private final String prefix;
|
||||
private final ChatColor color;
|
||||
private String name;
|
||||
private String prefix;
|
||||
private ChatColor color;
|
||||
private final FightSchematic schematic;
|
||||
private final Team team;
|
||||
private final boolean blue;
|
||||
@ -72,21 +73,19 @@ public class FightTeam implements IFightTeam{
|
||||
this.spawn = spawn;
|
||||
this.schemRegion = schemRegion;
|
||||
this.extendRegion = extendRegion;
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
this.ready = false;
|
||||
this.skip = false;
|
||||
this.blue = blue;
|
||||
this.designatedLeader = designatedLeader;
|
||||
this.color = ChatColor.getByChar(ChatColor.getLastColors(prefix).replace("§", ""));
|
||||
setPrefixAndName(prefix, name);
|
||||
this.schematic = new FightSchematic(this, rotate);
|
||||
new KitLoader();
|
||||
new SpectateHandler();
|
||||
|
||||
if(FightScoreboard.getScoreboard().getTeam(name) == null)
|
||||
team = FightScoreboard.getScoreboard().registerNewTeam(name);
|
||||
if(FightScoreboard.getBukkit().getTeam(name) == null)
|
||||
team = FightScoreboard.getBukkit().registerNewTeam(name);
|
||||
else
|
||||
team = FightScoreboard.getScoreboard().getTeam(name);
|
||||
team = FightScoreboard.getBukkit().getTeam(name);
|
||||
assert team != null;
|
||||
setTeamColor(team, color);
|
||||
//noinspection deprecation
|
||||
@ -94,6 +93,12 @@ public class FightTeam implements IFightTeam{
|
||||
team.setAllowFriendlyFire(false);
|
||||
}
|
||||
|
||||
public void setPrefixAndName(String prefix, String name){
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
this.color = ChatColor.getByChar(ChatColor.getLastColors(prefix).replace("§", ""));
|
||||
}
|
||||
|
||||
public UUID getDesignatedLeader(){
|
||||
return designatedLeader;
|
||||
}
|
||||
@ -166,7 +171,7 @@ public class FightTeam implements IFightTeam{
|
||||
|
||||
playerSet.forEach(this::addMember);
|
||||
|
||||
if(isLeaderless()){
|
||||
if(ArenaMode.VariableTeams.contains(Config.mode) && isLeaderless()){
|
||||
for(Player player : Bukkit.getOnlinePlayers()){
|
||||
if(Fight.getPlayerTeam(player) == null && canbeLeader(player)){
|
||||
addMember(player);
|
||||
@ -198,7 +203,7 @@ public class FightTeam implements IFightTeam{
|
||||
player.getInventory().setItem(7, new ItemBuilder(Material.BEACON).removeAllAttributs().setDisplayName("§eRespawn").build());
|
||||
if(ArenaMode.NotOnBau.contains(Config.mode))
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> new TablistNamePacket(SteamwarUser.get(player.getUniqueId()).getId(), prefix + player.getName()).send(player), 5);
|
||||
RecordSystem.playerJoins(player);
|
||||
GlobalRecorder.getInstance().playerJoins(player);
|
||||
TechHider.reloadChunks(player, chunksToReload, false);
|
||||
|
||||
if(isLeaderless())
|
||||
@ -216,7 +221,7 @@ public class FightTeam implements IFightTeam{
|
||||
if(fightPlayer.equals(leader))
|
||||
setLeader(null);
|
||||
|
||||
RecordSystem.entityDespawns(player);
|
||||
GlobalRecorder.getInstance().entityDespawns(player);
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.teleport(Config.SpecSpawn);
|
||||
player.getInventory().clear();
|
||||
@ -295,7 +300,15 @@ public class FightTeam implements IFightTeam{
|
||||
|
||||
public void pasteSchem(Schematic schematic){
|
||||
setSchem(schematic);
|
||||
testPasteAction();
|
||||
}
|
||||
|
||||
public void pasteSchem(int schemId, Clipboard clipboard){
|
||||
this.schematic.setSchematic(schemId, clipboard);
|
||||
testPasteAction();
|
||||
}
|
||||
|
||||
private void testPasteAction(){
|
||||
if(Config.test())
|
||||
this.schematic.enable();
|
||||
else if(Fight.getOpposite(this).hasSchematic()){
|
||||
@ -303,6 +316,10 @@ public class FightTeam implements IFightTeam{
|
||||
}
|
||||
}
|
||||
|
||||
public void pasteTeamName(){
|
||||
schematic.pasteTeamName();
|
||||
}
|
||||
|
||||
public void setSchem(Schematic schematic){
|
||||
this.schematic.setSchematic(schematic);
|
||||
broadcast(FightSystem.PREFIX + "§7Das §e" + Config.GameName + " " + schematic.getSchemName() + " §7wird für den Kampf verwendet!");
|
||||
@ -398,7 +415,7 @@ public class FightTeam implements IFightTeam{
|
||||
|
||||
private class KitLoader extends StateDependent {
|
||||
private KitLoader() {
|
||||
super(ArenaMode.All, FightState.Ingame);
|
||||
super(ArenaMode.AntiReplay, FightState.Ingame);
|
||||
register();
|
||||
}
|
||||
|
||||
@ -423,7 +440,7 @@ public class FightTeam implements IFightTeam{
|
||||
|
||||
private class SpectateHandler extends StateDependent {
|
||||
private SpectateHandler() {
|
||||
super(ArenaMode.All, FightState.Spectate);
|
||||
super(ArenaMode.AntiReplay, FightState.Spectate);
|
||||
register();
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class FightWorld extends StateDependent {
|
||||
paper = Bukkit.getVersion().contains("git-Paper");
|
||||
}
|
||||
|
||||
private final World world = Bukkit.getWorlds().get(0);
|
||||
private static final World world = Bukkit.getWorlds().get(0);
|
||||
|
||||
public FightWorld() {
|
||||
super(ArenaMode.Restartable, FightState.Schem);
|
||||
@ -56,6 +56,19 @@ public class FightWorld extends StateDependent {
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
resetWorld();
|
||||
}
|
||||
|
||||
public static void forceLoad(){
|
||||
Config.ArenaRegion.forEachChunk((cX, cZ) -> {
|
||||
world.loadChunk(cX, cZ);
|
||||
world.setChunkForceLoaded(cX, cZ, true);
|
||||
});
|
||||
world.setSpawnLocation(Config.SpecSpawn);
|
||||
world.setKeepSpawnInMemory(true);
|
||||
}
|
||||
|
||||
public static void resetWorld(){
|
||||
for(Entity entity : world.getEntities()){
|
||||
if(entity.getType() != EntityType.PLAYER){
|
||||
entity.remove();
|
||||
@ -68,7 +81,7 @@ public class FightWorld extends StateDependent {
|
||||
Bukkit.unloadWorld(backup, false);
|
||||
}
|
||||
|
||||
private void resetChunk(World backup, int x, int z, boolean isPaper){
|
||||
private static void resetChunk(World backup, int x, int z, boolean isPaper){
|
||||
VersionedRunnable.call(
|
||||
new VersionedRunnable(() -> FightWorld_8.resetChunk(world, backup, x, z, isPaper), 8),
|
||||
new VersionedRunnable(() -> FightWorld_9.resetChunk(world, backup, x, z, isPaper), 9),
|
||||
|
91
FightSystem_Main/src/de/steamwar/fightsystem/fight/FreezeWorld.java
Normale Datei
91
FightSystem_Main/src/de/steamwar/fightsystem/fight/FreezeWorld.java
Normale Datei
@ -0,0 +1,91 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.fight;
|
||||
|
||||
import de.steamwar.fightsystem.IFightSystem;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.*;
|
||||
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
|
||||
public class FreezeWorld implements Listener {
|
||||
public FreezeWorld(){
|
||||
Bukkit.getPluginManager().registerEvents(this, IFightSystem.getPlugin());
|
||||
}
|
||||
|
||||
public void disable(){
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPhysicsEvent(BlockPhysicsEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPistonExtend(BlockPistonExtendEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPistonRetract(BlockPistonRetractEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockGrow(BlockGrowEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRedstoneEvent(BlockRedstoneEvent e){
|
||||
e.setNewCurrent(e.getOldCurrent());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockDispense(BlockDispenseEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryMoveEvent(InventoryMoveItemEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockExplosion(BlockExplodeEvent e){
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void handlePlayerSwapHandItemsEvent(PlayerSwapHandItemsEvent event) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void handlePlayerInteract(PlayerInteractEvent event) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
@ -24,7 +24,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.record.GlobalRecorder;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
@ -64,7 +64,7 @@ public class Chat implements Listener {
|
||||
}
|
||||
|
||||
private void broadcastChat(String message) {
|
||||
RecordSystem.chat(message);
|
||||
GlobalRecorder.getInstance().chat(message);
|
||||
BaseComponent[] msg = TextComponent.fromLegacyText(message);
|
||||
for(Player p : Bukkit.getOnlinePlayers())
|
||||
BasicListener.toChat(p, msg);
|
||||
|
@ -42,7 +42,7 @@ public class EventJoin implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void playerLogin(PlayerLoginEvent event) {
|
||||
if(!Config.SpectateSystem)
|
||||
if(!Config.LiveReplay)
|
||||
return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
@ -89,7 +89,7 @@ public class EventJoin implements Listener {
|
||||
FightSystem.setEventLeiter(player);
|
||||
return;
|
||||
}
|
||||
if(Config.SpectateSystem)
|
||||
if(Config.LiveReplay)
|
||||
player.kickPlayer("§cDu bist kein Kampfteilnehmer");
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@ import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.countdown.Countdown;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.record.RecordSystem;
|
||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||
import de.steamwar.fightsystem.record.PacketProcessor;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
@ -43,20 +44,27 @@ import java.util.*;
|
||||
|
||||
public class FightScoreboard implements Listener, ScoreboardCallback {
|
||||
|
||||
public static Scoreboard getBukkit() {
|
||||
return Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard();
|
||||
}
|
||||
|
||||
private static final Set<FightState> fullScoreboard = EnumSet.of(FightState.RUNNING, FightState.SPECTATE);
|
||||
private static FightScoreboard scoreboard;
|
||||
|
||||
public static FightScoreboard getScoreboard(){
|
||||
return scoreboard;
|
||||
}
|
||||
|
||||
private int index = 0;
|
||||
|
||||
private String title = "";
|
||||
private final HashMap<String, Integer> scores = new HashMap<>();
|
||||
|
||||
public static Scoreboard getScoreboard() {
|
||||
return Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard();
|
||||
}
|
||||
|
||||
public FightScoreboard(){
|
||||
new StateDependentListener(ArenaMode.All, FightState.All, this);
|
||||
new StateDependentTask(ArenaMode.All, FightState.All, this::updateScoreboard, 0, 20);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this);
|
||||
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, this::updateScoreboard, 0, 20);
|
||||
scoreboard = this;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -105,7 +113,9 @@ public class FightScoreboard implements Listener, ScoreboardCallback {
|
||||
}
|
||||
|
||||
private void updateScoreboard() {
|
||||
scores.clear();
|
||||
if(PacketProcessor.isReplaying())
|
||||
return;
|
||||
|
||||
if ((index++ / 5) % 2 == 0) {
|
||||
generalScoreboard();
|
||||
} else {
|
||||
@ -115,14 +125,15 @@ public class FightScoreboard implements Listener, ScoreboardCallback {
|
||||
}
|
||||
}
|
||||
|
||||
private void setTitle(String t) {
|
||||
public void setTitle(String t) {
|
||||
scores.clear();
|
||||
title = t;
|
||||
RecordSystem.scoreboardTitle(t);
|
||||
GlobalRecorder.getInstance().scoreboardTitle(t);
|
||||
}
|
||||
|
||||
private void addScore(String string, int i) {
|
||||
public void addScore(String string, int i) {
|
||||
scores.put(string, i);
|
||||
RecordSystem.scoreboardData(string, i);
|
||||
GlobalRecorder.getInstance().scoreboardData(string, i);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,7 +35,7 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
public class HotbarGUI implements Listener {
|
||||
|
||||
public HotbarGUI() {
|
||||
new StateDependentListener(ArenaMode.All, FightState.Setup, this);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Setup, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -36,7 +36,7 @@ import java.util.Objects;
|
||||
public class InFightDamage implements Listener {
|
||||
|
||||
public InFightDamage() {
|
||||
new StateDependentListener(ArenaMode.All, FightState.Running, this);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -40,7 +40,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
public class InFightInventory implements Listener {
|
||||
|
||||
public InFightInventory() {
|
||||
new StateDependentListener(ArenaMode.All, FightState.Running, this);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -26,7 +26,7 @@ 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.record.GlobalRecorder;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -40,7 +40,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
public class IngameDeath implements Listener {
|
||||
|
||||
public IngameDeath() {
|
||||
new StateDependentListener(ArenaMode.All, FightState.Ingame, this);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Ingame, this);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
@ -71,7 +71,7 @@ public class IngameDeath implements Listener {
|
||||
if(fightPlayer.isLiving()) {
|
||||
Bukkit.broadcastMessage(FightSystem.PREFIX + "§cDer Spieler " + team.getPrefix() + player.getName() + " §chat den Kampf verlassen!");
|
||||
team.getFightPlayer(player).setOut();
|
||||
RecordSystem.entityDespawns(player);
|
||||
GlobalRecorder.getInstance().entityDespawns(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,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.REntity;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
@ -81,6 +82,8 @@ public class Permanent implements Listener {
|
||||
if(ArenaMode.NotOnBau.contains(Config.mode))
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> new TablistNamePacket(SteamwarUser.get(player.getUniqueId()).getId(), "§7" + player.getName()).send(player), 5);
|
||||
}
|
||||
|
||||
REntity.playerJoins(player);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -25,15 +25,16 @@ import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
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.record.GlobalRecorder;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -55,6 +56,7 @@ public class Recording implements Listener {
|
||||
|
||||
private static final int AIR = 0;
|
||||
private static final Random random = new Random();
|
||||
private static final World world = Bukkit.getWorlds().get(0);
|
||||
private static final PacketAdapter BOW_PACKET_PROCESSOR = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.BLOCK_PLACE) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
@ -66,23 +68,22 @@ public class Recording implements Listener {
|
||||
(hand == EnumWrappers.Hand.OFF_HAND && p.getInventory().getItemInOffHand().getType() == Material.BOW)))
|
||||
return;
|
||||
|
||||
RecordSystem.bowSpan(p, true, hand != EnumWrappers.Hand.MAIN_HAND);
|
||||
GlobalRecorder.getInstance().bowSpan(p, true, hand != EnumWrappers.Hand.MAIN_HAND);
|
||||
}
|
||||
};
|
||||
|
||||
private static final PacketAdapter BOW_PACKET_DEDRAW_PROCESSOR = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.BLOCK_DIG) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent e) {
|
||||
PacketContainer packetDig = e.getPacket();
|
||||
if(packetDig.getPlayerDigTypes().read(0) == EnumWrappers.PlayerDigType.RELEASE_USE_ITEM) {
|
||||
RecordSystem.bowSpan(e.getPlayer(), false, false);
|
||||
GlobalRecorder.getInstance().bowSpan(e.getPlayer(), false, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public Recording() {
|
||||
new StateDependentListener(Config.recording(), FightState.All, this);
|
||||
new StateDependent(Config.recording(), FightState.Ingame){
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this);
|
||||
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame){
|
||||
@Override
|
||||
public void enable() {
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
@ -98,7 +99,7 @@ public class Recording implements Listener {
|
||||
despawnTNT();
|
||||
}
|
||||
}.register();
|
||||
new StateDependent(Config.recording(), FightState.Ingame) {
|
||||
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
|
||||
@Override
|
||||
public void enable() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(BOW_PACKET_PROCESSOR);
|
||||
@ -111,6 +112,17 @@ public class Recording implements Listener {
|
||||
ProtocolLibrary.getProtocolManager().removePacketListener(BOW_PACKET_DEDRAW_PROCESSOR);
|
||||
}
|
||||
}.register();
|
||||
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
|
||||
GlobalRecorder.getInstance().tick();
|
||||
|
||||
if(FightState.getFightState() == FightState.SPECTATE || !GlobalRecorder.getInstance().recording())
|
||||
return;
|
||||
|
||||
for(TNTPrimed tnt : world.getEntitiesByClass(TNTPrimed.class)){
|
||||
GlobalRecorder.getInstance().entityMoves(tnt);
|
||||
GlobalRecorder.getInstance().entitySpeed(tnt);
|
||||
}
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -118,7 +130,7 @@ public class Recording implements Listener {
|
||||
if(isNotSent(e.getPlayer()))
|
||||
return;
|
||||
|
||||
RecordSystem.entityMoves(e.getPlayer());
|
||||
GlobalRecorder.getInstance().entityMoves(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
@ -126,12 +138,12 @@ public class Recording implements Listener {
|
||||
if(isNotSent(e.getEntity()))
|
||||
return;
|
||||
|
||||
RecordSystem.entityDespawns(e.getEntity());
|
||||
GlobalRecorder.getInstance().entityDespawns(e.getEntity());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBroadcast(BroadcastMessageEvent e){
|
||||
RecordSystem.systemChat(e.getMessage());
|
||||
GlobalRecorder.getInstance().systemChat(e.getMessage());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -139,7 +151,7 @@ public class Recording implements Listener {
|
||||
if(isNotSent(e.getPlayer()))
|
||||
return;
|
||||
|
||||
RecordSystem.playerSneak(e.getPlayer(), e.isSneaking());
|
||||
GlobalRecorder.getInstance().playerSneak(e.getPlayer(), e.isSneaking());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -148,7 +160,7 @@ public class Recording implements Listener {
|
||||
return;
|
||||
|
||||
if(e.getAnimationType() == PlayerAnimationType.ARM_SWING)
|
||||
RecordSystem.entityAnimation(e.getPlayer(), AIR);
|
||||
GlobalRecorder.getInstance().entityAnimation(e.getPlayer(), AIR);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -160,10 +172,10 @@ public class Recording implements Listener {
|
||||
if(isNotSent(p))
|
||||
return;
|
||||
|
||||
RecordSystem.damageAnimation(p);
|
||||
GlobalRecorder.getInstance().damageAnimation(p);
|
||||
|
||||
if(e.getCause() == EntityDamageEvent.DamageCause.FIRE_TICK || e.getCause() == EntityDamageEvent.DamageCause.FIRE)
|
||||
RecordSystem.setOnFire(p, false);
|
||||
GlobalRecorder.getInstance().setOnFire(p, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -175,22 +187,21 @@ public class Recording implements Listener {
|
||||
if(isNotSent(p))
|
||||
return;
|
||||
|
||||
RecordSystem.setOnFire(p, false);
|
||||
GlobalRecorder.getInstance().setOnFire(p, false);
|
||||
}
|
||||
|
||||
@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());
|
||||
GlobalRecorder.getInstance().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());
|
||||
GlobalRecorder.getInstance().blockChange(e.getBlock());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -199,9 +210,9 @@ public class Recording implements Listener {
|
||||
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);
|
||||
GlobalRecorder.getInstance().entityDespawns(e.getEntity());
|
||||
GlobalRecorder.getInstance().particle(loc.getX(), loc.getY(), loc.getZ(), Particle.EXPLOSION_HUGE.name());
|
||||
GlobalRecorder.getInstance().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)
|
||||
@ -209,7 +220,7 @@ public class Recording implements Listener {
|
||||
if(isNotSent(e.getPlayer()))
|
||||
return;
|
||||
|
||||
RecordSystem.item(e.getPlayer(), disarmNull(e.getPlayer().getInventory().getItem(e.getNewSlot())), "MAINHAND");
|
||||
GlobalRecorder.getInstance().item(e.getPlayer(), disarmNull(e.getPlayer().getInventory().getItem(e.getNewSlot())), "MAINHAND");
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -218,16 +229,16 @@ public class Recording implements Listener {
|
||||
return;
|
||||
|
||||
Player player = e.getPlayer();
|
||||
RecordSystem.item(player, disarmNull(e.getMainHandItem()), "MAINHAND");
|
||||
RecordSystem.item(player, disarmNull(e.getOffHandItem()), "OFFHAND");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(e.getMainHandItem()), "MAINHAND");
|
||||
GlobalRecorder.getInstance().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());
|
||||
GlobalRecorder.getInstance().fireballSpawn(e.getEntity());
|
||||
else if(e.getEntityType() == EntityType.ARROW)
|
||||
RecordSystem.arrowSpawn(e.getEntity());
|
||||
GlobalRecorder.getInstance().arrowSpawn(e.getEntity());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -241,17 +252,17 @@ public class Recording implements Listener {
|
||||
|
||||
switch(e.getSlot()){
|
||||
case 103:
|
||||
RecordSystem.item(player, disarmNull(e.getCurrentItem()), "HEAD");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(e.getCurrentItem()), "HEAD");
|
||||
break;
|
||||
case 102:
|
||||
RecordSystem.item(player, disarmNull(e.getCurrentItem()), "CHEST");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(e.getCurrentItem()), "CHEST");
|
||||
break;
|
||||
case 101:
|
||||
RecordSystem.item(player, disarmNull(e.getCurrentItem()), "LEGS");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(e.getCurrentItem()), "LEGS");
|
||||
break;
|
||||
case 100:
|
||||
default:
|
||||
RecordSystem.item(player, disarmNull(e.getCurrentItem()), "FEET");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(e.getCurrentItem()), "FEET");
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,12 +275,12 @@ public class Recording implements Listener {
|
||||
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");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getItemInMainHand()), "MAINHAND");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getItemInOffHand()), "OFFHAND");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getHelmet()), "HEAD");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getChestplate()), "CHEST");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getLeggings()), "LEGS");
|
||||
GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getBoots()), "FEET");
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,13 +293,13 @@ public class Recording implements Listener {
|
||||
private void despawnTeam(FightTeam team){
|
||||
for(FightPlayer player : team.getPlayers()){
|
||||
if(player.isLiving())
|
||||
RecordSystem.entityDespawns(player.getPlayer());
|
||||
GlobalRecorder.getInstance().entityDespawns(player.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
private void despawnTNT(){
|
||||
for(TNTPrimed tnt : Bukkit.getWorlds().get(0).getEntitiesByClass(TNTPrimed.class))
|
||||
RecordSystem.entityDespawns(tnt);
|
||||
GlobalRecorder.getInstance().entityDespawns(tnt);
|
||||
}
|
||||
|
||||
private boolean isNotSent(Player p){
|
||||
|
@ -32,7 +32,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
public class SetupQuit implements Listener {
|
||||
|
||||
public SetupQuit(){
|
||||
new StateDependentListener(ArenaMode.All, FightState.Setup, this);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Setup, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -20,6 +20,7 @@
|
||||
package de.steamwar.fightsystem.listener;
|
||||
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -36,7 +37,10 @@ public class Shutdown implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void handlePlayerQuit(PlayerQuitEvent event) {
|
||||
//Shutdown server if nobody online and its not an event server
|
||||
if(Config.replayserver())
|
||||
return;
|
||||
|
||||
//Shutdown server if nobody online
|
||||
if(Bukkit.getOnlinePlayers().isEmpty() || (Bukkit.getOnlinePlayers().size() == 1 && Bukkit.getOnlinePlayers().contains(event.getPlayer())))
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class WaterRemover implements Listener {
|
||||
private static final int MIN_Y = Config.BluePasteRegion.getMinY() + Config.WaterDepth;
|
||||
|
||||
public WaterRemover() {
|
||||
new StateDependentListener(ArenaMode.All, FightState.Running, this);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -19,120 +19,60 @@
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class FileRecorder extends Recorder {
|
||||
public class FileRecorder extends StateDependent implements Recorder {
|
||||
|
||||
private final DataOutputStream outputStream;
|
||||
private static final File file = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "recording.recording");
|
||||
private DataOutputStream outputStream;
|
||||
|
||||
public static File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public FileRecorder(){
|
||||
super();
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
File file = new File(world.getWorldFolder(), world.getName() + ".recording");
|
||||
super(ArenaMode.AntiReplay, FightState.Recording);
|
||||
register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataOutputStream getStream() {
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
try{
|
||||
file.createNewFile();
|
||||
outputStream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(file), 4096)));
|
||||
outputStream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(file), 4096)){
|
||||
@Override
|
||||
public synchronized void flush() {
|
||||
//Don't flush explicitly (performance)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try{
|
||||
super.flush();
|
||||
}catch(IOException e){
|
||||
//do nothing
|
||||
}
|
||||
super.close();
|
||||
}
|
||||
});
|
||||
}catch(IOException e){
|
||||
throw new SecurityException("Could not open file", e);
|
||||
}
|
||||
Recorder.super.enable();
|
||||
}
|
||||
|
||||
@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() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeRecorder() {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not close OutputStream", e);
|
||||
}
|
||||
public void disable() {
|
||||
Recorder.super.disable();
|
||||
}
|
||||
}
|
||||
|
65
FightSystem_Main/src/de/steamwar/fightsystem/record/FileSource.java
Normale Datei
65
FightSystem_Main/src/de/steamwar/fightsystem/record/FileSource.java
Normale Datei
@ -0,0 +1,65 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class FileSource extends PacketSource {
|
||||
|
||||
public static void startReplay() {
|
||||
if(Config.replayserver())
|
||||
return;
|
||||
|
||||
InputStream input = de.steamwar.sql.Fight.getReplay(Config.ReplayID);
|
||||
try {
|
||||
Files.copy(
|
||||
input,
|
||||
FileRecorder.getFile().toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
input.close();
|
||||
new FileSource(FileRecorder.getFile());
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Could not start replay", e);
|
||||
}
|
||||
}
|
||||
|
||||
public FileSource(File fightFile) throws IOException {
|
||||
super(new GZIPInputStream(new FileInputStream(fightFile)));
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isClosed() {
|
||||
try{
|
||||
return available() == 0;
|
||||
}catch (IOException e){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean async() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class GlobalRecorder extends OutputStream implements Recorder {
|
||||
|
||||
private static final GlobalRecorder recorder = new GlobalRecorder();
|
||||
|
||||
public static GlobalRecorder getInstance(){
|
||||
return recorder;
|
||||
}
|
||||
|
||||
private final List<Recorder> recorders = new ArrayList<>();
|
||||
private final DataOutputStream outputStream = new DataOutputStream(this);
|
||||
|
||||
public void add(Recorder recorder){
|
||||
recorders.add(recorder);
|
||||
}
|
||||
|
||||
public void remove(Recorder recorder){
|
||||
recorders.remove(recorder);
|
||||
}
|
||||
|
||||
public boolean recording(){
|
||||
return !recorders.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataOutputStream getStream() {
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int i) {
|
||||
foreach(stream -> stream.write(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] bytes, int i, int i1) {
|
||||
foreach(stream -> stream.write(bytes, i, i1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
foreach(OutputStream::flush);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
foreach(OutputStream::close);
|
||||
}
|
||||
|
||||
private void foreach(IOThrower thrower) {
|
||||
for(int i = 0; i < recorders.size(); i++) {
|
||||
Recorder stream = recorders.get(i);
|
||||
try{
|
||||
thrower.run(stream.getStream());
|
||||
}catch (IOException e){
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not operate on OutputStream", e);
|
||||
stream.disable();
|
||||
i--; // Recorder was removed from recorders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IOThrower{
|
||||
void run(OutputStream stream) throws IOException;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependent;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class LiveRecorder extends StateDependent implements Recorder {
|
||||
|
||||
private DataOutputStream outputStream;
|
||||
private Socket socket;
|
||||
|
||||
public LiveRecorder(){
|
||||
super(Config.LiveReplay, FightState.All);
|
||||
register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
try {
|
||||
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 disable
|
||||
socket.setTcpNoDelay(true); // Don't wait on ack
|
||||
outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), 1024));
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not init connection to spectate server", e);
|
||||
disable();
|
||||
}
|
||||
Recorder.super.enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "IOException on socket close", e);
|
||||
}
|
||||
Recorder.super.disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataOutputStream getStream() {
|
||||
return outputStream;
|
||||
}
|
||||
}
|
62
FightSystem_Main/src/de/steamwar/fightsystem/record/LiveServer.java
Normale Datei
62
FightSystem_Main/src/de/steamwar/fightsystem/record/LiveServer.java
Normale Datei
@ -0,0 +1,62 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class LiveServer {
|
||||
|
||||
private final ServerSocket socket;
|
||||
|
||||
public LiveServer() throws IOException {
|
||||
socket = new ServerSocket(Config.spectatePort);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(FightSystem.getPlugin(), this::acceptConnections);
|
||||
}
|
||||
|
||||
public void close(){
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not close socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void acceptConnections(){
|
||||
try {
|
||||
while(!socket.isClosed()){
|
||||
Socket s = socket.accept();
|
||||
if(PacketProcessor.isReplaying()){
|
||||
s.close();
|
||||
}else{
|
||||
new LiveSource(s);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.INFO, "Stopping accepting connections", e);
|
||||
}
|
||||
}
|
||||
}
|
55
FightSystem_Main/src/de/steamwar/fightsystem/record/LiveSource.java
Normale Datei
55
FightSystem_Main/src/de/steamwar/fightsystem/record/LiveSource.java
Normale Datei
@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class LiveSource extends PacketSource {
|
||||
private final Socket socket;
|
||||
|
||||
protected LiveSource(Socket socket) throws IOException {
|
||||
super(socket.getInputStream());
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "IOException on close", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isClosed() {
|
||||
return socket.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean async() {
|
||||
return true;
|
||||
}
|
||||
}
|
440
FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java
Normale Datei
440
FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java
Normale Datei
@ -0,0 +1,440 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.VersionedRunnable;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.countdown.EventSpectateCountdown;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.fight.FreezeWorld;
|
||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
||||
import de.steamwar.fightsystem.utils.TechHider;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import de.steamwar.sql.Team;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class PacketProcessor {
|
||||
|
||||
static boolean replaying = false;
|
||||
|
||||
public static boolean isReplaying(){
|
||||
return replaying;
|
||||
}
|
||||
|
||||
private static final World world = Bukkit.getWorlds().get(0);
|
||||
|
||||
private final PacketParser[] packetDecoder = new PacketParser[256];
|
||||
|
||||
private final PacketSource source;
|
||||
private final BukkitTask task;
|
||||
private final LinkedList<Runnable> syncList = new LinkedList<>();
|
||||
private final Set<Integer> hiddenBlockIds = TechHider.getHiddenBlockIds();
|
||||
private final int obfuscateWith = TechHider.getObfuscateWith();
|
||||
private final FreezeWorld freezer = new FreezeWorld();
|
||||
|
||||
private boolean rotateZ = false;
|
||||
private int arenaMinX = Config.ArenaRegion.getMinX();
|
||||
private int arenaMinY = Config.BluePasteRegion.getMinY();
|
||||
private int arenaMinZ = Config.ArenaRegion.getMinZ();
|
||||
|
||||
private boolean tickFinished = false;
|
||||
|
||||
public PacketProcessor(PacketSource source){
|
||||
this.source = source;
|
||||
replaying = true;
|
||||
|
||||
packetDecoder[0x00] = this::playerJoins;
|
||||
packetDecoder[0x01] = this::entityMoves;
|
||||
packetDecoder[0x02] = this::entityDespawns;
|
||||
packetDecoder[0x03] = this::entitySneak;
|
||||
packetDecoder[0x04] = this::entityAnimation;
|
||||
packetDecoder[0x05] = this::tntSpawn;
|
||||
packetDecoder[0x06] = this::entityVelocity;
|
||||
packetDecoder[0x07] = this::playerItem;
|
||||
packetDecoder[0x08] = this::arrowSpawn;
|
||||
packetDecoder[0x09] = this::fireballSpawn;
|
||||
packetDecoder[0x0a] = this::bow;
|
||||
packetDecoder[0x0b] = this::damage;
|
||||
packetDecoder[0x0c] = this::fireTick;
|
||||
packetDecoder[0x20] = this::arenaInfo;
|
||||
packetDecoder[0x30] = this::block;
|
||||
packetDecoder[0x31] = this::particle;
|
||||
packetDecoder[0x32] = this::sound;
|
||||
packetDecoder[0x33] = this::shortBlock;
|
||||
packetDecoder[0x34] = this::soundAtPlayer;
|
||||
packetDecoder[0x35] = this::shortRelativeBlock;
|
||||
packetDecoder[0xa0] = () -> send(ChatMessageType.CHAT);
|
||||
packetDecoder[0xa1] = () -> send(ChatMessageType.ACTION_BAR);
|
||||
packetDecoder[0xa2] = () -> send(ChatMessageType.SYSTEM);
|
||||
packetDecoder[0xb0] = () -> pasteSchem(Fight.getBlueTeam());
|
||||
packetDecoder[0xb1] = () -> pasteSchem(Fight.getRedTeam());
|
||||
packetDecoder[0xb2] = this::teams;
|
||||
packetDecoder[0xb3] = () -> pasteEmbeddedSchem(Fight.getBlueTeam());
|
||||
packetDecoder[0xb4] = () -> pasteEmbeddedSchem(Fight.getRedTeam());
|
||||
packetDecoder[0xc0] = this::scoreboardTitle;
|
||||
packetDecoder[0xc1] = this::scoreboardData;
|
||||
packetDecoder[0xef] = source::readUTF;
|
||||
packetDecoder[0xff] = this::tick;
|
||||
|
||||
if(source.async()) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(FightSystem.getPlugin(), this::process);
|
||||
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::runSync, 1, 1);
|
||||
}else
|
||||
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::process, 1, 1);
|
||||
}
|
||||
|
||||
private void runSync() {
|
||||
synchronized (syncList) {
|
||||
for(Runnable runnable : syncList) {
|
||||
try{
|
||||
runnable.run();
|
||||
}catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to execute packet", e);
|
||||
}
|
||||
}
|
||||
syncList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void execSync(Runnable runnable){
|
||||
if (!source.async()) {
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (syncList) {
|
||||
syncList.add(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
private void playerJoins() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
int userId = source.readInt();
|
||||
|
||||
execSync(() -> new REntity(entityId, userId));
|
||||
}
|
||||
|
||||
private void entityMoves() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
double locX = source.readDouble() - arenaMinX + Config.ArenaRegion.getMinX();
|
||||
double locY = source.readDouble() - arenaMinY + Config.BluePasteRegion.getMinY();
|
||||
double z = source.readDouble() - arenaMinZ;
|
||||
if(rotateZ)
|
||||
z = Config.ArenaRegion.getSizeZ() - z;
|
||||
double locZ = z + Config.ArenaRegion.getMinZ();
|
||||
float pitch = source.readFloat();
|
||||
float yaw = source.readFloat() + (rotateZ ? 360 : 0);
|
||||
byte headYaw = (byte)((source.readByte() + (rotateZ ? 128 : 0)) % 256);
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).move(locX, locY, locZ, pitch, yaw, headYaw));
|
||||
}
|
||||
|
||||
private void entityDespawns() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).die());
|
||||
}
|
||||
|
||||
private void entitySneak() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
boolean sneaking = source.readBoolean();
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).sneak(sneaking));
|
||||
}
|
||||
|
||||
private void entityAnimation() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
byte animation = source.readByte();
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).animation(animation));
|
||||
}
|
||||
|
||||
private void tntSpawn() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
|
||||
execSync(() -> new REntity(entityId, EntityType.PRIMED_TNT));
|
||||
}
|
||||
|
||||
private void entityVelocity() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
|
||||
double dX = source.readDouble();
|
||||
double dY = source.readDouble();
|
||||
double dZ = rotateZ ? -source.readDouble() : source.readDouble();
|
||||
|
||||
execSync(() -> {
|
||||
REntity entity = REntity.getEntity(entityId);
|
||||
if(entity != null)
|
||||
entity.setVelocity(dX, dY, dZ);
|
||||
});
|
||||
}
|
||||
|
||||
private void playerItem() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
String item = source.readUTF();
|
||||
boolean enchanted = source.readBoolean();
|
||||
String slot = source.readUTF();
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).setItem(item, enchanted, slot));
|
||||
}
|
||||
|
||||
private void arrowSpawn() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
|
||||
execSync(() -> new REntity(entityId, EntityType.ARROW));
|
||||
}
|
||||
|
||||
private void fireballSpawn() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
|
||||
execSync(() -> new REntity(entityId, EntityType.FIREBALL));
|
||||
}
|
||||
|
||||
private void send(ChatMessageType type) throws IOException {
|
||||
String message = source.readUTF();
|
||||
|
||||
BaseComponent[] text = TextComponent.fromLegacyText(message);
|
||||
Bukkit.getOnlinePlayers().forEach(p -> p.spigot().sendMessage(type, text));
|
||||
}
|
||||
|
||||
private void arenaInfo() throws IOException {
|
||||
rotateZ = source.readBoolean() != Config.blueNegZ();
|
||||
arenaMinY = Byte.toUnsignedInt(source.readByte());
|
||||
arenaMinX = source.readInt();
|
||||
arenaMinZ = source.readInt();
|
||||
}
|
||||
|
||||
private void shortBlock() throws IOException {
|
||||
int x = Byte.toUnsignedInt(source.readByte()) + Config.ArenaRegion.getMinX();
|
||||
int y = Byte.toUnsignedInt(source.readByte());
|
||||
int z = Byte.toUnsignedInt(source.readByte()) + Config.ArenaRegion.getMinZ();
|
||||
int blockState = source.readShort();
|
||||
|
||||
setBlock(x, y, z, blockState);
|
||||
}
|
||||
|
||||
private void shortRelativeBlock() throws IOException {
|
||||
int x = Byte.toUnsignedInt(source.readByte());
|
||||
int y = Byte.toUnsignedInt(source.readByte());
|
||||
int z = Byte.toUnsignedInt(source.readByte());
|
||||
int blockState = source.readShort();
|
||||
|
||||
if(rotateZ)
|
||||
z = Config.ArenaRegion.getSizeZ() - z;
|
||||
|
||||
setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState);
|
||||
}
|
||||
|
||||
private void block() throws IOException {
|
||||
int x = source.readInt() - arenaMinX;
|
||||
int y = Byte.toUnsignedInt(source.readByte()) - arenaMinY;
|
||||
int z = source.readInt() - arenaMinZ;
|
||||
int blockState = source.readInt();
|
||||
|
||||
if(rotateZ)
|
||||
z = Config.ArenaRegion.getSizeZ() - z;
|
||||
|
||||
setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState);
|
||||
}
|
||||
|
||||
private void setBlock(int x, int y, int z, int blockState){
|
||||
if(!Config.ArenaRegion.in2dRegion(x, z))
|
||||
return; //Outside of the arena
|
||||
|
||||
execSync(() -> setBlockInternal(x, y, z, TechHider.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState));
|
||||
}
|
||||
|
||||
private void particle() throws IOException {
|
||||
double x = source.readDouble();
|
||||
double y = source.readDouble();
|
||||
double z = source.readDouble();
|
||||
|
||||
String particleName = source.readUTF();
|
||||
|
||||
execSync(() -> world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1));
|
||||
}
|
||||
|
||||
private void sound() throws IOException {
|
||||
int x = source.readInt();
|
||||
int y = source.readInt();
|
||||
int z = source.readInt();
|
||||
|
||||
String soundName = source.readUTF();
|
||||
String soundCategory = source.readUTF();
|
||||
|
||||
float volume = source.readFloat();
|
||||
float pitch = source.readFloat();
|
||||
|
||||
Sound sound = Sound.valueOf(soundName);
|
||||
SoundCategory sCategory = SoundCategory.valueOf(soundCategory);
|
||||
|
||||
execSync(() -> world.playSound(new Location(world, x, y, z), sound, sCategory, volume, pitch));
|
||||
}
|
||||
|
||||
private void soundAtPlayer() throws IOException {
|
||||
String soundName = source.readUTF();
|
||||
|
||||
float volume = source.readFloat();
|
||||
float pitch = source.readFloat();
|
||||
|
||||
Sound sound = Sound.valueOf(soundName);
|
||||
|
||||
execSync(() -> {
|
||||
for(Player player : Bukkit.getOnlinePlayers()){
|
||||
player.playSound(player.getLocation(), sound, volume, pitch);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void pasteSchem(FightTeam team) throws IOException {
|
||||
int schemId = source.readInt();
|
||||
|
||||
execSync(() -> team.pasteSchem(Schematic.getSchemFromDB(schemId)));
|
||||
}
|
||||
|
||||
private void pasteEmbeddedSchem(FightTeam team) throws IOException {
|
||||
int schemId = source.readInt();
|
||||
Clipboard clipboard = Schematic.clipboardFromStream(source, Core.getVersion() > 12);
|
||||
|
||||
execSync(() -> team.pasteSchem(schemId, clipboard));
|
||||
}
|
||||
|
||||
private void teams() throws IOException {
|
||||
int blueId = source.readInt();
|
||||
int redId = source.readInt();
|
||||
|
||||
execSync(() -> {
|
||||
pasteForTeam(blueId, Fight.getBlueTeam());
|
||||
pasteForTeam(redId, Fight.getRedTeam());
|
||||
});
|
||||
}
|
||||
|
||||
private void pasteForTeam(int teamId, FightTeam fightTeam){
|
||||
Team team = Team.get(teamId);
|
||||
fightTeam.setPrefixAndName("§" + team.getTeamColor(), team.getTeamKuerzel());
|
||||
fightTeam.pasteTeamName();
|
||||
}
|
||||
|
||||
private void scoreboardTitle() throws IOException {
|
||||
String title = source.readUTF();
|
||||
|
||||
FightScoreboard.getScoreboard().setTitle(title);
|
||||
}
|
||||
|
||||
private void scoreboardData() throws IOException {
|
||||
String key = source.readUTF();
|
||||
int value = source.readInt();
|
||||
|
||||
FightScoreboard.getScoreboard().addScore(key, value);
|
||||
}
|
||||
|
||||
private void endReplay(){
|
||||
REntity.dieAll();
|
||||
freezer.disable();
|
||||
if(Config.replayserver() || ArenaMode.AntiReplay.contains(Config.mode)) {
|
||||
FightSystem.setSpectateState(null, "Replay ends");
|
||||
}else{
|
||||
Bukkit.broadcastMessage(FightSystem.PREFIX + "§cReplay beendet");
|
||||
new EventSpectateCountdown().enable();
|
||||
}
|
||||
replaying = false;
|
||||
}
|
||||
|
||||
private void bow() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
boolean drawn = source.readBoolean();
|
||||
boolean offHand = source.readBoolean();
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).setBowDrawn(drawn, offHand));
|
||||
}
|
||||
|
||||
private void damage() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).damage());
|
||||
}
|
||||
|
||||
private void fireTick() throws IOException {
|
||||
int entityId = source.readInt();
|
||||
boolean perma = source.readBoolean();
|
||||
|
||||
execSync(() -> REntity.getEntity(entityId).setOnFire(perma));
|
||||
}
|
||||
|
||||
private void tick(){
|
||||
execSync(REntity::tickFire);
|
||||
if(!source.async())
|
||||
tickFinished = true;
|
||||
}
|
||||
|
||||
private void process(){
|
||||
tickFinished = false;
|
||||
try{
|
||||
while(!source.isClosed() && !tickFinished){
|
||||
int packetType = Byte.toUnsignedInt(source.readByte());
|
||||
PacketParser parser = packetDecoder[packetType];
|
||||
if(parser != null){
|
||||
parser.process();
|
||||
}else{
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unknown packet " + packetType + " recieved, closing.");
|
||||
source.close();
|
||||
}
|
||||
}
|
||||
} catch (EOFException e) {
|
||||
Bukkit.getLogger().log(Level.INFO, "The FightServer is offline");
|
||||
source.close();
|
||||
} catch(IOException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not recieve packet", e);
|
||||
source.close();
|
||||
}
|
||||
|
||||
if(source.isClosed()){
|
||||
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay);
|
||||
task.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private static void setBlockInternal(int x, int y, int z, int blockState){
|
||||
VersionedRunnable.call(new VersionedRunnable(() -> RecordSystem_8.setBlock(world, x, y, z, blockState), 8),
|
||||
new VersionedRunnable(() -> RecordSystem_14.setBlock(world, x, y, z, blockState), 14),
|
||||
new VersionedRunnable(() -> RecordSystem_15.setBlock(world, x, y, z, blockState), 15));
|
||||
}
|
||||
|
||||
private interface PacketParser{
|
||||
void process() throws IOException;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public abstract class PacketSource extends DataInputStream {
|
||||
|
||||
protected PacketSource(InputStream inputStream){
|
||||
super(inputStream);
|
||||
new PacketProcessor(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(){
|
||||
try {
|
||||
super.close();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "IOException on disable", e);
|
||||
}
|
||||
}
|
||||
|
||||
abstract boolean isClosed();
|
||||
abstract boolean async();
|
||||
}
|
378
FightSystem_Main/src/de/steamwar/fightsystem/record/REntity.java
Normale Datei
378
FightSystem_Main/src/de/steamwar/fightsystem/record/REntity.java
Normale Datei
@ -0,0 +1,378 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.wrappers.*;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.VersionedCallable;
|
||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import net.royawesome.jlibnoise.MathHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scoreboard.NameTagVisibility;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class REntity {
|
||||
|
||||
private static final Map<Integer, REntity> entities = new HashMap<>();
|
||||
|
||||
public static REntity getEntity(int internalId){
|
||||
return entities.get(internalId);
|
||||
}
|
||||
|
||||
public static void tickFire() {
|
||||
entities.forEach((integer, entity) -> {
|
||||
if(entity.fireTick > 0) {
|
||||
entity.fireTick--;
|
||||
if(entity.fireTick == 0) {
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(entity.getDataWatcherPacket(0, (byte)0));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void playerJoins(Player player) {
|
||||
try{
|
||||
for(REntity entity : entities.values()){
|
||||
if(entity.entityType == EntityType.PLAYER){
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getPlayerInfoPacket());
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getNamedSpawnPacket());
|
||||
for (Map.Entry<String, ItemStack> entry : entity.itemSlots.entrySet()) {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getEquipmentPacket(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}else{
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getSpawnEntityPacket());
|
||||
}
|
||||
//ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getTeleportPacket()); Sollte nicht nötig sein?
|
||||
if(entity.fireTick != 0) {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(0, (byte) 1));
|
||||
}
|
||||
if(entity.sneaks) {
|
||||
if(Core.getVersion() > 12){
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(6, getPose(true)));
|
||||
}else{
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(0, (byte) 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(InvocationTargetException e){
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not sync player", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void dieAll(){
|
||||
entities.forEach((id, entity) -> entity.broadcastDeath());
|
||||
entities.clear();
|
||||
}
|
||||
|
||||
private static final String SCOREBOARD_TEAMNAME = "Replay";
|
||||
private static final Team team;
|
||||
|
||||
static {
|
||||
if(FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME) == null)
|
||||
team = FightScoreboard.getBukkit().registerNewTeam(SCOREBOARD_TEAMNAME);
|
||||
else
|
||||
team = FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME);
|
||||
team.setNameTagVisibility(NameTagVisibility.NEVER);
|
||||
}
|
||||
|
||||
private static int entityCount = Integer.MAX_VALUE;
|
||||
private static final Random random = new Random();
|
||||
|
||||
private final int internalId;
|
||||
private final int entityId;
|
||||
private final UUID uuid;
|
||||
private final EntityType entityType;
|
||||
private final PlayerInfoData playerInfoData;
|
||||
private final Map<String, ItemStack> itemSlots = new HashMap<>();
|
||||
|
||||
private double locX;
|
||||
private double locY;
|
||||
private double locZ;
|
||||
private byte yaw;
|
||||
private byte pitch;
|
||||
private byte headYaw;
|
||||
private int fireTick;
|
||||
private boolean sneaks;
|
||||
|
||||
public REntity(int internalId, int userId){
|
||||
this.internalId = internalId;
|
||||
this.entityType = EntityType.PLAYER;
|
||||
this.entityId = entityCount--;
|
||||
|
||||
SteamwarUser user = SteamwarUser.get(userId);
|
||||
this.uuid = user.getUUID();
|
||||
this.playerInfoData = new PlayerInfoData(WrappedGameProfile.fromHandle(new GameProfile(uuid, user.getUserName())), 0, EnumWrappers.NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(user.getUserName()));
|
||||
entities.put(internalId, this);
|
||||
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getPlayerInfoPacket());
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getNamedSpawnPacket());
|
||||
team.addEntry(user.getUserName());
|
||||
}
|
||||
|
||||
public REntity(int internalId, EntityType entityType){
|
||||
this.internalId = internalId;
|
||||
this.entityType = entityType;
|
||||
this.entityId = entityCount--;
|
||||
this.playerInfoData = null;
|
||||
this.uuid = new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L);
|
||||
entities.put(internalId, this);
|
||||
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getSpawnEntityPacket());
|
||||
}
|
||||
|
||||
public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw){
|
||||
this.locX = locX;
|
||||
this.locY = locY;
|
||||
this.locZ = locZ;
|
||||
this.yaw = (byte)((int)(yaw * 256.0F / 360.0F));
|
||||
this.pitch = (byte)((int)(pitch * 256.0F / 360.0F));
|
||||
this.headYaw = headYaw;
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getTeleportPacket());
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHeadRotationPacket());
|
||||
}
|
||||
|
||||
public void animation(byte animation) {
|
||||
PacketContainer animationPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ANIMATION);
|
||||
StructureModifier<Integer> ints = animationPacket.getIntegers();
|
||||
ints.write(0, entityId);
|
||||
ints.write(1, (int) animation);
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(animationPacket);
|
||||
}
|
||||
|
||||
public void setVelocity(double dX, double dY, double dZ) {
|
||||
PacketContainer velocityPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_VELOCITY);
|
||||
StructureModifier<Integer> ints = velocityPacket.getIntegers();
|
||||
ints.write(0, entityId);
|
||||
ints.write(1, calcVelocity(dX));
|
||||
ints.write(2, calcVelocity(dY));
|
||||
ints.write(3, calcVelocity(dZ));
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(velocityPacket);
|
||||
}
|
||||
|
||||
public void damage() {
|
||||
PacketContainer statusPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_STATUS);
|
||||
statusPacket.getIntegers().write(0, entityId);
|
||||
statusPacket.getBytes().write(0, (byte) 2);
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(statusPacket);
|
||||
}
|
||||
|
||||
public void sneak(boolean sneaking) {
|
||||
sneaks = sneaking;
|
||||
|
||||
if(Core.getVersion() > 12){
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(6, getPose(sneaking)));
|
||||
}else{
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(0, sneaking ? (byte) 2 : (byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnFire(boolean perma) {
|
||||
if(!perma) {
|
||||
fireTick = 21;
|
||||
} else {
|
||||
fireTick = -1;
|
||||
}
|
||||
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(0, (byte) 1));
|
||||
}
|
||||
|
||||
public void setBowDrawn(boolean drawn, boolean offHand) {
|
||||
if(Core.getVersion() > 8){
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(Core.getVersion() > 12 ? 7 : 6, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))));
|
||||
}else{
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(0, (byte)0x10));
|
||||
}
|
||||
}
|
||||
|
||||
public void setItem(String item, boolean enchanted, String slot) {
|
||||
ItemStack stack = new ItemStack(Material.valueOf(item.replace("minecraft:", "").toUpperCase()), 1);
|
||||
if(enchanted)
|
||||
stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
||||
itemSlots.put(slot, stack);
|
||||
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getEquipmentPacket(slot, stack));
|
||||
}
|
||||
|
||||
public void die(){
|
||||
broadcastDeath();
|
||||
entities.remove(internalId);
|
||||
}
|
||||
|
||||
private void broadcastDeath(){
|
||||
if(entityType == EntityType.PLAYER){
|
||||
PacketContainer infoPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO);
|
||||
infoPacket.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
infoPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(playerInfoData));
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(infoPacket);
|
||||
team.removeEntry(playerInfoData.getProfile().getName());
|
||||
}
|
||||
|
||||
PacketContainer destroyPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_DESTROY);
|
||||
destroyPacket.getIntegerArrays().write(0, new int[]{entityId});
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(destroyPacket);
|
||||
}
|
||||
|
||||
private int calcVelocity(double value) {
|
||||
return (int)(Math.max(-3.9, Math.min(value, 3.9)) * 8000);
|
||||
}
|
||||
|
||||
private void fillPositioningPacket(PacketContainer packet, StructureModifier<Integer> ints){
|
||||
ints.write(0, entityId);
|
||||
if(Core.getVersion() > 8){
|
||||
StructureModifier<Double> doubles = packet.getDoubles();
|
||||
doubles.write(0, locX);
|
||||
doubles.write(1, locY);
|
||||
doubles.write(2, locZ);
|
||||
}else{
|
||||
ints.write(1, MathHelper.floor(locX * 32));
|
||||
ints.write(2, MathHelper.floor(locY * 32));
|
||||
ints.write(3, MathHelper.floor(locZ * 32));
|
||||
}
|
||||
}
|
||||
|
||||
private void fillByteRotation(PacketContainer packet){
|
||||
StructureModifier<Byte> bytes = packet.getBytes();
|
||||
bytes.write(0, yaw);
|
||||
bytes.write(1, pitch);
|
||||
}
|
||||
|
||||
private PacketContainer getDataWatcherPacket(int index, Object value) {
|
||||
PacketContainer metadataPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
|
||||
metadataPacket.getIntegers().write(0, entityId);
|
||||
WrappedWatchableObject watchable = new WrappedWatchableObject(new WrappedDataWatcher.WrappedDataWatcherObject(index, WrappedDataWatcher.Registry.get(value.getClass())), value);
|
||||
watchable.setDirtyState(true);
|
||||
metadataPacket.getWatchableCollectionModifier().write(0, Collections.singletonList(watchable));
|
||||
return metadataPacket;
|
||||
}
|
||||
|
||||
private PacketContainer getTeleportPacket(){
|
||||
PacketContainer teleportPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_TELEPORT);
|
||||
fillPositioningPacket(teleportPacket, teleportPacket.getIntegers());
|
||||
fillByteRotation(teleportPacket);
|
||||
return teleportPacket;
|
||||
}
|
||||
|
||||
private PacketContainer getHeadRotationPacket(){
|
||||
PacketContainer headRotation = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
|
||||
headRotation.getIntegers().write(0, entityId);
|
||||
headRotation.getBytes().write(0, headYaw);
|
||||
return headRotation;
|
||||
}
|
||||
|
||||
private PacketContainer getSpawnEntityPacket(){
|
||||
PacketContainer spawnPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.SPAWN_ENTITY);
|
||||
StructureModifier<Integer> ints = spawnPacket.getIntegers();
|
||||
fillPositioningPacket(spawnPacket, ints);
|
||||
spawnPacket.getUUIDs().write(0, uuid);
|
||||
if(Core.getVersion() > 8){
|
||||
spawnPacket.getUUIDs().write(0, uuid);
|
||||
ints.write(1, 0); // dX
|
||||
ints.write(2, 0); // dY
|
||||
ints.write(3, 0); // dZ
|
||||
}
|
||||
ints.write(4, (int)pitch);
|
||||
ints.write(5, (int)yaw);
|
||||
if(Core.getVersion() > 12){
|
||||
spawnPacket.getEntityTypeModifier().write(0, entityType);
|
||||
}else{
|
||||
switch(entityType){
|
||||
case PRIMED_TNT:
|
||||
ints.write(6, 50);
|
||||
break;
|
||||
case ARROW:
|
||||
ints.write(6, 60);
|
||||
break;
|
||||
case FIREBALL:
|
||||
ints.write(6, 63);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return spawnPacket;
|
||||
}
|
||||
|
||||
private PacketContainer getEquipmentPacket(String slot, ItemStack stack){
|
||||
PacketContainer equipmentPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_EQUIPMENT);
|
||||
StructureModifier<Integer> ints = equipmentPacket.getIntegers();
|
||||
ints.write(0, entityId);
|
||||
if(Core.getVersion() == 8){
|
||||
switch(slot){
|
||||
case "MAINHAND":
|
||||
case "OFFHAND":
|
||||
ints.write(1, 0);
|
||||
break;
|
||||
case "HEAD":
|
||||
ints.write(1, 4);
|
||||
break;
|
||||
case "CHEST":
|
||||
ints.write(1, 3);
|
||||
break;
|
||||
case "LEGS":
|
||||
ints.write(1, 2);
|
||||
break;
|
||||
case "FEET":
|
||||
default:
|
||||
ints.write(1, 1);
|
||||
}
|
||||
}else{
|
||||
equipmentPacket.getItemSlots().write(0, EnumWrappers.ItemSlot.valueOf(slot));
|
||||
}
|
||||
equipmentPacket.getItemModifier().write(0, stack);
|
||||
return equipmentPacket;
|
||||
}
|
||||
|
||||
private PacketContainer getPlayerInfoPacket(){
|
||||
PacketContainer infoPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO);
|
||||
infoPacket.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
infoPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(playerInfoData));
|
||||
return infoPacket;
|
||||
}
|
||||
|
||||
private PacketContainer getNamedSpawnPacket(){
|
||||
PacketContainer namedSpawnPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
||||
StructureModifier<Integer> ints = namedSpawnPacket.getIntegers();
|
||||
fillPositioningPacket(namedSpawnPacket, ints);
|
||||
namedSpawnPacket.getUUIDs().write(0, uuid);
|
||||
fillByteRotation(namedSpawnPacket);
|
||||
if(Core.getVersion() < 13){
|
||||
namedSpawnPacket.getDataWatcherModifier().write(0, new WrappedDataWatcher());
|
||||
}
|
||||
return namedSpawnPacket;
|
||||
}
|
||||
|
||||
private static Object getPose(boolean sneaking){
|
||||
return VersionedCallable.call(new VersionedCallable<>(() -> RecordSystem_14.getPose(sneaking), 14),
|
||||
new VersionedCallable<>(() -> RecordSystem_15.getPose(sneaking), 15));
|
||||
}
|
||||
}
|
@ -1,328 +0,0 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import de.steamwar.core.VersionedCallable;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.*;
|
||||
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.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);
|
||||
if (Config.SpectateSystem)
|
||||
new SpectateConnection();
|
||||
new FileRecorder();
|
||||
if(Config.mode == ArenaMode.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
|
||||
* BowSpanPacket (0x0A) + int EntityId + boolean start + hand
|
||||
* PlayerDamagePacket (0x0B) + int EntityId
|
||||
* SetOnFire (0x0C) + int EntityId + boolean perma
|
||||
*
|
||||
*
|
||||
* 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)(VersionedCallable.call(
|
||||
new VersionedCallable<>(() -> FightWorld_8.headRotation(e), 8),
|
||||
new VersionedCallable<>(() -> FightWorld_9.headRotation(e), 9),
|
||||
new VersionedCallable<>(() -> FightWorld_10.headRotation(e), 10),
|
||||
new VersionedCallable<>(() -> FightWorld_12.headRotation(e), 12),
|
||||
new VersionedCallable<>(() -> FightWorld_14.headRotation(e), 14),
|
||||
new VersionedCallable<>(() -> FightWorld_15.headRotation(e), 15)
|
||||
) * 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);
|
||||
if(e.getFireTicks() > 0)
|
||||
setOnFire(e, true);
|
||||
}
|
||||
|
||||
public static synchronized void fireballSpawn(Entity e){
|
||||
Recorder.rByte(0x09);
|
||||
spawnEntity(e);
|
||||
}
|
||||
|
||||
public static synchronized void bowSpan(Entity e, boolean start, boolean offHand) {
|
||||
Recorder.rByte(0x0A);
|
||||
Recorder.rInt(e.getEntityId());
|
||||
Recorder.rBoolean(start);
|
||||
Recorder.rBoolean(offHand);
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
public static synchronized void damageAnimation(Player p) {
|
||||
Recorder.rByte(0x0B);
|
||||
Recorder.rInt(p.getEntityId());
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
public static synchronized void setOnFire(Entity e, boolean perma) {
|
||||
Recorder.rByte(0x0C);
|
||||
Recorder.rInt(e.getEntityId());
|
||||
Recorder.rBoolean(perma);
|
||||
Recorder.flush();
|
||||
}
|
||||
|
||||
public static synchronized void blockChange(Block block){
|
||||
int blockState = blockToId(block);
|
||||
|
||||
int shortX = block.getX() - Config.ArenaRegion.getMinX();
|
||||
int shortZ = block.getZ() - Config.ArenaRegion.getMinZ();
|
||||
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(FightState.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){
|
||||
return VersionedCallable.call(new VersionedCallable<>(() -> RecordSystem_8.blockToId(block), 8),
|
||||
new VersionedCallable<>(() -> RecordSystem_15.blockToId(block), 15));
|
||||
}
|
||||
}
|
@ -19,72 +19,301 @@
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import de.steamwar.core.VersionedCallable;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.fight.*;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public abstract class Recorder {
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
|
||||
private static final List<Recorder> recorders = new ArrayList<>();
|
||||
public interface Recorder {
|
||||
DataOutputStream getStream();
|
||||
|
||||
public static void rBoolean(boolean b){
|
||||
recorders.forEach((recorder) -> recorder.writeBoolean(b));
|
||||
default void enable() {
|
||||
GlobalRecorder.getInstance().add(this);
|
||||
|
||||
if(ArenaMode.Event.contains(Config.mode)){
|
||||
teamIds(Config.EventTeamBlueID, Config.EventTeamRedID);
|
||||
}
|
||||
|
||||
arenaInfo();
|
||||
enableTeam(Fight.getBlueTeam());
|
||||
enableTeam(Fight.getRedTeam());
|
||||
}
|
||||
|
||||
public static void rByte(int b){
|
||||
recorders.forEach((recorder) -> recorder.writeByte(b));
|
||||
default void enableTeam(FightTeam team){
|
||||
if(FightState.Schem.contains(FightState.getFightState())){
|
||||
if(team.isBlue())
|
||||
blueSchem(team.getSchematic());
|
||||
else
|
||||
redSchem(team.getSchematic());
|
||||
}
|
||||
|
||||
if(FightState.AntiSpectate.contains(FightState.getFightState())){
|
||||
for(FightPlayer player : team.getPlayers()){
|
||||
if(player.isLiving()){
|
||||
playerJoins(player.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void rShort(short s){
|
||||
recorders.forEach((recorder) -> recorder.writeShort(s));
|
||||
default void disable() {
|
||||
GlobalRecorder.getInstance().remove(this);
|
||||
try {
|
||||
getStream().close();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not close OutputStream", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void rInt(int i){
|
||||
recorders.forEach((recorder) -> recorder.writeInt(i));
|
||||
/*
|
||||
* 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
|
||||
* BowSpanPacket (0x0A) + int EntityId + boolean start + hand
|
||||
* PlayerDamagePacket (0x0B) + int EntityId
|
||||
* SetOnFire (0x0C) + int EntityId + boolean perma
|
||||
*
|
||||
* ArenaInfo (0x20) + bool blueNegZ + byte arenaY + int arenaMinX + int arenaMinZ
|
||||
*
|
||||
* 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
|
||||
* ShortBlockPacket (0x35) + pos relative to ArenaMinX,BluePasteY,ArenaMinZ byte, byte, byte + short BlockState
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* BlueEmbeddedSchemPacket (0xB3) + int blueSchemId + gzipt NBT blob
|
||||
* RedEmbeddedSchemPacket (0xB4) + int redSchemId + gzipt NBT blob
|
||||
*
|
||||
* ScoreboardTitlePacket (0xC0) + String scoreboardTitle
|
||||
* ScoreboardDataPacket (0xC1) + String key + int value
|
||||
*
|
||||
* CommentPacket (0xfe) + String comment
|
||||
* TickPacket (0xff)
|
||||
* */
|
||||
|
||||
default void playerJoins(Player p){
|
||||
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
|
||||
|
||||
write(0x00, p.getEntityId(), user.getId());
|
||||
entityMoves(p);
|
||||
}
|
||||
|
||||
public static void rLong(long l){
|
||||
recorders.forEach((recorder) -> recorder.writeLong(l));
|
||||
default void entityMoves(Entity e){
|
||||
Location location = e.getLocation();
|
||||
write(0x01, e.getEntityId(), location.getX(), location.getY(), location.getZ(), location.getPitch(), location.getYaw(), (byte)(VersionedCallable.call(
|
||||
new VersionedCallable<>(() -> FightWorld_8.headRotation(e), 8),
|
||||
new VersionedCallable<>(() -> FightWorld_9.headRotation(e), 9),
|
||||
new VersionedCallable<>(() -> FightWorld_10.headRotation(e), 10),
|
||||
new VersionedCallable<>(() -> FightWorld_12.headRotation(e), 12),
|
||||
new VersionedCallable<>(() -> FightWorld_14.headRotation(e), 14),
|
||||
new VersionedCallable<>(() -> FightWorld_15.headRotation(e), 15)
|
||||
) * 256 / 360));
|
||||
}
|
||||
|
||||
public static void rFloat(float f){
|
||||
recorders.forEach((recorder) -> recorder.writeFloat(f));
|
||||
default void entityDespawns(Entity e){
|
||||
write(0x02, e.getEntityId());
|
||||
}
|
||||
|
||||
public static void rDouble(double d){
|
||||
recorders.forEach((recorder) -> recorder.writeDouble(d));
|
||||
default void playerSneak(Player p, boolean sneaks){
|
||||
write(0x03, p.getEntityId(), sneaks);
|
||||
}
|
||||
|
||||
public static void rString(String s){
|
||||
recorders.forEach((recorder) -> recorder.writeString(s));
|
||||
default void entityAnimation(Entity e, int animation){
|
||||
write(0x04, e.getEntityId(), (byte)animation);
|
||||
}
|
||||
|
||||
public static void flush(){
|
||||
recorders.forEach(Recorder::doFlush);
|
||||
default void tntSpawn(Entity e){
|
||||
write(0x05, e.getEntityId());
|
||||
entityMoves(e);
|
||||
entitySpeed(e);
|
||||
}
|
||||
|
||||
public static void closeAll(){
|
||||
while(!recorders.isEmpty())
|
||||
recorders.get(0).close();
|
||||
default void entitySpeed(Entity e){
|
||||
Vector velocity = e.getVelocity();
|
||||
write(0x06, e.getEntityId(), velocity.getX(), velocity.getY(), velocity.getZ());
|
||||
}
|
||||
|
||||
protected Recorder(){
|
||||
recorders.add(this);
|
||||
default void item(Player p, ItemStack item, String slot){
|
||||
write(0x07, p.getEntityId(), "minecraft:" + item.getType().name().toLowerCase(), !item.getEnchantments().isEmpty(), slot);
|
||||
}
|
||||
|
||||
protected void close(){
|
||||
closeRecorder();
|
||||
recorders.remove(this);
|
||||
default void arrowSpawn(Entity e){
|
||||
write(0x08, e.getEntityId());
|
||||
entityMoves(e);
|
||||
entitySpeed(e);
|
||||
if(e.getFireTicks() > 0)
|
||||
setOnFire(e, true);
|
||||
}
|
||||
|
||||
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();
|
||||
default void fireballSpawn(Entity e){
|
||||
write(0x09, e.getEntityId());
|
||||
entityMoves(e);
|
||||
entitySpeed(e);
|
||||
}
|
||||
|
||||
protected abstract void closeRecorder();
|
||||
default void bowSpan(Entity e, boolean start, boolean offHand) {
|
||||
write(0x0a, e.getEntityId(), start, offHand);
|
||||
}
|
||||
|
||||
default void damageAnimation(Player p) {
|
||||
write(0x0b, p.getEntityId());
|
||||
}
|
||||
|
||||
default void setOnFire(Entity e, boolean perma) {
|
||||
write(0x0c, e.getEntityId(), perma);
|
||||
}
|
||||
|
||||
default void arenaInfo(){
|
||||
write(0x20, Config.blueNegZ(), (byte)Config.BluePasteRegion.getMinY(),
|
||||
Config.ArenaRegion.getMinX(), Config.ArenaRegion.getMinZ());
|
||||
}
|
||||
|
||||
default void blockChange(Block block){
|
||||
int blockState = VersionedCallable.call(new VersionedCallable<>(() -> RecordSystem_8.blockToId(block), 8),
|
||||
new VersionedCallable<>(() -> RecordSystem_14.blockToId(block), 14),
|
||||
new VersionedCallable<>(() -> RecordSystem_15.blockToId(block), 15));
|
||||
|
||||
int shortX = block.getX() - Config.ArenaRegion.getMinX();
|
||||
int shortY = block.getY() - Config.BluePasteRegion.getMinY();
|
||||
int shortZ = block.getZ() - Config.ArenaRegion.getMinZ();
|
||||
if((short)blockState == blockState && shortX >= 0 && shortX < 256 && shortY >= 0 && shortZ >= 0 && shortZ < 256){
|
||||
//Short block packet
|
||||
write(0x35, (byte)shortX, (byte)shortY, (byte)shortZ, (short)blockState);
|
||||
}else{
|
||||
//Block packet
|
||||
write(0x30, block.getX(), (byte)block.getY(), block.getZ(), blockState);
|
||||
}
|
||||
}
|
||||
|
||||
default void particle(double x, double y, double z, String particleType){
|
||||
write(0x31, x, y, z, particleType);
|
||||
}
|
||||
|
||||
default void sound(int x, int y, int z, String soundType, String soundCategory, float volume, float pitch){
|
||||
write(0x32, x, y, z, soundType, soundCategory, volume, pitch);
|
||||
}
|
||||
|
||||
default void soundAtPlayer(String soundType, float volume, float pitch){
|
||||
write(0x34, soundType, volume, pitch);
|
||||
}
|
||||
|
||||
default void chat(String s) {
|
||||
write(0xa0, s);
|
||||
}
|
||||
|
||||
default void actionBar(String s) {
|
||||
write(0xa1, s);
|
||||
}
|
||||
|
||||
default void systemChat(String s) {
|
||||
write(0xa2, s);
|
||||
}
|
||||
|
||||
default void teamIds(int blueTeamId, int redTeamId) {
|
||||
write(0xb2, blueTeamId, redTeamId);
|
||||
}
|
||||
|
||||
default void blueSchem(int schemId) {
|
||||
try {
|
||||
write(0xb3, schemId, Schematic.getSchemFromDB(schemId).schemData());
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not embed schematic", e);
|
||||
write(0xb0, schemId);
|
||||
}
|
||||
}
|
||||
|
||||
default void redSchem(int schemId) {
|
||||
try {
|
||||
write(0xb4, schemId, Schematic.getSchemFromDB(schemId).schemData());
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not embed schematic", e);
|
||||
write(0xb1, schemId);
|
||||
}
|
||||
}
|
||||
|
||||
default void scoreboardTitle(String title){
|
||||
write(0xc0, title);
|
||||
}
|
||||
|
||||
default void scoreboardData(String key, int value){
|
||||
write(0xc1, key, value);
|
||||
}
|
||||
|
||||
default void tick(){
|
||||
write(0xff);
|
||||
}
|
||||
|
||||
default void write(int id, Object... objects){
|
||||
DataOutputStream stream = getStream();
|
||||
try {
|
||||
stream.writeByte(id);
|
||||
for(Object o : objects){
|
||||
if(o instanceof Boolean)
|
||||
stream.writeBoolean((Boolean)o);
|
||||
else if(o instanceof Byte)
|
||||
stream.writeByte((Byte)o);
|
||||
else if(o instanceof Short)
|
||||
stream.writeShort((Short)o);
|
||||
else if(o instanceof Integer)
|
||||
stream.writeInt((Integer)o);
|
||||
else if(o instanceof Float)
|
||||
stream.writeFloat((Float)o);
|
||||
else if(o instanceof Double)
|
||||
stream.writeDouble((Double)o);
|
||||
else if(o instanceof String)
|
||||
stream.writeUTF((String)o);
|
||||
else if(o instanceof InputStream)
|
||||
copy((InputStream) o, stream);
|
||||
else
|
||||
throw new SecurityException("Undefined write for: " + o.getClass().getName());
|
||||
}
|
||||
stream.flush();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not write", e);
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException ioException) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not close", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void copy(InputStream var0, OutputStream var1) throws IOException {
|
||||
int var5;
|
||||
for(byte[] var4 = new byte[8192]; (var5 = var0.read(var4)) > 0;) {
|
||||
var1.write(var4, 0, var5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,9 @@ public enum FightState {
|
||||
public static final Set<FightState> Ingame = Collections.unmodifiableSet(EnumSet.of(PRE_RUNNING, RUNNING));
|
||||
public static final Set<FightState> TeamFix = Collections.unmodifiableSet(EnumSet.of(PRE_RUNNING, RUNNING, SPECTATE));
|
||||
public static final Set<FightState> Schem = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PRE_LEADER_SETUP, PRE_SCHEM_SETUP)));
|
||||
public static final Set<FightState> Recording = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PRE_LEADER_SETUP, PRE_SCHEM_SETUP, SPECTATE)));
|
||||
public static final Set<FightState> AntiRunning = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(RUNNING)));
|
||||
public static final Set<FightState> AntiSpectate = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(SPECTATE)));
|
||||
|
||||
private static final Map<IStateDependent, Boolean> stateDependentFeatures = new HashMap<>();
|
||||
private static FightState fightState = PRE_LEADER_SETUP;
|
||||
|
@ -19,23 +19,27 @@
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.countdown.Countdown;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||
import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.record.FileRecorder;
|
||||
import de.steamwar.fightsystem.winconditions.Wincondition;
|
||||
import de.steamwar.sql.Elo;
|
||||
import de.steamwar.sql.Schematic;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static de.steamwar.sql.Fight.create;
|
||||
import static de.steamwar.sql.Fight.setReplay;
|
||||
|
||||
public class FightStatistics {
|
||||
private FightStatistics(){}
|
||||
@ -92,6 +96,12 @@ public class FightStatistics {
|
||||
savePlayerStats(fp, fightId);
|
||||
for (FightPlayer fp : Fight.getRedTeam().getPlayers())
|
||||
savePlayerStats(fp, fightId);
|
||||
|
||||
setReplay(fightId, Files.readAllBytes(FileRecorder.getFile().toPath()));
|
||||
|
||||
if(ArenaMode.Event.contains(Config.mode)){
|
||||
FightSystem.getEventFight().setFight(fightId);
|
||||
}
|
||||
}catch(Exception e){
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Failed to save statistics", e);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ import static de.steamwar.fightsystem.utils.ITechHider.bypass;
|
||||
|
||||
public class TechHider extends StateDependent {
|
||||
|
||||
private static final boolean enabled = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
||||
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
||||
|
||||
private final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
private final Map<PacketContainer, PacketContainer> packetCache = new HashMap<>();
|
||||
@ -59,16 +59,10 @@ public class TechHider extends StateDependent {
|
||||
private final int threadMultiplier;
|
||||
|
||||
public TechHider(){
|
||||
super(enabled, FightState.Schem);
|
||||
super(ENABLED, FightState.Schem);
|
||||
|
||||
Set<Integer> hiddenBlockIds = VersionedCallable.call(
|
||||
new VersionedCallable<>(TechHider_8::getHiddenBlockIds, 8),
|
||||
new VersionedCallable<>(TechHider_14::getHiddenBlockIds, 14),
|
||||
new VersionedCallable<>(TechHider_15::getHiddenBlockIds, 15));
|
||||
int obfuscateWith = VersionedCallable.call(
|
||||
new VersionedCallable<>(TechHider_8::getObfuscateWith, 8),
|
||||
new VersionedCallable<>(TechHider_14::getObfuscateWith, 14),
|
||||
new VersionedCallable<>(TechHider_15::getObfuscateWith, 15));
|
||||
Set<Integer> hiddenBlockIds = getHiddenBlockIds();
|
||||
int obfuscateWith = getObfuscateWith();
|
||||
|
||||
obfuscateMaterial = Material.getMaterial(Config.ObfuscateWith.toUpperCase());
|
||||
chunkHider = VersionedCallable.call(new VersionedCallable<>(() -> null, 8),
|
||||
@ -263,8 +257,22 @@ public class TechHider extends StateDependent {
|
||||
}
|
||||
};
|
||||
|
||||
public static Set<Integer> getHiddenBlockIds(){
|
||||
return VersionedCallable.call(
|
||||
new VersionedCallable<>(TechHider_8::getHiddenBlockIds, 8),
|
||||
new VersionedCallable<>(TechHider_14::getHiddenBlockIds, 14),
|
||||
new VersionedCallable<>(TechHider_15::getHiddenBlockIds, 15));
|
||||
}
|
||||
|
||||
public static int getObfuscateWith(){
|
||||
return VersionedCallable.call(
|
||||
new VersionedCallable<>(TechHider_8::getObfuscateWith, 8),
|
||||
new VersionedCallable<>(TechHider_14::getObfuscateWith, 14),
|
||||
new VersionedCallable<>(TechHider_15::getObfuscateWith, 15));
|
||||
}
|
||||
|
||||
public static List<ChunkPos> prepareChunkReload(Player p, boolean hide){
|
||||
if(!enabled)
|
||||
if(!ENABLED)
|
||||
return Collections.emptyList();
|
||||
List<ChunkPos> chunksToReload = new ArrayList<>();
|
||||
Config.ArenaRegion.forEachChunk((x, z) -> {
|
||||
@ -275,7 +283,7 @@ public class TechHider extends StateDependent {
|
||||
}
|
||||
|
||||
public static void reloadChunks(Player p, List<ChunkPos> chunksToReload, boolean hide){
|
||||
if(!enabled)
|
||||
if(!ENABLED)
|
||||
return;
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
for(ChunkPos chunk : chunksToReload){
|
||||
|
@ -52,7 +52,7 @@ public class WinconditionTimeTechKO extends Wincondition {
|
||||
public WinconditionTimeTechKO(){
|
||||
super("TechKO");
|
||||
|
||||
if(Config.BlueToRedZ > 0) {
|
||||
if(Config.blueNegZ()) {
|
||||
smallerZteam = Fight.getBlueTeam();
|
||||
biggerZteam = Fight.getRedTeam();
|
||||
}else{
|
||||
|
@ -18,6 +18,7 @@ commands:
|
||||
remove:
|
||||
leader:
|
||||
lockschem:
|
||||
replay:
|
||||
state:
|
||||
skip:
|
||||
win:
|
In neuem Issue referenzieren
Einen Benutzer sperren