From af6c4337e369925de28586e3d20ba5d5781590d2 Mon Sep 17 00:00:00 2001 From: HarvelsX <90945793+HarvelsX@users.noreply.github.com> Date: Fri, 15 Apr 2022 00:44:14 +0300 Subject: [PATCH 1/3] Fix error translate block entity position & code cleanup; --- pom.xml | 6 +- src/fake_respawn_code.java | 21 - .../CoordinateOffset.java | 9 +- .../CoordinatesObfuscator.java | 385 ++++---- .../CoordsOffsetsManager.java | 3 - .../LastPlayerCoordinateManager.java | 21 +- .../coordinatesobfuscator/PlayerManager.java | 223 ++--- .../TranslatorClientbound.java | 904 +++++++++--------- .../TranslatorServerbound.java | 152 ++- 9 files changed, 850 insertions(+), 874 deletions(-) delete mode 100644 src/fake_respawn_code.java diff --git a/pom.xml b/pom.xml index d0f2af6..399d9aa 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.warp CoordinatesObfuscator - 1.4.3 + 1.4.4 CoordinatesObfuscator @@ -52,13 +52,13 @@ com.comphenix.protocol ProtocolLib - 4.7.0 + 5.0.0-SNAPSHOT provided io.papermc.paper paper-api - 1.17-R0.1-SNAPSHOT + 1.18.2-R0.1-SNAPSHOT provided diff --git a/src/fake_respawn_code.java b/src/fake_respawn_code.java deleted file mode 100644 index 83e61ee..0000000 --- a/src/fake_respawn_code.java +++ /dev/null @@ -1,21 +0,0 @@ -try { - { - var respawnFakePacket = new PacketContainer(Server.RESPAWN); - respawnFakePacket.getIntegers().write(0,Environment.NORMAL.getId()); - respawnFakePacket.getLongs().write(0,839834L); - respawnFakePacket.getGameModes().write(0,NativeGameMode.fromBukkit(player.getGameMode())); - respawnFakePacket.getWorldTypeModifier().write(0,player.getWorld().getWorldType()); - ProtocolLibrary.getProtocolManager().sendServerPacket(player,respawnFakePacket); - } - - { - var respawnFakePacket = new PacketContainer(Server.RESPAWN); - respawnFakePacket.getIntegers().write(0,player.getWorld().getEnvironment().getId()); - respawnFakePacket.getLongs().write(0,player.getWorld().getSeed()); - respawnFakePacket.getGameModes().write(0,NativeGameMode.fromBukkit(player.getGameMode())); - respawnFakePacket.getWorldTypeModifier().write(0,player.getWorld().getWorldType()); - ProtocolLibrary.getProtocolManager().sendServerPacket(player,respawnFakePacket); - } -} catch (InvocationTargetException e) { - e.printStackTrace(); -} \ No newline at end of file diff --git a/src/main/java/org/warp/coordinatesobfuscator/CoordinateOffset.java b/src/main/java/org/warp/coordinatesobfuscator/CoordinateOffset.java index 9155ee1..064c63a 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/CoordinateOffset.java +++ b/src/main/java/org/warp/coordinatesobfuscator/CoordinateOffset.java @@ -38,11 +38,11 @@ public void validate() { if ((int) (Math.round(z / 16f) * 16) != z) { throw new IllegalArgumentException("z is not aligned with the chunks!"); } - double reconvertedX = (double) ((int) x); + double reconvertedX = (int) x; if (reconvertedX != x) { throw new IllegalArgumentException("x is not safe to convert between double and int"); } - double reconvertedZ = (double) ((int) z); + double reconvertedZ = (int) z; if (reconvertedZ != z) { throw new IllegalArgumentException("z is not safe to convert between double and int"); } @@ -151,10 +151,7 @@ public boolean equals(final Object o) { if (Double.compare(this.getX(), other.getX()) != 0) { return false; } - if (Double.compare(this.getZ(), other.getZ()) != 0) { - return false; - } - return true; + return Double.compare(this.getZ(), other.getZ()) == 0; } public int hashCode() { diff --git a/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java b/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java index 2d27ef4..325c874 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java +++ b/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java @@ -15,11 +15,13 @@ import com.comphenix.protocol.injector.GamePhase; import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; import com.comphenix.protocol.wrappers.nbt.NbtBase; + import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.logging.Logger; + import org.bukkit.Bukkit; import org.bukkit.World.Environment; import org.bukkit.entity.Player; @@ -32,198 +34,197 @@ public class CoordinatesObfuscator extends JavaPlugin implements Listener { + public static final boolean DEBUG_ENABLED = "debug".equals(System.getProperty("coordinates_obfuscator.env")); + public static final boolean DISALLOW_REMOVING_NONEXISTENT_COORDINATES = false; + private Logger logger; + + @Override + public void onDisable() { + PlayerManager.unload(); + } + - public static final boolean DEBUG_ENABLED = "debug".equals(System.getProperty("coordinates_obfuscator.env")); - public static final boolean DISALLOW_REMOVING_NONEXISTENT_COORDINATES = false; - private Logger logger; - - @Override - public void onDisable() { - PlayerManager.unload(); - } + @SuppressWarnings("CommentedOutCode") + @Override + public void onEnable() { + this.logger = getLogger(); + PlayerManager.load(logger); + + Bukkit.getPluginManager().registerEvents(this, this); + + final ProtocolManager pm = ProtocolLibrary.getProtocolManager(); + + final HashSet packets = new HashSet(); - - @SuppressWarnings("CommentedOutCode") - @Override - public void onEnable() { - this.logger = getLogger(); - PlayerManager.load(logger); - - Bukkit.getPluginManager().registerEvents(this, this); - - final ProtocolManager pm = ProtocolLibrary.getProtocolManager(); - - final HashSet packets = new HashSet(); - - // /Server side packets - { - final PacketAdapter.AdapterParameteters paramsServer = PacketAdapter.params(); - paramsServer.plugin(this); - paramsServer.connectionSide(ConnectionSide.SERVER_SIDE); - paramsServer.listenerPriority(ListenerPriority.HIGHEST); - paramsServer.gamePhase(GamePhase.PLAYING); - - packets.add(PacketType.Play.Server.BLOCK_ACTION); - packets.add(PacketType.Play.Server.BLOCK_BREAK); - packets.add(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); - packets.add(PacketType.Play.Server.BLOCK_CHANGE); - packets.add(PacketType.Play.Server.MULTI_BLOCK_CHANGE); - packets.add(PacketType.Play.Server.MAP_CHUNK); - packets.add(Server.UNLOAD_CHUNK); - packets.add(PacketType.Play.Server.LIGHT_UPDATE); - packets.add(PacketType.Play.Server.EXPLOSION); - packets.add(PacketType.Play.Server.SPAWN_POSITION); - - packets.add(PacketType.Play.Server.RESPAWN); - packets.add(PacketType.Play.Server.POSITION); - - packets.add(PacketType.Play.Server.WORLD_PARTICLES); - packets.add(PacketType.Play.Server.WORLD_EVENT); - - packets.add(PacketType.Play.Server.NAMED_SOUND_EFFECT); - - packets.add(PacketType.Play.Server.NAMED_ENTITY_SPAWN); - packets.add(PacketType.Play.Server.SPAWN_ENTITY); - packets.add(PacketType.Play.Server.SPAWN_ENTITY_LIVING); - packets.add(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB); - packets.add(PacketType.Play.Server.SPAWN_ENTITY_PAINTING); - packets.add(PacketType.Play.Server.ENTITY_TELEPORT); - - packets.add(PacketType.Play.Server.OPEN_SIGN_EDITOR); - packets.add(PacketType.Play.Server.ADD_VIBRATION_SIGNAL); - - packets.add(PacketType.Play.Server.ENTITY_METADATA); - packets.add(PacketType.Play.Server.VIEW_CENTRE); - packets.add(PacketType.Play.Server.WINDOW_ITEMS); - packets.add(PacketType.Play.Server.WINDOW_DATA); - packets.add(PacketType.Play.Server.SET_SLOT); - - packets.add(Server.TILE_ENTITY_DATA); - - //todo: these packets shouldn't have position. Check if some of them must be translated - // packets.add(Server.ENTITY_DESTROY); - // packets.add(Server.ENTITY_EQUIPMENT); - // packets.add(Server.ENTITY_LOOK); - // packets.add(Server.ENTITY_EFFECT); - // packets.add(Server.ENTITY_HEAD_ROTATION); - // packets.add(Server.ENTITY_SOUND); - // packets.add(Server.ENTITY_STATUS); - // packets.add(Server.ENTITY_VELOCITY); - // packets.add(Server.REL_ENTITY_MOVE); - // packets.add(Server.REL_ENTITY_MOVE_LOOK); - // packets.add(Server.ATTACH_ENTITY); - - paramsServer.types(packets); - - pm.addPacketListener(new PacketAdapter(paramsServer) { - @SuppressWarnings("DuplicateBranchesInSwitch") - @Override - public void onPacketSending(final PacketEvent event) { - - PacketContainer packet; - - switch (event.getPacket().getType().name()) { - case "LIGHT_UPDATE" -> packet = event.getPacket().shallowClone(); - case "TILE_ENTITY_DATA" -> packet = cloneTileEntityData(event.getPacket()); - case "MAP_CHUNK" -> packet = cloneMapChunkEntitiesData(event.getPacket()); - default -> packet = event.getPacket().shallowClone(); - } - - Player player = event.getPlayer(); - - boolean cancel = TranslatorClientbound.outgoing(logger, packet, player); - - event.setPacket(packet); - - if (cancel) { - event.setCancelled(true); - } - } - - }); - - } - // End Server Packets - - // /Client side Packets - { - final PacketAdapter.AdapterParameteters paramsClient = PacketAdapter.params(); - paramsClient.plugin(this); - paramsClient.connectionSide(ConnectionSide.CLIENT_SIDE); - paramsClient.listenerPriority(ListenerPriority.LOWEST); - paramsClient.gamePhase(GamePhase.PLAYING); - - packets.clear(); - - packets.add(PacketType.Play.Client.POSITION); - packets.add(PacketType.Play.Client.POSITION_LOOK); - packets.add(PacketType.Play.Client.BLOCK_DIG); - packets.add(PacketType.Play.Client.BLOCK_PLACE); - packets.add(PacketType.Play.Client.USE_ITEM); - packets.add(PacketType.Play.Client.USE_ENTITY); - packets.add(PacketType.Play.Client.VEHICLE_MOVE); - packets.add(PacketType.Play.Client.SET_COMMAND_BLOCK); - packets.add(PacketType.Play.Client.SET_JIGSAW); - packets.add(PacketType.Play.Client.STRUCT); - packets.add(PacketType.Play.Client.UPDATE_SIGN); - - paramsClient.types(packets); - - pm.addPacketListener(new PacketAdapter(paramsClient) { - - - @Override - public void onPacketReceiving(final PacketEvent event) { - try { - TranslatorServerbound.incoming(logger, event.getPacket(), event.getPlayer()); - } catch (final UnsupportedOperationException e) { - event.setCancelled(true); - e.printStackTrace(); - if (event.getPlayer() != null) { - Bukkit.getServer().broadcastMessage("Failed: " + event.getPacket().getType().name()); - } - } - } - }); - } - // End client packets - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerQuit(final PlayerQuitEvent event) { - PlayerManager.exitPlayer(event.getPlayer()); - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerJoin(final PlayerJoinEvent event) { - // This part of code has been commented because this event is fired too late. - //PlayerManager.joinPlayer(event.getPlayer()); - } - - - private PacketContainer cloneTileEntityData(PacketContainer packet) { - packet = packet.shallowClone(); - int i = 0; - for (final NbtBase obj : packet.getNbtModifier().getValues()) { - packet.getNbtModifier().write(i, obj.deepClone()); - i++; - } - - return packet; - } - - private PacketContainer cloneMapChunkEntitiesData(PacketContainer packet) { - packet = packet.shallowClone(); - int i = 0; - for (final List> obj : packet.getListNbtModifier().getValues()) { - ArrayList> newList = new ArrayList>(obj.size()); - for (NbtBase nbtBase : obj) { - newList.add(nbtBase.deepClone()); - } - packet.getListNbtModifier().write(i, newList); - i++; - } - - return packet; - } + // /Server side packets + { + final PacketAdapter.AdapterParameteters paramsServer = PacketAdapter.params(); + paramsServer.plugin(this); + paramsServer.connectionSide(ConnectionSide.SERVER_SIDE); + paramsServer.listenerPriority(ListenerPriority.HIGHEST); + paramsServer.gamePhase(GamePhase.PLAYING); + + packets.add(PacketType.Play.Server.BLOCK_ACTION); + packets.add(PacketType.Play.Server.BLOCK_BREAK); + packets.add(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); + packets.add(PacketType.Play.Server.BLOCK_CHANGE); + packets.add(PacketType.Play.Server.MULTI_BLOCK_CHANGE); + packets.add(PacketType.Play.Server.MAP_CHUNK); + packets.add(Server.UNLOAD_CHUNK); + packets.add(PacketType.Play.Server.LIGHT_UPDATE); + packets.add(PacketType.Play.Server.EXPLOSION); + packets.add(PacketType.Play.Server.SPAWN_POSITION); + + packets.add(PacketType.Play.Server.RESPAWN); + packets.add(PacketType.Play.Server.POSITION); + + packets.add(PacketType.Play.Server.WORLD_PARTICLES); + packets.add(PacketType.Play.Server.WORLD_EVENT); + + packets.add(PacketType.Play.Server.NAMED_SOUND_EFFECT); + + packets.add(PacketType.Play.Server.NAMED_ENTITY_SPAWN); + packets.add(PacketType.Play.Server.SPAWN_ENTITY); + packets.add(PacketType.Play.Server.SPAWN_ENTITY_LIVING); + packets.add(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB); + packets.add(PacketType.Play.Server.SPAWN_ENTITY_PAINTING); + packets.add(PacketType.Play.Server.ENTITY_TELEPORT); + + packets.add(PacketType.Play.Server.OPEN_SIGN_EDITOR); + packets.add(PacketType.Play.Server.ADD_VIBRATION_SIGNAL); + + packets.add(PacketType.Play.Server.ENTITY_METADATA); + packets.add(PacketType.Play.Server.VIEW_CENTRE); + packets.add(PacketType.Play.Server.WINDOW_ITEMS); + packets.add(PacketType.Play.Server.WINDOW_DATA); + packets.add(PacketType.Play.Server.SET_SLOT); + + packets.add(Server.TILE_ENTITY_DATA); + + //todo: these packets shouldn't have position. Check if some of them must be translated + // packets.add(Server.ENTITY_DESTROY); + // packets.add(Server.ENTITY_EQUIPMENT); + // packets.add(Server.ENTITY_LOOK); + // packets.add(Server.ENTITY_EFFECT); + // packets.add(Server.ENTITY_HEAD_ROTATION); + // packets.add(Server.ENTITY_SOUND); + // packets.add(Server.ENTITY_STATUS); + // packets.add(Server.ENTITY_VELOCITY); + // packets.add(Server.REL_ENTITY_MOVE); + // packets.add(Server.REL_ENTITY_MOVE_LOOK); + // packets.add(Server.ATTACH_ENTITY); + + paramsServer.types(packets); + + pm.addPacketListener(new PacketAdapter(paramsServer) { + @SuppressWarnings("DuplicateBranchesInSwitch") + @Override + public void onPacketSending(final PacketEvent event) { + + PacketContainer packet; + + switch (event.getPacket().getType().name()) { + case "LIGHT_UPDATE" -> packet = event.getPacket().shallowClone(); + case "TILE_ENTITY_DATA" -> packet = cloneTileEntityData(event.getPacket()); + case "MAP_CHUNK" -> packet = cloneMapChunkEntitiesData(event.getPacket()); + default -> packet = event.getPacket().shallowClone(); + } + + Player player = event.getPlayer(); + + boolean cancel = TranslatorClientbound.outgoing(logger, packet, player); + + event.setPacket(packet); + + if (cancel) { + event.setCancelled(true); + } + } + + }); + + } + // End Server Packets + + // /Client side Packets + { + final PacketAdapter.AdapterParameteters paramsClient = PacketAdapter.params(); + paramsClient.plugin(this); + paramsClient.connectionSide(ConnectionSide.CLIENT_SIDE); + paramsClient.listenerPriority(ListenerPriority.LOWEST); + paramsClient.gamePhase(GamePhase.PLAYING); + + packets.clear(); + + packets.add(PacketType.Play.Client.POSITION); + packets.add(PacketType.Play.Client.POSITION_LOOK); + packets.add(PacketType.Play.Client.BLOCK_DIG); + packets.add(PacketType.Play.Client.BLOCK_PLACE); + packets.add(PacketType.Play.Client.USE_ITEM); + packets.add(PacketType.Play.Client.USE_ENTITY); + packets.add(PacketType.Play.Client.VEHICLE_MOVE); + packets.add(PacketType.Play.Client.SET_COMMAND_BLOCK); + packets.add(PacketType.Play.Client.SET_JIGSAW); + packets.add(PacketType.Play.Client.STRUCT); + packets.add(PacketType.Play.Client.UPDATE_SIGN); + + paramsClient.types(packets); + + pm.addPacketListener(new PacketAdapter(paramsClient) { + + + @Override + public void onPacketReceiving(final PacketEvent event) { + try { + TranslatorServerbound.incoming(logger, event.getPacket(), event.getPlayer()); + } catch (final UnsupportedOperationException e) { + event.setCancelled(true); + e.printStackTrace(); + if (event.getPlayer() != null) { + Bukkit.getServer().broadcastMessage("Failed: " + event.getPacket().getType().name()); + } + } + } + }); + } + // End client packets + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerQuit(final PlayerQuitEvent event) { + PlayerManager.exitPlayer(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerJoin(final PlayerJoinEvent event) { + // This part of code has been commented because this event is fired too late. + //PlayerManager.joinPlayer(event.getPlayer()); + } + + + private PacketContainer cloneTileEntityData(PacketContainer packet) { + packet = packet.shallowClone(); + int i = 0; + for (final NbtBase obj : packet.getNbtModifier().getValues()) { + packet.getNbtModifier().write(i, obj.deepClone()); + i++; + } + + return packet; + } + + private PacketContainer cloneMapChunkEntitiesData(PacketContainer packet) { + packet = packet.shallowClone(); + int i = 0; + for (final List> obj : packet.getListNbtModifier().getValues()) { + ArrayList> newList = new ArrayList>(obj.size()); + for (NbtBase nbtBase : obj) { + newList.add(nbtBase.deepClone()); + } + packet.getListNbtModifier().write(i, newList); + i++; + } + + return packet; + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java b/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java index 69c5bf4..700d87d 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java +++ b/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java @@ -145,9 +145,6 @@ private CoordinateOffset getValueOrNull(UUID playerUUID, UUID worldUUID) { return null; } CoordinateOffset offset = worldsMap.get(worldUUID); - if (offset == null) { - return null; - } return offset; } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java b/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java index 59970f2..3c32432 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java +++ b/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java @@ -4,20 +4,21 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; + import org.bukkit.Location; public class LastPlayerCoordinateManager { - Map locations = new HashMap<>(); + Map locations = new HashMap<>(); - public synchronized Optional getLastPlayerLocation(UUID player) { - return Optional.ofNullable(locations.getOrDefault(player, null)); - } + public synchronized Optional getLastPlayerLocation(UUID player) { + return Optional.ofNullable(locations.getOrDefault(player, null)); + } - public synchronized void setLastPlayerLocation(UUID player, Location location) { - locations.put(player, location); - } + public synchronized void setLastPlayerLocation(UUID player, Location location) { + locations.put(player, location); + } - public synchronized void resetLastPlayerLocation(UUID player) { - locations.remove(player); - } + public synchronized void resetLastPlayerLocation(UUID player) { + locations.remove(player); + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java b/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java index 20339ff..e640565 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java +++ b/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java @@ -1,124 +1,125 @@ package org.warp.coordinatesobfuscator; -import com.comphenix.protocol.injector.server.TemporaryPlayer; import java.util.Optional; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; + +import com.comphenix.protocol.injector.temporary.TemporaryPlayer; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; public class PlayerManager { - private static final Random random = new Random(); - private static final int staticXOffset = getRandomChunkOffsetBase(); - private static final int staticZOffset = getRandomChunkOffsetBase(); - private static Logger logger; - private static CoordsOffsetsManager coordsOffsetsManager; - private static LastPlayerCoordinateManager lastPlayerCoordinateManager; - - public static void spawnPlayer(final Player player, final World world) { - coordsOffsetsManager.put(player, world, generateOffset()); - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - } - - public static CoordinateOffset respawnPlayer(final Player player, final World world) { - CoordinateOffset offset = generateOffset(); - coordsOffsetsManager.replace(player, world, offset); - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - return offset; - } - - public static CoordinateOffset teleportPlayer(final Player player, final World world, boolean overrideLastLocation) { - CoordinateOffset offset = generateOffset(); - coordsOffsetsManager.replace(player, world, offset); - if (overrideLastLocation) { - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - } - - return offset; - } - - public static void joinPlayer(final Player player) { - if (!(player instanceof TemporaryPlayer)) { - coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - } else { - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } - } - - private static CoordinateOffset generateOffset() { - //return CoordinateOffset.of(64 * 16, 64 * 16); - return CoordinateOffset.of(getRandomChunkOffset(true) * 16, getRandomChunkOffset(false) * 16); - } - - private static int getRandomChunkOffset(boolean x) { - return getRandomChunkOffsetBase() + (x ? staticXOffset : staticZOffset); - } - - private static int getRandomChunkOffsetBase() { - int number = 64 + random.nextInt((int) Math.floor(496000d / 16d) - 64); - if (random.nextBoolean()) { - number *= -1; - } - return number; - } - - public static void exitPlayer(final Player player) { - coordsOffsetsManager.remove(player.getUniqueId()); - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } - - public static void load(Logger pluginLogger) { - logger = pluginLogger; - coordsOffsetsManager = new CoordsOffsetsManager(pluginLogger); - lastPlayerCoordinateManager = new LastPlayerCoordinateManager(); - } - - public static void unload() { - logger = null; - coordsOffsetsManager = null; - lastPlayerCoordinateManager = null; - } - - public static CoordinateOffset getOffset(Player player) { - return coordsOffsetsManager.get(player, player.getWorld()); - } - - public static CoordinateOffset getOffset(Player player, World world) { - return coordsOffsetsManager.get(player, world); - } - - public static CoordinateOffset getOffsetOrNull(Player player, World world) { - return coordsOffsetsManager.getOrNull(player, world); - } - - public static CoordinateOffset getOffsetOrJoinPlayer(Player player, World world) { - AtomicBoolean generated = new AtomicBoolean(false); - CoordinateOffset result = coordsOffsetsManager.getOrPut(player, world, () -> { - generated.set(true); - return generateOffset(); - }); - if (generated.get()) { - if (!(player instanceof TemporaryPlayer)) { - coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); - } - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } - return result; - } - - public static Optional getLastPlayerLocation(Player player) { - return lastPlayerCoordinateManager.getLastPlayerLocation(player.getUniqueId()); - } - - public static void setLastPlayerLocation(Player player, Location location) { - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), location); - } - - public static void resetLastPlayerLocation(Player player) { - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } + private static final Random random = new Random(); + private static final int staticXOffset = getRandomChunkOffsetBase(); + private static final int staticZOffset = getRandomChunkOffsetBase(); + private static Logger logger; + private static CoordsOffsetsManager coordsOffsetsManager; + private static LastPlayerCoordinateManager lastPlayerCoordinateManager; + + public static void spawnPlayer(final Player player, final World world) { + coordsOffsetsManager.put(player, world, generateOffset()); + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + } + + public static CoordinateOffset respawnPlayer(final Player player, final World world) { + CoordinateOffset offset = generateOffset(); + coordsOffsetsManager.replace(player, world, offset); + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + return offset; + } + + public static CoordinateOffset teleportPlayer(final Player player, final World world, boolean overrideLastLocation) { + CoordinateOffset offset = generateOffset(); + coordsOffsetsManager.replace(player, world, offset); + if (overrideLastLocation) { + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + } + + return offset; + } + + public static void joinPlayer(final Player player) { + if (!(player instanceof TemporaryPlayer)) { + coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + } else { + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } + } + + private static CoordinateOffset generateOffset() { + //return CoordinateOffset.of(64 * 16, 64 * 16); + return CoordinateOffset.of(getRandomChunkOffset(true) * 16, getRandomChunkOffset(false) * 16); + } + + private static int getRandomChunkOffset(boolean x) { + return getRandomChunkOffsetBase() + (x ? staticXOffset : staticZOffset); + } + + private static int getRandomChunkOffsetBase() { + int number = 64 + random.nextInt((int) Math.floor(496000d / 16d) - 64); + if (random.nextBoolean()) { + number *= -1; + } + return number; + } + + public static void exitPlayer(final Player player) { + coordsOffsetsManager.remove(player.getUniqueId()); + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } + + public static void load(Logger pluginLogger) { + logger = pluginLogger; + coordsOffsetsManager = new CoordsOffsetsManager(pluginLogger); + lastPlayerCoordinateManager = new LastPlayerCoordinateManager(); + } + + public static void unload() { + logger = null; + coordsOffsetsManager = null; + lastPlayerCoordinateManager = null; + } + + public static CoordinateOffset getOffset(Player player) { + return coordsOffsetsManager.get(player, player.getWorld()); + } + + public static CoordinateOffset getOffset(Player player, World world) { + return coordsOffsetsManager.get(player, world); + } + + public static CoordinateOffset getOffsetOrNull(Player player, World world) { + return coordsOffsetsManager.getOrNull(player, world); + } + + public static CoordinateOffset getOffsetOrJoinPlayer(Player player, World world) { + AtomicBoolean generated = new AtomicBoolean(false); + CoordinateOffset result = coordsOffsetsManager.getOrPut(player, world, () -> { + generated.set(true); + return generateOffset(); + }); + if (generated.get()) { + if (!(player instanceof TemporaryPlayer)) { + coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); + } + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } + return result; + } + + public static Optional getLastPlayerLocation(Player player) { + return lastPlayerCoordinateManager.getLastPlayerLocation(player.getUniqueId()); + } + + public static void setLastPlayerLocation(Player player, Location location) { + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), location); + } + + public static void resetLastPlayerLocation(Player player) { + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java b/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java index 74f1400..37a78cd 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java +++ b/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java @@ -1,466 +1,470 @@ package org.warp.coordinatesobfuscator; +import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.injector.server.TemporaryPlayer; +import com.comphenix.protocol.injector.temporary.TemporaryPlayer; +import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.BlockPosition; import com.comphenix.protocol.wrappers.Converters; import com.comphenix.protocol.wrappers.WrappedWatchableObject; -import com.comphenix.protocol.wrappers.nbt.NbtBase; import com.comphenix.protocol.wrappers.nbt.NbtCompound; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.logging.Logger; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +import java.util.logging.Logger; + public class TranslatorClientbound { - private static final Class NMS_BLOCK_POSITION_CLASS; - private static final Method NMS_BLOCK_POSITION_ADD_CLASS; - - static { - Class blockPositionClass = null; - try { - blockPositionClass = Class.forName("net.minecraft.core.BlockPosition"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - NMS_BLOCK_POSITION_CLASS = blockPositionClass; - - Method blockPositionAddMethod = null; - try { - blockPositionAddMethod = blockPositionClass.getDeclaredMethod("c", int.class, int.class, int.class); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - NMS_BLOCK_POSITION_ADD_CLASS = blockPositionAddMethod; - } - - public static boolean outgoing(Logger logger, final PacketContainer packet, final Player player) { - if (player instanceof TemporaryPlayer) { - return false; - } - CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); - Objects.requireNonNull(offset); - switch (packet.getType().name()) { - case "WINDOW_DATA": - break; - case "WINDOW_ITEMS": - fixWindowItems(logger, packet, offset); - break; - case "SET_SLOT": - fixWindowItem(logger, packet, offset); - break; - case "SPAWN_POSITION": - case "WORLD_EVENT": - case "UPDATE_SIGN": - case "BLOCK_BREAK": - case "BLOCK_BREAK_ANIMATION": - case "BLOCK_ACTION": - case "BLOCK_CHANGE": - case "SPAWN_ENTITY_PAINTING": - case "OPEN_SIGN_EDITOR": - sendBlockPosition(logger, packet, offset); - break; - case "ADD_VIBRATION_SIGNAL": - fixVibrationSignal(logger, packet, offset); - break; - case "RESPAWN": - logger.fine("[out]Respawning player"); - respawn(logger, offset, player); - break; - case "POSITION_LOOK": - case "POSITION": - boolean isRelativeX = false; - boolean isRelativeZ = false; - Set items = packet.getSets(Converters.passthrough(Enum.class)).read(0); - //noinspection rawtypes - for (Enum item : items) { - switch (item.name()) { - case "X": - isRelativeX = true; - break; - case "Z": - isRelativeZ = true; - break; - } - } - if (!isRelativeX || !isRelativeZ) { - logger.fine("[out]Repositioning player"); - CoordinateOffset positionOffset; - if (!isRelativeX && !isRelativeZ) { - positionOffset = respawn(logger, offset, player); - } else { - positionOffset = offset; - } - if (packet.getDoubles().size() > 2) { - if (!isRelativeX) { - packet.getDoubles().modify(0, x -> x == null ? null : x - positionOffset.getX()); - } - if (!isRelativeZ) { - packet.getDoubles().modify(2, z -> z == null ? null : z - positionOffset.getZ()); - } - } else { - logger.severe("Packet size error"); - } - } - break; - case "BED": - //todo: remove - //sendInt(packet, offset, 1); - break; - case "NAMED_ENTITY_SPAWN": - case "SPAWN_ENTITY": - Objects.requireNonNull(offset); - sendDouble(logger, packet, offset); - break; - case "SPAWN_ENTITY_LIVING": - case "WORLD_PARTICLES": - case "SPAWN_ENTITY_WEATHER": - case "SPAWN_ENTITY_EXPERIENCE_ORB": - case "ENTITY_TELEPORT": - sendDouble(logger, packet, offset); - break; - case "UNLOAD_CHUNK": - sendChunk(logger, packet, offset, false, false); - break; - case "LIGHT_UPDATE": - sendChunk(logger, packet, offset, false, true); - break; - case "MAP_CHUNK": - sendChunk(logger, packet, offset, true, false); - break; - case "MULTI_BLOCK_CHANGE": - sendChunkUpdate(logger, packet, offset); - break; - case "VIEW_CENTRE": - sendIntChunk(logger, packet, offset); - break; - case "MAP_CHUNK_BULK": - sendChunkBulk(logger, packet, offset); - break; - case "EXPLOSION": - sendExplosion(logger, packet, offset); - break; - case "NAMED_SOUND_EFFECT": - sendInt8(logger, packet, offset); - break; - case "ENTITY_METADATA": - if (packet.getWatchableCollectionModifier().size() > 0) { - packet.getWatchableCollectionModifier().modify(0, wrappedWatchableObjects -> { - if (wrappedWatchableObjects == null) - return null; - ArrayList result = new ArrayList(wrappedWatchableObjects.size()); - for (WrappedWatchableObject wrappedWatchableObject : wrappedWatchableObjects) { - if (wrappedWatchableObject == null) { - result.add(null); - continue; - } - - Object oldValue = wrappedWatchableObject.getValue(); - if (oldValue instanceof Optional) { - //noinspection rawtypes - Optional opt = (Optional) oldValue; - if (opt.isPresent()) { - Object val = opt.get(); - if (NMS_BLOCK_POSITION_CLASS.isInstance(val)) { - wrappedWatchableObject.setValue(Optional.of(offsetPositionMc(logger, offset, val))); - } - } - } else if (oldValue instanceof BlockPosition blockPosition) { - wrappedWatchableObject.setValue(offsetPosition(logger, offset, blockPosition)); - } - result.add(wrappedWatchableObject); - } - return result; - }); - } - break; - case "TILE_ENTITY_DATA": - sendTileEntityData(logger, packet, offset); - break; - case "PLAYER_INFO": - break; - default: - logger.fine(packet.getType().name()); - break; - } - return false; - } - - private static CoordinateOffset respawn(Logger logger, CoordinateOffset offset, Player player) { - boolean hasSetLastLocation = false; - Optional lastLocationOpt = PlayerManager.getLastPlayerLocation(player); - if (lastLocationOpt.isPresent()) { - Location lastLocation = lastLocationOpt.get(); - if (lastLocation.getWorld().getUID().equals(player.getLocation().getWorld().getUID())) { - int clientViewDistance = 64; //player.getClientViewDistance(); - int minTeleportDistance = clientViewDistance * 2 * 16 + 2; - minTeleportDistance *= minTeleportDistance; // squared - if (lastLocation.distanceSquared(player.getLocation()) > minTeleportDistance) { - offset = PlayerManager.teleportPlayer(player, player.getWorld(), true); - logger.fine("Teleporting player. Prev[" + lastLocation.getBlockX() + "," + lastLocation.getBlockZ() + "] Next[" + player.getLocation().getX() + "," + player.getLocation().getZ() + "]" ); - hasSetLastLocation = true; - } - } - } - if (hasSetLastLocation) { - PlayerManager.setLastPlayerLocation(player, player.getLocation()); - } - return offset; - } - - private static void fixWindowItems(Logger logger, PacketContainer packet, CoordinateOffset offset) { - packet.getItemListModifier().modify(0, itemStacks -> { - if (itemStacks == null) - return null; - List newItems = new ArrayList<>(itemStacks.size()); - for (ItemStack itemStack : itemStacks) { - if (itemStack == null) { - newItems.add(null); - continue; - } - newItems.add(transformItemStack(logger, itemStack, offset)); - } - return newItems; - }); - } - - private static void fixWindowItem(Logger logger, PacketContainer packet, CoordinateOffset offset) { - packet.getItemModifier().modify(0, itemStack -> { - if (itemStack == null) { - return null; - } - return transformItemStack(logger, itemStack, offset); - }); - } - - private static ItemStack transformItemStack(Logger logger, ItemStack itemStack, CoordinateOffset offset) { - itemStack = itemStack.clone(); - - if (itemStack.hasItemMeta()) { - ItemMeta itemMeta = itemStack.getItemMeta(); - - if (itemMeta instanceof org.bukkit.inventory.meta.CompassMeta) { - org.bukkit.inventory.meta.CompassMeta compassMeta = (org.bukkit.inventory.meta.CompassMeta) itemMeta; - Location lodestoneLocation = compassMeta.getLodestone(); - if (lodestoneLocation != null) { - compassMeta.setLodestone(lodestoneLocation.subtract(offset.getXInt(), 0, offset.getZInt())); - if (!itemStack.setItemMeta(compassMeta)) { - logger.severe("Can't apply meta"); - } - } - } - } - return itemStack; - } - - - private static void sendChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset, boolean includesEntities, boolean includeLight) { - StructureModifier integers = packet.getIntegers(); - integers.modify(0, curr_x -> { - if (curr_x != null) { - return curr_x - offset.getXChunk(); - } else { - return null; - } - }); - integers.modify(1, curr_z -> { - if (curr_z != null) { - return curr_z - offset.getZChunk(); - } else { - return null; - } - }); - if (includeLight) { - StructureModifier> byteArrays = packet.getLists(Converters.passthrough(byte[].class)); - for (int i = 0; i < 2; i++) { - byteArrays.modify(i, list -> { - if (list == null) return null; - ArrayList newList = new ArrayList<>(list); - newList.replaceAll(bytes -> Arrays.copyOf(bytes, bytes.length)); - return newList; - }); - } - } - if (includesEntities) { - packet.getListNbtModifier().modify(0, entities -> { - if (entities != null) { - for (NbtBase entity : entities) { - NbtCompound entityCompound = (NbtCompound) entity; - if (entityCompound.containsKey("x") && entityCompound.containsKey("z")) { - entityCompound.put("x", entityCompound.getInteger("x") - offset.getXInt()); - entityCompound.put("z", entityCompound.getInteger("z") - offset.getZInt()); - } - } - return entities; - } else { - return null; - } - }); - } - } - - - private static void sendChunkBulk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getIntegerArrays().size() > 1) { - final int[] x = packet.getIntegerArrays().read(0).clone(); - final int[] z = packet.getIntegerArrays().read(1).clone(); - - for (int i = 0; i < x.length; i++) { - - x[i] = x[i] - offset.getXChunk(); - z[i] = z[i] - offset.getZChunk(); - } - - packet.getIntegerArrays().write(0, x); - packet.getIntegerArrays().write(1, z); - } else { - logger.severe("Packet size error"); - } - } - - private static void sendChunkUpdate(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - BlockPosition sp = packet.getSectionPositions().read(0); - if (sp == null) { - return; - } - packet.getSectionPositions().write(0, sp.subtract(new BlockPosition(offset.getXChunk(), 0, offset.getZChunk()))); - } - - - private static void sendDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getDoubles().size() > 2) { - packet.getDoubles().modify(0, x -> x == null ? null : x - offset.getX()); - packet.getDoubles().modify(2, z -> z == null ? null : z - offset.getZ()); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendExplosion(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - sendDouble(logger, packet, offset); - - packet.getBlockPositionCollectionModifier().modify(0, lst -> { - if (lst == null) return null; - ArrayList newLst = new ArrayList(lst.size()); - for (BlockPosition blockPosition : lst) { - newLst.add(blockPosition.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); - } - return newLst; - }); - } - - - private static void sendFixedPointNumber(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 5)); - packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 5)); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendFloat(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getFloat().size() > 2) { - packet.getFloat().modify(index, curr_x -> curr_x == null ? null : (float) (curr_x - offset.getX())); - packet.getFloat().modify(index + 2, curr_z -> curr_z == null ? null : (float) (curr_z - offset.getZ())); - } else { - logger.severe("Packet size error"); - } - } - - private static void sendInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - offset.getXInt()); - packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - offset.getZInt()); - } else { - logger.severe("Packet size error"); - } - } - - private static void sendIntChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getIntegers().size() > 1) { - packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - offset.getXChunk()); - packet.getIntegers().modify(1, curr_z -> curr_z == null ? null : curr_z - offset.getZChunk()); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendBlockPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getBlockPositionModifier().size() > 0) { - packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - } - - private static void fixVibrationSignal(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getBlockPositionModifier().size() >= 1) { - packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - if (packet.getBlockPositionModifier().size() >= 2) { - packet.getBlockPositionModifier().modify(1, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - } - - private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { - if (pos == null) return null; - return pos.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); - } - - private static Object offsetPositionMc(Logger logger, CoordinateOffset offset, Object pos) { - if (pos == null) return null; - try { - return NMS_BLOCK_POSITION_ADD_CLASS.invoke(pos, -offset.getXInt(), -0, -offset.getZInt()); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - - private static void sendInt8(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 3)); - packet.getIntegers().modify(2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 3)); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendTileEntityData(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - sendBlockPosition(logger, packet, offset); - - packet.getNbtModifier().modify(0, nbtBase -> { - if (nbtBase == null) return null; - if (nbtBase instanceof NbtCompound) { - final NbtCompound nbt = (NbtCompound) (((NbtCompound) nbtBase).deepClone()); - if (nbt.containsKey("x") && nbt.containsKey("z")) { - nbt.put("x", nbt.getInteger("x") - offset.getXInt()); - nbt.put("z", nbt.getInteger("z") - offset.getZInt()); - } - return nbt; - } else { - return nbtBase; - } - }); - } + private static final Class NMS_BLOCK_POSITION_CLASS; + private static final Method NMS_BLOCK_POSITION_ADD_CLASS; + private static final EquivalentConverter INTERNAL_STRUCTURE_CONVERTER; + + static { + Class blockPositionClass = null; + try { + blockPositionClass = Class.forName("net.minecraft.core.BlockPosition"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + NMS_BLOCK_POSITION_CLASS = blockPositionClass; + + Method blockPositionAddMethod = null; + try { + blockPositionAddMethod = blockPositionClass.getDeclaredMethod("c", int.class, int.class, int.class); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + NMS_BLOCK_POSITION_ADD_CLASS = blockPositionAddMethod; + + EquivalentConverter internalStructureEquivalentConverter = null; + try { + Field internalStructureConverter = InternalStructure.class.getDeclaredField("CONVERTER"); + internalStructureConverter.setAccessible(true); + internalStructureEquivalentConverter = (EquivalentConverter) internalStructureConverter.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + INTERNAL_STRUCTURE_CONVERTER = internalStructureEquivalentConverter; + } + + public static boolean outgoing(Logger logger, final PacketContainer packet, final Player player) { + if (player instanceof TemporaryPlayer) { + return false; + } + CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); + Objects.requireNonNull(offset); + switch (packet.getType().name()) { + case "WINDOW_DATA": + break; + case "WINDOW_ITEMS": + fixWindowItems(logger, packet, offset); + break; + case "SET_SLOT": + fixWindowItem(logger, packet, offset); + break; + case "SPAWN_POSITION": + case "WORLD_EVENT": + case "UPDATE_SIGN": + case "BLOCK_BREAK": + case "BLOCK_BREAK_ANIMATION": + case "BLOCK_ACTION": + case "BLOCK_CHANGE": + case "SPAWN_ENTITY_PAINTING": + case "OPEN_SIGN_EDITOR": + sendBlockPosition(logger, packet, offset); + break; + case "ADD_VIBRATION_SIGNAL": + fixVibrationSignal(logger, packet, offset); + break; + case "RESPAWN": + logger.fine("[out]Respawning player"); + respawn(logger, offset, player); + break; + case "POSITION_LOOK": + case "POSITION": + boolean isRelativeX = false; + boolean isRelativeZ = false; + Set items = packet.getSets(Converters.passthrough(Enum.class)).read(0); + //noinspection rawtypes + for (Enum item : items) { + switch (item.name()) { + case "X": + isRelativeX = true; + break; + case "Z": + isRelativeZ = true; + break; + } + } + if (!isRelativeX || !isRelativeZ) { + logger.fine("[out]Repositioning player"); + CoordinateOffset positionOffset; + if (!isRelativeX && !isRelativeZ) { + positionOffset = respawn(logger, offset, player); + } else { + positionOffset = offset; + } + if (packet.getDoubles().size() > 2) { + if (!isRelativeX) { + packet.getDoubles().modify(0, x -> x == null ? null : x - positionOffset.getX()); + } + if (!isRelativeZ) { + packet.getDoubles().modify(2, z -> z == null ? null : z - positionOffset.getZ()); + } + } else { + logger.severe("Packet size error"); + } + } + break; + case "BED": + //todo: remove + //sendInt(packet, offset, 1); + break; + case "NAMED_ENTITY_SPAWN": + case "SPAWN_ENTITY": + Objects.requireNonNull(offset); + sendDouble(logger, packet, offset); + break; + case "SPAWN_ENTITY_LIVING": + case "WORLD_PARTICLES": + case "SPAWN_ENTITY_WEATHER": + case "SPAWN_ENTITY_EXPERIENCE_ORB": + case "ENTITY_TELEPORT": + sendDouble(logger, packet, offset); + break; + case "UNLOAD_CHUNK": + sendChunk(logger, packet, offset, false, false); + break; + case "LIGHT_UPDATE": + sendChunk(logger, packet, offset, false, true); + break; + case "MAP_CHUNK": + sendChunk(logger, packet, offset, true, false); + break; + case "MULTI_BLOCK_CHANGE": + sendChunkUpdate(logger, packet, offset); + break; + case "VIEW_CENTRE": + sendIntChunk(logger, packet, offset); + break; + case "MAP_CHUNK_BULK": + sendChunkBulk(logger, packet, offset); + break; + case "EXPLOSION": + sendExplosion(logger, packet, offset); + break; + case "NAMED_SOUND_EFFECT": + sendInt8(logger, packet, offset); + break; + case "ENTITY_METADATA": + if (packet.getWatchableCollectionModifier().size() > 0) { + packet.getWatchableCollectionModifier().modify(0, wrappedWatchableObjects -> { + if (wrappedWatchableObjects == null) return null; + ArrayList result = new ArrayList(wrappedWatchableObjects.size()); + for (WrappedWatchableObject wrappedWatchableObject : wrappedWatchableObjects) { + if (wrappedWatchableObject == null) { + result.add(null); + continue; + } + + Object oldValue = wrappedWatchableObject.getValue(); + if (oldValue instanceof Optional) { + //noinspection rawtypes + Optional opt = (Optional) oldValue; + if (opt.isPresent()) { + Object val = opt.get(); + if (NMS_BLOCK_POSITION_CLASS.isInstance(val)) { + wrappedWatchableObject.setValue(Optional.of(offsetPositionMc(logger, offset, val))); + } + } + } else if (oldValue instanceof BlockPosition blockPosition) { + wrappedWatchableObject.setValue(offsetPosition(logger, offset, blockPosition)); + } + result.add(wrappedWatchableObject); + } + return result; + }); + } + break; + case "TILE_ENTITY_DATA": + sendTileEntityData(logger, packet, offset); + break; + case "PLAYER_INFO": + break; + default: + logger.fine(packet.getType().name()); + break; + } + return false; + } + + private static CoordinateOffset respawn(Logger logger, CoordinateOffset offset, Player player) { + boolean hasSetLastLocation = false; + Optional lastLocationOpt = PlayerManager.getLastPlayerLocation(player); + if (lastLocationOpt.isPresent()) { + Location lastLocation = lastLocationOpt.get(); + if (lastLocation.getWorld().getUID().equals(player.getLocation().getWorld().getUID())) { + int clientViewDistance = 64; //player.getClientViewDistance(); + int minTeleportDistance = clientViewDistance * 2 * 16 + 2; + minTeleportDistance *= minTeleportDistance; // squared + if (lastLocation.distanceSquared(player.getLocation()) > minTeleportDistance) { + offset = PlayerManager.teleportPlayer(player, player.getWorld(), true); + logger.fine("Teleporting player. Prev[" + lastLocation.getBlockX() + "," + lastLocation.getBlockZ() + "] Next[" + player.getLocation().getX() + "," + player.getLocation().getZ() + "]"); + hasSetLastLocation = true; + } + } + } + if (hasSetLastLocation) { + PlayerManager.setLastPlayerLocation(player, player.getLocation()); + } + return offset; + } + + private static void fixWindowItems(Logger logger, PacketContainer packet, CoordinateOffset offset) { + packet.getItemListModifier().modify(0, itemStacks -> { + if (itemStacks == null) return null; + List newItems = new ArrayList<>(itemStacks.size()); + for (ItemStack itemStack : itemStacks) { + if (itemStack == null) { + newItems.add(null); + continue; + } + newItems.add(transformItemStack(logger, itemStack, offset)); + } + return newItems; + }); + } + + private static void fixWindowItem(Logger logger, PacketContainer packet, CoordinateOffset offset) { + packet.getItemModifier().modify(0, itemStack -> { + if (itemStack == null) { + return null; + } + return transformItemStack(logger, itemStack, offset); + }); + } + + private static ItemStack transformItemStack(Logger logger, ItemStack itemStack, CoordinateOffset offset) { + itemStack = itemStack.clone(); + + if (itemStack.hasItemMeta()) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + if (itemMeta instanceof org.bukkit.inventory.meta.CompassMeta) { + org.bukkit.inventory.meta.CompassMeta compassMeta = (org.bukkit.inventory.meta.CompassMeta) itemMeta; + Location lodestoneLocation = compassMeta.getLodestone(); + if (lodestoneLocation != null) { + compassMeta.setLodestone(lodestoneLocation.subtract(offset.getXInt(), 0, offset.getZInt())); + if (!itemStack.setItemMeta(compassMeta)) { + logger.severe("Can't apply meta"); + } + } + } + } + return itemStack; + } + + + private static void sendChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset, boolean includesEntities, boolean includeLight) { + StructureModifier integers = packet.getIntegers(); + integers.modify(0, curr_x -> { + if (curr_x != null) { + return curr_x - offset.getXChunk(); + } else { + return null; + } + }); + integers.modify(1, curr_z -> { + if (curr_z != null) { + return curr_z - offset.getZChunk(); + } else { + return null; + } + }); + if (includeLight) { + StructureModifier> byteArrays = packet.getStructures().read(0).getLists(Converters.passthrough(byte[].class)); + for (int i = 0; i < 2; i++) { + byteArrays.modify(i, list -> { + if (list == null) return null; + ArrayList newList = new ArrayList<>(list); + newList.replaceAll(bytes -> Arrays.copyOf(bytes, bytes.length)); + return newList; + }); + } + } + if (includesEntities) { + packet.getStructures().read(0).getLists(INTERNAL_STRUCTURE_CONVERTER).modify(0, entities -> { + if (entities == null) return null; + for (InternalStructure entity : entities) { + // ((blockX & 15) << 4) | (blockZ & 15) + entity.getIntegers().modify(0, packedXZ -> { + int x = (packedXZ >> 4) - offset.getXInt(); + int y = (packedXZ & 15) - offset.getZInt(); + return ((x & 15) << 4) | (y & 15); + }); + } + return entities; + }); + } + } + + private static void sendChunkBulk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getIntegerArrays().size() > 1) { + final int[] x = packet.getIntegerArrays().read(0).clone(); + final int[] z = packet.getIntegerArrays().read(1).clone(); + + for (int i = 0; i < x.length; i++) { + + x[i] = x[i] - offset.getXChunk(); + z[i] = z[i] - offset.getZChunk(); + } + + packet.getIntegerArrays().write(0, x); + packet.getIntegerArrays().write(1, z); + } else { + logger.severe("Packet size error"); + } + } + + private static void sendChunkUpdate(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + BlockPosition sp = packet.getSectionPositions().read(0); + if (sp == null) { + return; + } + packet.getSectionPositions().write(0, sp.subtract(new BlockPosition(offset.getXChunk(), 0, offset.getZChunk()))); + } + + + private static void sendDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getDoubles().size() > 2) { + packet.getDoubles().modify(0, x -> x == null ? null : x - offset.getX()); + packet.getDoubles().modify(2, z -> z == null ? null : z - offset.getZ()); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendExplosion(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + sendDouble(logger, packet, offset); + + packet.getBlockPositionCollectionModifier().modify(0, lst -> { + if (lst == null) return null; + ArrayList newLst = new ArrayList(lst.size()); + for (BlockPosition blockPosition : lst) { + newLst.add(blockPosition.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); + } + return newLst; + }); + } + + + private static void sendFixedPointNumber(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 5)); + packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 5)); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendFloat(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getFloat().size() > 2) { + packet.getFloat().modify(index, curr_x -> curr_x == null ? null : (float) (curr_x - offset.getX())); + packet.getFloat().modify(index + 2, curr_z -> curr_z == null ? null : (float) (curr_z - offset.getZ())); + } else { + logger.severe("Packet size error"); + } + } + + private static void sendInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - offset.getXInt()); + packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - offset.getZInt()); + } else { + logger.severe("Packet size error"); + } + } + + private static void sendIntChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getIntegers().size() > 1) { + packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - offset.getXChunk()); + packet.getIntegers().modify(1, curr_z -> curr_z == null ? null : curr_z - offset.getZChunk()); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendBlockPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getBlockPositionModifier().size() > 0) { + packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + } + + private static void fixVibrationSignal(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getBlockPositionModifier().size() >= 1) { + packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + if (packet.getBlockPositionModifier().size() >= 2) { + packet.getBlockPositionModifier().modify(1, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + } + + private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { + if (pos == null) return null; + return pos.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); + } + + private static Object offsetPositionMc(Logger logger, CoordinateOffset offset, Object pos) { + if (pos == null) return null; + try { + return NMS_BLOCK_POSITION_ADD_CLASS.invoke(pos, -offset.getXInt(), -0, -offset.getZInt()); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + + private static void sendInt8(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 3)); + packet.getIntegers().modify(2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 3)); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendTileEntityData(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + sendBlockPosition(logger, packet, offset); + + packet.getNbtModifier().modify(0, nbtBase -> { + if (nbtBase == null) return null; + if (nbtBase instanceof NbtCompound) { + final NbtCompound nbt = (NbtCompound) (((NbtCompound) nbtBase).deepClone()); + if (nbt.containsKey("x") && nbt.containsKey("z")) { + nbt.put("x", nbt.getInteger("x") - offset.getXInt()); + nbt.put("z", nbt.getInteger("z") - offset.getZInt()); + } + return nbt; + } else { + return nbtBase; + } + }); + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java b/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java index 8f3f167..f01736c 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java +++ b/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java @@ -1,95 +1,91 @@ package org.warp.coordinatesobfuscator; -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Play.Client; import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.injector.server.TemporaryPlayer; +import com.comphenix.protocol.injector.temporary.TemporaryPlayer; import com.comphenix.protocol.wrappers.BlockPosition; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Objects; -import java.util.logging.Logger; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.util.Vector; +import java.util.Objects; +import java.util.logging.Logger; + public class TranslatorServerbound { - private static final String USE_ITEM = "BLOCK_PLACE"; - private static final String BLOCK_PLACE = "USE_ITEM"; + private static final String USE_ITEM = "BLOCK_PLACE"; + private static final String BLOCK_PLACE = "USE_ITEM"; - public static void incoming(Logger logger, final PacketContainer packet, final Player player) { - if (player == null || player instanceof TemporaryPlayer) { - return; - } - CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); - Objects.requireNonNull(offset); - switch (packet.getType().name()) { - case "POSITION": - case "VEHICLE_MOVE": - case "POSITION_LOOK": - PlayerManager.setLastPlayerLocation(player, player.getLocation()); - recvDouble(logger, packet, offset); - break; - case "STRUCT": - case "SET_JIGSAW": - case "SET_COMMAND_BLOCK": - case "UPDATE_SIGN": - case "BLOCK_DIG": - recvPosition(logger, packet, offset); - break; - case USE_ITEM: - break; - case BLOCK_PLACE: - recvMovingPosition(logger, packet, offset); - break; - case "USE_ENTITY": - break; - default: - break; - } - } + public static void incoming(Logger logger, final PacketContainer packet, final Player player) { + if (player == null || player instanceof TemporaryPlayer) { + return; + } + CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); + Objects.requireNonNull(offset); + switch (packet.getType().name()) { + case "POSITION": + case "VEHICLE_MOVE": + case "POSITION_LOOK": + PlayerManager.setLastPlayerLocation(player, player.getLocation()); + recvDouble(logger, packet, offset); + break; + case "STRUCT": + case "SET_JIGSAW": + case "SET_COMMAND_BLOCK": + case "UPDATE_SIGN": + case "BLOCK_DIG": + recvPosition(logger, packet, offset); + break; + case USE_ITEM: + break; + case BLOCK_PLACE: + recvMovingPosition(logger, packet, offset); + break; + case "USE_ENTITY": + break; + default: + break; + } + } - private static void recvDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getDoubles().size() > 2) { - packet.getDoubles().modify(0, x -> x == null ? null : x + offset.getX()); - packet.getDoubles().modify(2, z -> z == null ? null : z + offset.getZ()); - } else { - int size = packet.getDoubles().size(); - logger.severe("Packet size error: " + size); - } - } + private static void recvDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getDoubles().size() > 2) { + packet.getDoubles().modify(0, x -> x == null ? null : x + offset.getX()); + packet.getDoubles().modify(2, z -> z == null ? null : z + offset.getZ()); + } else { + int size = packet.getDoubles().size(); + logger.severe("Packet size error: " + size); + } + } - private static void recvInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x + offset.getXInt()); - packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z + offset.getZInt()); - } else { - logger.severe("Packet size error"); - } - } + private static void recvInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x + offset.getXInt()); + packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z + offset.getZInt()); + } else { + logger.severe("Packet size error"); + } + } - private static void recvPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getBlockPositionModifier().size() > 0) { - packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - } + private static void recvPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getBlockPositionModifier().size() > 0) { + packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + } - private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { - if (pos == null) return null; - return pos.add(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); - } + private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { + if (pos == null) return null; + return pos.add(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); + } - private static void recvMovingPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - var mopb = packet.getMovingBlockPositions().read(0); - if (mopb == null) { - return; - } - mopb.setBlockPosition(mopb.getBlockPosition().add(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); - mopb.setPosVector(mopb.getPosVector().add(new Vector(offset.getX(), 0, offset.getZ()))); - packet.getMovingBlockPositions().write(0, mopb); - } + private static void recvMovingPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + var mopb = packet.getMovingBlockPositions().read(0); + if (mopb == null) { + return; + } + mopb.setBlockPosition(mopb.getBlockPosition().add(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); + mopb.setPosVector(mopb.getPosVector().add(new Vector(offset.getX(), 0, offset.getZ()))); + packet.getMovingBlockPositions().write(0, mopb); + } } From cc18aa427259f34e0c46015dd7270ccf3f4793e8 Mon Sep 17 00:00:00 2001 From: HarvelsX <90945793+HarvelsX@users.noreply.github.com> Date: Fri, 15 Apr 2022 05:30:52 +0300 Subject: [PATCH 2/3] Reformat code & create basic .editorconfig; Please export code style to projects repositories; --- .editorconfig | 1366 +++++++++++++++++ README.md | 7 +- pom.xml | 126 +- .../CoordinatesObfuscator.java | 403 +++-- .../CoordsOffsetsManager.java | 5 +- .../LastPlayerCoordinateManager.java | 24 +- .../coordinatesobfuscator/PlayerManager.java | 230 +-- .../TranslatorClientbound.java | 890 +++++------ .../TranslatorServerbound.java | 140 +- src/main/resources/plugin.yml | 2 +- 10 files changed, 2275 insertions(+), 918 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..df87802 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,1366 @@ +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 120 +tab_width = 4 +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false + +[*.css] +ij_css_align_closing_brace_with_properties = false +ij_css_blank_lines_around_nested_selector = 1 +ij_css_blank_lines_between_blocks = 1 +ij_css_block_comment_add_space = false +ij_css_brace_placement = end_of_line +ij_css_enforce_quotes_on_format = false +ij_css_hex_color_long_format = false +ij_css_hex_color_lower_case = false +ij_css_hex_color_short_format = false +ij_css_hex_color_upper_case = false +ij_css_keep_blank_lines_in_code = 2 +ij_css_keep_indents_on_empty_lines = false +ij_css_keep_single_line_blocks = false +ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_css_space_after_colon = true +ij_css_space_before_opening_brace = true +ij_css_use_double_quotes = true +ij_css_value_alignment = do_not_align + +[*.feature] +indent_size = 2 +ij_gherkin_keep_indents_on_empty_lines = false + +[*.haml] +indent_size = 2 +ij_haml_keep_indents_on_empty_lines = false + +[*.java] +indent_style = tab +ij_smart_tabs = true +ij_java_align_consecutive_assignments = false +ij_java_align_consecutive_variable_declarations = false +ij_java_align_group_field_declarations = false +ij_java_align_multiline_annotation_parameters = false +ij_java_align_multiline_array_initializer_expression = false +ij_java_align_multiline_assignment = false +ij_java_align_multiline_binary_operation = false +ij_java_align_multiline_chained_methods = false +ij_java_align_multiline_extends_list = false +ij_java_align_multiline_for = true +ij_java_align_multiline_method_parentheses = false +ij_java_align_multiline_parameters = true +ij_java_align_multiline_parameters_in_calls = false +ij_java_align_multiline_parenthesized_expression = false +ij_java_align_multiline_records = true +ij_java_align_multiline_resources = true +ij_java_align_multiline_ternary_operation = false +ij_java_align_multiline_text_blocks = false +ij_java_align_multiline_throws_list = false +ij_java_align_subsequent_simple_methods = false +ij_java_align_throws_keyword = false +ij_java_align_types_in_multi_catch = true +ij_java_annotation_parameter_wrap = off +ij_java_array_initializer_new_line_after_left_brace = false +ij_java_array_initializer_right_brace_on_new_line = false +ij_java_array_initializer_wrap = off +ij_java_assert_statement_colon_on_next_line = false +ij_java_assert_statement_wrap = off +ij_java_assignment_wrap = off +ij_java_binary_operation_sign_on_next_line = false +ij_java_binary_operation_wrap = off +ij_java_blank_lines_after_anonymous_class_header = 0 +ij_java_blank_lines_after_class_header = 0 +ij_java_blank_lines_after_imports = 1 +ij_java_blank_lines_after_package = 1 +ij_java_blank_lines_around_class = 1 +ij_java_blank_lines_around_field = 0 +ij_java_blank_lines_around_field_in_interface = 0 +ij_java_blank_lines_around_initializer = 1 +ij_java_blank_lines_around_method = 1 +ij_java_blank_lines_around_method_in_interface = 1 +ij_java_blank_lines_before_class_end = 0 +ij_java_blank_lines_before_imports = 1 +ij_java_blank_lines_before_method_body = 0 +ij_java_blank_lines_before_package = 0 +ij_java_block_brace_style = end_of_line +ij_java_block_comment_add_space = false +ij_java_block_comment_at_first_column = true +ij_java_builder_methods = none +ij_java_call_parameters_new_line_after_left_paren = false +ij_java_call_parameters_right_paren_on_new_line = false +ij_java_call_parameters_wrap = off +ij_java_case_statement_on_separate_line = true +ij_java_catch_on_new_line = false +ij_java_class_annotation_wrap = split_into_lines +ij_java_class_brace_style = end_of_line +ij_java_class_count_to_use_import_on_demand = 5 +ij_java_class_names_in_javadoc = 1 +ij_java_do_not_indent_top_level_class_members = false +ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_not_wrap_after_single_annotation_in_parameter = false +ij_java_do_while_brace_force = never +ij_java_doc_add_blank_line_after_description = true +ij_java_doc_add_blank_line_after_param_comments = false +ij_java_doc_add_blank_line_after_return = false +ij_java_doc_add_p_tag_on_empty_lines = true +ij_java_doc_align_exception_comments = true +ij_java_doc_align_param_comments = true +ij_java_doc_do_not_wrap_if_one_line = false +ij_java_doc_enable_formatting = true +ij_java_doc_enable_leading_asterisks = true +ij_java_doc_indent_on_continuation = false +ij_java_doc_keep_empty_lines = true +ij_java_doc_keep_empty_parameter_tag = true +ij_java_doc_keep_empty_return_tag = true +ij_java_doc_keep_empty_throws_tag = true +ij_java_doc_keep_invalid_tags = true +ij_java_doc_param_description_on_new_line = false +ij_java_doc_preserve_line_breaks = false +ij_java_doc_use_throws_not_exception_tag = true +ij_java_else_on_new_line = false +ij_java_entity_dd_suffix = EJB +ij_java_entity_eb_suffix = Bean +ij_java_entity_hi_suffix = Home +ij_java_entity_lhi_prefix = Local +ij_java_entity_lhi_suffix = Home +ij_java_entity_li_prefix = Local +ij_java_entity_pk_class = java.lang.String +ij_java_entity_vo_suffix = VO +ij_java_enum_constants_wrap = off +ij_java_extends_keyword_wrap = off +ij_java_extends_list_wrap = off +ij_java_field_annotation_wrap = split_into_lines +ij_java_finally_on_new_line = false +ij_java_for_brace_force = never +ij_java_for_statement_new_line_after_left_paren = false +ij_java_for_statement_right_paren_on_new_line = false +ij_java_for_statement_wrap = off +ij_java_generate_final_locals = false +ij_java_generate_final_parameters = false +ij_java_if_brace_force = never +ij_java_imports_layout = *, |, javax.**, java.**, |, $* +ij_java_indent_case_from_switch = true +ij_java_insert_inner_class_imports = false +ij_java_insert_override_annotation = true +ij_java_keep_blank_lines_before_right_brace = 2 +ij_java_keep_blank_lines_between_package_declaration_and_header = 2 +ij_java_keep_blank_lines_in_code = 2 +ij_java_keep_blank_lines_in_declarations = 2 +ij_java_keep_builder_methods_indents = false +ij_java_keep_control_statement_in_one_line = true +ij_java_keep_first_column_comment = true +ij_java_keep_indents_on_empty_lines = false +ij_java_keep_line_breaks = true +ij_java_keep_multiple_expressions_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = false +ij_java_keep_simple_classes_in_one_line = false +ij_java_keep_simple_lambdas_in_one_line = false +ij_java_keep_simple_methods_in_one_line = false +ij_java_label_indent_absolute = false +ij_java_label_indent_size = 0 +ij_java_lambda_brace_style = end_of_line +ij_java_layout_static_imports_separately = true +ij_java_line_comment_add_space = false +ij_java_line_comment_add_space_on_reformat = false +ij_java_line_comment_at_first_column = true +ij_java_message_dd_suffix = EJB +ij_java_message_eb_suffix = Bean +ij_java_method_annotation_wrap = split_into_lines +ij_java_method_brace_style = end_of_line +ij_java_method_call_chain_wrap = off +ij_java_method_parameters_new_line_after_left_paren = false +ij_java_method_parameters_right_paren_on_new_line = false +ij_java_method_parameters_wrap = off +ij_java_modifier_list_wrap = false +ij_java_multi_catch_types_wrap = normal +ij_java_names_count_to_use_import_on_demand = 3 +ij_java_new_line_after_lparen_in_annotation = false +ij_java_new_line_after_lparen_in_record_header = false +ij_java_packages_to_use_import_on_demand = java.awt.*, javax.swing.* +ij_java_parameter_annotation_wrap = off +ij_java_parentheses_expression_new_line_after_left_paren = false +ij_java_parentheses_expression_right_paren_on_new_line = false +ij_java_place_assignment_sign_on_next_line = false +ij_java_prefer_longer_names = true +ij_java_prefer_parameters_wrap = false +ij_java_record_components_wrap = normal +ij_java_repeat_synchronized = true +ij_java_replace_instanceof_and_cast = false +ij_java_replace_null_check = true +ij_java_replace_sum_lambda_with_method_ref = true +ij_java_resource_list_new_line_after_left_paren = false +ij_java_resource_list_right_paren_on_new_line = false +ij_java_resource_list_wrap = off +ij_java_rparen_on_new_line_in_annotation = false +ij_java_rparen_on_new_line_in_record_header = false +ij_java_session_dd_suffix = EJB +ij_java_session_eb_suffix = Bean +ij_java_session_hi_suffix = Home +ij_java_session_lhi_prefix = Local +ij_java_session_lhi_suffix = Home +ij_java_session_li_prefix = Local +ij_java_session_si_suffix = Service +ij_java_space_after_closing_angle_bracket_in_type_argument = false +ij_java_space_after_colon = true +ij_java_space_after_comma = true +ij_java_space_after_comma_in_type_arguments = true +ij_java_space_after_for_semicolon = true +ij_java_space_after_quest = true +ij_java_space_after_type_cast = true +ij_java_space_before_annotation_array_initializer_left_brace = false +ij_java_space_before_annotation_parameter_list = false +ij_java_space_before_array_initializer_left_brace = false +ij_java_space_before_catch_keyword = true +ij_java_space_before_catch_left_brace = true +ij_java_space_before_catch_parentheses = true +ij_java_space_before_class_left_brace = true +ij_java_space_before_colon = true +ij_java_space_before_colon_in_foreach = true +ij_java_space_before_comma = false +ij_java_space_before_do_left_brace = true +ij_java_space_before_else_keyword = true +ij_java_space_before_else_left_brace = true +ij_java_space_before_finally_keyword = true +ij_java_space_before_finally_left_brace = true +ij_java_space_before_for_left_brace = true +ij_java_space_before_for_parentheses = true +ij_java_space_before_for_semicolon = false +ij_java_space_before_if_left_brace = true +ij_java_space_before_if_parentheses = true +ij_java_space_before_method_call_parentheses = false +ij_java_space_before_method_left_brace = true +ij_java_space_before_method_parentheses = false +ij_java_space_before_opening_angle_bracket_in_type_parameter = false +ij_java_space_before_quest = true +ij_java_space_before_switch_left_brace = true +ij_java_space_before_switch_parentheses = true +ij_java_space_before_synchronized_left_brace = true +ij_java_space_before_synchronized_parentheses = true +ij_java_space_before_try_left_brace = true +ij_java_space_before_try_parentheses = true +ij_java_space_before_type_parameter_list = false +ij_java_space_before_while_keyword = true +ij_java_space_before_while_left_brace = true +ij_java_space_before_while_parentheses = true +ij_java_space_inside_one_line_enum_braces = false +ij_java_space_within_empty_array_initializer_braces = false +ij_java_space_within_empty_method_call_parentheses = false +ij_java_space_within_empty_method_parentheses = false +ij_java_spaces_around_additive_operators = true +ij_java_spaces_around_annotation_eq = true +ij_java_spaces_around_assignment_operators = true +ij_java_spaces_around_bitwise_operators = true +ij_java_spaces_around_equality_operators = true +ij_java_spaces_around_lambda_arrow = true +ij_java_spaces_around_logical_operators = true +ij_java_spaces_around_method_ref_dbl_colon = false +ij_java_spaces_around_multiplicative_operators = true +ij_java_spaces_around_relational_operators = true +ij_java_spaces_around_shift_operators = true +ij_java_spaces_around_type_bounds_in_type_parameters = true +ij_java_spaces_around_unary_operator = false +ij_java_spaces_within_angle_brackets = false +ij_java_spaces_within_annotation_parentheses = false +ij_java_spaces_within_array_initializer_braces = false +ij_java_spaces_within_braces = false +ij_java_spaces_within_brackets = false +ij_java_spaces_within_cast_parentheses = false +ij_java_spaces_within_catch_parentheses = false +ij_java_spaces_within_for_parentheses = false +ij_java_spaces_within_if_parentheses = false +ij_java_spaces_within_method_call_parentheses = false +ij_java_spaces_within_method_parentheses = false +ij_java_spaces_within_parentheses = false +ij_java_spaces_within_record_header = false +ij_java_spaces_within_switch_parentheses = false +ij_java_spaces_within_synchronized_parentheses = false +ij_java_spaces_within_try_parentheses = false +ij_java_spaces_within_while_parentheses = false +ij_java_special_else_if_treatment = true +ij_java_subclass_name_suffix = Impl +ij_java_ternary_operation_signs_on_next_line = false +ij_java_ternary_operation_wrap = off +ij_java_test_name_suffix = Test +ij_java_throws_keyword_wrap = off +ij_java_throws_list_wrap = off +ij_java_use_external_annotations = false +ij_java_use_fq_class_names = false +ij_java_use_relative_indents = false +ij_java_use_single_class_imports = true +ij_java_variable_annotation_wrap = off +ij_java_visibility = public +ij_java_while_brace_force = never +ij_java_while_on_new_line = false +ij_java_wrap_comments = false +ij_java_wrap_first_method_in_call_chain = false +ij_java_wrap_long_lines = false + +[*.less] +indent_size = 2 +ij_less_align_closing_brace_with_properties = false +ij_less_blank_lines_around_nested_selector = 1 +ij_less_blank_lines_between_blocks = 1 +ij_less_block_comment_add_space = false +ij_less_brace_placement = 0 +ij_less_enforce_quotes_on_format = false +ij_less_hex_color_long_format = false +ij_less_hex_color_lower_case = false +ij_less_hex_color_short_format = false +ij_less_hex_color_upper_case = false +ij_less_keep_blank_lines_in_code = 2 +ij_less_keep_indents_on_empty_lines = false +ij_less_keep_single_line_blocks = false +ij_less_line_comment_add_space = false +ij_less_line_comment_at_first_column = false +ij_less_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_less_space_after_colon = true +ij_less_space_before_opening_brace = true +ij_less_use_double_quotes = true +ij_less_value_alignment = 0 + +[*.nbtt] +max_line_length = 150 +ij_continuation_indent_size = 4 +ij_nbtt_keep_indents_on_empty_lines = false +ij_nbtt_space_after_colon = true +ij_nbtt_space_after_comma = true +ij_nbtt_space_before_colon = true +ij_nbtt_space_before_comma = false +ij_nbtt_spaces_within_brackets = false +ij_nbtt_spaces_within_parentheses = false + +[*.proto] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_protobuf_keep_blank_lines_in_code = 2 +ij_protobuf_keep_indents_on_empty_lines = false +ij_protobuf_keep_line_breaks = true +ij_protobuf_space_after_comma = true +ij_protobuf_space_before_comma = false +ij_protobuf_spaces_around_assignment_operators = true +ij_protobuf_spaces_within_braces = false +ij_protobuf_spaces_within_brackets = false + +[*.sass] +indent_size = 2 +ij_sass_align_closing_brace_with_properties = false +ij_sass_blank_lines_around_nested_selector = 1 +ij_sass_blank_lines_between_blocks = 1 +ij_sass_brace_placement = 0 +ij_sass_enforce_quotes_on_format = false +ij_sass_hex_color_long_format = false +ij_sass_hex_color_lower_case = false +ij_sass_hex_color_short_format = false +ij_sass_hex_color_upper_case = false +ij_sass_keep_blank_lines_in_code = 2 +ij_sass_keep_indents_on_empty_lines = false +ij_sass_keep_single_line_blocks = false +ij_sass_line_comment_add_space = false +ij_sass_line_comment_at_first_column = false +ij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_sass_space_after_colon = true +ij_sass_space_before_opening_brace = true +ij_sass_use_double_quotes = true +ij_sass_value_alignment = 0 + +[*.scala] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_scala_align_composite_pattern = true +ij_scala_align_extends_with = 0 +ij_scala_align_group_field_declarations = false +ij_scala_align_if_else = false +ij_scala_align_in_columns_case_branch = false +ij_scala_align_multiline_binary_operation = false +ij_scala_align_multiline_chained_methods = false +ij_scala_align_multiline_for = true +ij_scala_align_multiline_parameters = true +ij_scala_align_multiline_parameters_in_calls = false +ij_scala_align_multiline_parenthesized_expression = false +ij_scala_align_parameter_types_in_multiline_declarations = 0 +ij_scala_align_tuple_elements = false +ij_scala_alternate_continuation_indent_for_params = 4 +ij_scala_binary_operation_wrap = off +ij_scala_blank_lines_after_anonymous_class_header = 0 +ij_scala_blank_lines_after_class_header = 0 +ij_scala_blank_lines_after_imports = 1 +ij_scala_blank_lines_after_package = 1 +ij_scala_blank_lines_around_class = 1 +ij_scala_blank_lines_around_class_in_inner_scopes = 0 +ij_scala_blank_lines_around_field = 0 +ij_scala_blank_lines_around_field_in_inner_scopes = 0 +ij_scala_blank_lines_around_field_in_interface = 0 +ij_scala_blank_lines_around_method = 1 +ij_scala_blank_lines_around_method_in_inner_scopes = 1 +ij_scala_blank_lines_around_method_in_interface = 1 +ij_scala_blank_lines_before_class_end = 0 +ij_scala_blank_lines_before_imports = 1 +ij_scala_blank_lines_before_method_body = 0 +ij_scala_blank_lines_before_package = 0 +ij_scala_block_brace_style = end_of_line +ij_scala_block_comment_at_first_column = true +ij_scala_call_parameters_new_line_after_lparen = 0 +ij_scala_call_parameters_right_paren_on_new_line = false +ij_scala_call_parameters_wrap = off +ij_scala_case_clause_brace_force = never +ij_scala_catch_on_new_line = false +ij_scala_class_annotation_wrap = split_into_lines +ij_scala_class_brace_style = end_of_line +ij_scala_closure_brace_force = never +ij_scala_do_not_align_block_expr_params = true +ij_scala_do_not_indent_case_clause_body = false +ij_scala_do_not_indent_tuples_close_brace = true +ij_scala_do_while_brace_force = never +ij_scala_else_on_new_line = false +ij_scala_enable_scaladoc_formatting = true +ij_scala_enforce_functional_syntax_for_unit = true +ij_scala_extends_keyword_wrap = off +ij_scala_extends_list_wrap = off +ij_scala_field_annotation_wrap = split_into_lines +ij_scala_finally_brace_force = never +ij_scala_finally_on_new_line = false +ij_scala_for_brace_force = never +ij_scala_for_statement_wrap = off +ij_scala_formatter = 0 +ij_scala_if_brace_force = never +ij_scala_implicit_value_class_suffix = Ops +ij_scala_indent_braced_function_args = true +ij_scala_indent_case_from_switch = true +ij_scala_indent_first_parameter = true +ij_scala_indent_first_parameter_clause = false +ij_scala_indent_type_arguments = true +ij_scala_indent_type_parameters = true +ij_scala_indent_yield_after_one_line_enumerators = true +ij_scala_keep_blank_lines_before_right_brace = 2 +ij_scala_keep_blank_lines_in_code = 2 +ij_scala_keep_blank_lines_in_declarations = 2 +ij_scala_keep_comments_on_same_line = true +ij_scala_keep_first_column_comment = false +ij_scala_keep_indents_on_empty_lines = false +ij_scala_keep_line_breaks = true +ij_scala_keep_one_line_lambdas_in_arg_list = false +ij_scala_keep_simple_blocks_in_one_line = false +ij_scala_keep_simple_methods_in_one_line = false +ij_scala_keep_xml_formatting = false +ij_scala_line_comment_add_space = false +ij_scala_line_comment_at_first_column = true +ij_scala_method_annotation_wrap = split_into_lines +ij_scala_method_brace_force = never +ij_scala_method_brace_style = end_of_line +ij_scala_method_call_chain_wrap = off +ij_scala_method_parameters_new_line_after_left_paren = false +ij_scala_method_parameters_right_paren_on_new_line = false +ij_scala_method_parameters_wrap = off +ij_scala_modifier_list_wrap = false +ij_scala_multiline_string_align_dangling_closing_quotes = false +ij_scala_multiline_string_closing_quotes_on_new_line = false +ij_scala_multiline_string_insert_margin_on_enter = true +ij_scala_multiline_string_margin_char = | +ij_scala_multiline_string_margin_indent = 2 +ij_scala_multiline_string_opening_quotes_on_new_line = true +ij_scala_multiline_string_process_margin_on_copy_paste = true +ij_scala_newline_after_annotations = false +ij_scala_not_continuation_indent_for_params = false +ij_scala_parameter_annotation_wrap = off +ij_scala_parentheses_expression_new_line_after_left_paren = false +ij_scala_parentheses_expression_right_paren_on_new_line = false +ij_scala_place_closure_parameters_on_new_line = false +ij_scala_place_self_type_on_new_line = true +ij_scala_prefer_parameters_wrap = false +ij_scala_preserve_space_after_method_declaration_name = false +ij_scala_reformat_on_compile = false +ij_scala_replace_case_arrow_with_unicode_char = false +ij_scala_replace_for_generator_arrow_with_unicode_char = false +ij_scala_replace_lambda_with_greek_letter = false +ij_scala_replace_map_arrow_with_unicode_char = false +ij_scala_scalafmt_fallback_to_default_settings = false +ij_scala_scalafmt_reformat_on_files_save = false +ij_scala_scalafmt_show_invalid_code_warnings = true +ij_scala_scalafmt_use_intellij_formatter_for_range_format = true +ij_scala_sd_align_exception_comments = true +ij_scala_sd_align_list_item_content = true +ij_scala_sd_align_other_tags_comments = true +ij_scala_sd_align_parameters_comments = true +ij_scala_sd_align_return_comments = true +ij_scala_sd_blank_line_after_parameters_comments = false +ij_scala_sd_blank_line_after_return_comments = false +ij_scala_sd_blank_line_before_parameters = false +ij_scala_sd_blank_line_before_tags = true +ij_scala_sd_blank_line_between_parameters = false +ij_scala_sd_keep_blank_lines_between_tags = false +ij_scala_sd_preserve_spaces_in_tags = false +ij_scala_space_after_comma = true +ij_scala_space_after_for_semicolon = true +ij_scala_space_after_modifiers_constructor = false +ij_scala_space_after_type_colon = true +ij_scala_space_before_brace_method_call = true +ij_scala_space_before_class_left_brace = true +ij_scala_space_before_for_parentheses = true +ij_scala_space_before_if_parentheses = true +ij_scala_space_before_infix_like_method_parentheses = false +ij_scala_space_before_infix_method_call_parentheses = false +ij_scala_space_before_infix_operator_like_method_call_parentheses = true +ij_scala_space_before_method_call_parentheses = false +ij_scala_space_before_method_left_brace = true +ij_scala_space_before_method_parentheses = false +ij_scala_space_before_type_colon = false +ij_scala_space_before_type_parameter_in_def_list = false +ij_scala_space_before_type_parameter_leading_context_bound_colon = false +ij_scala_space_before_type_parameter_leading_context_bound_colon_hk = true +ij_scala_space_before_type_parameter_list = false +ij_scala_space_before_type_parameter_rest_context_bound_colons = true +ij_scala_space_before_while_parentheses = true +ij_scala_space_inside_closure_braces = true +ij_scala_space_inside_self_type_braces = true +ij_scala_space_within_empty_method_call_parentheses = false +ij_scala_spaces_around_at_in_patterns = false +ij_scala_spaces_in_imports = false +ij_scala_spaces_in_one_line_blocks = false +ij_scala_spaces_within_brackets = false +ij_scala_spaces_within_for_parentheses = false +ij_scala_spaces_within_if_parentheses = false +ij_scala_spaces_within_method_call_parentheses = false +ij_scala_spaces_within_method_parentheses = false +ij_scala_spaces_within_parentheses = false +ij_scala_spaces_within_while_parentheses = false +ij_scala_special_else_if_treatment = true +ij_scala_trailing_comma_arg_list_enabled = true +ij_scala_trailing_comma_import_selector_enabled = false +ij_scala_trailing_comma_mode = trailing_comma_keep +ij_scala_trailing_comma_params_enabled = true +ij_scala_trailing_comma_pattern_arg_list_enabled = false +ij_scala_trailing_comma_tuple_enabled = false +ij_scala_trailing_comma_tuple_type_enabled = false +ij_scala_trailing_comma_type_params_enabled = false +ij_scala_try_brace_force = never +ij_scala_type_annotation_exclude_constant = true +ij_scala_type_annotation_exclude_in_dialect_sources = true +ij_scala_type_annotation_exclude_in_test_sources = false +ij_scala_type_annotation_exclude_member_of_anonymous_class = false +ij_scala_type_annotation_exclude_member_of_private_class = false +ij_scala_type_annotation_exclude_when_type_is_stable = true +ij_scala_type_annotation_function_parameter = false +ij_scala_type_annotation_implicit_modifier = true +ij_scala_type_annotation_local_definition = false +ij_scala_type_annotation_private_member = false +ij_scala_type_annotation_protected_member = true +ij_scala_type_annotation_public_member = true +ij_scala_type_annotation_structural_type = true +ij_scala_type_annotation_underscore_parameter = false +ij_scala_type_annotation_unit_type = true +ij_scala_use_alternate_continuation_indent_for_params = false +ij_scala_use_scala3_indentation_based_syntax = true +ij_scala_use_scaladoc2_formatting = false +ij_scala_variable_annotation_wrap = off +ij_scala_while_brace_force = never +ij_scala_while_on_new_line = false +ij_scala_wrap_before_with_keyword = false +ij_scala_wrap_first_method_in_call_chain = false +ij_scala_wrap_long_lines = false + +[*.scss] +indent_size = 2 +ij_scss_align_closing_brace_with_properties = false +ij_scss_blank_lines_around_nested_selector = 1 +ij_scss_blank_lines_between_blocks = 1 +ij_scss_block_comment_add_space = false +ij_scss_brace_placement = 0 +ij_scss_enforce_quotes_on_format = false +ij_scss_hex_color_long_format = false +ij_scss_hex_color_lower_case = false +ij_scss_hex_color_short_format = false +ij_scss_hex_color_upper_case = false +ij_scss_keep_blank_lines_in_code = 2 +ij_scss_keep_indents_on_empty_lines = false +ij_scss_keep_single_line_blocks = false +ij_scss_line_comment_add_space = false +ij_scss_line_comment_at_first_column = false +ij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_scss_space_after_colon = true +ij_scss_space_before_opening_brace = true +ij_scss_use_double_quotes = true +ij_scss_value_alignment = 0 + +[*.styl] +indent_size = 2 +ij_stylus_align_closing_brace_with_properties = false +ij_stylus_blank_lines_around_nested_selector = 1 +ij_stylus_blank_lines_between_blocks = 1 +ij_stylus_brace_placement = 0 +ij_stylus_enforce_quotes_on_format = false +ij_stylus_hex_color_long_format = false +ij_stylus_hex_color_lower_case = false +ij_stylus_hex_color_short_format = false +ij_stylus_hex_color_upper_case = false +ij_stylus_keep_blank_lines_in_code = 2 +ij_stylus_keep_indents_on_empty_lines = false +ij_stylus_keep_single_line_blocks = false +ij_stylus_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow +ij_stylus_space_after_colon = true +ij_stylus_space_before_opening_brace = true +ij_stylus_use_double_quotes = true +ij_stylus_value_alignment = 0 + +[.editorconfig] +ij_editorconfig_align_group_field_declarations = false +ij_editorconfig_space_after_colon = false +ij_editorconfig_space_after_comma = true +ij_editorconfig_space_before_colon = false +ij_editorconfig_space_before_comma = false +ij_editorconfig_spaces_around_assignment_operators = true + +[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] +ij_xml_align_attributes = true +ij_xml_align_text = false +ij_xml_attribute_wrap = normal +ij_xml_block_comment_add_space = false +ij_xml_block_comment_at_first_column = true +ij_xml_keep_blank_lines = 2 +ij_xml_keep_indents_on_empty_lines = false +ij_xml_keep_line_breaks = true +ij_xml_keep_line_breaks_in_text = true +ij_xml_keep_whitespaces = false +ij_xml_keep_whitespaces_around_cdata = preserve +ij_xml_keep_whitespaces_inside_cdata = false +ij_xml_line_comment_at_first_column = true +ij_xml_space_after_tag_name = false +ij_xml_space_around_equals_in_attribute = false +ij_xml_space_inside_empty_tag = false +ij_xml_text_wrap = normal +ij_xml_use_custom_settings = false + +[{*.ats,*.cts,*.mts,*.ts}] +ij_continuation_indent_size = 4 +ij_typescript_align_imports = false +ij_typescript_align_multiline_array_initializer_expression = false +ij_typescript_align_multiline_binary_operation = false +ij_typescript_align_multiline_chained_methods = false +ij_typescript_align_multiline_extends_list = false +ij_typescript_align_multiline_for = true +ij_typescript_align_multiline_parameters = true +ij_typescript_align_multiline_parameters_in_calls = false +ij_typescript_align_multiline_ternary_operation = false +ij_typescript_align_object_properties = 0 +ij_typescript_align_union_types = false +ij_typescript_align_var_statements = 0 +ij_typescript_array_initializer_new_line_after_left_brace = false +ij_typescript_array_initializer_right_brace_on_new_line = false +ij_typescript_array_initializer_wrap = off +ij_typescript_assignment_wrap = off +ij_typescript_binary_operation_sign_on_next_line = false +ij_typescript_binary_operation_wrap = off +ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/** +ij_typescript_blank_lines_after_imports = 1 +ij_typescript_blank_lines_around_class = 1 +ij_typescript_blank_lines_around_field = 0 +ij_typescript_blank_lines_around_field_in_interface = 0 +ij_typescript_blank_lines_around_function = 1 +ij_typescript_blank_lines_around_method = 1 +ij_typescript_blank_lines_around_method_in_interface = 1 +ij_typescript_block_brace_style = end_of_line +ij_typescript_block_comment_add_space = false +ij_typescript_block_comment_at_first_column = true +ij_typescript_call_parameters_new_line_after_left_paren = false +ij_typescript_call_parameters_right_paren_on_new_line = false +ij_typescript_call_parameters_wrap = off +ij_typescript_catch_on_new_line = false +ij_typescript_chained_call_dot_on_new_line = true +ij_typescript_class_brace_style = end_of_line +ij_typescript_comma_on_new_line = false +ij_typescript_do_while_brace_force = never +ij_typescript_else_on_new_line = false +ij_typescript_enforce_trailing_comma = keep +ij_typescript_enum_constants_wrap = on_every_item +ij_typescript_extends_keyword_wrap = off +ij_typescript_extends_list_wrap = off +ij_typescript_field_prefix = _ +ij_typescript_file_name_style = relaxed +ij_typescript_finally_on_new_line = false +ij_typescript_for_brace_force = never +ij_typescript_for_statement_new_line_after_left_paren = false +ij_typescript_for_statement_right_paren_on_new_line = false +ij_typescript_for_statement_wrap = off +ij_typescript_force_quote_style = false +ij_typescript_force_semicolon_style = false +ij_typescript_function_expression_brace_style = end_of_line +ij_typescript_if_brace_force = never +ij_typescript_import_merge_members = global +ij_typescript_import_prefer_absolute_path = global +ij_typescript_import_sort_members = true +ij_typescript_import_sort_module_name = false +ij_typescript_import_use_node_resolution = true +ij_typescript_imports_wrap = on_every_item +ij_typescript_indent_case_from_switch = true +ij_typescript_indent_chained_calls = true +ij_typescript_indent_package_children = 0 +ij_typescript_jsdoc_include_types = false +ij_typescript_jsx_attribute_value = braces +ij_typescript_keep_blank_lines_in_code = 2 +ij_typescript_keep_first_column_comment = true +ij_typescript_keep_indents_on_empty_lines = false +ij_typescript_keep_line_breaks = true +ij_typescript_keep_simple_blocks_in_one_line = false +ij_typescript_keep_simple_methods_in_one_line = false +ij_typescript_line_comment_add_space = true +ij_typescript_line_comment_at_first_column = false +ij_typescript_method_brace_style = end_of_line +ij_typescript_method_call_chain_wrap = off +ij_typescript_method_parameters_new_line_after_left_paren = false +ij_typescript_method_parameters_right_paren_on_new_line = false +ij_typescript_method_parameters_wrap = off +ij_typescript_object_literal_wrap = on_every_item +ij_typescript_parentheses_expression_new_line_after_left_paren = false +ij_typescript_parentheses_expression_right_paren_on_new_line = false +ij_typescript_place_assignment_sign_on_next_line = false +ij_typescript_prefer_as_type_cast = false +ij_typescript_prefer_explicit_types_function_expression_returns = false +ij_typescript_prefer_explicit_types_function_returns = false +ij_typescript_prefer_explicit_types_vars_fields = false +ij_typescript_prefer_parameters_wrap = false +ij_typescript_reformat_c_style_comments = false +ij_typescript_space_after_colon = true +ij_typescript_space_after_comma = true +ij_typescript_space_after_dots_in_rest_parameter = false +ij_typescript_space_after_generator_mult = true +ij_typescript_space_after_property_colon = true +ij_typescript_space_after_quest = true +ij_typescript_space_after_type_colon = true +ij_typescript_space_after_unary_not = false +ij_typescript_space_before_async_arrow_lparen = true +ij_typescript_space_before_catch_keyword = true +ij_typescript_space_before_catch_left_brace = true +ij_typescript_space_before_catch_parentheses = true +ij_typescript_space_before_class_lbrace = true +ij_typescript_space_before_class_left_brace = true +ij_typescript_space_before_colon = true +ij_typescript_space_before_comma = false +ij_typescript_space_before_do_left_brace = true +ij_typescript_space_before_else_keyword = true +ij_typescript_space_before_else_left_brace = true +ij_typescript_space_before_finally_keyword = true +ij_typescript_space_before_finally_left_brace = true +ij_typescript_space_before_for_left_brace = true +ij_typescript_space_before_for_parentheses = true +ij_typescript_space_before_for_semicolon = false +ij_typescript_space_before_function_left_parenth = true +ij_typescript_space_before_generator_mult = false +ij_typescript_space_before_if_left_brace = true +ij_typescript_space_before_if_parentheses = true +ij_typescript_space_before_method_call_parentheses = false +ij_typescript_space_before_method_left_brace = true +ij_typescript_space_before_method_parentheses = false +ij_typescript_space_before_property_colon = false +ij_typescript_space_before_quest = true +ij_typescript_space_before_switch_left_brace = true +ij_typescript_space_before_switch_parentheses = true +ij_typescript_space_before_try_left_brace = true +ij_typescript_space_before_type_colon = false +ij_typescript_space_before_unary_not = false +ij_typescript_space_before_while_keyword = true +ij_typescript_space_before_while_left_brace = true +ij_typescript_space_before_while_parentheses = true +ij_typescript_spaces_around_additive_operators = true +ij_typescript_spaces_around_arrow_function_operator = true +ij_typescript_spaces_around_assignment_operators = true +ij_typescript_spaces_around_bitwise_operators = true +ij_typescript_spaces_around_equality_operators = true +ij_typescript_spaces_around_logical_operators = true +ij_typescript_spaces_around_multiplicative_operators = true +ij_typescript_spaces_around_relational_operators = true +ij_typescript_spaces_around_shift_operators = true +ij_typescript_spaces_around_unary_operator = false +ij_typescript_spaces_within_array_initializer_brackets = false +ij_typescript_spaces_within_brackets = false +ij_typescript_spaces_within_catch_parentheses = false +ij_typescript_spaces_within_for_parentheses = false +ij_typescript_spaces_within_if_parentheses = false +ij_typescript_spaces_within_imports = false +ij_typescript_spaces_within_interpolation_expressions = false +ij_typescript_spaces_within_method_call_parentheses = false +ij_typescript_spaces_within_method_parentheses = false +ij_typescript_spaces_within_object_literal_braces = false +ij_typescript_spaces_within_object_type_braces = true +ij_typescript_spaces_within_parentheses = false +ij_typescript_spaces_within_switch_parentheses = false +ij_typescript_spaces_within_type_assertion = false +ij_typescript_spaces_within_union_types = true +ij_typescript_spaces_within_while_parentheses = false +ij_typescript_special_else_if_treatment = true +ij_typescript_ternary_operation_signs_on_next_line = false +ij_typescript_ternary_operation_wrap = off +ij_typescript_union_types_wrap = on_every_item +ij_typescript_use_chained_calls_group_indents = false +ij_typescript_use_double_quotes = true +ij_typescript_use_explicit_js_extension = auto +ij_typescript_use_path_mapping = always +ij_typescript_use_public_modifier = false +ij_typescript_use_semicolon_after_statement = true +ij_typescript_var_declaration_wrap = normal +ij_typescript_while_brace_force = never +ij_typescript_while_on_new_line = false +ij_typescript_wrap_comments = false + +[{*.bash,*.sh,*.zsh}] +indent_size = 2 +tab_width = 2 +ij_shell_binary_ops_start_line = false +ij_shell_keep_column_alignment_padding = false +ij_shell_minify_program = false +ij_shell_redirect_followed_by_space = false +ij_shell_switch_cases_indented = false +ij_shell_use_unix_line_separator = true + +[{*.cjs,*.js}] +ij_continuation_indent_size = 4 +ij_javascript_align_imports = false +ij_javascript_align_multiline_array_initializer_expression = false +ij_javascript_align_multiline_binary_operation = false +ij_javascript_align_multiline_chained_methods = false +ij_javascript_align_multiline_extends_list = false +ij_javascript_align_multiline_for = true +ij_javascript_align_multiline_parameters = true +ij_javascript_align_multiline_parameters_in_calls = false +ij_javascript_align_multiline_ternary_operation = false +ij_javascript_align_object_properties = 0 +ij_javascript_align_union_types = false +ij_javascript_align_var_statements = 0 +ij_javascript_array_initializer_new_line_after_left_brace = false +ij_javascript_array_initializer_right_brace_on_new_line = false +ij_javascript_array_initializer_wrap = off +ij_javascript_assignment_wrap = off +ij_javascript_binary_operation_sign_on_next_line = false +ij_javascript_binary_operation_wrap = off +ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/** +ij_javascript_blank_lines_after_imports = 1 +ij_javascript_blank_lines_around_class = 1 +ij_javascript_blank_lines_around_field = 0 +ij_javascript_blank_lines_around_function = 1 +ij_javascript_blank_lines_around_method = 1 +ij_javascript_block_brace_style = end_of_line +ij_javascript_block_comment_add_space = false +ij_javascript_block_comment_at_first_column = true +ij_javascript_call_parameters_new_line_after_left_paren = false +ij_javascript_call_parameters_right_paren_on_new_line = false +ij_javascript_call_parameters_wrap = off +ij_javascript_catch_on_new_line = false +ij_javascript_chained_call_dot_on_new_line = true +ij_javascript_class_brace_style = end_of_line +ij_javascript_comma_on_new_line = false +ij_javascript_do_while_brace_force = never +ij_javascript_else_on_new_line = false +ij_javascript_enforce_trailing_comma = keep +ij_javascript_extends_keyword_wrap = off +ij_javascript_extends_list_wrap = off +ij_javascript_field_prefix = _ +ij_javascript_file_name_style = relaxed +ij_javascript_finally_on_new_line = false +ij_javascript_for_brace_force = never +ij_javascript_for_statement_new_line_after_left_paren = false +ij_javascript_for_statement_right_paren_on_new_line = false +ij_javascript_for_statement_wrap = off +ij_javascript_force_quote_style = false +ij_javascript_force_semicolon_style = false +ij_javascript_function_expression_brace_style = end_of_line +ij_javascript_if_brace_force = never +ij_javascript_import_merge_members = global +ij_javascript_import_prefer_absolute_path = global +ij_javascript_import_sort_members = true +ij_javascript_import_sort_module_name = false +ij_javascript_import_use_node_resolution = true +ij_javascript_imports_wrap = on_every_item +ij_javascript_indent_case_from_switch = true +ij_javascript_indent_chained_calls = true +ij_javascript_indent_package_children = 0 +ij_javascript_jsx_attribute_value = braces +ij_javascript_keep_blank_lines_in_code = 2 +ij_javascript_keep_first_column_comment = true +ij_javascript_keep_indents_on_empty_lines = false +ij_javascript_keep_line_breaks = true +ij_javascript_keep_simple_blocks_in_one_line = false +ij_javascript_keep_simple_methods_in_one_line = false +ij_javascript_line_comment_add_space = true +ij_javascript_line_comment_at_first_column = false +ij_javascript_method_brace_style = end_of_line +ij_javascript_method_call_chain_wrap = off +ij_javascript_method_parameters_new_line_after_left_paren = false +ij_javascript_method_parameters_right_paren_on_new_line = false +ij_javascript_method_parameters_wrap = off +ij_javascript_object_literal_wrap = on_every_item +ij_javascript_parentheses_expression_new_line_after_left_paren = false +ij_javascript_parentheses_expression_right_paren_on_new_line = false +ij_javascript_place_assignment_sign_on_next_line = false +ij_javascript_prefer_as_type_cast = false +ij_javascript_prefer_explicit_types_function_expression_returns = false +ij_javascript_prefer_explicit_types_function_returns = false +ij_javascript_prefer_explicit_types_vars_fields = false +ij_javascript_prefer_parameters_wrap = false +ij_javascript_reformat_c_style_comments = false +ij_javascript_space_after_colon = true +ij_javascript_space_after_comma = true +ij_javascript_space_after_dots_in_rest_parameter = false +ij_javascript_space_after_generator_mult = true +ij_javascript_space_after_property_colon = true +ij_javascript_space_after_quest = true +ij_javascript_space_after_type_colon = true +ij_javascript_space_after_unary_not = false +ij_javascript_space_before_async_arrow_lparen = true +ij_javascript_space_before_catch_keyword = true +ij_javascript_space_before_catch_left_brace = true +ij_javascript_space_before_catch_parentheses = true +ij_javascript_space_before_class_lbrace = true +ij_javascript_space_before_class_left_brace = true +ij_javascript_space_before_colon = true +ij_javascript_space_before_comma = false +ij_javascript_space_before_do_left_brace = true +ij_javascript_space_before_else_keyword = true +ij_javascript_space_before_else_left_brace = true +ij_javascript_space_before_finally_keyword = true +ij_javascript_space_before_finally_left_brace = true +ij_javascript_space_before_for_left_brace = true +ij_javascript_space_before_for_parentheses = true +ij_javascript_space_before_for_semicolon = false +ij_javascript_space_before_function_left_parenth = true +ij_javascript_space_before_generator_mult = false +ij_javascript_space_before_if_left_brace = true +ij_javascript_space_before_if_parentheses = true +ij_javascript_space_before_method_call_parentheses = false +ij_javascript_space_before_method_left_brace = true +ij_javascript_space_before_method_parentheses = false +ij_javascript_space_before_property_colon = false +ij_javascript_space_before_quest = true +ij_javascript_space_before_switch_left_brace = true +ij_javascript_space_before_switch_parentheses = true +ij_javascript_space_before_try_left_brace = true +ij_javascript_space_before_type_colon = false +ij_javascript_space_before_unary_not = false +ij_javascript_space_before_while_keyword = true +ij_javascript_space_before_while_left_brace = true +ij_javascript_space_before_while_parentheses = true +ij_javascript_spaces_around_additive_operators = true +ij_javascript_spaces_around_arrow_function_operator = true +ij_javascript_spaces_around_assignment_operators = true +ij_javascript_spaces_around_bitwise_operators = true +ij_javascript_spaces_around_equality_operators = true +ij_javascript_spaces_around_logical_operators = true +ij_javascript_spaces_around_multiplicative_operators = true +ij_javascript_spaces_around_relational_operators = true +ij_javascript_spaces_around_shift_operators = true +ij_javascript_spaces_around_unary_operator = false +ij_javascript_spaces_within_array_initializer_brackets = false +ij_javascript_spaces_within_brackets = false +ij_javascript_spaces_within_catch_parentheses = false +ij_javascript_spaces_within_for_parentheses = false +ij_javascript_spaces_within_if_parentheses = false +ij_javascript_spaces_within_imports = false +ij_javascript_spaces_within_interpolation_expressions = false +ij_javascript_spaces_within_method_call_parentheses = false +ij_javascript_spaces_within_method_parentheses = false +ij_javascript_spaces_within_object_literal_braces = false +ij_javascript_spaces_within_object_type_braces = true +ij_javascript_spaces_within_parentheses = false +ij_javascript_spaces_within_switch_parentheses = false +ij_javascript_spaces_within_type_assertion = false +ij_javascript_spaces_within_union_types = true +ij_javascript_spaces_within_while_parentheses = false +ij_javascript_special_else_if_treatment = true +ij_javascript_ternary_operation_signs_on_next_line = false +ij_javascript_ternary_operation_wrap = off +ij_javascript_union_types_wrap = on_every_item +ij_javascript_use_chained_calls_group_indents = false +ij_javascript_use_double_quotes = true +ij_javascript_use_explicit_js_extension = auto +ij_javascript_use_path_mapping = always +ij_javascript_use_public_modifier = false +ij_javascript_use_semicolon_after_statement = true +ij_javascript_var_declaration_wrap = normal +ij_javascript_while_brace_force = never +ij_javascript_while_on_new_line = false +ij_javascript_wrap_comments = false + +[{*.comp,*.frag,*.fsh,*.geom,*.glsl,*.shader,*.tesc,*.tese,*.vert,*.vsh}] +ij_glsl_keep_indents_on_empty_lines = false + +[{*.ft,*.vm,*.vsl}] +ij_vtl_keep_indents_on_empty_lines = false + +[{*.gant,*.groovy,*.gy}] +ij_groovy_align_group_field_declarations = false +ij_groovy_align_multiline_array_initializer_expression = false +ij_groovy_align_multiline_assignment = false +ij_groovy_align_multiline_binary_operation = false +ij_groovy_align_multiline_chained_methods = false +ij_groovy_align_multiline_extends_list = false +ij_groovy_align_multiline_for = true +ij_groovy_align_multiline_list_or_map = true +ij_groovy_align_multiline_method_parentheses = false +ij_groovy_align_multiline_parameters = true +ij_groovy_align_multiline_parameters_in_calls = false +ij_groovy_align_multiline_resources = true +ij_groovy_align_multiline_ternary_operation = false +ij_groovy_align_multiline_throws_list = false +ij_groovy_align_named_args_in_map = true +ij_groovy_align_throws_keyword = false +ij_groovy_array_initializer_new_line_after_left_brace = false +ij_groovy_array_initializer_right_brace_on_new_line = false +ij_groovy_array_initializer_wrap = off +ij_groovy_assert_statement_wrap = off +ij_groovy_assignment_wrap = off +ij_groovy_binary_operation_wrap = off +ij_groovy_blank_lines_after_class_header = 0 +ij_groovy_blank_lines_after_imports = 1 +ij_groovy_blank_lines_after_package = 1 +ij_groovy_blank_lines_around_class = 1 +ij_groovy_blank_lines_around_field = 0 +ij_groovy_blank_lines_around_field_in_interface = 0 +ij_groovy_blank_lines_around_method = 1 +ij_groovy_blank_lines_around_method_in_interface = 1 +ij_groovy_blank_lines_before_imports = 1 +ij_groovy_blank_lines_before_method_body = 0 +ij_groovy_blank_lines_before_package = 0 +ij_groovy_block_brace_style = end_of_line +ij_groovy_block_comment_add_space = false +ij_groovy_block_comment_at_first_column = true +ij_groovy_call_parameters_new_line_after_left_paren = false +ij_groovy_call_parameters_right_paren_on_new_line = false +ij_groovy_call_parameters_wrap = off +ij_groovy_catch_on_new_line = false +ij_groovy_class_annotation_wrap = split_into_lines +ij_groovy_class_brace_style = end_of_line +ij_groovy_class_count_to_use_import_on_demand = 5 +ij_groovy_do_while_brace_force = never +ij_groovy_else_on_new_line = false +ij_groovy_enable_groovydoc_formatting = true +ij_groovy_enum_constants_wrap = off +ij_groovy_extends_keyword_wrap = off +ij_groovy_extends_list_wrap = off +ij_groovy_field_annotation_wrap = split_into_lines +ij_groovy_finally_on_new_line = false +ij_groovy_for_brace_force = never +ij_groovy_for_statement_new_line_after_left_paren = false +ij_groovy_for_statement_right_paren_on_new_line = false +ij_groovy_for_statement_wrap = off +ij_groovy_if_brace_force = never +ij_groovy_import_annotation_wrap = 2 +ij_groovy_imports_layout = *, |, javax.**, java.**, |, $* +ij_groovy_indent_case_from_switch = true +ij_groovy_indent_label_blocks = true +ij_groovy_insert_inner_class_imports = false +ij_groovy_keep_blank_lines_before_right_brace = 2 +ij_groovy_keep_blank_lines_in_code = 2 +ij_groovy_keep_blank_lines_in_declarations = 2 +ij_groovy_keep_control_statement_in_one_line = true +ij_groovy_keep_first_column_comment = true +ij_groovy_keep_indents_on_empty_lines = false +ij_groovy_keep_line_breaks = true +ij_groovy_keep_multiple_expressions_in_one_line = false +ij_groovy_keep_simple_blocks_in_one_line = false +ij_groovy_keep_simple_classes_in_one_line = true +ij_groovy_keep_simple_lambdas_in_one_line = true +ij_groovy_keep_simple_methods_in_one_line = true +ij_groovy_label_indent_absolute = false +ij_groovy_label_indent_size = 0 +ij_groovy_lambda_brace_style = end_of_line +ij_groovy_layout_static_imports_separately = true +ij_groovy_line_comment_add_space = false +ij_groovy_line_comment_add_space_on_reformat = false +ij_groovy_line_comment_at_first_column = true +ij_groovy_method_annotation_wrap = split_into_lines +ij_groovy_method_brace_style = end_of_line +ij_groovy_method_call_chain_wrap = off +ij_groovy_method_parameters_new_line_after_left_paren = false +ij_groovy_method_parameters_right_paren_on_new_line = false +ij_groovy_method_parameters_wrap = off +ij_groovy_modifier_list_wrap = false +ij_groovy_names_count_to_use_import_on_demand = 3 +ij_groovy_packages_to_use_import_on_demand = java.awt.*, javax.swing.* +ij_groovy_parameter_annotation_wrap = off +ij_groovy_parentheses_expression_new_line_after_left_paren = false +ij_groovy_parentheses_expression_right_paren_on_new_line = false +ij_groovy_prefer_parameters_wrap = false +ij_groovy_resource_list_new_line_after_left_paren = false +ij_groovy_resource_list_right_paren_on_new_line = false +ij_groovy_resource_list_wrap = off +ij_groovy_space_after_assert_separator = true +ij_groovy_space_after_colon = true +ij_groovy_space_after_comma = true +ij_groovy_space_after_comma_in_type_arguments = true +ij_groovy_space_after_for_semicolon = true +ij_groovy_space_after_quest = true +ij_groovy_space_after_type_cast = true +ij_groovy_space_before_annotation_parameter_list = false +ij_groovy_space_before_array_initializer_left_brace = false +ij_groovy_space_before_assert_separator = false +ij_groovy_space_before_catch_keyword = true +ij_groovy_space_before_catch_left_brace = true +ij_groovy_space_before_catch_parentheses = true +ij_groovy_space_before_class_left_brace = true +ij_groovy_space_before_closure_left_brace = true +ij_groovy_space_before_colon = true +ij_groovy_space_before_comma = false +ij_groovy_space_before_do_left_brace = true +ij_groovy_space_before_else_keyword = true +ij_groovy_space_before_else_left_brace = true +ij_groovy_space_before_finally_keyword = true +ij_groovy_space_before_finally_left_brace = true +ij_groovy_space_before_for_left_brace = true +ij_groovy_space_before_for_parentheses = true +ij_groovy_space_before_for_semicolon = false +ij_groovy_space_before_if_left_brace = true +ij_groovy_space_before_if_parentheses = true +ij_groovy_space_before_method_call_parentheses = false +ij_groovy_space_before_method_left_brace = true +ij_groovy_space_before_method_parentheses = false +ij_groovy_space_before_quest = true +ij_groovy_space_before_record_parentheses = false +ij_groovy_space_before_switch_left_brace = true +ij_groovy_space_before_switch_parentheses = true +ij_groovy_space_before_synchronized_left_brace = true +ij_groovy_space_before_synchronized_parentheses = true +ij_groovy_space_before_try_left_brace = true +ij_groovy_space_before_try_parentheses = true +ij_groovy_space_before_while_keyword = true +ij_groovy_space_before_while_left_brace = true +ij_groovy_space_before_while_parentheses = true +ij_groovy_space_in_named_argument = true +ij_groovy_space_in_named_argument_before_colon = false +ij_groovy_space_within_empty_array_initializer_braces = false +ij_groovy_space_within_empty_method_call_parentheses = false +ij_groovy_spaces_around_additive_operators = true +ij_groovy_spaces_around_assignment_operators = true +ij_groovy_spaces_around_bitwise_operators = true +ij_groovy_spaces_around_equality_operators = true +ij_groovy_spaces_around_lambda_arrow = true +ij_groovy_spaces_around_logical_operators = true +ij_groovy_spaces_around_multiplicative_operators = true +ij_groovy_spaces_around_regex_operators = true +ij_groovy_spaces_around_relational_operators = true +ij_groovy_spaces_around_shift_operators = true +ij_groovy_spaces_within_annotation_parentheses = false +ij_groovy_spaces_within_array_initializer_braces = false +ij_groovy_spaces_within_braces = true +ij_groovy_spaces_within_brackets = false +ij_groovy_spaces_within_cast_parentheses = false +ij_groovy_spaces_within_catch_parentheses = false +ij_groovy_spaces_within_for_parentheses = false +ij_groovy_spaces_within_gstring_injection_braces = false +ij_groovy_spaces_within_if_parentheses = false +ij_groovy_spaces_within_list_or_map = false +ij_groovy_spaces_within_method_call_parentheses = false +ij_groovy_spaces_within_method_parentheses = false +ij_groovy_spaces_within_parentheses = false +ij_groovy_spaces_within_switch_parentheses = false +ij_groovy_spaces_within_synchronized_parentheses = false +ij_groovy_spaces_within_try_parentheses = false +ij_groovy_spaces_within_tuple_expression = false +ij_groovy_spaces_within_while_parentheses = false +ij_groovy_special_else_if_treatment = true +ij_groovy_ternary_operation_wrap = off +ij_groovy_throws_keyword_wrap = off +ij_groovy_throws_list_wrap = off +ij_groovy_use_flying_geese_braces = false +ij_groovy_use_fq_class_names = false +ij_groovy_use_fq_class_names_in_javadoc = true +ij_groovy_use_relative_indents = false +ij_groovy_use_single_class_imports = true +ij_groovy_variable_annotation_wrap = off +ij_groovy_while_brace_force = never +ij_groovy_while_on_new_line = false +ij_groovy_wrap_chain_calls_after_dot = false +ij_groovy_wrap_long_lines = false + +[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}] +indent_size = 2 +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = true +ij_json_space_before_comma = false +ij_json_spaces_within_braces = false +ij_json_spaces_within_brackets = false +ij_json_wrap_long_lines = false + +[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] +ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3 +ij_html_align_attributes = true +ij_html_align_text = false +ij_html_attribute_wrap = normal +ij_html_block_comment_add_space = false +ij_html_block_comment_at_first_column = true +ij_html_do_not_align_children_of_min_lines = 0 +ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p +ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot +ij_html_enforce_quotes = false +ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var +ij_html_keep_blank_lines = 2 +ij_html_keep_indents_on_empty_lines = false +ij_html_keep_line_breaks = true +ij_html_keep_line_breaks_in_text = true +ij_html_keep_whitespaces = false +ij_html_keep_whitespaces_inside = span, pre, textarea +ij_html_line_comment_at_first_column = true +ij_html_new_line_after_last_attribute = never +ij_html_new_line_before_first_attribute = never +ij_html_quote_style = double +ij_html_remove_new_line_before_tags = br +ij_html_space_after_tag_name = false +ij_html_space_around_equality_in_attribute = false +ij_html_space_inside_empty_tag = false +ij_html_text_wrap = normal + +[{*.jsf,*.jsp,*.jspf,*.tag,*.tagf,*.xjsp}] +ij_jsp_jsp_prefer_comma_separated_import_list = false +ij_jsp_keep_indents_on_empty_lines = false + +[{*.jspx,*.tagx}] +ij_jspx_keep_indents_on_empty_lines = false + +[{*.kt,*.kts}] +ij_kotlin_align_in_columns_case_branch = false +ij_kotlin_align_multiline_binary_operation = false +ij_kotlin_align_multiline_extends_list = false +ij_kotlin_align_multiline_method_parentheses = false +ij_kotlin_align_multiline_parameters = true +ij_kotlin_align_multiline_parameters_in_calls = false +ij_kotlin_allow_trailing_comma = false +ij_kotlin_allow_trailing_comma_on_call_site = false +ij_kotlin_assignment_wrap = off +ij_kotlin_blank_lines_after_class_header = 0 +ij_kotlin_blank_lines_around_block_when_branches = 0 +ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 +ij_kotlin_block_comment_add_space = false +ij_kotlin_block_comment_at_first_column = true +ij_kotlin_call_parameters_new_line_after_left_paren = false +ij_kotlin_call_parameters_right_paren_on_new_line = false +ij_kotlin_call_parameters_wrap = off +ij_kotlin_catch_on_new_line = false +ij_kotlin_class_annotation_wrap = split_into_lines +ij_kotlin_continuation_indent_for_chained_calls = true +ij_kotlin_continuation_indent_for_expression_bodies = true +ij_kotlin_continuation_indent_in_argument_lists = true +ij_kotlin_continuation_indent_in_elvis = true +ij_kotlin_continuation_indent_in_if_conditions = true +ij_kotlin_continuation_indent_in_parameter_lists = true +ij_kotlin_continuation_indent_in_supertype_lists = true +ij_kotlin_else_on_new_line = false +ij_kotlin_enum_constants_wrap = off +ij_kotlin_extends_list_wrap = off +ij_kotlin_field_annotation_wrap = split_into_lines +ij_kotlin_finally_on_new_line = false +ij_kotlin_if_rparen_on_new_line = false +ij_kotlin_import_nested_classes = false +ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, ^ +ij_kotlin_insert_whitespaces_in_simple_one_line_method = true +ij_kotlin_keep_blank_lines_before_right_brace = 2 +ij_kotlin_keep_blank_lines_in_code = 2 +ij_kotlin_keep_blank_lines_in_declarations = 2 +ij_kotlin_keep_first_column_comment = true +ij_kotlin_keep_indents_on_empty_lines = false +ij_kotlin_keep_line_breaks = true +ij_kotlin_lbrace_on_next_line = false +ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_add_space_on_reformat = false +ij_kotlin_line_comment_at_first_column = true +ij_kotlin_method_annotation_wrap = split_into_lines +ij_kotlin_method_call_chain_wrap = off +ij_kotlin_method_parameters_new_line_after_left_paren = false +ij_kotlin_method_parameters_right_paren_on_new_line = false +ij_kotlin_method_parameters_wrap = off +ij_kotlin_name_count_to_use_star_import = 5 +ij_kotlin_name_count_to_use_star_import_for_members = 3 +ij_kotlin_packages_to_use_import_on_demand = java.util.*, kotlinx.android.synthetic.**, io.ktor.** +ij_kotlin_parameter_annotation_wrap = off +ij_kotlin_space_after_comma = true +ij_kotlin_space_after_extend_colon = true +ij_kotlin_space_after_type_colon = true +ij_kotlin_space_before_catch_parentheses = true +ij_kotlin_space_before_comma = false +ij_kotlin_space_before_extend_colon = true +ij_kotlin_space_before_for_parentheses = true +ij_kotlin_space_before_if_parentheses = true +ij_kotlin_space_before_lambda_arrow = true +ij_kotlin_space_before_type_colon = false +ij_kotlin_space_before_when_parentheses = true +ij_kotlin_space_before_while_parentheses = true +ij_kotlin_spaces_around_additive_operators = true +ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_equality_operators = true +ij_kotlin_spaces_around_function_type_arrow = true +ij_kotlin_spaces_around_logical_operators = true +ij_kotlin_spaces_around_multiplicative_operators = true +ij_kotlin_spaces_around_range = false +ij_kotlin_spaces_around_relational_operators = true +ij_kotlin_spaces_around_unary_operator = false +ij_kotlin_spaces_around_when_arrow = true +ij_kotlin_variable_annotation_wrap = off +ij_kotlin_while_on_new_line = false +ij_kotlin_wrap_elvis_expressions = 1 +ij_kotlin_wrap_expression_body_functions = 0 +ij_kotlin_wrap_first_method_in_call_chain = false + +[{*.markdown,*.md}] +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_insert_quote_arrows_on_wrap = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_keep_line_breaks_inside_text_blocks = true +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 +ij_markdown_wrap_text_if_long = true +ij_markdown_wrap_text_inside_blockquotes = true + +[{*.pb,*.textproto}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_prototext_keep_blank_lines_in_code = 2 +ij_prototext_keep_indents_on_empty_lines = false +ij_prototext_keep_line_breaks = true +ij_prototext_space_after_colon = true +ij_prototext_space_after_comma = true +ij_prototext_space_before_colon = false +ij_prototext_space_before_comma = false +ij_prototext_spaces_within_braces = true +ij_prototext_spaces_within_brackets = false + +[{*.properties,spring.handlers,spring.schemas}] +ij_properties_align_group_field_declarations = false +ij_properties_keep_blank_lines = false +ij_properties_key_value_delimiter = equals +ij_properties_spaces_around_key_value_delimiter = false + +[{*.qute.html,*.qute.json,*.qute.txt,*.qute.yaml,*.qute.yml}] +ij_qute_keep_indents_on_empty_lines = false + +[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}] +ij_toml_keep_indents_on_empty_lines = false + +[{*.yaml,*.yml}] +indent_size = 2 +ij_yaml_align_values_properties = do_not_align +ij_yaml_autoinsert_sequence_marker = true +ij_yaml_block_mapping_on_new_line = false +ij_yaml_indent_sequence_value = true +ij_yaml_keep_indents_on_empty_lines = false +ij_yaml_keep_line_breaks = true +ij_yaml_sequence_on_new_line = false +ij_yaml_space_before_colon = false +ij_yaml_spaces_within_braces = true +ij_yaml_spaces_within_brackets = true diff --git a/README.md b/README.md index 76b968e..14b42dd 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,10 @@ CoordinatesObfuscator **Hide the real coordinates to the players.** - -This plugin helps the owner to make sure that players with modded clients do not take unfair advantage of vanilla players when `/gamerule reducedDebugInfo` is set to `true`. +This plugin helps the owner to make sure that players with modded clients do not take unfair advantage of vanilla +players when `/gamerule reducedDebugInfo` is set to `true`. How it works ------------ -Every time a player changes position, dies, joins a server or changes a world, the **X** and **Z** coordinates will be shifted by a random number, making useless every tool that uses absolute coordinates systems. +Every time a player changes position, dies, joins a server or changes a world, the **X** and **Z** coordinates will be +shifted by a random number, making useless every tool that uses absolute coordinates systems. diff --git a/pom.xml b/pom.xml index 399d9aa..bb7c9ad 100644 --- a/pom.xml +++ b/pom.xml @@ -1,65 +1,65 @@ - - 4.0.0 - org.warp - CoordinatesObfuscator - 1.4.4 - CoordinatesObfuscator - - - - src/main/resources - true - - plugin.yml - - - - src/main/resources - false - - plugin.yml - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 16 - - - - - - - papermc - https://papermc.io/repo/repository/maven-public/ - - - dmulloy2-repo - https://repo.dmulloy2.net/content/groups/public/ - - - spigotmc-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - - - com.comphenix.protocol - ProtocolLib - 5.0.0-SNAPSHOT - provided - - - io.papermc.paper - paper-api - 1.18.2-R0.1-SNAPSHOT - provided - - + + 4.0.0 + org.warp + CoordinatesObfuscator + 1.4.4 + CoordinatesObfuscator + + + + src/main/resources + true + + plugin.yml + + + + src/main/resources + false + + plugin.yml + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 16 + + + + + + + papermc + https://papermc.io/repo/repository/maven-public/ + + + dmulloy2-repo + https://repo.dmulloy2.net/content/groups/public/ + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + + + com.comphenix.protocol + ProtocolLib + 5.0.0-SNAPSHOT + provided + + + io.papermc.paper + paper-api + 1.18.2-R0.1-SNAPSHOT + provided + + \ No newline at end of file diff --git a/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java b/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java index 325c874..9aa8e34 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java +++ b/src/main/java/org/warp/coordinatesobfuscator/CoordinatesObfuscator.java @@ -1,29 +1,13 @@ package org.warp.coordinatesobfuscator; import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Play; -import com.comphenix.protocol.PacketType.Play.Client; import com.comphenix.protocol.PacketType.Play.Server; -import com.comphenix.protocol.ProtocolLib; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.ConnectionSide; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.*; import com.comphenix.protocol.injector.GamePhase; -import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; import com.comphenix.protocol.wrappers.nbt.NbtBase; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.logging.Logger; - import org.bukkit.Bukkit; -import org.bukkit.World.Environment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -32,199 +16,204 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.java.JavaPlugin; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.logging.Logger; + public class CoordinatesObfuscator extends JavaPlugin implements Listener { - public static final boolean DEBUG_ENABLED = "debug".equals(System.getProperty("coordinates_obfuscator.env")); - public static final boolean DISALLOW_REMOVING_NONEXISTENT_COORDINATES = false; - private Logger logger; - - @Override - public void onDisable() { - PlayerManager.unload(); - } + public static final boolean DEBUG_ENABLED = "debug".equals(System.getProperty("coordinates_obfuscator.env")); + public static final boolean DISALLOW_REMOVING_NONEXISTENT_COORDINATES = false; + private Logger logger; + + @Override + public void onDisable() { + PlayerManager.unload(); + } - @SuppressWarnings("CommentedOutCode") - @Override - public void onEnable() { - this.logger = getLogger(); - PlayerManager.load(logger); - - Bukkit.getPluginManager().registerEvents(this, this); - - final ProtocolManager pm = ProtocolLibrary.getProtocolManager(); - - final HashSet packets = new HashSet(); + @SuppressWarnings("CommentedOutCode") + @Override + public void onEnable() { + this.logger = getLogger(); + PlayerManager.load(logger); + + Bukkit.getPluginManager().registerEvents(this, this); + + final ProtocolManager pm = ProtocolLibrary.getProtocolManager(); + + final HashSet packets = new HashSet(); - // /Server side packets - { - final PacketAdapter.AdapterParameteters paramsServer = PacketAdapter.params(); - paramsServer.plugin(this); - paramsServer.connectionSide(ConnectionSide.SERVER_SIDE); - paramsServer.listenerPriority(ListenerPriority.HIGHEST); - paramsServer.gamePhase(GamePhase.PLAYING); - - packets.add(PacketType.Play.Server.BLOCK_ACTION); - packets.add(PacketType.Play.Server.BLOCK_BREAK); - packets.add(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); - packets.add(PacketType.Play.Server.BLOCK_CHANGE); - packets.add(PacketType.Play.Server.MULTI_BLOCK_CHANGE); - packets.add(PacketType.Play.Server.MAP_CHUNK); - packets.add(Server.UNLOAD_CHUNK); - packets.add(PacketType.Play.Server.LIGHT_UPDATE); - packets.add(PacketType.Play.Server.EXPLOSION); - packets.add(PacketType.Play.Server.SPAWN_POSITION); - - packets.add(PacketType.Play.Server.RESPAWN); - packets.add(PacketType.Play.Server.POSITION); - - packets.add(PacketType.Play.Server.WORLD_PARTICLES); - packets.add(PacketType.Play.Server.WORLD_EVENT); - - packets.add(PacketType.Play.Server.NAMED_SOUND_EFFECT); - - packets.add(PacketType.Play.Server.NAMED_ENTITY_SPAWN); - packets.add(PacketType.Play.Server.SPAWN_ENTITY); - packets.add(PacketType.Play.Server.SPAWN_ENTITY_LIVING); - packets.add(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB); - packets.add(PacketType.Play.Server.SPAWN_ENTITY_PAINTING); - packets.add(PacketType.Play.Server.ENTITY_TELEPORT); - - packets.add(PacketType.Play.Server.OPEN_SIGN_EDITOR); - packets.add(PacketType.Play.Server.ADD_VIBRATION_SIGNAL); - - packets.add(PacketType.Play.Server.ENTITY_METADATA); - packets.add(PacketType.Play.Server.VIEW_CENTRE); - packets.add(PacketType.Play.Server.WINDOW_ITEMS); - packets.add(PacketType.Play.Server.WINDOW_DATA); - packets.add(PacketType.Play.Server.SET_SLOT); - - packets.add(Server.TILE_ENTITY_DATA); - - //todo: these packets shouldn't have position. Check if some of them must be translated - // packets.add(Server.ENTITY_DESTROY); - // packets.add(Server.ENTITY_EQUIPMENT); - // packets.add(Server.ENTITY_LOOK); - // packets.add(Server.ENTITY_EFFECT); - // packets.add(Server.ENTITY_HEAD_ROTATION); - // packets.add(Server.ENTITY_SOUND); - // packets.add(Server.ENTITY_STATUS); - // packets.add(Server.ENTITY_VELOCITY); - // packets.add(Server.REL_ENTITY_MOVE); - // packets.add(Server.REL_ENTITY_MOVE_LOOK); - // packets.add(Server.ATTACH_ENTITY); - - paramsServer.types(packets); - - pm.addPacketListener(new PacketAdapter(paramsServer) { - @SuppressWarnings("DuplicateBranchesInSwitch") - @Override - public void onPacketSending(final PacketEvent event) { - - PacketContainer packet; - - switch (event.getPacket().getType().name()) { - case "LIGHT_UPDATE" -> packet = event.getPacket().shallowClone(); - case "TILE_ENTITY_DATA" -> packet = cloneTileEntityData(event.getPacket()); - case "MAP_CHUNK" -> packet = cloneMapChunkEntitiesData(event.getPacket()); - default -> packet = event.getPacket().shallowClone(); - } - - Player player = event.getPlayer(); - - boolean cancel = TranslatorClientbound.outgoing(logger, packet, player); - - event.setPacket(packet); - - if (cancel) { - event.setCancelled(true); - } - } - - }); - - } - // End Server Packets - - // /Client side Packets - { - final PacketAdapter.AdapterParameteters paramsClient = PacketAdapter.params(); - paramsClient.plugin(this); - paramsClient.connectionSide(ConnectionSide.CLIENT_SIDE); - paramsClient.listenerPriority(ListenerPriority.LOWEST); - paramsClient.gamePhase(GamePhase.PLAYING); - - packets.clear(); - - packets.add(PacketType.Play.Client.POSITION); - packets.add(PacketType.Play.Client.POSITION_LOOK); - packets.add(PacketType.Play.Client.BLOCK_DIG); - packets.add(PacketType.Play.Client.BLOCK_PLACE); - packets.add(PacketType.Play.Client.USE_ITEM); - packets.add(PacketType.Play.Client.USE_ENTITY); - packets.add(PacketType.Play.Client.VEHICLE_MOVE); - packets.add(PacketType.Play.Client.SET_COMMAND_BLOCK); - packets.add(PacketType.Play.Client.SET_JIGSAW); - packets.add(PacketType.Play.Client.STRUCT); - packets.add(PacketType.Play.Client.UPDATE_SIGN); - - paramsClient.types(packets); - - pm.addPacketListener(new PacketAdapter(paramsClient) { - - - @Override - public void onPacketReceiving(final PacketEvent event) { - try { - TranslatorServerbound.incoming(logger, event.getPacket(), event.getPlayer()); - } catch (final UnsupportedOperationException e) { - event.setCancelled(true); - e.printStackTrace(); - if (event.getPlayer() != null) { - Bukkit.getServer().broadcastMessage("Failed: " + event.getPacket().getType().name()); - } - } - } - }); - } - // End client packets - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerQuit(final PlayerQuitEvent event) { - PlayerManager.exitPlayer(event.getPlayer()); - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerJoin(final PlayerJoinEvent event) { - // This part of code has been commented because this event is fired too late. - //PlayerManager.joinPlayer(event.getPlayer()); - } - - - private PacketContainer cloneTileEntityData(PacketContainer packet) { - packet = packet.shallowClone(); - int i = 0; - for (final NbtBase obj : packet.getNbtModifier().getValues()) { - packet.getNbtModifier().write(i, obj.deepClone()); - i++; - } - - return packet; - } - - private PacketContainer cloneMapChunkEntitiesData(PacketContainer packet) { - packet = packet.shallowClone(); - int i = 0; - for (final List> obj : packet.getListNbtModifier().getValues()) { - ArrayList> newList = new ArrayList>(obj.size()); - for (NbtBase nbtBase : obj) { - newList.add(nbtBase.deepClone()); - } - packet.getListNbtModifier().write(i, newList); - i++; - } - - return packet; - } + // /Server side packets + { + final PacketAdapter.AdapterParameteters paramsServer = PacketAdapter.params(); + paramsServer.plugin(this); + paramsServer.connectionSide(ConnectionSide.SERVER_SIDE); + paramsServer.listenerPriority(ListenerPriority.HIGHEST); + paramsServer.gamePhase(GamePhase.PLAYING); + + packets.add(PacketType.Play.Server.BLOCK_ACTION); + packets.add(PacketType.Play.Server.BLOCK_BREAK); + packets.add(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); + packets.add(PacketType.Play.Server.BLOCK_CHANGE); + packets.add(PacketType.Play.Server.MULTI_BLOCK_CHANGE); + packets.add(PacketType.Play.Server.MAP_CHUNK); + packets.add(Server.UNLOAD_CHUNK); + packets.add(PacketType.Play.Server.LIGHT_UPDATE); + packets.add(PacketType.Play.Server.EXPLOSION); + packets.add(PacketType.Play.Server.SPAWN_POSITION); + + packets.add(PacketType.Play.Server.RESPAWN); + packets.add(PacketType.Play.Server.POSITION); + + packets.add(PacketType.Play.Server.WORLD_PARTICLES); + packets.add(PacketType.Play.Server.WORLD_EVENT); + + packets.add(PacketType.Play.Server.NAMED_SOUND_EFFECT); + + packets.add(PacketType.Play.Server.NAMED_ENTITY_SPAWN); + packets.add(PacketType.Play.Server.SPAWN_ENTITY); + packets.add(PacketType.Play.Server.SPAWN_ENTITY_LIVING); + packets.add(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB); + packets.add(PacketType.Play.Server.SPAWN_ENTITY_PAINTING); + packets.add(PacketType.Play.Server.ENTITY_TELEPORT); + + packets.add(PacketType.Play.Server.OPEN_SIGN_EDITOR); + packets.add(PacketType.Play.Server.ADD_VIBRATION_SIGNAL); + + packets.add(PacketType.Play.Server.ENTITY_METADATA); + packets.add(PacketType.Play.Server.VIEW_CENTRE); + packets.add(PacketType.Play.Server.WINDOW_ITEMS); + packets.add(PacketType.Play.Server.WINDOW_DATA); + packets.add(PacketType.Play.Server.SET_SLOT); + + packets.add(Server.TILE_ENTITY_DATA); + + //todo: these packets shouldn't have position. Check if some of them must be translated + // packets.add(Server.ENTITY_DESTROY); + // packets.add(Server.ENTITY_EQUIPMENT); + // packets.add(Server.ENTITY_LOOK); + // packets.add(Server.ENTITY_EFFECT); + // packets.add(Server.ENTITY_HEAD_ROTATION); + // packets.add(Server.ENTITY_SOUND); + // packets.add(Server.ENTITY_STATUS); + // packets.add(Server.ENTITY_VELOCITY); + // packets.add(Server.REL_ENTITY_MOVE); + // packets.add(Server.REL_ENTITY_MOVE_LOOK); + // packets.add(Server.ATTACH_ENTITY); + + paramsServer.types(packets); + + pm.addPacketListener(new PacketAdapter(paramsServer) { + @SuppressWarnings("DuplicateBranchesInSwitch") + @Override + public void onPacketSending(final PacketEvent event) { + + PacketContainer packet; + + switch (event.getPacket().getType().name()) { + case "LIGHT_UPDATE" -> packet = event.getPacket().shallowClone(); + case "TILE_ENTITY_DATA" -> packet = cloneTileEntityData(event.getPacket()); + case "MAP_CHUNK" -> packet = cloneMapChunkEntitiesData(event.getPacket()); + default -> packet = event.getPacket().shallowClone(); + } + + Player player = event.getPlayer(); + + boolean cancel = TranslatorClientbound.outgoing(logger, packet, player); + + event.setPacket(packet); + + if (cancel) { + event.setCancelled(true); + } + } + + }); + + } + // End Server Packets + + // /Client side Packets + { + final PacketAdapter.AdapterParameteters paramsClient = PacketAdapter.params(); + paramsClient.plugin(this); + paramsClient.connectionSide(ConnectionSide.CLIENT_SIDE); + paramsClient.listenerPriority(ListenerPriority.LOWEST); + paramsClient.gamePhase(GamePhase.PLAYING); + + packets.clear(); + + packets.add(PacketType.Play.Client.POSITION); + packets.add(PacketType.Play.Client.POSITION_LOOK); + packets.add(PacketType.Play.Client.BLOCK_DIG); + packets.add(PacketType.Play.Client.BLOCK_PLACE); + packets.add(PacketType.Play.Client.USE_ITEM); + packets.add(PacketType.Play.Client.USE_ENTITY); + packets.add(PacketType.Play.Client.VEHICLE_MOVE); + packets.add(PacketType.Play.Client.SET_COMMAND_BLOCK); + packets.add(PacketType.Play.Client.SET_JIGSAW); + packets.add(PacketType.Play.Client.STRUCT); + packets.add(PacketType.Play.Client.UPDATE_SIGN); + + paramsClient.types(packets); + + pm.addPacketListener(new PacketAdapter(paramsClient) { + + + @Override + public void onPacketReceiving(final PacketEvent event) { + try { + TranslatorServerbound.incoming(logger, event.getPacket(), event.getPlayer()); + } catch (final UnsupportedOperationException e) { + event.setCancelled(true); + e.printStackTrace(); + if (event.getPlayer() != null) { + Bukkit.getServer().broadcastMessage("Failed: " + event.getPacket().getType().name()); + } + } + } + }); + } + // End client packets + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerQuit(final PlayerQuitEvent event) { + PlayerManager.exitPlayer(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerJoin(final PlayerJoinEvent event) { + // This part of code has been commented because this event is fired too late. + //PlayerManager.joinPlayer(event.getPlayer()); + } + + + private PacketContainer cloneTileEntityData(PacketContainer packet) { + packet = packet.shallowClone(); + int i = 0; + for (final NbtBase obj : packet.getNbtModifier().getValues()) { + packet.getNbtModifier().write(i, obj.deepClone()); + i++; + } + + return packet; + } + + private PacketContainer cloneMapChunkEntitiesData(PacketContainer packet) { + packet = packet.shallowClone(); + int i = 0; + for (final List> obj : packet.getListNbtModifier().getValues()) { + ArrayList> newList = new ArrayList>(obj.size()); + for (NbtBase nbtBase : obj) { + newList.add(nbtBase.deepClone()); + } + packet.getListNbtModifier().write(i, newList); + i++; + } + + return packet; + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java b/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java index 700d87d..b243359 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java +++ b/src/main/java/org/warp/coordinatesobfuscator/CoordsOffsetsManager.java @@ -1,12 +1,13 @@ package org.warp.coordinatesobfuscator; +import org.bukkit.World; +import org.bukkit.entity.Player; + import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.function.Supplier; import java.util.logging.Logger; -import org.bukkit.World; -import org.bukkit.entity.Player; public class CoordsOffsetsManager { private final Map> playerCoordsPerWorld = new HashMap<>(); diff --git a/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java b/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java index 3c32432..9d81a9b 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java +++ b/src/main/java/org/warp/coordinatesobfuscator/LastPlayerCoordinateManager.java @@ -1,24 +1,24 @@ package org.warp.coordinatesobfuscator; +import org.bukkit.Location; + import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; -import org.bukkit.Location; - public class LastPlayerCoordinateManager { - Map locations = new HashMap<>(); + Map locations = new HashMap<>(); - public synchronized Optional getLastPlayerLocation(UUID player) { - return Optional.ofNullable(locations.getOrDefault(player, null)); - } + public synchronized Optional getLastPlayerLocation(UUID player) { + return Optional.ofNullable(locations.getOrDefault(player, null)); + } - public synchronized void setLastPlayerLocation(UUID player, Location location) { - locations.put(player, location); - } + public synchronized void setLastPlayerLocation(UUID player, Location location) { + locations.put(player, location); + } - public synchronized void resetLastPlayerLocation(UUID player) { - locations.remove(player); - } + public synchronized void resetLastPlayerLocation(UUID player) { + locations.remove(player); + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java b/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java index e640565..67122ce 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java +++ b/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java @@ -1,125 +1,125 @@ package org.warp.coordinatesobfuscator; -import java.util.Optional; -import java.util.Random; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Logger; - import com.comphenix.protocol.injector.temporary.TemporaryPlayer; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; +import java.util.Optional; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Logger; + public class PlayerManager { - private static final Random random = new Random(); - private static final int staticXOffset = getRandomChunkOffsetBase(); - private static final int staticZOffset = getRandomChunkOffsetBase(); - private static Logger logger; - private static CoordsOffsetsManager coordsOffsetsManager; - private static LastPlayerCoordinateManager lastPlayerCoordinateManager; - - public static void spawnPlayer(final Player player, final World world) { - coordsOffsetsManager.put(player, world, generateOffset()); - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - } - - public static CoordinateOffset respawnPlayer(final Player player, final World world) { - CoordinateOffset offset = generateOffset(); - coordsOffsetsManager.replace(player, world, offset); - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - return offset; - } - - public static CoordinateOffset teleportPlayer(final Player player, final World world, boolean overrideLastLocation) { - CoordinateOffset offset = generateOffset(); - coordsOffsetsManager.replace(player, world, offset); - if (overrideLastLocation) { - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - } - - return offset; - } - - public static void joinPlayer(final Player player) { - if (!(player instanceof TemporaryPlayer)) { - coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); - } else { - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } - } - - private static CoordinateOffset generateOffset() { - //return CoordinateOffset.of(64 * 16, 64 * 16); - return CoordinateOffset.of(getRandomChunkOffset(true) * 16, getRandomChunkOffset(false) * 16); - } - - private static int getRandomChunkOffset(boolean x) { - return getRandomChunkOffsetBase() + (x ? staticXOffset : staticZOffset); - } - - private static int getRandomChunkOffsetBase() { - int number = 64 + random.nextInt((int) Math.floor(496000d / 16d) - 64); - if (random.nextBoolean()) { - number *= -1; - } - return number; - } - - public static void exitPlayer(final Player player) { - coordsOffsetsManager.remove(player.getUniqueId()); - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } - - public static void load(Logger pluginLogger) { - logger = pluginLogger; - coordsOffsetsManager = new CoordsOffsetsManager(pluginLogger); - lastPlayerCoordinateManager = new LastPlayerCoordinateManager(); - } - - public static void unload() { - logger = null; - coordsOffsetsManager = null; - lastPlayerCoordinateManager = null; - } - - public static CoordinateOffset getOffset(Player player) { - return coordsOffsetsManager.get(player, player.getWorld()); - } - - public static CoordinateOffset getOffset(Player player, World world) { - return coordsOffsetsManager.get(player, world); - } - - public static CoordinateOffset getOffsetOrNull(Player player, World world) { - return coordsOffsetsManager.getOrNull(player, world); - } - - public static CoordinateOffset getOffsetOrJoinPlayer(Player player, World world) { - AtomicBoolean generated = new AtomicBoolean(false); - CoordinateOffset result = coordsOffsetsManager.getOrPut(player, world, () -> { - generated.set(true); - return generateOffset(); - }); - if (generated.get()) { - if (!(player instanceof TemporaryPlayer)) { - coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); - } - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } - return result; - } - - public static Optional getLastPlayerLocation(Player player) { - return lastPlayerCoordinateManager.getLastPlayerLocation(player.getUniqueId()); - } - - public static void setLastPlayerLocation(Player player, Location location) { - lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), location); - } - - public static void resetLastPlayerLocation(Player player) { - lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); - } + private static final Random random = new Random(); + private static final int staticXOffset = getRandomChunkOffsetBase(); + private static final int staticZOffset = getRandomChunkOffsetBase(); + private static Logger logger; + private static CoordsOffsetsManager coordsOffsetsManager; + private static LastPlayerCoordinateManager lastPlayerCoordinateManager; + + public static void spawnPlayer(final Player player, final World world) { + coordsOffsetsManager.put(player, world, generateOffset()); + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + } + + public static CoordinateOffset respawnPlayer(final Player player, final World world) { + CoordinateOffset offset = generateOffset(); + coordsOffsetsManager.replace(player, world, offset); + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + return offset; + } + + public static CoordinateOffset teleportPlayer(final Player player, final World world, boolean overrideLastLocation) { + CoordinateOffset offset = generateOffset(); + coordsOffsetsManager.replace(player, world, offset); + if (overrideLastLocation) { + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + } + + return offset; + } + + public static void joinPlayer(final Player player) { + if (!(player instanceof TemporaryPlayer)) { + coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), player.getLocation()); + } else { + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } + } + + private static CoordinateOffset generateOffset() { + //return CoordinateOffset.of(64 * 16, 64 * 16); + return CoordinateOffset.of(getRandomChunkOffset(true) * 16, getRandomChunkOffset(false) * 16); + } + + private static int getRandomChunkOffset(boolean x) { + return getRandomChunkOffsetBase() + (x ? staticXOffset : staticZOffset); + } + + private static int getRandomChunkOffsetBase() { + int number = 64 + random.nextInt((int) Math.floor(496000d / 16d) - 64); + if (random.nextBoolean()) { + number *= -1; + } + return number; + } + + public static void exitPlayer(final Player player) { + coordsOffsetsManager.remove(player.getUniqueId()); + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } + + public static void load(Logger pluginLogger) { + logger = pluginLogger; + coordsOffsetsManager = new CoordsOffsetsManager(pluginLogger); + lastPlayerCoordinateManager = new LastPlayerCoordinateManager(); + } + + public static void unload() { + logger = null; + coordsOffsetsManager = null; + lastPlayerCoordinateManager = null; + } + + public static CoordinateOffset getOffset(Player player) { + return coordsOffsetsManager.get(player, player.getWorld()); + } + + public static CoordinateOffset getOffset(Player player, World world) { + return coordsOffsetsManager.get(player, world); + } + + public static CoordinateOffset getOffsetOrNull(Player player, World world) { + return coordsOffsetsManager.getOrNull(player, world); + } + + public static CoordinateOffset getOffsetOrJoinPlayer(Player player, World world) { + AtomicBoolean generated = new AtomicBoolean(false); + CoordinateOffset result = coordsOffsetsManager.getOrPut(player, world, () -> { + generated.set(true); + return generateOffset(); + }); + if (generated.get()) { + if (!(player instanceof TemporaryPlayer)) { + coordsOffsetsManager.getOrPut(player, player.getWorld(), PlayerManager::generateOffset); + } + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } + return result; + } + + public static Optional getLastPlayerLocation(Player player) { + return lastPlayerCoordinateManager.getLastPlayerLocation(player.getUniqueId()); + } + + public static void setLastPlayerLocation(Player player, Location location) { + lastPlayerCoordinateManager.setLastPlayerLocation(player.getUniqueId(), location); + } + + public static void resetLastPlayerLocation(Player player) { + lastPlayerCoordinateManager.resetLastPlayerLocation(player.getUniqueId()); + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java b/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java index 37a78cd..5ea81bf 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java +++ b/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java @@ -22,449 +22,449 @@ public class TranslatorClientbound { - private static final Class NMS_BLOCK_POSITION_CLASS; - private static final Method NMS_BLOCK_POSITION_ADD_CLASS; - private static final EquivalentConverter INTERNAL_STRUCTURE_CONVERTER; - - static { - Class blockPositionClass = null; - try { - blockPositionClass = Class.forName("net.minecraft.core.BlockPosition"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - NMS_BLOCK_POSITION_CLASS = blockPositionClass; - - Method blockPositionAddMethod = null; - try { - blockPositionAddMethod = blockPositionClass.getDeclaredMethod("c", int.class, int.class, int.class); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - NMS_BLOCK_POSITION_ADD_CLASS = blockPositionAddMethod; - - EquivalentConverter internalStructureEquivalentConverter = null; - try { - Field internalStructureConverter = InternalStructure.class.getDeclaredField("CONVERTER"); - internalStructureConverter.setAccessible(true); - internalStructureEquivalentConverter = (EquivalentConverter) internalStructureConverter.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - INTERNAL_STRUCTURE_CONVERTER = internalStructureEquivalentConverter; - } - - public static boolean outgoing(Logger logger, final PacketContainer packet, final Player player) { - if (player instanceof TemporaryPlayer) { - return false; - } - CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); - Objects.requireNonNull(offset); - switch (packet.getType().name()) { - case "WINDOW_DATA": - break; - case "WINDOW_ITEMS": - fixWindowItems(logger, packet, offset); - break; - case "SET_SLOT": - fixWindowItem(logger, packet, offset); - break; - case "SPAWN_POSITION": - case "WORLD_EVENT": - case "UPDATE_SIGN": - case "BLOCK_BREAK": - case "BLOCK_BREAK_ANIMATION": - case "BLOCK_ACTION": - case "BLOCK_CHANGE": - case "SPAWN_ENTITY_PAINTING": - case "OPEN_SIGN_EDITOR": - sendBlockPosition(logger, packet, offset); - break; - case "ADD_VIBRATION_SIGNAL": - fixVibrationSignal(logger, packet, offset); - break; - case "RESPAWN": - logger.fine("[out]Respawning player"); - respawn(logger, offset, player); - break; - case "POSITION_LOOK": - case "POSITION": - boolean isRelativeX = false; - boolean isRelativeZ = false; - Set items = packet.getSets(Converters.passthrough(Enum.class)).read(0); - //noinspection rawtypes - for (Enum item : items) { - switch (item.name()) { - case "X": - isRelativeX = true; - break; - case "Z": - isRelativeZ = true; - break; - } - } - if (!isRelativeX || !isRelativeZ) { - logger.fine("[out]Repositioning player"); - CoordinateOffset positionOffset; - if (!isRelativeX && !isRelativeZ) { - positionOffset = respawn(logger, offset, player); - } else { - positionOffset = offset; - } - if (packet.getDoubles().size() > 2) { - if (!isRelativeX) { - packet.getDoubles().modify(0, x -> x == null ? null : x - positionOffset.getX()); - } - if (!isRelativeZ) { - packet.getDoubles().modify(2, z -> z == null ? null : z - positionOffset.getZ()); - } - } else { - logger.severe("Packet size error"); - } - } - break; - case "BED": - //todo: remove - //sendInt(packet, offset, 1); - break; - case "NAMED_ENTITY_SPAWN": - case "SPAWN_ENTITY": - Objects.requireNonNull(offset); - sendDouble(logger, packet, offset); - break; - case "SPAWN_ENTITY_LIVING": - case "WORLD_PARTICLES": - case "SPAWN_ENTITY_WEATHER": - case "SPAWN_ENTITY_EXPERIENCE_ORB": - case "ENTITY_TELEPORT": - sendDouble(logger, packet, offset); - break; - case "UNLOAD_CHUNK": - sendChunk(logger, packet, offset, false, false); - break; - case "LIGHT_UPDATE": - sendChunk(logger, packet, offset, false, true); - break; - case "MAP_CHUNK": - sendChunk(logger, packet, offset, true, false); - break; - case "MULTI_BLOCK_CHANGE": - sendChunkUpdate(logger, packet, offset); - break; - case "VIEW_CENTRE": - sendIntChunk(logger, packet, offset); - break; - case "MAP_CHUNK_BULK": - sendChunkBulk(logger, packet, offset); - break; - case "EXPLOSION": - sendExplosion(logger, packet, offset); - break; - case "NAMED_SOUND_EFFECT": - sendInt8(logger, packet, offset); - break; - case "ENTITY_METADATA": - if (packet.getWatchableCollectionModifier().size() > 0) { - packet.getWatchableCollectionModifier().modify(0, wrappedWatchableObjects -> { - if (wrappedWatchableObjects == null) return null; - ArrayList result = new ArrayList(wrappedWatchableObjects.size()); - for (WrappedWatchableObject wrappedWatchableObject : wrappedWatchableObjects) { - if (wrappedWatchableObject == null) { - result.add(null); - continue; - } - - Object oldValue = wrappedWatchableObject.getValue(); - if (oldValue instanceof Optional) { - //noinspection rawtypes - Optional opt = (Optional) oldValue; - if (opt.isPresent()) { - Object val = opt.get(); - if (NMS_BLOCK_POSITION_CLASS.isInstance(val)) { - wrappedWatchableObject.setValue(Optional.of(offsetPositionMc(logger, offset, val))); - } - } - } else if (oldValue instanceof BlockPosition blockPosition) { - wrappedWatchableObject.setValue(offsetPosition(logger, offset, blockPosition)); - } - result.add(wrappedWatchableObject); - } - return result; - }); - } - break; - case "TILE_ENTITY_DATA": - sendTileEntityData(logger, packet, offset); - break; - case "PLAYER_INFO": - break; - default: - logger.fine(packet.getType().name()); - break; - } - return false; - } - - private static CoordinateOffset respawn(Logger logger, CoordinateOffset offset, Player player) { - boolean hasSetLastLocation = false; - Optional lastLocationOpt = PlayerManager.getLastPlayerLocation(player); - if (lastLocationOpt.isPresent()) { - Location lastLocation = lastLocationOpt.get(); - if (lastLocation.getWorld().getUID().equals(player.getLocation().getWorld().getUID())) { - int clientViewDistance = 64; //player.getClientViewDistance(); - int minTeleportDistance = clientViewDistance * 2 * 16 + 2; - minTeleportDistance *= minTeleportDistance; // squared - if (lastLocation.distanceSquared(player.getLocation()) > minTeleportDistance) { - offset = PlayerManager.teleportPlayer(player, player.getWorld(), true); - logger.fine("Teleporting player. Prev[" + lastLocation.getBlockX() + "," + lastLocation.getBlockZ() + "] Next[" + player.getLocation().getX() + "," + player.getLocation().getZ() + "]"); - hasSetLastLocation = true; - } - } - } - if (hasSetLastLocation) { - PlayerManager.setLastPlayerLocation(player, player.getLocation()); - } - return offset; - } - - private static void fixWindowItems(Logger logger, PacketContainer packet, CoordinateOffset offset) { - packet.getItemListModifier().modify(0, itemStacks -> { - if (itemStacks == null) return null; - List newItems = new ArrayList<>(itemStacks.size()); - for (ItemStack itemStack : itemStacks) { - if (itemStack == null) { - newItems.add(null); - continue; - } - newItems.add(transformItemStack(logger, itemStack, offset)); - } - return newItems; - }); - } - - private static void fixWindowItem(Logger logger, PacketContainer packet, CoordinateOffset offset) { - packet.getItemModifier().modify(0, itemStack -> { - if (itemStack == null) { - return null; - } - return transformItemStack(logger, itemStack, offset); - }); - } - - private static ItemStack transformItemStack(Logger logger, ItemStack itemStack, CoordinateOffset offset) { - itemStack = itemStack.clone(); - - if (itemStack.hasItemMeta()) { - ItemMeta itemMeta = itemStack.getItemMeta(); - - if (itemMeta instanceof org.bukkit.inventory.meta.CompassMeta) { - org.bukkit.inventory.meta.CompassMeta compassMeta = (org.bukkit.inventory.meta.CompassMeta) itemMeta; - Location lodestoneLocation = compassMeta.getLodestone(); - if (lodestoneLocation != null) { - compassMeta.setLodestone(lodestoneLocation.subtract(offset.getXInt(), 0, offset.getZInt())); - if (!itemStack.setItemMeta(compassMeta)) { - logger.severe("Can't apply meta"); - } - } - } - } - return itemStack; - } - - - private static void sendChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset, boolean includesEntities, boolean includeLight) { - StructureModifier integers = packet.getIntegers(); - integers.modify(0, curr_x -> { - if (curr_x != null) { - return curr_x - offset.getXChunk(); - } else { - return null; - } - }); - integers.modify(1, curr_z -> { - if (curr_z != null) { - return curr_z - offset.getZChunk(); - } else { - return null; - } - }); - if (includeLight) { - StructureModifier> byteArrays = packet.getStructures().read(0).getLists(Converters.passthrough(byte[].class)); - for (int i = 0; i < 2; i++) { - byteArrays.modify(i, list -> { - if (list == null) return null; - ArrayList newList = new ArrayList<>(list); - newList.replaceAll(bytes -> Arrays.copyOf(bytes, bytes.length)); - return newList; - }); - } - } - if (includesEntities) { - packet.getStructures().read(0).getLists(INTERNAL_STRUCTURE_CONVERTER).modify(0, entities -> { - if (entities == null) return null; - for (InternalStructure entity : entities) { - // ((blockX & 15) << 4) | (blockZ & 15) - entity.getIntegers().modify(0, packedXZ -> { - int x = (packedXZ >> 4) - offset.getXInt(); - int y = (packedXZ & 15) - offset.getZInt(); - return ((x & 15) << 4) | (y & 15); - }); - } - return entities; - }); - } - } - - private static void sendChunkBulk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getIntegerArrays().size() > 1) { - final int[] x = packet.getIntegerArrays().read(0).clone(); - final int[] z = packet.getIntegerArrays().read(1).clone(); - - for (int i = 0; i < x.length; i++) { - - x[i] = x[i] - offset.getXChunk(); - z[i] = z[i] - offset.getZChunk(); - } - - packet.getIntegerArrays().write(0, x); - packet.getIntegerArrays().write(1, z); - } else { - logger.severe("Packet size error"); - } - } - - private static void sendChunkUpdate(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - BlockPosition sp = packet.getSectionPositions().read(0); - if (sp == null) { - return; - } - packet.getSectionPositions().write(0, sp.subtract(new BlockPosition(offset.getXChunk(), 0, offset.getZChunk()))); - } - - - private static void sendDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getDoubles().size() > 2) { - packet.getDoubles().modify(0, x -> x == null ? null : x - offset.getX()); - packet.getDoubles().modify(2, z -> z == null ? null : z - offset.getZ()); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendExplosion(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - sendDouble(logger, packet, offset); - - packet.getBlockPositionCollectionModifier().modify(0, lst -> { - if (lst == null) return null; - ArrayList newLst = new ArrayList(lst.size()); - for (BlockPosition blockPosition : lst) { - newLst.add(blockPosition.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); - } - return newLst; - }); - } - - - private static void sendFixedPointNumber(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 5)); - packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 5)); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendFloat(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getFloat().size() > 2) { - packet.getFloat().modify(index, curr_x -> curr_x == null ? null : (float) (curr_x - offset.getX())); - packet.getFloat().modify(index + 2, curr_z -> curr_z == null ? null : (float) (curr_z - offset.getZ())); - } else { - logger.severe("Packet size error"); - } - } - - private static void sendInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - offset.getXInt()); - packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - offset.getZInt()); - } else { - logger.severe("Packet size error"); - } - } - - private static void sendIntChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getIntegers().size() > 1) { - packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - offset.getXChunk()); - packet.getIntegers().modify(1, curr_z -> curr_z == null ? null : curr_z - offset.getZChunk()); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendBlockPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getBlockPositionModifier().size() > 0) { - packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - } - - private static void fixVibrationSignal(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getBlockPositionModifier().size() >= 1) { - packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - if (packet.getBlockPositionModifier().size() >= 2) { - packet.getBlockPositionModifier().modify(1, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - } - - private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { - if (pos == null) return null; - return pos.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); - } - - private static Object offsetPositionMc(Logger logger, CoordinateOffset offset, Object pos) { - if (pos == null) return null; - try { - return NMS_BLOCK_POSITION_ADD_CLASS.invoke(pos, -offset.getXInt(), -0, -offset.getZInt()); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - - private static void sendInt8(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 3)); - packet.getIntegers().modify(2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 3)); - } else { - logger.severe("Packet size error"); - } - } - - - private static void sendTileEntityData(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - sendBlockPosition(logger, packet, offset); - - packet.getNbtModifier().modify(0, nbtBase -> { - if (nbtBase == null) return null; - if (nbtBase instanceof NbtCompound) { - final NbtCompound nbt = (NbtCompound) (((NbtCompound) nbtBase).deepClone()); - if (nbt.containsKey("x") && nbt.containsKey("z")) { - nbt.put("x", nbt.getInteger("x") - offset.getXInt()); - nbt.put("z", nbt.getInteger("z") - offset.getZInt()); - } - return nbt; - } else { - return nbtBase; - } - }); - } + private static final Class NMS_BLOCK_POSITION_CLASS; + private static final Method NMS_BLOCK_POSITION_ADD_CLASS; + private static final EquivalentConverter INTERNAL_STRUCTURE_CONVERTER; + + static { + Class blockPositionClass = null; + try { + blockPositionClass = Class.forName("net.minecraft.core.BlockPosition"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + NMS_BLOCK_POSITION_CLASS = blockPositionClass; + + Method blockPositionAddMethod = null; + try { + blockPositionAddMethod = blockPositionClass.getDeclaredMethod("c", int.class, int.class, int.class); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + NMS_BLOCK_POSITION_ADD_CLASS = blockPositionAddMethod; + + EquivalentConverter internalStructureEquivalentConverter = null; + try { + Field internalStructureConverter = InternalStructure.class.getDeclaredField("CONVERTER"); + internalStructureConverter.setAccessible(true); + internalStructureEquivalentConverter = (EquivalentConverter) internalStructureConverter.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + INTERNAL_STRUCTURE_CONVERTER = internalStructureEquivalentConverter; + } + + public static boolean outgoing(Logger logger, final PacketContainer packet, final Player player) { + if (player instanceof TemporaryPlayer) { + return false; + } + CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); + Objects.requireNonNull(offset); + switch (packet.getType().name()) { + case "WINDOW_DATA": + break; + case "WINDOW_ITEMS": + fixWindowItems(logger, packet, offset); + break; + case "SET_SLOT": + fixWindowItem(logger, packet, offset); + break; + case "SPAWN_POSITION": + case "WORLD_EVENT": + case "UPDATE_SIGN": + case "BLOCK_BREAK": + case "BLOCK_BREAK_ANIMATION": + case "BLOCK_ACTION": + case "BLOCK_CHANGE": + case "SPAWN_ENTITY_PAINTING": + case "OPEN_SIGN_EDITOR": + sendBlockPosition(logger, packet, offset); + break; + case "ADD_VIBRATION_SIGNAL": + fixVibrationSignal(logger, packet, offset); + break; + case "RESPAWN": + logger.fine("[out]Respawning player"); + respawn(logger, offset, player); + break; + case "POSITION_LOOK": + case "POSITION": + boolean isRelativeX = false; + boolean isRelativeZ = false; + Set items = packet.getSets(Converters.passthrough(Enum.class)).read(0); + //noinspection rawtypes + for (Enum item : items) { + switch (item.name()) { + case "X": + isRelativeX = true; + break; + case "Z": + isRelativeZ = true; + break; + } + } + if (!isRelativeX || !isRelativeZ) { + logger.fine("[out]Repositioning player"); + CoordinateOffset positionOffset; + if (!isRelativeX && !isRelativeZ) { + positionOffset = respawn(logger, offset, player); + } else { + positionOffset = offset; + } + if (packet.getDoubles().size() > 2) { + if (!isRelativeX) { + packet.getDoubles().modify(0, x -> x == null ? null : x - positionOffset.getX()); + } + if (!isRelativeZ) { + packet.getDoubles().modify(2, z -> z == null ? null : z - positionOffset.getZ()); + } + } else { + logger.severe("Packet size error"); + } + } + break; + case "BED": + //todo: remove + //sendInt(packet, offset, 1); + break; + case "NAMED_ENTITY_SPAWN": + case "SPAWN_ENTITY": + Objects.requireNonNull(offset); + sendDouble(logger, packet, offset); + break; + case "SPAWN_ENTITY_LIVING": + case "WORLD_PARTICLES": + case "SPAWN_ENTITY_WEATHER": + case "SPAWN_ENTITY_EXPERIENCE_ORB": + case "ENTITY_TELEPORT": + sendDouble(logger, packet, offset); + break; + case "UNLOAD_CHUNK": + sendChunk(logger, packet, offset, false, false); + break; + case "LIGHT_UPDATE": + sendChunk(logger, packet, offset, false, true); + break; + case "MAP_CHUNK": + sendChunk(logger, packet, offset, true, false); + break; + case "MULTI_BLOCK_CHANGE": + sendChunkUpdate(logger, packet, offset); + break; + case "VIEW_CENTRE": + sendIntChunk(logger, packet, offset); + break; + case "MAP_CHUNK_BULK": + sendChunkBulk(logger, packet, offset); + break; + case "EXPLOSION": + sendExplosion(logger, packet, offset); + break; + case "NAMED_SOUND_EFFECT": + sendInt8(logger, packet, offset); + break; + case "ENTITY_METADATA": + if (packet.getWatchableCollectionModifier().size() > 0) { + packet.getWatchableCollectionModifier().modify(0, wrappedWatchableObjects -> { + if (wrappedWatchableObjects == null) return null; + ArrayList result = new ArrayList(wrappedWatchableObjects.size()); + for (WrappedWatchableObject wrappedWatchableObject : wrappedWatchableObjects) { + if (wrappedWatchableObject == null) { + result.add(null); + continue; + } + + Object oldValue = wrappedWatchableObject.getValue(); + if (oldValue instanceof Optional) { + //noinspection rawtypes + Optional opt = (Optional) oldValue; + if (opt.isPresent()) { + Object val = opt.get(); + if (NMS_BLOCK_POSITION_CLASS.isInstance(val)) { + wrappedWatchableObject.setValue(Optional.of(offsetPositionMc(logger, offset, val))); + } + } + } else if (oldValue instanceof BlockPosition blockPosition) { + wrappedWatchableObject.setValue(offsetPosition(logger, offset, blockPosition)); + } + result.add(wrappedWatchableObject); + } + return result; + }); + } + break; + case "TILE_ENTITY_DATA": + sendTileEntityData(logger, packet, offset); + break; + case "PLAYER_INFO": + break; + default: + logger.fine(packet.getType().name()); + break; + } + return false; + } + + private static CoordinateOffset respawn(Logger logger, CoordinateOffset offset, Player player) { + boolean hasSetLastLocation = false; + Optional lastLocationOpt = PlayerManager.getLastPlayerLocation(player); + if (lastLocationOpt.isPresent()) { + Location lastLocation = lastLocationOpt.get(); + if (lastLocation.getWorld().getUID().equals(player.getLocation().getWorld().getUID())) { + int clientViewDistance = 64; //player.getClientViewDistance(); + int minTeleportDistance = clientViewDistance * 2 * 16 + 2; + minTeleportDistance *= minTeleportDistance; // squared + if (lastLocation.distanceSquared(player.getLocation()) > minTeleportDistance) { + offset = PlayerManager.teleportPlayer(player, player.getWorld(), true); + logger.fine("Teleporting player. Prev[" + lastLocation.getBlockX() + "," + lastLocation.getBlockZ() + "] Next[" + player.getLocation().getX() + "," + player.getLocation().getZ() + "]"); + hasSetLastLocation = true; + } + } + } + if (hasSetLastLocation) { + PlayerManager.setLastPlayerLocation(player, player.getLocation()); + } + return offset; + } + + private static void fixWindowItems(Logger logger, PacketContainer packet, CoordinateOffset offset) { + packet.getItemListModifier().modify(0, itemStacks -> { + if (itemStacks == null) return null; + List newItems = new ArrayList<>(itemStacks.size()); + for (ItemStack itemStack : itemStacks) { + if (itemStack == null) { + newItems.add(null); + continue; + } + newItems.add(transformItemStack(logger, itemStack, offset)); + } + return newItems; + }); + } + + private static void fixWindowItem(Logger logger, PacketContainer packet, CoordinateOffset offset) { + packet.getItemModifier().modify(0, itemStack -> { + if (itemStack == null) { + return null; + } + return transformItemStack(logger, itemStack, offset); + }); + } + + private static ItemStack transformItemStack(Logger logger, ItemStack itemStack, CoordinateOffset offset) { + itemStack = itemStack.clone(); + + if (itemStack.hasItemMeta()) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + if (itemMeta instanceof org.bukkit.inventory.meta.CompassMeta) { + org.bukkit.inventory.meta.CompassMeta compassMeta = (org.bukkit.inventory.meta.CompassMeta) itemMeta; + Location lodestoneLocation = compassMeta.getLodestone(); + if (lodestoneLocation != null) { + compassMeta.setLodestone(lodestoneLocation.subtract(offset.getXInt(), 0, offset.getZInt())); + if (!itemStack.setItemMeta(compassMeta)) { + logger.severe("Can't apply meta"); + } + } + } + } + return itemStack; + } + + + private static void sendChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset, boolean includesEntities, boolean includeLight) { + StructureModifier integers = packet.getIntegers(); + integers.modify(0, curr_x -> { + if (curr_x != null) { + return curr_x - offset.getXChunk(); + } else { + return null; + } + }); + integers.modify(1, curr_z -> { + if (curr_z != null) { + return curr_z - offset.getZChunk(); + } else { + return null; + } + }); + if (includeLight) { + StructureModifier> byteArrays = packet.getStructures().read(0).getLists(Converters.passthrough(byte[].class)); + for (int i = 0; i < 2; i++) { + byteArrays.modify(i, list -> { + if (list == null) return null; + ArrayList newList = new ArrayList<>(list); + newList.replaceAll(bytes -> Arrays.copyOf(bytes, bytes.length)); + return newList; + }); + } + } + if (includesEntities) { + packet.getStructures().read(0).getLists(INTERNAL_STRUCTURE_CONVERTER).modify(0, entities -> { + if (entities == null) return null; + for (InternalStructure entity : entities) { + // ((blockX & 15) << 4) | (blockZ & 15) + entity.getIntegers().modify(0, packedXZ -> { + int x = (packedXZ >> 4) - offset.getXInt(); + int y = (packedXZ & 15) - offset.getZInt(); + return ((x & 15) << 4) | (y & 15); + }); + } + return entities; + }); + } + } + + private static void sendChunkBulk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getIntegerArrays().size() > 1) { + final int[] x = packet.getIntegerArrays().read(0).clone(); + final int[] z = packet.getIntegerArrays().read(1).clone(); + + for (int i = 0; i < x.length; i++) { + + x[i] = x[i] - offset.getXChunk(); + z[i] = z[i] - offset.getZChunk(); + } + + packet.getIntegerArrays().write(0, x); + packet.getIntegerArrays().write(1, z); + } else { + logger.severe("Packet size error"); + } + } + + private static void sendChunkUpdate(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + BlockPosition sp = packet.getSectionPositions().read(0); + if (sp == null) { + return; + } + packet.getSectionPositions().write(0, sp.subtract(new BlockPosition(offset.getXChunk(), 0, offset.getZChunk()))); + } + + + private static void sendDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getDoubles().size() > 2) { + packet.getDoubles().modify(0, x -> x == null ? null : x - offset.getX()); + packet.getDoubles().modify(2, z -> z == null ? null : z - offset.getZ()); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendExplosion(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + sendDouble(logger, packet, offset); + + packet.getBlockPositionCollectionModifier().modify(0, lst -> { + if (lst == null) return null; + ArrayList newLst = new ArrayList(lst.size()); + for (BlockPosition blockPosition : lst) { + newLst.add(blockPosition.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); + } + return newLst; + }); + } + + + private static void sendFixedPointNumber(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 5)); + packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 5)); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendFloat(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getFloat().size() > 2) { + packet.getFloat().modify(index, curr_x -> curr_x == null ? null : (float) (curr_x - offset.getX())); + packet.getFloat().modify(index + 2, curr_z -> curr_z == null ? null : (float) (curr_z - offset.getZ())); + } else { + logger.severe("Packet size error"); + } + } + + private static void sendInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x - offset.getXInt()); + packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z - offset.getZInt()); + } else { + logger.severe("Packet size error"); + } + } + + private static void sendIntChunk(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getIntegers().size() > 1) { + packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - offset.getXChunk()); + packet.getIntegers().modify(1, curr_z -> curr_z == null ? null : curr_z - offset.getZChunk()); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendBlockPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getBlockPositionModifier().size() > 0) { + packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + } + + private static void fixVibrationSignal(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getBlockPositionModifier().size() >= 1) { + packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + if (packet.getBlockPositionModifier().size() >= 2) { + packet.getBlockPositionModifier().modify(1, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + } + + private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { + if (pos == null) return null; + return pos.subtract(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); + } + + private static Object offsetPositionMc(Logger logger, CoordinateOffset offset, Object pos) { + if (pos == null) return null; + try { + return NMS_BLOCK_POSITION_ADD_CLASS.invoke(pos, -offset.getXInt(), -0, -offset.getZInt()); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + + private static void sendInt8(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(0, curr_x -> curr_x == null ? null : curr_x - (offset.getXInt() << 3)); + packet.getIntegers().modify(2, curr_z -> curr_z == null ? null : curr_z - (offset.getZInt() << 3)); + } else { + logger.severe("Packet size error"); + } + } + + + private static void sendTileEntityData(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + sendBlockPosition(logger, packet, offset); + + packet.getNbtModifier().modify(0, nbtBase -> { + if (nbtBase == null) return null; + if (nbtBase instanceof NbtCompound) { + final NbtCompound nbt = (NbtCompound) (((NbtCompound) nbtBase).deepClone()); + if (nbt.containsKey("x") && nbt.containsKey("z")) { + nbt.put("x", nbt.getInteger("x") - offset.getXInt()); + nbt.put("z", nbt.getInteger("z") - offset.getZInt()); + } + return nbt; + } else { + return nbtBase; + } + }); + } } diff --git a/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java b/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java index f01736c..ff08a8e 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java +++ b/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java @@ -11,81 +11,81 @@ public class TranslatorServerbound { - private static final String USE_ITEM = "BLOCK_PLACE"; - private static final String BLOCK_PLACE = "USE_ITEM"; + private static final String USE_ITEM = "BLOCK_PLACE"; + private static final String BLOCK_PLACE = "USE_ITEM"; - public static void incoming(Logger logger, final PacketContainer packet, final Player player) { - if (player == null || player instanceof TemporaryPlayer) { - return; - } - CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); - Objects.requireNonNull(offset); - switch (packet.getType().name()) { - case "POSITION": - case "VEHICLE_MOVE": - case "POSITION_LOOK": - PlayerManager.setLastPlayerLocation(player, player.getLocation()); - recvDouble(logger, packet, offset); - break; - case "STRUCT": - case "SET_JIGSAW": - case "SET_COMMAND_BLOCK": - case "UPDATE_SIGN": - case "BLOCK_DIG": - recvPosition(logger, packet, offset); - break; - case USE_ITEM: - break; - case BLOCK_PLACE: - recvMovingPosition(logger, packet, offset); - break; - case "USE_ENTITY": - break; - default: - break; - } - } + public static void incoming(Logger logger, final PacketContainer packet, final Player player) { + if (player == null || player instanceof TemporaryPlayer) { + return; + } + CoordinateOffset offset = PlayerManager.getOffsetOrJoinPlayer(player, player.getWorld()); + Objects.requireNonNull(offset); + switch (packet.getType().name()) { + case "POSITION": + case "VEHICLE_MOVE": + case "POSITION_LOOK": + PlayerManager.setLastPlayerLocation(player, player.getLocation()); + recvDouble(logger, packet, offset); + break; + case "STRUCT": + case "SET_JIGSAW": + case "SET_COMMAND_BLOCK": + case "UPDATE_SIGN": + case "BLOCK_DIG": + recvPosition(logger, packet, offset); + break; + case USE_ITEM: + break; + case BLOCK_PLACE: + recvMovingPosition(logger, packet, offset); + break; + case "USE_ENTITY": + break; + default: + break; + } + } - private static void recvDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getDoubles().size() > 2) { - packet.getDoubles().modify(0, x -> x == null ? null : x + offset.getX()); - packet.getDoubles().modify(2, z -> z == null ? null : z + offset.getZ()); - } else { - int size = packet.getDoubles().size(); - logger.severe("Packet size error: " + size); - } - } + private static void recvDouble(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getDoubles().size() > 2) { + packet.getDoubles().modify(0, x -> x == null ? null : x + offset.getX()); + packet.getDoubles().modify(2, z -> z == null ? null : z + offset.getZ()); + } else { + int size = packet.getDoubles().size(); + logger.severe("Packet size error: " + size); + } + } - private static void recvInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { - if (packet.getIntegers().size() > 2) { - packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x + offset.getXInt()); - packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z + offset.getZInt()); - } else { - logger.severe("Packet size error"); - } - } + private static void recvInt(Logger logger, final PacketContainer packet, final CoordinateOffset offset, final int index) { + if (packet.getIntegers().size() > 2) { + packet.getIntegers().modify(index, curr_x -> curr_x == null ? null : curr_x + offset.getXInt()); + packet.getIntegers().modify(index + 2, curr_z -> curr_z == null ? null : curr_z + offset.getZInt()); + } else { + logger.severe("Packet size error"); + } + } - private static void recvPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - if (packet.getBlockPositionModifier().size() > 0) { - packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); - } else { - logger.severe("Packet size error"); - } - } + private static void recvPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + if (packet.getBlockPositionModifier().size() > 0) { + packet.getBlockPositionModifier().modify(0, pos -> offsetPosition(logger, offset, pos)); + } else { + logger.severe("Packet size error"); + } + } - private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { - if (pos == null) return null; - return pos.add(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); - } + private static BlockPosition offsetPosition(Logger logger, CoordinateOffset offset, BlockPosition pos) { + if (pos == null) return null; + return pos.add(new BlockPosition(offset.getXInt(), 0, offset.getZInt())); + } - private static void recvMovingPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { - var mopb = packet.getMovingBlockPositions().read(0); - if (mopb == null) { - return; - } - mopb.setBlockPosition(mopb.getBlockPosition().add(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); - mopb.setPosVector(mopb.getPosVector().add(new Vector(offset.getX(), 0, offset.getZ()))); - packet.getMovingBlockPositions().write(0, mopb); - } + private static void recvMovingPosition(Logger logger, final PacketContainer packet, final CoordinateOffset offset) { + var mopb = packet.getMovingBlockPositions().read(0); + if (mopb == null) { + return; + } + mopb.setBlockPosition(mopb.getBlockPosition().add(new BlockPosition(offset.getXInt(), 0, offset.getZInt()))); + mopb.setPosVector(mopb.getPosVector().add(new Vector(offset.getX(), 0, offset.getZ()))); + packet.getMovingBlockPositions().write(0, mopb); + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 03bed6a..871bfdb 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,4 +3,4 @@ main: ${project.groupId}.coordinatesobfuscator.CoordinatesObfuscator version: ${project.version} api-version: 1.17 author: Cavallium -depend: [ProtocolLib] \ No newline at end of file +depend: [ ProtocolLib ] \ No newline at end of file From 94aeac35fe55b766e0965ef96d3871bb1878e00b Mon Sep 17 00:00:00 2001 From: HarvelsX <90945793+HarvelsX@users.noreply.github.com> Date: Fri, 15 Apr 2022 21:29:59 +0300 Subject: [PATCH 3/3] Downgrade ProtocolLib to 4.8.0: more stability --- pom.xml | 2 +- src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java | 2 +- .../org/warp/coordinatesobfuscator/TranslatorClientbound.java | 2 +- .../org/warp/coordinatesobfuscator/TranslatorServerbound.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index bb7c9ad..8332a1b 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ com.comphenix.protocol ProtocolLib - 5.0.0-SNAPSHOT + 4.8.0 provided diff --git a/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java b/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java index 67122ce..232efeb 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java +++ b/src/main/java/org/warp/coordinatesobfuscator/PlayerManager.java @@ -1,6 +1,6 @@ package org.warp.coordinatesobfuscator; -import com.comphenix.protocol.injector.temporary.TemporaryPlayer; +import com.comphenix.protocol.injector.server.TemporaryPlayer; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; diff --git a/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java b/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java index 5ea81bf..6196bb3 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java +++ b/src/main/java/org/warp/coordinatesobfuscator/TranslatorClientbound.java @@ -2,7 +2,7 @@ import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.injector.temporary.TemporaryPlayer; +import com.comphenix.protocol.injector.server.TemporaryPlayer; import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.BlockPosition; diff --git a/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java b/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java index ff08a8e..c79f27a 100644 --- a/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java +++ b/src/main/java/org/warp/coordinatesobfuscator/TranslatorServerbound.java @@ -1,7 +1,7 @@ package org.warp.coordinatesobfuscator; import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.injector.temporary.TemporaryPlayer; +import com.comphenix.protocol.injector.server.TemporaryPlayer; import com.comphenix.protocol.wrappers.BlockPosition; import org.bukkit.entity.Player; import org.bukkit.util.Vector;