forked from SteamWar/SteamWar
merge upstream
This commit is contained in:
+18
-4
@@ -24,13 +24,16 @@ import de.steamwar.bausystem.configplayer.Config;
|
|||||||
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
||||||
import de.steamwar.bausystem.features.tracer.Trace;
|
import de.steamwar.bausystem.features.tracer.Trace;
|
||||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||||
|
import de.steamwar.entity.RBlockDisplay;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.util.Transformation;
|
||||||
|
import org.joml.Quaternionf;
|
||||||
|
import org.joml.Vector3f;
|
||||||
import yapion.hierarchy.types.YAPIONValue;
|
import yapion.hierarchy.types.YAPIONValue;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -41,7 +44,16 @@ import static de.steamwar.bausystem.features.util.TNTClickListener.TNT_CLICK_DET
|
|||||||
/**
|
/**
|
||||||
* Wrapper for the rendering of a record bundle
|
* Wrapper for the rendering of a record bundle
|
||||||
*/
|
*/
|
||||||
public class TraceEntity extends RFallingBlockEntity {
|
public class TraceEntity extends RBlockDisplay {
|
||||||
|
|
||||||
|
private static final float TNT_VISUAL_SCALE = 0.98F;
|
||||||
|
private static final float TNT_VISUAL_OFFSET = -TNT_VISUAL_SCALE / 2.0F;
|
||||||
|
private static final Transformation TNT_VISUAL_TRANSFORM = new Transformation(
|
||||||
|
new Vector3f(TNT_VISUAL_OFFSET, 0.0F, TNT_VISUAL_OFFSET),
|
||||||
|
new Quaternionf(0, 0, 0, 1),
|
||||||
|
new Vector3f(TNT_VISUAL_SCALE, TNT_VISUAL_SCALE, TNT_VISUAL_SCALE),
|
||||||
|
new Quaternionf(0, 0, 0, 1)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The records represented by this REntity
|
* The records represented by this REntity
|
||||||
@@ -57,11 +69,13 @@ public class TraceEntity extends RFallingBlockEntity {
|
|||||||
private final Trace trace;
|
private final Trace trace;
|
||||||
|
|
||||||
public TraceEntity(REntityServer server, Location location, boolean isExplosion, List<TNTPoint> records, Trace trace) {
|
public TraceEntity(REntityServer server, Location location, boolean isExplosion, List<TNTPoint> records, Trace trace) {
|
||||||
super(server, location, isExplosion ? Material.RED_STAINED_GLASS : Material.TNT);
|
super(server, location);
|
||||||
|
Material material = isExplosion ? Material.RED_STAINED_GLASS : Material.TNT;
|
||||||
this.records = records;
|
this.records = records;
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
uniqueTntIdsString = records.stream().map(TNTPoint::getTntId).distinct().map(Object::toString).collect(Collectors.joining(" "));
|
uniqueTntIdsString = records.stream().map(TNTPoint::getTntId).distinct().map(Object::toString).collect(Collectors.joining(" "));
|
||||||
setNoGravity(true);
|
setTransform(TNT_VISUAL_TRANSFORM);
|
||||||
|
setBlock(material.createBlockData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+46
-7
@@ -38,7 +38,11 @@ import net.minecraft.core.registries.BuiltInRegistries;
|
|||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.craftbukkit.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -46,10 +50,12 @@ import org.bukkit.event.EventHandler;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class TechHiderWrapper extends StateDependent implements Listener {
|
public class TechHiderWrapper extends StateDependent implements Listener {
|
||||||
|
|
||||||
@@ -57,9 +63,21 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
|
||||||
|
private final HullHider hullHider;
|
||||||
|
|
||||||
public TechHiderWrapper(HullHider hullHider) {
|
public TechHiderWrapper(HullHider hullHider) {
|
||||||
super(ENABLED, FightState.All);
|
super(ENABLED, FightState.All);
|
||||||
|
|
||||||
|
this.hullHider = hullHider;
|
||||||
|
|
||||||
|
new StateDependentListener(ENABLED, FightState.All, this);
|
||||||
|
register();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
Set<BlockState> blockStatesToObfuscate = getBlockStatesToHideFromMaterials(Config.GameModeConfig.Techhider.HiddenBlocks);
|
||||||
|
|
||||||
Set<Block> blocksToObfuscate = Config.GameModeConfig.Techhider.HiddenBlocks.stream()
|
Set<Block> blocksToObfuscate = Config.GameModeConfig.Techhider.HiddenBlocks.stream()
|
||||||
.map(CraftMagicNumbers::getBlock)
|
.map(CraftMagicNumbers::getBlock)
|
||||||
.collect(Collectors.toUnmodifiableSet());
|
.collect(Collectors.toUnmodifiableSet());
|
||||||
@@ -94,6 +112,11 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block);
|
return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlayerPrivilegedToAccessBlockState(Player p, int blockX, int blockY, int blockZ, BlockState blockState) {
|
||||||
|
return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blockStatesToObfuscate.contains(blockState);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO will require entity tracking on the netty thread to prevent future race conditions
|
// TODO will require entity tracking on the netty thread to prevent future race conditions
|
||||||
@Override
|
@Override
|
||||||
public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) {
|
public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) {
|
||||||
@@ -116,13 +139,6 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
return p.getGameMode() != GameMode.SPECTATOR;
|
return p.getGameMode() != GameMode.SPECTATOR;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
new StateDependentListener(ENABLED, FightState.All, this);
|
|
||||||
register();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enable() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,4 +191,27 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
|
|
||||||
return Fight.getOpposite(team).getExtendRegion();
|
return Fight.getOpposite(team).getExtendRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stream<BlockState> getWaterloggedBlockStates() {
|
||||||
|
FluidState waterFluidState = Fluids.WATER.getSource(false);
|
||||||
|
|
||||||
|
return BuiltInRegistries.BLOCK.stream()
|
||||||
|
.map((block) -> block.getStateDefinition().getPossibleStates())
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.filter((blockState -> blockState.getFluidState() == waterFluidState));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<BlockState> getBlockStatesToHideFromMaterials(Set<Material> materials) {
|
||||||
|
Stream<BlockState> allStatesFromMaterials = materials.stream()
|
||||||
|
.map(CraftMagicNumbers::getBlock)
|
||||||
|
.map((block) -> block.getStateDefinition().getPossibleStates())
|
||||||
|
.flatMap(Collection::stream);
|
||||||
|
|
||||||
|
if(materials.contains(Material.WATER)) {
|
||||||
|
return Stream.concat(allStatesFromMaterials, getWaterloggedBlockStates()).collect(Collectors.toUnmodifiableSet());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return allStatesFromMaterials.collect(Collectors.toUnmodifiableSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package de.steamwar.techhider;
|
|||||||
|
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public interface AccessPrivilegeProvider {
|
public interface AccessPrivilegeProvider {
|
||||||
@@ -30,6 +31,8 @@ public interface AccessPrivilegeProvider {
|
|||||||
|
|
||||||
boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block);
|
boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block);
|
||||||
|
|
||||||
|
boolean isPlayerPrivilegedToAccessBlockState(Player p, int blockX, int blockY, int blockZ, BlockState blockState);
|
||||||
|
|
||||||
boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId);
|
boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId);
|
||||||
|
|
||||||
boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type);
|
boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type);
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ public class ChunkHider {
|
|||||||
out.readBytes(data);
|
out.readBytes(data);
|
||||||
|
|
||||||
List<Object> blockEntities = chunkBlockEntitiesDataField.get(chunkData);
|
List<Object> blockEntities = chunkBlockEntitiesDataField.get(chunkData);
|
||||||
List<Object> filteredBlockEntities = filterBlockEntities(player, blockEntities);
|
List<Object> filteredBlockEntities = filterBlockEntities(player, blockEntities, chunkX, chunkZ);
|
||||||
|
|
||||||
return buildNewChunkPacket(packet, data, filteredBlockEntities);
|
return buildNewChunkPacket(packet, data, filteredBlockEntities);
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ public class ChunkHider {
|
|||||||
Block block = blockState.getBlock();
|
Block block = blockState.getBlock();
|
||||||
|
|
||||||
|
|
||||||
if (accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) {
|
if (accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlockState(player, worldX, worldY, worldZ, blockState)) {
|
||||||
obfuscatedData[blockDataIndex] = blockId;
|
obfuscatedData[blockDataIndex] = blockId;
|
||||||
} else {
|
} else {
|
||||||
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
|
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
|
||||||
@@ -256,18 +256,24 @@ public class ChunkHider {
|
|||||||
private static final Reflection.Field<Integer> packedXZField = Reflection.getField(blockEntitiyInfoClass, int.class, 0);
|
private static final Reflection.Field<Integer> packedXZField = Reflection.getField(blockEntitiyInfoClass, int.class, 0);
|
||||||
private static final Reflection.Field<Integer> yField = Reflection.getField(blockEntitiyInfoClass, int.class, 1);
|
private static final Reflection.Field<Integer> yField = Reflection.getField(blockEntitiyInfoClass, int.class, 1);
|
||||||
|
|
||||||
private List<Object> filterBlockEntities(Player player, List<Object> blockEntities) {
|
private List<Object> filterBlockEntities(Player player, List<Object> blockEntities, int chunkX, int chunkZ) {
|
||||||
|
int fourBitBitmask = 0b0000_1111;
|
||||||
|
|
||||||
return blockEntities.stream()
|
return blockEntities.stream()
|
||||||
.filter((blockEntityInfo) -> {
|
.filter((blockEntityInfo) -> {
|
||||||
BlockEntityType<?> type = blockEntityInfoTypeField.get(blockEntityInfo);
|
BlockEntityType<?> type = blockEntityInfoTypeField.get(blockEntityInfo);
|
||||||
|
|
||||||
int packedXZ = packedXZField.get(blockEntityInfo);
|
int packedXZ = packedXZField.get(blockEntityInfo);
|
||||||
|
|
||||||
int y = yField.get(blockEntityInfo);
|
int localX = (packedXZ >> 4) & fourBitBitmask;
|
||||||
int x = SectionPos.sectionRelativeX((short) packedXZ);
|
int localZ = packedXZ & fourBitBitmask;
|
||||||
int z = SectionPos.sectionRelativeZ((short) packedXZ);
|
|
||||||
|
|
||||||
return accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, x, y, z) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlockEntity(player, x, y, z, type);
|
int worldX = (chunkX * SECTION_SPAN_SIZE) + localX;
|
||||||
|
int worldZ = (chunkZ * SECTION_SPAN_SIZE) + localZ;
|
||||||
|
|
||||||
|
int worldY = yField.get(blockEntityInfo);
|
||||||
|
|
||||||
|
return accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlockEntity(player, worldX, worldY, worldZ, type);
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -423,12 +423,13 @@ public class TechHider {
|
|||||||
|
|
||||||
private Packet<?> processBlockUpdatePacket(Player player, ClientboundBlockUpdatePacket packet) {
|
private Packet<?> processBlockUpdatePacket(Player player, ClientboundBlockUpdatePacket packet) {
|
||||||
BlockPos blockPos = packet.getPos();
|
BlockPos blockPos = packet.getPos();
|
||||||
Block block = packet.getBlockState().getBlock();
|
BlockState blockState = packet.getBlockState();
|
||||||
|
Block block = blockState.getBlock();
|
||||||
int blockX = blockPos.getX();
|
int blockX = blockPos.getX();
|
||||||
int blockY = blockPos.getY();
|
int blockY = blockPos.getY();
|
||||||
int blockZ = blockPos.getZ();
|
int blockZ = blockPos.getZ();
|
||||||
|
|
||||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block)) {
|
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block) && privilegeProvider.isPlayerPrivilegedToAccessBlockState(player, blockX, blockY, blockZ, blockState)) {
|
||||||
return packet;
|
return packet;
|
||||||
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||||
return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation);
|
return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation);
|
||||||
@@ -471,7 +472,6 @@ public class TechHider {
|
|||||||
short[] oldPos = oldPosField.get(packet);
|
short[] oldPos = oldPosField.get(packet);
|
||||||
BlockState[] oldStates = oldStatesField.get(packet);
|
BlockState[] oldStates = oldStatesField.get(packet);
|
||||||
|
|
||||||
boolean modified = false;
|
|
||||||
List<Short> filteredPos = new ArrayList<>(oldPos.length);
|
List<Short> filteredPos = new ArrayList<>(oldPos.length);
|
||||||
List<BlockState> filteredStates = new ArrayList<>(oldStates.length);
|
List<BlockState> filteredStates = new ArrayList<>(oldStates.length);
|
||||||
|
|
||||||
@@ -484,12 +484,10 @@ public class TechHider {
|
|||||||
int worldY = sectionPos.relativeToBlockY(posShort);
|
int worldY = sectionPos.relativeToBlockY(posShort);
|
||||||
int worldZ = sectionPos.relativeToBlockZ(posShort);
|
int worldZ = sectionPos.relativeToBlockZ(posShort);
|
||||||
|
|
||||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) {
|
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block) && privilegeProvider.isPlayerPrivilegedToAccessBlockState(p, worldX, worldY, worldZ, state)) {
|
||||||
// TODO statefull !!!
|
|
||||||
filteredPos.add(posShort);
|
filteredPos.add(posShort);
|
||||||
filteredStates.add(state);
|
filteredStates.add(state);
|
||||||
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)) {
|
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)) {
|
||||||
modified = true;
|
|
||||||
filteredPos.add(posShort);
|
filteredPos.add(posShort);
|
||||||
filteredStates.add(blockStateUsedForObfuscation);
|
filteredStates.add(blockStateUsedForObfuscation);
|
||||||
}
|
}
|
||||||
@@ -498,9 +496,6 @@ public class TechHider {
|
|||||||
if (filteredStates.isEmpty()) {
|
if (filteredStates.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!modified) {
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
short[] newPos = new short[filteredPos.size()];
|
short[] newPos = new short[filteredPos.size()];
|
||||||
for (int i = 0; i < newPos.length; i++) {
|
for (int i = 0; i < newPos.length; i++) {
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ import net.md_5.bungee.api.chat.ClickEvent
|
|||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
object InviteCommand : SWCommand("invite") {
|
object InviteCommand : SWCommand("invite") {
|
||||||
|
init {
|
||||||
|
message = de.steamwar.tntleague.message
|
||||||
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
fun invitePlayer(@Validator("isLeader") sender: Player, target: Player) {
|
fun invitePlayer(@Validator("isLeader") sender: Player, target: Player) {
|
||||||
|
|||||||
@@ -42,6 +42,13 @@ public class ReplayCommand extends SWCommand {
|
|||||||
super("replay");
|
super("replay");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Register
|
||||||
|
public void genericCommand(PlayerChatter sender) {
|
||||||
|
sender.system("REPLAY_UNAVAILABLE");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
@Register
|
@Register
|
||||||
public void genericCommand(PlayerChatter sender, int replayId, @StaticValue(value = {"", "-a"}, allowISE = true) @OptionalValue("") boolean isAdmin, @OptionalValue("") String optionalMap) {
|
public void genericCommand(PlayerChatter sender, int replayId, @StaticValue(value = {"", "-a"}, allowISE = true) @OptionalValue("") boolean isAdmin, @OptionalValue("") String optionalMap) {
|
||||||
Fight fight = Fight.getById(replayId);
|
Fight fight = Fight.getById(replayId);
|
||||||
@@ -109,4 +116,5 @@ public class ReplayCommand extends SWCommand {
|
|||||||
private Message parseLeader(SteamwarUser leader, int players, boolean winner) {
|
private Message parseLeader(SteamwarUser leader, int players, boolean winner) {
|
||||||
return new Message("REPLAY_" + (players > 1 ? "" : "SOLO_") + (winner ? "WINNER" : "LOSER"), leader.getUserName(), players - 1);
|
return new Message("REPLAY_" + (players > 1 ? "" : "SOLO_") + (winner ? "WINNER" : "LOSER"), leader.getUserName(), players - 1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user