Compare commits

..
13 Commits
Author SHA1 Message Date
Jones e72e064dcc Release 2.1.43 (#540) 2025-12-23 20:22:55 +01:00
Jones 4dcafc9c91 Remove leftover mentions of Sonar's "Fallback" 2025-12-23 20:18:02 +01:00
Jones 7f2e910c2d Log full stacktraces in UpdateChecker 2025-12-23 14:36:20 +01:00
Jones b391ce38fb Refactor Sonar to stop using the "Fallback" branding 2025-12-23 14:34:17 +01:00
Jones 261f8e20e8 Remove "duplicate slot" check for stability reasons 2025-12-23 14:27:12 +01:00
Jones 4c1c509bfa Implement Italian translations (thanks to Augu0107) 2025-12-16 15:08:28 +01:00
Jones a5948bc494 Fix client brand regex issues with norisk client 2025-12-15 21:36:30 +01:00
Jones de5750e4eb Release 2.1.42 (#535) 2025-12-09 18:17:10 +00:00
Jones 71b4bad41c 1.21.11 Support (#534)
* [wip] Add 1.21.11 protocol version

* [wip] Add 1.21.11 codec

* [wip] Add 1.21.11 entity mappings

* [wip] Add 1.21.11 item component mappings
2025-12-09 18:13:32 +00:00
Jones 05d2e55d69 Minor codestyle improvements 2025-12-02 21:36:36 +01:00
Jones 41fe39cf0f Fix incorrect file license header 2025-12-02 21:35:24 +01:00
Jones fa2e68be20 Implement complex CAPTCHA design (PoC) 2025-12-02 21:34:23 +01:00
Jones 2139147952 Update sponsors 2025-11-16 13:47:40 +01:00
132 changed files with 1259 additions and 861 deletions

No files matched your search

+2 -1
View File
@@ -57,10 +57,11 @@ If you or one of your players experiences a false positive, make sure to report
## Sponsors
Massive thanks to the sponsors of Sonar who help keep this project running:
<a href="https://github.com/Hydoxl"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/107579333?v=4&h=50&w=50&fit=cover&mask=circle&maxage=7d" alt="logo" align="center"></a>
<a href="https://github.com/Chumb3x"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/79834154?v=4&h=50&w=50&fit=cover&mask=circle&maxage=7d" alt="logo" align="center"></a>
### Past Sponsors
<a href="https://github.com/Hydoxl"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/107579333?v=4&h=50&w=50&fit=cover&mask=circle&maxage=7d" alt="logo" align="center"></a>
<a href="https://github.com/ItzErpandX"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/84748484?v=4?s=400?v=4&h=50&w=50&fit=cover&mask=circle&maxage=7d" alt="logo" align="center"></a>
## Building
@@ -21,11 +21,11 @@ import net.kyori.adventure.audience.Audience;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.antibot.AntiBot;
import xyz.jonesdev.sonar.api.command.subcommand.SubcommandRegistry;
import xyz.jonesdev.sonar.api.config.SonarConfiguration;
import xyz.jonesdev.sonar.api.database.controller.VerifiedPlayerController;
import xyz.jonesdev.sonar.api.event.SonarEventManager;
import xyz.jonesdev.sonar.api.fallback.Fallback;
import xyz.jonesdev.sonar.api.logger.LoggerWrapper;
import xyz.jonesdev.sonar.api.notification.ActionBarNotificationHandler;
import xyz.jonesdev.sonar.api.notification.ChatNotificationHandler;
@@ -152,12 +152,12 @@ public interface Sonar {
}
/**
* Gets the anti-bot handler (called "Fallback") for Sonar.
* Gets the anti-bot handler for Sonar.
*
* @return The {@link Fallback} instance.
* @return The {@link AntiBot} instance.
*/
@NotNull default Fallback getFallback() {
return Fallback.INSTANCE;
@NotNull default AntiBot getAntiBot() {
return AntiBot.INSTANCE;
}
/**
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.api.fallback;
package xyz.jonesdev.sonar.api.antibot;
import com.github.benmanes.caffeine.cache.Cache;
import lombok.AccessLevel;
@@ -23,9 +23,9 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.antibot.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.api.antibot.ratelimit.Ratelimiter;
import xyz.jonesdev.sonar.api.config.SonarConfiguration;
import xyz.jonesdev.sonar.api.fallback.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.api.fallback.ratelimit.Ratelimiter;
import java.net.InetAddress;
import java.util.concurrent.ConcurrentHashMap;
@@ -33,12 +33,12 @@ import java.util.concurrent.ConcurrentMap;
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class Fallback {
public static final Fallback INSTANCE = new Fallback();
public final class AntiBot {
public static final AntiBot INSTANCE = new AntiBot();
private final ConcurrentMap<InetAddress, Integer> online = new ConcurrentHashMap<>(128);
private final ConcurrentMap<InetAddress, Boolean> connected = new ConcurrentHashMap<>(256);
private final FallbackLoginQueue queue = new FallbackLoginQueue();
private final LoginQueue queue = new LoginQueue();
@Setter
private Cache<String, Integer> blacklist;
@Setter
@@ -15,17 +15,17 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.api.fallback;
package xyz.jonesdev.sonar.api.antibot;
public interface FallbackPipelines {
String FALLBACK_INACTIVE_LISTENER = "sonar-inactive-listener";
String FALLBACK_INBOUND_HANDLER = "sonar-inbound-handler";
String FALLBACK_FRAME_DECODER = "sonar-frame-decoder";
String FALLBACK_FRAME_ENCODER = "sonar-frame-encoder";
String FALLBACK_TIMEOUT = "sonar-timeout";
String FALLBACK_PACKET_HANDLER = "sonar-packet-handler";
String FALLBACK_PACKET_ENCODER = "sonar-packet-encoder";
String FALLBACK_PACKET_DECODER = "sonar-packet-decoder";
String FALLBACK_TAIL_EXCEPTIONS = "sonar-exception-tail";
String FALLBACK_BANDWIDTH = "sonar-bandwidth-counter";
public interface ChannelPipelines {
String SONAR_INACTIVE_LISTENER = "sonar-inactive-listener";
String SONAR_INBOUND_HANDLER = "sonar-inbound-handler";
String SONAR_FRAME_DECODER = "sonar-frame-decoder";
String SONAR_FRAME_ENCODER = "sonar-frame-encoder";
String SONAR_TIMEOUT = "sonar-timeout";
String SONAR_PACKET_HANDLER = "sonar-packet-handler";
String SONAR_PACKET_ENCODER = "sonar-packet-encoder";
String SONAR_PACKET_DECODER = "sonar-packet-decoder";
String SONAR_TAIL_EXCEPTIONS = "sonar-exception-tail";
String SONAR_BANDWIDTH = "sonar-bandwidth-counter";
}
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.api.fallback;
package xyz.jonesdev.sonar.api.antibot;
import lombok.AccessLevel;
import lombok.Getter;
@@ -30,7 +30,7 @@ import java.util.concurrent.Executors;
@Getter
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public final class FallbackLoginQueue {
public final class LoginQueue {
// Fixed thread pool executor for all new verifications
private static final int THREAD_POOL_SIZE = Math.min(0x7fff, Runtime.getRuntime().availableProcessors() * 2);
private static final ExecutorService QUEUE_EXECUTOR = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
@@ -15,18 +15,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.api.fallback;
package xyz.jonesdev.sonar.api.antibot;
import io.netty.channel.Channel;
import io.netty.util.ReferenceCountUtil;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.timer.SystemTimer;
import java.net.InetAddress;
public interface FallbackUser {
public interface SonarUser {
@NotNull Channel channel();
@NotNull InetAddress getInetAddress();
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.api.fallback.captcha;
package xyz.jonesdev.sonar.api.antibot.captcha;
import org.jetbrains.annotations.NotNull;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.api.fallback.protocol;
package xyz.jonesdev.sonar.api.antibot.protocol;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -74,7 +74,8 @@ public enum ProtocolVersion {
MINECRAFT_1_21_5(770, "1.21.5"),
MINECRAFT_1_21_6(771, "1.21.6"),
MINECRAFT_1_21_7(772, "1.21.7"),
MINECRAFT_1_21_9(773, "1.21.9");
MINECRAFT_1_21_9(773, "1.21.9"),
MINECRAFT_1_21_11(774, "1.21.11");
private final int protocol;
private final String name;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.api.fallback.ratelimit;
package xyz.jonesdev.sonar.api.antibot.ratelimit;
import org.jetbrains.annotations.NotNull;
@@ -20,8 +20,8 @@ package xyz.jonesdev.sonar.api.event.impl;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import xyz.jonesdev.sonar.api.antibot.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.api.event.SonarEvent;
import xyz.jonesdev.sonar.api.fallback.captcha.CaptchaGenerator;
@Getter
@Setter
@@ -20,12 +20,12 @@ package xyz.jonesdev.sonar.api.event.impl;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import xyz.jonesdev.sonar.api.antibot.SonarUser;
import xyz.jonesdev.sonar.api.event.SonarEvent;
import xyz.jonesdev.sonar.api.fallback.FallbackUser;
@Getter
@ToString
@RequiredArgsConstructor
public final class UserBlacklistedEvent implements SonarEvent {
private final FallbackUser user;
private final SonarUser user;
}
@@ -21,13 +21,13 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.antibot.SonarUser;
import xyz.jonesdev.sonar.api.event.SonarEvent;
import xyz.jonesdev.sonar.api.fallback.FallbackUser;
@Getter
@ToString
@RequiredArgsConstructor
public final class UserVerifyFailedEvent implements SonarEvent {
private final @NotNull FallbackUser user;
private final @NotNull SonarUser user;
private final @NotNull String reason;
}
@@ -20,12 +20,12 @@ package xyz.jonesdev.sonar.api.event.impl;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import xyz.jonesdev.sonar.api.antibot.SonarUser;
import xyz.jonesdev.sonar.api.event.SonarEvent;
import xyz.jonesdev.sonar.api.fallback.FallbackUser;
@Getter
@ToString
@RequiredArgsConstructor
public final class UserVerifyJoinEvent implements SonarEvent {
private final FallbackUser user;
private final SonarUser user;
}
@@ -20,12 +20,12 @@ package xyz.jonesdev.sonar.api.event.impl;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import xyz.jonesdev.sonar.api.antibot.SonarUser;
import xyz.jonesdev.sonar.api.event.SonarEvent;
import xyz.jonesdev.sonar.api.fallback.FallbackUser;
@Getter
@ToString
@RequiredArgsConstructor
public final class UserVerifySuccessEvent implements SonarEvent {
private final FallbackUser user;
private final SonarUser user;
}
@@ -56,9 +56,9 @@ public class ActionBarNotificationHandler extends NotificationHandler {
Placeholder.unparsed("animation", nextAnimation()),
Placeholder.unparsed("process-cpu", Sonar.DECIMAL_FORMAT.format(getProcessCPUUsage())),
Placeholder.unparsed("system-cpu", Sonar.DECIMAL_FORMAT.format(getSystemCPUUsage())),
Placeholder.unparsed("queued", DECIMAL_FORMAT.format(Sonar.get0().getFallback().getQueue().getPlayers().size())),
Placeholder.unparsed("verifying", DECIMAL_FORMAT.format(Sonar.get0().getFallback().getConnected().size())),
Placeholder.unparsed("blacklisted", DECIMAL_FORMAT.format(Sonar.get0().getFallback().getBlacklist().estimatedSize())),
Placeholder.unparsed("queued", DECIMAL_FORMAT.format(Sonar.get0().getAntiBot().getQueue().getPlayers().size())),
Placeholder.unparsed("verifying", DECIMAL_FORMAT.format(Sonar.get0().getAntiBot().getConnected().size())),
Placeholder.unparsed("blacklisted", DECIMAL_FORMAT.format(Sonar.get0().getAntiBot().getBlacklist().estimatedSize())),
Placeholder.unparsed("total-joins", DECIMAL_FORMAT.format(Sonar.get0().getStatistics().getTotalPlayersJoined())),
Placeholder.unparsed("logins-per-second", DECIMAL_FORMAT.format(Sonar.get0().getStatistics().getLoginsPerSecond())),
Placeholder.unparsed("connections-per-second", DECIMAL_FORMAT.format(Sonar.get0().getStatistics().getConnectionsPerSecond())),
@@ -54,9 +54,9 @@ public final class ChatNotificationHandler extends NotificationHandler {
for (int i = 0; i < chatNotificationComponents.length; i++) {
chatNotificationComponents[i] = MiniMessage.miniMessage().deserialize(chatNotification.get(i),
Placeholder.component("prefix", Sonar.get0().getConfig().getPrefix()),
Placeholder.unparsed("queued", DECIMAL_FORMAT.format(Sonar.get0().getFallback().getQueue().getPlayers().size())),
Placeholder.unparsed("verifying", DECIMAL_FORMAT.format(Sonar.get0().getFallback().getConnected().size())),
Placeholder.unparsed("blacklisted", DECIMAL_FORMAT.format(Sonar.get0().getFallback().getBlacklist().estimatedSize())),
Placeholder.unparsed("queued", DECIMAL_FORMAT.format(Sonar.get0().getAntiBot().getQueue().getPlayers().size())),
Placeholder.unparsed("verifying", DECIMAL_FORMAT.format(Sonar.get0().getAntiBot().getConnected().size())),
Placeholder.unparsed("blacklisted", DECIMAL_FORMAT.format(Sonar.get0().getAntiBot().getBlacklist().estimatedSize())),
Placeholder.unparsed("total-joins", DECIMAL_FORMAT.format(Sonar.get0().getStatistics().getTotalPlayersJoined())),
Placeholder.unparsed("logins-per-second", DECIMAL_FORMAT.format(Sonar.get0().getStatistics().getLoginsPerSecond())),
Placeholder.unparsed("connections-per-second", DECIMAL_FORMAT.format(Sonar.get0().getStatistics().getConnectionsPerSecond())),
@@ -53,8 +53,8 @@ public final class AttackTracker {
public void checkIfUnderAttack() {
final long joinsPerSecond = Sonar.get0().getStatistics().getLoginsPerSecond();
final int verifyingPlayers = Sonar.get0().getFallback().getConnected().size();
final int queuedPlayers = Sonar.get0().getFallback().getQueue().getPlayers().size();
final int verifyingPlayers = Sonar.get0().getAntiBot().getConnected().size();
final int queuedPlayers = Sonar.get0().getAntiBot().getQueue().getPlayers().size();
final int minPlayers = Sonar.get0().getConfig().getMinPlayersForAttack();
if (joinsPerSecond > minPlayers // Check the number of bots/joins per second.
@@ -116,7 +116,7 @@ public final class AttackTracker {
final String formattedDuration = String.format("%d minutes, %.0f seconds", minutes, seconds);
final String startTimestamp = String.valueOf(currentAttack.duration.getStart() / 1000L);
final String endTimestamp = String.valueOf(System.currentTimeMillis() / 1000L);
final long blacklisted = Sonar.get0().getFallback().getBlacklist().estimatedSize();
final long blacklisted = Sonar.get0().getAntiBot().getBlacklist().estimatedSize();
// Calculate during-attack-statistics using their deltas
final long totalVerified = Sonar.get0().getVerifiedPlayerController().getCache().size();
final long verified = Math.max(totalVerified - currentAttack.successfulVerifications, 0);
@@ -65,6 +65,7 @@ public class UpdateChecker {
}
} catch (Throwable throwable) {
Sonar.get0().getLogger().warn("Unable to retrieve version information: {}", throwable);
throwable.printStackTrace(System.err);
lastCheckResult = CheckResult.API_ERROR;
}
});
@@ -28,8 +28,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.SonarPlatform;
import xyz.jonesdev.sonar.api.logger.LoggerWrapper;
import xyz.jonesdev.sonar.bukkit.antibot.BukkitInjector;
import xyz.jonesdev.sonar.bukkit.command.BukkitSonarCommand;
import xyz.jonesdev.sonar.bukkit.fallback.FallbackBukkitInjector;
import xyz.jonesdev.sonar.bukkit.listener.BukkitJoinListener;
import xyz.jonesdev.sonar.common.boot.SonarBootstrap;
@@ -108,8 +108,8 @@ public final class SonarBukkit extends SonarBootstrap<SonarBukkitPlugin> {
Objects.requireNonNull(getPlugin().getCommand("sonar")).setExecutor(new BukkitSonarCommand());
// Try to inject into the server
if (FallbackBukkitInjector.isLateBindEnabled()) {
getPlugin().getServer().getScheduler().runTask(getPlugin(), FallbackBukkitInjector::inject);
if (BukkitInjector.isLateBindEnabled()) {
getPlugin().getServer().getScheduler().runTask(getPlugin(), BukkitInjector::inject);
} else {
getPlugin().getServer().getPluginManager().registerEvents(new BukkitJoinListener(), getPlugin());
}
@@ -18,7 +18,7 @@
package xyz.jonesdev.sonar.bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import xyz.jonesdev.sonar.bukkit.fallback.FallbackBukkitInjector;
import xyz.jonesdev.sonar.bukkit.antibot.BukkitInjector;
public final class SonarBukkitPlugin extends JavaPlugin {
private SonarBukkit bootstrap;
@@ -26,8 +26,8 @@ public final class SonarBukkitPlugin extends JavaPlugin {
@Override
public void onLoad() {
// Inject early if late-bind is disabled
if (!FallbackBukkitInjector.isLateBindEnabled()) {
FallbackBukkitInjector.inject();
if (!BukkitInjector.isLateBindEnabled()) {
BukkitInjector.inject();
}
}
@@ -15,35 +15,35 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.bukkit.fallback;
package xyz.jonesdev.sonar.bukkit.antibot;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DecoderException;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.FallbackInboundHandlerAdapter;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketRegistry;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.handshake.HandshakePacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.login.LoginStartPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.InboundHandlerAdapter;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.SonarPacketRegistry;
import xyz.jonesdev.sonar.common.protocol.packets.handshake.HandshakePacket;
import xyz.jonesdev.sonar.common.protocol.packets.login.LoginStartPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
import java.net.InetSocketAddress;
import java.util.Objects;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.FALLBACK_INBOUND_HANDLER;
import static xyz.jonesdev.sonar.common.fallback.protocol.packets.handshake.HandshakePacket.*;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.SONAR_INBOUND_HANDLER;
import static xyz.jonesdev.sonar.common.protocol.packets.handshake.HandshakePacket.*;
final class FallbackBukkitInboundHandler extends FallbackInboundHandlerAdapter {
final class BukkitInboundHandler extends InboundHandlerAdapter {
private static final ProtocolVersion DEFAULT_PROTOCOL_VERSION = ProtocolVersion.MINECRAFT_1_7_2;
private FallbackPacketRegistry.ProtocolRegistry registry;
private SonarPacketRegistry.ProtocolRegistry registry;
FallbackBukkitInboundHandler() {
updateRegistry(FallbackPacketRegistry.HANDSHAKE, DEFAULT_PROTOCOL_VERSION);
BukkitInboundHandler() {
updateRegistry(SonarPacketRegistry.HANDSHAKE, DEFAULT_PROTOCOL_VERSION);
super.channelRemovalListener = (pipeline, name, handler) -> {
final ChannelInactiveListener inactiveListener = pipeline.get(ChannelInactiveListener.class);
@@ -54,9 +54,9 @@ final class FallbackBukkitInboundHandler extends FallbackInboundHandlerAdapter {
};
}
public void updateRegistry(final @NotNull FallbackPacketRegistry registry,
public void updateRegistry(final @NotNull SonarPacketRegistry registry,
final @NotNull ProtocolVersion protocolVersion) {
this.registry = registry.getProtocolRegistry(FallbackPacketRegistry.Direction.SERVERBOUND, protocolVersion);
this.registry = registry.getProtocolRegistry(SonarPacketRegistry.Direction.SERVERBOUND, protocolVersion);
}
@Override
@@ -79,7 +79,7 @@ final class FallbackBukkitInboundHandler extends FallbackInboundHandlerAdapter {
}
final int packetId = ProtocolUtil.readVarInt(byteBuf);
final FallbackPacket packet = registry.createPacket(packetId);
final SonarPacket packet = registry.createPacket(packetId);
// Skip the packet if it's not registered within Sonar's packet registry
if (packet == null) {
@@ -119,7 +119,7 @@ final class FallbackBukkitInboundHandler extends FallbackInboundHandlerAdapter {
// Let the actual handler know about the handshake packet
handleHandshake(ctx, handshake.getHostname(), handshake.getProtocolVersionId());
// Be ready for the next packet (which is supposed to be a login packet)
updateRegistry(FallbackPacketRegistry.LOGIN, Objects.requireNonNull(protocolVersion));
updateRegistry(SonarPacketRegistry.LOGIN, Objects.requireNonNull(protocolVersion));
break;
default:
byteBuf.release();
@@ -136,9 +136,9 @@ final class FallbackBukkitInboundHandler extends FallbackInboundHandlerAdapter {
byteBuf.readerIndex(originalReaderIndex);
ctx.fireChannelRead(byteBuf.retain());
// TODO: recode this?
final ChannelHandler inboundHandler = ctx.pipeline().remove(FALLBACK_INBOUND_HANDLER);
final ChannelHandler inboundHandler = ctx.pipeline().remove(SONAR_INBOUND_HANDLER);
if (inboundHandler != null && channelRemovalListener != null) {
channelRemovalListener.accept(ctx.pipeline(), FALLBACK_INBOUND_HANDLER, inboundHandler);
channelRemovalListener.accept(ctx.pipeline(), SONAR_INBOUND_HANDLER, inboundHandler);
}
}, loginStart.getUsername(), socketAddress);
byteBuf.release();
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.bukkit.fallback;
package xyz.jonesdev.sonar.bukkit.antibot;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
@@ -26,7 +26,7 @@ import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.common.fallback.netty.FallbackInjectedChannelInitializer;
import xyz.jonesdev.sonar.common.netty.SonarInjectedChannelInitializer;
import xyz.jonesdev.sonar.common.util.exception.ReflectiveOperationException;
import java.lang.reflect.Field;
@@ -34,8 +34,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.FALLBACK_INACTIVE_LISTENER;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.FALLBACK_PACKET_DECODER;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.SONAR_INACTIVE_LISTENER;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.SONAR_PACKET_DECODER;
import static xyz.jonesdev.sonar.bukkit.SonarBukkit.INITIALIZE_LISTENER;
// Check out these links if you want to see some more magic
@@ -43,7 +43,7 @@ import static xyz.jonesdev.sonar.bukkit.SonarBukkit.INITIALIZE_LISTENER;
// https://github.com/dmulloy2/ProtocolLib/blob/master/TinyProtocol/src/main/java/com/comphenix/tinyprotocol/TinyProtocol.java
// https://github.com/ViaVersion/ViaVersion/blob/master/bukkit/src/main/java/com/viaversion/viaversion/bukkit/handlers/BukkitChannelInitializer.java
@UtilityClass
public class FallbackBukkitInjector {
public class BukkitInjector {
private final String LEGACY_NMS_PACKAGE;
private final String OBC_PACKAGE;
@@ -253,10 +253,10 @@ public class FallbackBukkitInjector {
INITIALIZE_LISTENER.thenAccept(__ -> {
try {
childHandlerField.set(_bootstrap, new FallbackInjectedChannelInitializer(originalInitializer,
childHandlerField.set(_bootstrap, new SonarInjectedChannelInitializer(originalInitializer,
pipeline -> {
pipeline.addAfter("splitter", FALLBACK_PACKET_DECODER, new FallbackBukkitInboundHandler());
pipeline.addFirst(FALLBACK_INACTIVE_LISTENER, new ChannelInactiveListener());
pipeline.addAfter("splitter", SONAR_PACKET_DECODER, new BukkitInboundHandler());
pipeline.addFirst(SONAR_INACTIVE_LISTENER, new ChannelInactiveListener());
}
));
} catch (IllegalAccessException exception) {
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.bukkit.fallback;
package xyz.jonesdev.sonar.bukkit.antibot;
import lombok.Getter;
@@ -78,7 +78,10 @@ public enum BukkitServerVersion {
MINECRAFT_1_21_5,
MINECRAFT_1_21_6,
MINECRAFT_1_21_7,
MINECRAFT_1_21_8;
MINECRAFT_1_21_8,
MINECRAFT_1_21_9,
MINECRAFT_1_21_10,
MINECRAFT_1_21_11;
static final BukkitServerVersion[] REVERSED_VALUES;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.bukkit.fallback;
package xyz.jonesdev.sonar.bukkit.antibot;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.*;
@@ -24,7 +24,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.bukkit.fallback.FallbackBukkitInjector;
import xyz.jonesdev.sonar.bukkit.antibot.BukkitInjector;
import xyz.jonesdev.sonar.common.util.FakeChannelUtil;
import java.lang.invoke.MethodHandle;
@@ -32,7 +32,7 @@ import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.FALLBACK_BANDWIDTH;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.SONAR_BANDWIDTH;
// https://github.com/ViaVersion/ViaVersion/blob/master/bukkit/src/main/java/com/viaversion/viaversion/bukkit/listeners/JoinListener.java
public final class BukkitJoinListener implements Listener {
@@ -46,13 +46,13 @@ public final class BukkitJoinListener implements Listener {
static {
try {
final Method handleMethod = FallbackBukkitInjector.getOBCClass("entity.CraftPlayer")
final Method handleMethod = BukkitInjector.getOBCClass("entity.CraftPlayer")
.getDeclaredMethod("getHandle");
final Field listenerField = FallbackBukkitInjector.findField(false, handleMethod.getReturnType(),
final Field listenerField = BukkitInjector.findField(false, handleMethod.getReturnType(),
"PlayerConnection", "ServerGamePacketListenerImpl");
final Field networkManagerField = FallbackBukkitInjector.findField(true, listenerField.getType(),
final Field networkManagerField = BukkitInjector.findField(true, listenerField.getType(),
"NetworkManager", "Connection");
final Field channelField = FallbackBukkitInjector.getFieldAt(networkManagerField.getType(), Channel.class, 0);
final Field channelField = BukkitInjector.getFieldAt(networkManagerField.getType(), Channel.class, 0);
_handleMethod = MethodHandles.lookup().unreflect(handleMethod);
_listenerField = MethodHandles.lookup().unreflectGetter(listenerField);
@@ -88,7 +88,7 @@ public final class BukkitJoinListener implements Listener {
}
// Close the channel if Sonar's handlers are not found when the PlayerJoinEvent is called
if (channel.pipeline().context(FALLBACK_BANDWIDTH) == null) {
if (channel.pipeline().context(SONAR_BANDWIDTH) == null) {
channel.close();
}
} catch (Throwable throwable) {
@@ -28,8 +28,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.SonarPlatform;
import xyz.jonesdev.sonar.api.logger.LoggerWrapper;
import xyz.jonesdev.sonar.bungee.antibot.BungeeInjector;
import xyz.jonesdev.sonar.bungee.command.BungeeSonarCommand;
import xyz.jonesdev.sonar.bungee.fallback.FallbackBungeeInjector;
import xyz.jonesdev.sonar.common.boot.SonarBootstrap;
import java.util.UUID;
@@ -107,7 +107,7 @@ public final class SonarBungee extends SonarBootstrap<SonarBungeePlugin> {
getPlugin().getServer().getPluginManager().registerCommand(getPlugin(), new BungeeSonarCommand());
// Make sure to inject into the server's connection handler
FallbackBungeeInjector.inject();
BungeeInjector.inject();
}
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.bungee.fallback;
package xyz.jonesdev.sonar.bungee.antibot;
import io.netty.channel.ChannelHandlerContext;
import net.md_5.bungee.netty.ChannelWrapper;
@@ -25,16 +25,16 @@ import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.packet.Handshake;
import net.md_5.bungee.protocol.packet.LoginRequest;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.common.fallback.FallbackInboundHandlerAdapter;
import xyz.jonesdev.sonar.common.InboundHandlerAdapter;
import xyz.jonesdev.sonar.common.util.exception.ReflectiveOperationException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.net.InetSocketAddress;
import static xyz.jonesdev.sonar.common.fallback.protocol.packets.handshake.HandshakePacket.STATUS;
import static xyz.jonesdev.sonar.common.protocol.packets.handshake.HandshakePacket.STATUS;
final class FallbackBungeeInboundHandler extends FallbackInboundHandlerAdapter {
final class BungeeInboundHandler extends InboundHandlerAdapter {
private static final MethodHandle CHANNEL_WRAPPER_GETTER;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.bungee.fallback;
package xyz.jonesdev.sonar.bungee.antibot;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
@@ -27,15 +27,15 @@ import net.md_5.bungee.protocol.channel.BungeeChannelInitializer;
import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.common.fallback.netty.FallbackInjectedChannelInitializer;
import xyz.jonesdev.sonar.common.netty.SonarInjectedChannelInitializer;
import java.lang.reflect.Field;
import static net.md_5.bungee.netty.PipelineUtils.PACKET_DECODER;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.FALLBACK_PACKET_HANDLER;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.SONAR_PACKET_HANDLER;
@UtilityClass
public class FallbackBungeeInjector {
public class BungeeInjector {
public void inject() {
try {
final Field childField;
@@ -61,9 +61,9 @@ public class FallbackBungeeInjector {
// Make sure to store the original channel initializer
//noinspection unchecked
val originalInitializer = (ChannelInitializer<Channel>) childField.get(null);
final ChannelInitializer<Channel> injectedInitializer = new FallbackInjectedChannelInitializer(
originalInitializer, pipeline -> pipeline.addAfter(PACKET_DECODER, FALLBACK_PACKET_HANDLER,
new FallbackBungeeInboundHandler()));
final ChannelInitializer<Channel> injectedInitializer = new SonarInjectedChannelInitializer(
originalInitializer, pipeline -> pipeline.addAfter(PACKET_DECODER, SONAR_PACKET_HANDLER,
new BungeeInboundHandler()));
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
@@ -86,9 +86,9 @@ public class FallbackBungeeInjector {
if (!original.getChannelAcceptor().accept(channel)) {
return false;
}
FallbackInjectedChannelInitializer.inject(channel,
pipeline -> pipeline.addAfter(PACKET_DECODER, FALLBACK_PACKET_HANDLER,
new FallbackBungeeInboundHandler()));
SonarInjectedChannelInitializer.inject(channel,
pipeline -> pipeline.addAfter(PACKET_DECODER, SONAR_PACKET_HANDLER,
new BungeeInboundHandler()));
return true;
});
ProxyServer.getInstance().unsafe().setFrontendChannelInitializer(newInitializer);
@@ -23,7 +23,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.fallback.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.api.antibot.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.captcha.filters.CurvesOverlayFilter;
import xyz.jonesdev.sonar.captcha.filters.NoiseOverlayFilter;
@@ -49,8 +49,11 @@ public final class StandardCaptchaGenerator implements CaptchaGenerator {
private static final Random RANDOM = new Random();
private static final Color[] COLORS = new Color[4];
private static final float[] COLOR_FRACTIONS = new float[COLORS.length];
static final Font FONT;
static {
FONT = TTFFontProvider.loadFont("/assets/fonts/Kingthings_Trypewriter_2.ttf");
FBM.setAmount(0.6f);
FBM.setScale(15);
@@ -124,8 +127,7 @@ public final class StandardCaptchaGenerator implements CaptchaGenerator {
for (int i = 0; i < answer.length; i++) {
// Create a glyph vector for the character with a random font
final Font font = StandardTTFFontProvider.FONTS[RANDOM.nextInt(StandardTTFFontProvider.FONTS.length)];
glyphs[i] = font.createGlyphVector(ctx, String.valueOf(answer[i]));
glyphs[i] = FONT.createGlyphVector(ctx, String.valueOf(answer[i]));
}
final double scalingXY = 5 - Math.min(answer.length, 5) * 0.65;
@@ -135,7 +137,7 @@ public final class StandardCaptchaGenerator implements CaptchaGenerator {
.mapToDouble(glyph -> glyph.getLogicalBounds().getWidth() * scalingXY - 1)
.sum();
double beginX = Math.max(Math.min(width / 2D - totalWidth / 2D, totalWidth), 0);
double beginY = (height + StandardTTFFontProvider.STANDARD_FONT_SIZE / 2D) / 2D + scalingXY;
double beginY = (height + TTFFontProvider.STANDARD_FONT_SIZE / 2D) / 2D + scalingXY;
// Draw each glyph one by one
for (final GlyphVector glyph : glyphs) {
@@ -17,26 +17,16 @@
package xyz.jonesdev.sonar.captcha;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.io.InputStream;
import java.util.Objects;
@UtilityClass
class StandardTTFFontProvider {
private static final String[] FONT_NAMES = {"Kingthings_Trypewriter_2"};
static final Font[] FONTS = new Font[FONT_NAMES.length];
public final class TTFFontProvider {
static final int STANDARD_FONT_SIZE = 25;
static {
for (int i = 0; i < FONT_NAMES.length; i++) {
FONTS[i] = loadFont(String.format("/assets/fonts/%s.ttf", FONT_NAMES[i]));
}
}
private static Font loadFont(final @NotNull String path) {
public static Font loadFont(final @NotNull String path) {
try (final InputStream inputStream = StandardCaptchaGenerator.class.getResourceAsStream(path)) {
// Load the font from the TTF file
final Font customFont = Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(inputStream));
@@ -0,0 +1,210 @@
/*
* Copyright (C) 2025 Sonar Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.captcha.complex;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.antibot.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.captcha.TTFFontProvider;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.QuadCurve2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;
@RequiredArgsConstructor
public final class ComplexCaptchaGenerator implements CaptchaGenerator {
private final File background;
private final int width = 128, height = 128;
private BufferedImage backgroundImage;
private static final Font[] FONTS = {
TTFFontProvider.loadFont("/assets/fonts/dotness.ttf"), // by http://bythebutterfly.com/
TTFFontProvider.loadFont("/assets/fonts/DotMatrix.ttf"),
};
private static final Random RANDOM = new SecureRandom();
private static final double MAX_ROTATION_RADIANS = Math.toRadians(15);
private static final int LINE_COUNT = 8;
private static final int MIN_LINE_COLOR = 100;
private static final int MAX_TEXT_COLOR = 150;
private static final int DOT_COUNT = 100;
private @NotNull BufferedImage createBackgroundImage() {
final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
final Graphics2D graphics = image.createGraphics();
if (background == null) {
graphics.setBackground(Color.WHITE);
graphics.clearRect(0, 0, image.getWidth(), image.getHeight());
return image;
}
if (backgroundImage == null) {
try {
backgroundImage = ImageIO.read(background);
} catch (IOException exception) {
throw new IllegalStateException("Could not read background image", exception);
}
}
graphics.drawImage(backgroundImage, 0, 0, Color.WHITE, null);
return image;
}
@Override
public @NotNull BufferedImage createImage(char @NotNull [] answer) {
final BufferedImage image = createBackgroundImage();
final Graphics2D graphics = image.createGraphics();
final String text = new String(answer);
final int padding = 12;
final double maxWidth = width - 2D * padding;
final double maxHeight = height - 2D * padding;
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
final FontRenderContext frc = graphics.getFontRenderContext();
float optimalSize = 24;
final float trialSize = 100;
final Rectangle2D trialBounds = FONTS[0].deriveFont(trialSize).getStringBounds(text, frc);
if (trialBounds.getWidth() > 0 && trialBounds.getHeight() > 0) {
final double scaleFactorWidth = maxWidth / trialBounds.getWidth();
final double scaleFactorHeight = maxHeight / trialBounds.getHeight();
optimalSize = (float) (trialSize * Math.min(scaleFactorWidth, scaleFactorHeight));
}
if (optimalSize < 1f) {
optimalSize = 1f;
}
final Font finalFont = FONTS[0].deriveFont(optimalSize);
graphics.setFont(finalFont);
final Rectangle2D fullBounds = finalFont.getStringBounds(text, frc);
double currentX = (width - fullBounds.getWidth()) / 2D;
final double baselineY = (height / 2D) - (fullBounds.getHeight() / 2D) - fullBounds.getY();
double currentY = baselineY;
for (final char c : answer) {
final Font font = FONTS[RANDOM.nextInt(FONTS.length)].deriveFont(optimalSize);
graphics.setFont(font);
final String character = String.valueOf(c);
final Rectangle2D charBounds = font.getStringBounds(character, frc);
final double charWidth = charBounds.getWidth();
final double charHeight = charBounds.getHeight();
final double charCenterX = currentX + charWidth / 2D;
final double charCenterY = baselineY + charBounds.getY() + charHeight / 2D;
final Color[] colors = new Color[2 + RANDOM.nextInt(2)];
final float[] colorFractions = new float[colors.length];
for (int i = 0; i < colors.length; i++) {
colors[i] = getRandomTextColor();
colorFractions[i] = i / (float) colors.length;
}
graphics.setPaint(new RadialGradientPaint((float) currentX, (float) currentY, (float) charWidth,
colorFractions, colors, MultipleGradientPaint.CycleMethod.REFLECT));
final double rotation = (RANDOM.nextDouble() * 2 * MAX_ROTATION_RADIANS) - MAX_ROTATION_RADIANS;
final AffineTransform originalTransform = graphics.getTransform();
graphics.rotate(rotation, charCenterX, charCenterY);
final TextLayout layout = new TextLayout(character, font, frc);
final AffineTransform translate = AffineTransform.getTranslateInstance(currentX, currentY);
final Shape outline = layout.getOutline(translate);
graphics.fill(outline);
graphics.setTransform(originalTransform);
currentX += charWidth;
currentY += RANDOM.nextDouble(charHeight / 4) - charHeight / 8;
}
drawNoiseLines(graphics);
drawNoiseDots(graphics);
graphics.dispose();
return image;
}
private @NotNull Color getRandomTextColor() {
final int r = Math.min(RANDOM.nextInt(256), MAX_TEXT_COLOR);
final int g = Math.min(RANDOM.nextInt(256), MAX_TEXT_COLOR);
final int b = Math.min(RANDOM.nextInt(256), MAX_TEXT_COLOR);
return new Color(r, g, b, 220);
}
private @NotNull Color getRandomColor() {
final int r = Math.max(RANDOM.nextInt(256), MIN_LINE_COLOR);
final int g = Math.max(RANDOM.nextInt(256), MIN_LINE_COLOR);
final int b = Math.max(RANDOM.nextInt(256), MIN_LINE_COLOR);
final int a = Math.max(Math.min(RANDOM.nextInt(256), 200), MIN_LINE_COLOR);
return new Color(r, g, b, a);
}
private void drawNoiseLines(final @NotNull Graphics2D graphics) {
for (int i = 0; i < LINE_COUNT; i++) {
graphics.setColor(getRandomColor());
graphics.setStroke(new BasicStroke(1f + RANDOM.nextFloat() * 2f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
if (RANDOM.nextBoolean()) {
float x1 = RANDOM.nextInt(width);
float y1 = RANDOM.nextInt(height);
float ctrlX = RANDOM.nextInt(width);
float ctrlY = RANDOM.nextInt(height);
float x2 = RANDOM.nextInt(width);
float y2 = RANDOM.nextInt(height);
graphics.draw(new QuadCurve2D.Float(x1, y1, ctrlX, ctrlY, x2, y2));
} else {
int x1 = RANDOM.nextInt(width);
int y1 = RANDOM.nextInt(height);
int x2 = RANDOM.nextInt(width);
int y2 = RANDOM.nextInt(height);
graphics.drawLine(x1, y1, x2, y2);
}
}
}
private void drawNoiseDots(final @NotNull Graphics2D graphics) {
for (int i = 0; i < DOT_COUNT; i++) {
graphics.setColor(getRandomColor());
final int x = RANDOM.nextInt(width);
final int y = RANDOM.nextInt(height);
final int radius = 1 + RANDOM.nextInt(5);
graphics.fillOval(x, y, radius, radius);
}
}
}
@@ -1,86 +0,0 @@
/*
* Copyright (C) 2025 Sonar Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.captcha.filters;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
@Getter
@RequiredArgsConstructor
public final class CircleInverseFilter {
private final int amount, minRadius, maxRadiusExpansion;
private static final Random RANDOM = new Random();
public void transform(final @NotNull BufferedImage image) {
final int minX = image.getWidth() / 4;
final int minY = image.getHeight() / 4;
for (int i = 0; i < amount; i++) {
// Generate random position and radius for the circle
final float centerX = minX + RANDOM.nextInt(image.getWidth() - minX * 2);
final float centerY = minY + RANDOM.nextInt(image.getHeight() - minY * 2);
final int radius = minRadius + RANDOM.nextInt(maxRadiusExpansion);
final Circle circle = new Circle(centerX, centerY, radius);
// Draw inverted circle
_addInvertedCircle(image, circle);
}
}
private static void _addInvertedCircle(final @NotNull BufferedImage bufferedImage,
final @NotNull Circle circle) {
for (int x = 0; x < bufferedImage.getWidth(); x++) {
for (int y = 0; y < bufferedImage.getHeight(); y++) {
if (isWithinCircle(x, y, circle, circle.radius)) {
// Invert colors within the circle
final int rgb = bufferedImage.getRGB(x, y);
final int invertedRGB = invertColorAndFilter(rgb);
bufferedImage.setRGB(x, y, invertedRGB);
}
}
}
}
private static boolean isWithinCircle(final float x, final float y, final @NotNull Circle circle, int radius) {
final float distanceX = x - circle.centerX;
final float distanceY = y - circle.centerY;
return distanceX * distanceX + distanceY * distanceY <= radius * radius;
}
@Getter
@RequiredArgsConstructor
static final class Circle {
private final float centerX;
private final float centerY;
private final int radius;
}
private static int invertColorAndFilter(final int rgb) {
final Color color = new Color(rgb);
final int red = Math.max(Color.LIGHT_GRAY.getRed() - color.getRed(), 0);
final int green = Math.max(Color.LIGHT_GRAY.getGreen() - color.getGreen(), 0);
final int blue = Math.max(Color.LIGHT_GRAY.getBlue() - color.getBlue(), 0);
return new Color(red, green, blue).getRGB();
}
}
@@ -1,51 +0,0 @@
/*
* Copyright (C) 2025 Sonar Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.captcha.filters;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
@Getter
@RequiredArgsConstructor
public final class GridOverlayFilter {
private final int amount, lineWidth, randomOffset;
private static final Random RANDOM = new Random();
public void transform(final @NotNull BufferedImage image,
final @NotNull Graphics2D graphics) {
final int spacingX = image.getWidth() / amount + lineWidth;
final int spacingY = image.getHeight() / amount + lineWidth;
int currentX = spacingX / 2;
int currentY = spacingY / 2;
for (int i = 0; i < amount; i++) {
graphics.setStroke(new BasicStroke(lineWidth * 0.5f + lineWidth * RANDOM.nextFloat()));
graphics.drawLine(currentX, 0, currentX + RANDOM.nextInt(randomOffset), image.getHeight());
graphics.drawLine(0, currentY, image.getWidth(), currentY + RANDOM.nextInt(randomOffset));
currentX += spacingX + lineWidth;
currentY += spacingY + lineWidth;
}
}
}
@@ -22,7 +22,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.fallback.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.api.antibot.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.captcha.filters.NoiseOverlayFilter;
import javax.imageio.ImageIO;
Binary file not shown.
@@ -0,0 +1,5 @@
My fonts are free for personal use. You also MAY redistribute the fonts on your website as long as you guve credit to http://bythebutterfly.com as the creator of the fonts. If you are interested in commercial use, please email me at BYTHEBUTTERFLY@GMAIL.COM
Thanks, and enjoy :)
Vanessa
+3 -2
View File
@@ -16,7 +16,8 @@
*/
import lombok.experimental.UtilityClass;
import xyz.jonesdev.sonar.captcha.StandardCaptchaGenerator;
import xyz.jonesdev.sonar.api.antibot.captcha.CaptchaGenerator;
import xyz.jonesdev.sonar.captcha.complex.ComplexCaptchaGenerator;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
@@ -28,7 +29,7 @@ import java.util.Random;
public class Main {
public void main(final String... args) throws IOException {
final Random random = new Random();
final StandardCaptchaGenerator standardCaptchaGenerator = new StandardCaptchaGenerator(null);
final CaptchaGenerator standardCaptchaGenerator = new ComplexCaptchaGenerator(null);
final long start = System.currentTimeMillis();
final char[] dictionary = {'a', 'b', 'c', 'd', 'e', 'f'/*, 'g'*/, 'h'/*, 'i'*/, 'j',
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback;
package xyz.jonesdev.sonar.common;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler;
@@ -29,8 +29,8 @@ import xyz.jonesdev.sonar.common.statistics.GlobalSonarStatistics;
@ChannelHandler.Sharable
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class FallbackBandwidthHandler extends ChannelDuplexHandler {
public static final ChannelHandler INSTANCE = new FallbackBandwidthHandler();
public final class BandwidthHandler extends ChannelDuplexHandler {
public static final ChannelHandler INSTANCE = new BandwidthHandler();
@Override
public void channelRead(final ChannelHandlerContext ctx, final @NotNull Object msg) throws Exception {
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback;
package xyz.jonesdev.sonar.common;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
@@ -31,7 +31,7 @@ import java.net.InetAddress;
import java.util.function.Consumer;
@RequiredArgsConstructor
public final class FallbackInboundHandler extends ChannelInboundHandlerAdapter {
public final class InboundHandler extends ChannelInboundHandlerAdapter {
private final Consumer<ChannelPipeline> sonarPipelineInjector;
@Setter
@Getter
@@ -55,11 +55,11 @@ public final class FallbackInboundHandler extends ChannelInboundHandlerAdapter {
// Account for this by checking if the inetAddress has been set yet
if (inetAddress != null) {
// Remove the IP address from the queue
Sonar.get0().getFallback().getQueue().getPlayers().compute(inetAddress, (ignored, action) -> {
Sonar.get0().getAntiBot().getQueue().getPlayers().compute(inetAddress, (ignored, action) -> {
// The player is not queued, so we need to remove them from other maps as well
if (action == null) {
// Remove the IP address from the connected players, if needed
Sonar.get0().getFallback().getConnected().compute(inetAddress, (__, v) -> {
Sonar.get0().getAntiBot().getConnected().compute(inetAddress, (__, v) -> {
/*
* Remove this account from the online players or decrement the number of accounts
* with the same IP, but only if the player is logging into the backend server.
@@ -67,7 +67,7 @@ public final class FallbackInboundHandler extends ChannelInboundHandlerAdapter {
* we've never actually incremented it in the first place ¯\_(ツ)_/¯
*/
if (v == null) {
Sonar.get0().getFallback().getOnline().compute(inetAddress,
Sonar.get0().getAntiBot().getOnline().compute(inetAddress,
(ignored1, count) -> count == null || count <= 1 ? null : count - 1);
}
return null;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback;
package xyz.jonesdev.sonar.common;
import io.netty.channel.*;
import lombok.AllArgsConstructor;
@@ -23,12 +23,12 @@ import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.fingerprint.FingerprintingUtil;
import xyz.jonesdev.sonar.common.fallback.netty.FallbackTimeoutHandler;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketEncoder;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketRegistry;
import xyz.jonesdev.sonar.common.netty.SonarTimeoutHandler;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.SonarPacketEncoder;
import xyz.jonesdev.sonar.common.protocol.SonarPacketRegistry;
import xyz.jonesdev.sonar.common.statistics.GlobalSonarStatistics;
import xyz.jonesdev.sonar.common.util.GeyserUtil;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@@ -39,12 +39,12 @@ import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.*;
import static xyz.jonesdev.sonar.common.fallback.protocol.FallbackPreparer.*;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.*;
import static xyz.jonesdev.sonar.common.protocol.SonarPacketPreparer.*;
@AllArgsConstructor
@RequiredArgsConstructor
public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandlerAdapter {
public abstract class InboundHandlerAdapter extends ChannelInboundHandlerAdapter {
protected @Nullable String username;
protected ProtocolVersion protocolVersion;
protected @Nullable RemovalListener channelRemovalListener;
@@ -64,7 +64,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
throw QuietDecoderException.INSTANCE;
}
protocolVersion = ProtocolVersion.fromId(protocol);
ctx.pipeline().addFirst(FALLBACK_BANDWIDTH, FallbackBandwidthHandler.INSTANCE);
ctx.pipeline().addFirst(SONAR_BANDWIDTH, BandwidthHandler.INSTANCE);
}
/**
@@ -94,10 +94,10 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
this.username = username;
final InetAddress inetAddress = socketAddress.getAddress();
ctx.pipeline().get(FallbackInboundHandler.class).setInetAddress(inetAddress);
ctx.pipeline().get(InboundHandler.class).setInetAddress(inetAddress);
// Check if Fallback is already verifying a player with the same IP address
if (Sonar.get0().getFallback().getConnected().containsKey(inetAddress)) {
// Check if Sonar is already verifying a player with the same IP address
if (Sonar.get0().getAntiBot().getConnected().containsKey(inetAddress)) {
customDisconnect(ctx.channel(), alreadyVerifying, protocolVersion);
return;
}
@@ -112,7 +112,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
// Check if the player failed the verification too many times
final int limit = Sonar.get0().getConfig().getVerification().getBlacklistThreshold();
if (limit > 0) {
final int score = Sonar.get0().getFallback().getBlacklist().asMap().getOrDefault(hostAddress, 0);
final int score = Sonar.get0().getAntiBot().getBlacklist().asMap().getOrDefault(hostAddress, 0);
if (score >= limit) {
customDisconnect(ctx.channel(), blacklisted, protocolVersion);
return;
@@ -120,7 +120,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
}
// Don't continue the verification process if the verification is disabled
if (!Sonar.get0().getFallback().shouldVerifyNewPlayers()) {
if (!Sonar.get0().getAntiBot().shouldVerifyNewPlayers()) {
initialLogin(ctx.channel(), inetAddress, initialLoginAction);
return;
}
@@ -140,7 +140,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
}
// Check if the IP address is currently being rate-limited
if (!Sonar.get0().getFallback().getRatelimiter().attempt(inetAddress)) {
if (!Sonar.get0().getAntiBot().getRatelimiter().attempt(inetAddress)) {
customDisconnect(ctx.channel(), reconnectedTooFast, protocolVersion);
return;
}
@@ -149,7 +149,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
rewriteProtocol(ctx, channelRemovalListener);
// Queue the connection for further processing
Sonar.get0().getFallback().getQueue().getPlayers().compute(inetAddress, (__, runnable) -> {
Sonar.get0().getAntiBot().getQueue().getPlayers().compute(inetAddress, (__, runnable) -> {
// Check if the player is already queued since we don't want bots to flood the queue
if (runnable != null) {
customDisconnect(ctx.channel(), alreadyQueued, protocolVersion);
@@ -158,7 +158,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
}
// Create an instance for the user and let the verification handler take over the channel
return () -> new FallbackUserWrapper(ctx, inetAddress, protocolVersion, username, fingerprint, geyser);
return () -> new UserWrapper(ctx, inetAddress, protocolVersion, username, fingerprint, geyser);
});
}
@@ -170,7 +170,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
final @NotNull Runnable loginPacket) throws Exception {
final int maxOnlinePerIp = Sonar.get0().getConfig().getMaxOnlinePerIp();
if (maxOnlinePerIp > 0) {
final int newCount = Sonar.get0().getFallback().getOnline().compute(inetAddress,
final int newCount = Sonar.get0().getAntiBot().getOnline().compute(inetAddress,
(__, count) -> count == null ? 1 : count + 1);
if (newCount > maxOnlinePerIp) {
customDisconnect(channel, tooManyOnlinePerIP, protocolVersion);
@@ -200,14 +200,14 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
}
}
// Add our read/write timeout handler
ctx.pipeline().addFirst(FALLBACK_TIMEOUT, new FallbackTimeoutHandler(
ctx.pipeline().addFirst(SONAR_TIMEOUT, new SonarTimeoutHandler(
Sonar.get0().getConfig().getVerification().getReadTimeout(),
Sonar.get0().getConfig().getVerification().getWriteTimeout(),
TimeUnit.MILLISECONDS));
}
private static void customDisconnect(final @NotNull Channel channel,
final @NotNull FallbackPacket packet,
final @NotNull SonarPacket packet,
final @NotNull ProtocolVersion protocolVersion) {
if (channel.isActive()) {
if (channel.eventLoop().inEventLoop()) {
@@ -222,7 +222,7 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
* Disconnect the player before verification (during login)
*/
private static void _customDisconnect(final @NotNull Channel channel,
final @NotNull FallbackPacket packet,
final @NotNull SonarPacket packet,
final @NotNull ProtocolVersion protocolVersion) {
// TODO: recode this
// Remove the connection handler pipeline to completely take over the channel
@@ -235,10 +235,10 @@ public abstract class FallbackInboundHandlerAdapter extends ChannelInboundHandle
// Close the channel if no encoder exists
if (currentEncoder != null) {
// We don't need to update the encoder if it has already been replaced by Sonar
if (!(currentEncoder instanceof FallbackPacketEncoder)) {
final FallbackPacketEncoder newEncoder = new FallbackPacketEncoder(protocolVersion);
newEncoder.updateRegistry(FallbackPacketRegistry.LOGIN);
channel.pipeline().replace(encoder, FALLBACK_PACKET_ENCODER, newEncoder);
if (!(currentEncoder instanceof SonarPacketEncoder)) {
final SonarPacketEncoder newEncoder = new SonarPacketEncoder(protocolVersion);
newEncoder.updateRegistry(SonarPacketRegistry.LOGIN);
channel.pipeline().replace(encoder, SONAR_PACKET_ENCODER, newEncoder);
}
ProtocolUtil.closeWith(channel, protocolVersion, packet);
} else {
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback;
package xyz.jonesdev.sonar.common;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
@@ -26,29 +26,29 @@ import lombok.experimental.Accessors;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.antibot.SonarUser;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.event.impl.UserVerifyJoinEvent;
import xyz.jonesdev.sonar.api.fallback.FallbackUser;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.timer.SystemTimer;
import xyz.jonesdev.sonar.common.fallback.netty.FallbackTailExceptionsHandler;
import xyz.jonesdev.sonar.common.fallback.netty.FallbackVarInt21FrameDecoder;
import xyz.jonesdev.sonar.common.fallback.netty.FallbackVarIntLengthEncoder;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketDecoder;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketEncoder;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketRegistry;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPreparer;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.play.DisconnectPacket;
import xyz.jonesdev.sonar.common.fallback.verification.FallbackPreJoinHandler;
import xyz.jonesdev.sonar.common.netty.MinecraftVarInt21FrameDecoder;
import xyz.jonesdev.sonar.common.netty.MinecraftVarIntLengthEncoder;
import xyz.jonesdev.sonar.common.netty.TailExceptionsHandler;
import xyz.jonesdev.sonar.common.protocol.SonarPacketDecoder;
import xyz.jonesdev.sonar.common.protocol.SonarPacketEncoder;
import xyz.jonesdev.sonar.common.protocol.SonarPacketPreparer;
import xyz.jonesdev.sonar.common.protocol.SonarPacketRegistry;
import xyz.jonesdev.sonar.common.protocol.packets.play.DisconnectPacket;
import xyz.jonesdev.sonar.common.statistics.GlobalSonarStatistics;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import xyz.jonesdev.sonar.common.verification.LoginHandler;
import java.net.InetAddress;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.*;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.*;
@Getter
@ToString(of = {"protocolVersion", "inetAddress", "geyser"})
public final class FallbackUserWrapper implements FallbackUser {
public final class UserWrapper implements SonarUser {
@Accessors(fluent = true)
private final Channel channel;
private final InetAddress inetAddress;
@@ -60,12 +60,12 @@ public final class FallbackUserWrapper implements FallbackUser {
@Setter
private boolean forceCaptcha;
public FallbackUserWrapper(final @NotNull ChannelHandlerContext ctx,
final @NotNull InetAddress inetAddress,
final @NotNull ProtocolVersion protocolVersion,
final @NotNull String username,
final @NotNull String fingerprint,
final boolean geyser) {
public UserWrapper(final @NotNull ChannelHandlerContext ctx,
final @NotNull InetAddress inetAddress,
final @NotNull ProtocolVersion protocolVersion,
final @NotNull String username,
final @NotNull String fingerprint,
final boolean geyser) {
this.channel = ctx.channel();
this.inetAddress = inetAddress;
this.protocolVersion = protocolVersion;
@@ -97,48 +97,48 @@ public final class FallbackUserWrapper implements FallbackUser {
}
// How? Is there some kind of de-sync or race condition?
if (channel.pipeline().context(FALLBACK_FRAME_ENCODER) != null) {
if (channel.pipeline().context(SONAR_FRAME_ENCODER) != null) {
channel.close(); // Nope ¯\_(ツ)_/¯
return;
}
// Mark the player as connected by caching them in a map of verifying players
Sonar.get0().getFallback().getConnected().compute(inetAddress, (__, v) -> true);
Sonar.get0().getAntiBot().getConnected().compute(inetAddress, (__, v) -> true);
// Replace normal encoder to allow custom packets
final FallbackPacketEncoder newEncoder = new FallbackPacketEncoder(protocolVersion);
channel.pipeline().addFirst(FALLBACK_FRAME_ENCODER, FallbackVarIntLengthEncoder.INSTANCE);
channel.pipeline().addLast(FALLBACK_PACKET_ENCODER, newEncoder);
final SonarPacketEncoder newEncoder = new SonarPacketEncoder(protocolVersion);
channel.pipeline().addFirst(SONAR_FRAME_ENCODER, MinecraftVarIntLengthEncoder.INSTANCE);
channel.pipeline().addLast(SONAR_PACKET_ENCODER, newEncoder);
// Replace normal decoder to allow custom packets
final FallbackPacketDecoder newDecoder = new FallbackPacketDecoder(protocolVersion);
channel.pipeline().addFirst(FALLBACK_FRAME_DECODER, new FallbackVarInt21FrameDecoder());
channel.pipeline().addLast(FALLBACK_PACKET_DECODER, newDecoder);
final SonarPacketDecoder newDecoder = new SonarPacketDecoder(protocolVersion);
channel.pipeline().addFirst(SONAR_FRAME_DECODER, new MinecraftVarInt21FrameDecoder());
channel.pipeline().addLast(SONAR_PACKET_DECODER, newDecoder);
// We're sending the LoginSuccess packet now
newDecoder.updateRegistry(FallbackPacketRegistry.LOGIN);
newEncoder.updateRegistry(FallbackPacketRegistry.LOGIN);
newDecoder.updateRegistry(SonarPacketRegistry.LOGIN);
newEncoder.updateRegistry(SonarPacketRegistry.LOGIN);
// Send LoginSuccess packet to make the client think they are joining the server
write(FallbackPreparer.loginSuccess);
write(SonarPacketPreparer.loginSuccess);
// pre-1.20.2 clients do not have the configuration stage
if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_20_2)) {
newDecoder.updateRegistry(FallbackPacketRegistry.GAME);
newEncoder.updateRegistry(FallbackPacketRegistry.GAME);
newDecoder.updateRegistry(SonarPacketRegistry.GAME);
newEncoder.updateRegistry(SonarPacketRegistry.GAME);
}
// Listen for all incoming packets by setting the packet listener
newDecoder.setListener(new FallbackPreJoinHandler(this));
newDecoder.setListener(new LoginHandler(this));
// Make sure to catch all exceptions during the verification
channel.pipeline().addLast(FALLBACK_TAIL_EXCEPTIONS, FallbackTailExceptionsHandler.INSTANCE);
channel.pipeline().addLast(SONAR_TAIL_EXCEPTIONS, TailExceptionsHandler.INSTANCE);
});
}
@Override
public void disconnect(final @NotNull Component reason) {
final FallbackPacketEncoder encoder = channel.pipeline().get(FallbackPacketEncoder.class);
final boolean duringLogin = encoder != null && encoder.getPacketRegistry() == FallbackPacketRegistry.LOGIN;
final SonarPacketEncoder encoder = channel.pipeline().get(SonarPacketEncoder.class);
final boolean duringLogin = encoder != null && encoder.getPacketRegistry() == SonarPacketRegistry.LOGIN;
ProtocolUtil.closeWith(channel, protocolVersion, new DisconnectPacket(reason, duringLogin));
}
}
@@ -36,9 +36,9 @@ import xyz.jonesdev.sonar.api.notification.ActionBarNotificationHandler;
import xyz.jonesdev.sonar.api.notification.ChatNotificationHandler;
import xyz.jonesdev.sonar.api.statistics.SonarStatistics;
import xyz.jonesdev.sonar.api.timer.SystemTimer;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPreparer;
import xyz.jonesdev.sonar.common.fallback.ratelimit.CaffeineCacheRatelimiter;
import xyz.jonesdev.sonar.common.fallback.ratelimit.NoopCacheRatelimiter;
import xyz.jonesdev.sonar.common.protocol.SonarPacketPreparer;
import xyz.jonesdev.sonar.common.ratelimit.CaffeineCacheRatelimiter;
import xyz.jonesdev.sonar.common.ratelimit.NoopCacheRatelimiter;
import xyz.jonesdev.sonar.common.service.ScheduledServiceManager;
import xyz.jonesdev.sonar.common.statistics.GlobalSonarStatistics;
import xyz.jonesdev.sonar.common.subcommand.*;
@@ -137,26 +137,26 @@ public abstract class SonarBootstrap<T> implements Sonar {
// Prepare cached packets
getLogger().info("Taking cached snapshots of all packets...");
FallbackPreparer.prepare();
SonarPacketPreparer.prepare();
// Update ratelimiter cache
getFallback().setRatelimiter(getConfig().getVerification().getReconnectDelay() > 0L
getAntiBot().setRatelimiter(getConfig().getVerification().getReconnectDelay() > 0L
? new CaffeineCacheRatelimiter(Duration.ofMillis(getConfig().getVerification().getReconnectDelay()))
: NoopCacheRatelimiter.INSTANCE);
// Update blacklist cache
final long blacklistTime = getConfig().getVerification().getBlacklistTime();
final boolean blacklistExists = getFallback().getBlacklist() != null;
final boolean blacklistExists = getAntiBot().getBlacklist() != null;
// Make sure the blacklist is only set when we need it to prevent data loss
if (!blacklistExists // Make sure we create a new cache if it doesn't exist yet
|| getFallback().getBlacklistTime() != blacklistTime) {
|| getAntiBot().getBlacklistTime() != blacklistTime) {
// Create a new cache with the configured blacklist time
getFallback().setBlacklist(Caffeine.newBuilder()
getAntiBot().setBlacklist(Caffeine.newBuilder()
.expireAfterWrite(Duration.ofMillis(getConfig().getVerification().getBlacklistTime()))
.ticker(Ticker.systemTicker())
.build());
// Store the new blacklist time, so we don't have to reset the blacklist every reload
getFallback().setBlacklistTime(blacklistTime);
getAntiBot().setBlacklistTime(blacklistTime);
// Warn the user about changing the expiry of the blacklist values
if (blacklistExists) {
getLogger().warn("The blacklist has been reset as the duration of entries has changed.");
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.netty;
package xyz.jonesdev.sonar.common.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -29,7 +29,7 @@ import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
import java.util.List;
// https://github.com/PaperMC/Velocity/blob/dev/3.0.0/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftVarintFrameDecoder.java
public final class FallbackVarInt21FrameDecoder extends ByteToMessageDecoder {
public final class MinecraftVarInt21FrameDecoder extends ByteToMessageDecoder {
@Override
protected void decode(final @NotNull ChannelHandlerContext ctx,
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.netty;
package xyz.jonesdev.sonar.common.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
@@ -28,8 +28,8 @@ import java.util.List;
// https://github.com/PaperMC/Velocity/blob/dev/3.0.0/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftVarintLengthEncoder.java
@ChannelHandler.Sharable
public final class FallbackVarIntLengthEncoder extends MessageToMessageEncoder<ByteBuf> {
public static final FallbackVarIntLengthEncoder INSTANCE = new FallbackVarIntLengthEncoder();
public final class MinecraftVarIntLengthEncoder extends MessageToMessageEncoder<ByteBuf> {
public static final MinecraftVarIntLengthEncoder INSTANCE = new MinecraftVarIntLengthEncoder();
@Override
protected void encode(final @NotNull ChannelHandlerContext ctx,
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.netty;
package xyz.jonesdev.sonar.common.netty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
@@ -24,7 +24,7 @@ import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.SonarPlatform;
import xyz.jonesdev.sonar.common.fallback.FallbackInboundHandler;
import xyz.jonesdev.sonar.common.InboundHandler;
import xyz.jonesdev.sonar.common.util.FakeChannelUtil;
import xyz.jonesdev.sonar.common.util.exception.ReflectiveOperationException;
@@ -33,10 +33,10 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.function.Consumer;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.FALLBACK_INBOUND_HANDLER;
import static xyz.jonesdev.sonar.api.antibot.ChannelPipelines.SONAR_INBOUND_HANDLER;
@RequiredArgsConstructor
public final class FallbackInjectedChannelInitializer extends ChannelInitializer<Channel> {
public final class SonarInjectedChannelInitializer extends ChannelInitializer<Channel> {
private static final MethodHandle INIT_CHANNEL_METHOD;
static {
@@ -71,13 +71,13 @@ public final class FallbackInjectedChannelInitializer extends ChannelInitializer
// Inject Sonar's channel handler into the pipeline;
// Also make sure the player is not a fake player to avoid compatibility issues
if (channel.isActive() && !FakeChannelUtil.isFakeChannel(channel)) {
final FallbackInboundHandler inboundHandler = new FallbackInboundHandler(sonarPipelineInjector);
final InboundHandler inboundHandler = new InboundHandler(sonarPipelineInjector);
// We need to be careful on Bukkit, as the encoder can be different
if (Sonar.get0().getPlatform() == SonarPlatform.BUKKIT) {
final String encoder = Sonar.get0().getPlatform().getEncoder().apply(channel.pipeline());
channel.pipeline().addBefore(encoder, FALLBACK_INBOUND_HANDLER, inboundHandler);
channel.pipeline().addBefore(encoder, SONAR_INBOUND_HANDLER, inboundHandler);
} else {
channel.pipeline().addFirst(FALLBACK_INBOUND_HANDLER, inboundHandler);
channel.pipeline().addFirst(SONAR_INBOUND_HANDLER, inboundHandler);
}
}
}
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.netty;
package xyz.jonesdev.sonar.common.netty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateEvent;
@@ -24,8 +24,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.concurrent.TimeUnit;
public final class FallbackTimeoutHandler extends IdleStateHandler {
public FallbackTimeoutHandler(final int readTimeout, final int writeTimeout, final TimeUnit timeUnit) {
public final class SonarTimeoutHandler extends IdleStateHandler {
public SonarTimeoutHandler(final int readTimeout, final int writeTimeout, final TimeUnit timeUnit) {
super(false, readTimeout, writeTimeout, 0L, timeUnit);
}
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.netty;
package xyz.jonesdev.sonar.common.netty;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
@@ -23,8 +23,8 @@ import io.netty.channel.ChannelHandlerContext;
import org.jetbrains.annotations.NotNull;
@ChannelHandler.Sharable
public final class FallbackTailExceptionsHandler extends ChannelDuplexHandler {
public static final FallbackTailExceptionsHandler INSTANCE = new FallbackTailExceptionsHandler();
public final class TailExceptionsHandler extends ChannelDuplexHandler {
public static final TailExceptionsHandler INSTANCE = new TailExceptionsHandler();
// We can override the default exceptionCaught method since the server
// does not have any other pipelines that could handle this error.
@@ -15,14 +15,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import lombok.experimental.UtilityClass;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.event.impl.CaptchaGenerationEndEvent;
import xyz.jonesdev.sonar.api.timer.SystemTimer;
import xyz.jonesdev.sonar.common.fallback.protocol.map.MapCaptchaInfo;
import xyz.jonesdev.sonar.common.fallback.protocol.map.MapColorPalette;
import xyz.jonesdev.sonar.common.protocol.map.MapCaptchaInfo;
import xyz.jonesdev.sonar.common.protocol.map.MapColorPalette;
import java.awt.image.BufferedImage;
import java.util.Random;
@@ -62,7 +62,7 @@ public class CaptchaPreparer {
for (int j = 0; j < answer.length; j++) {
answer[j] = alphabet[RANDOM.nextInt(alphabet.length)];
}
final BufferedImage image = Sonar.get0().getFallback().getCaptchaGenerator().createImage(answer);
final BufferedImage image = Sonar.get0().getAntiBot().getCaptchaGenerator().createImage(answer);
// Convert and cache converted Minecraft map bytes
cached[preparedAmount++] = new MapCaptchaInfo(new String(answer), MapColorPalette.imageToBuffer(image));
}
@@ -15,12 +15,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import io.netty.buffer.ByteBuf;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
public interface FallbackPacket {
public interface SonarPacket {
/**
* Encodes the packet sent by the server
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -24,22 +24,22 @@ import io.netty.handler.codec.DecoderException;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
import static xyz.jonesdev.sonar.common.fallback.protocol.FallbackPreparer.maxTotalPacketsSent;
import static xyz.jonesdev.sonar.common.protocol.SonarPacketPreparer.maxTotalPacketsSent;
@RequiredArgsConstructor
public final class FallbackPacketDecoder extends ChannelInboundHandlerAdapter {
public final class SonarPacketDecoder extends ChannelInboundHandlerAdapter {
private final ProtocolVersion protocolVersion;
private FallbackPacketRegistry.ProtocolRegistry registry;
private SonarPacketRegistry.ProtocolRegistry registry;
@Setter
private FallbackPacketListener listener;
private SonarPacketListener listener;
private int totalPacketsSent;
public void updateRegistry(final @NotNull FallbackPacketRegistry registry) {
this.registry = registry.getProtocolRegistry(FallbackPacketRegistry.Direction.SERVERBOUND, protocolVersion);
public void updateRegistry(final @NotNull SonarPacketRegistry registry) {
this.registry = registry.getProtocolRegistry(SonarPacketRegistry.Direction.SERVERBOUND, protocolVersion);
}
@Override
@@ -62,7 +62,7 @@ public final class FallbackPacketDecoder extends ChannelInboundHandlerAdapter {
// Read the packet ID and then create the packet from it
final int packetId = ProtocolUtil.readVarInt(byteBuf);
final FallbackPacket packet = registry.createPacket(packetId);
final SonarPacket packet = registry.createPacket(packetId);
// Skip the packet if it's not registered within Sonar's packet registry
if (packet == null) {
@@ -98,7 +98,7 @@ public final class FallbackPacketDecoder extends ChannelInboundHandlerAdapter {
}
}
private void checkPacketSize(final int packetSize, final @NotNull FallbackPacket packet) throws Exception {
private void checkPacketSize(final int packetSize, final @NotNull SonarPacket packet) throws Exception {
final int expectedMaxLen = packet.expectedMaxLength(protocolVersion);
if (expectedMaxLen != -1 && packetSize > expectedMaxLen) {
throw ProtocolUtil.DEBUG ? new DecoderException("Packet too large: " + packetSize + " max: " + expectedMaxLen)
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -23,27 +23,27 @@ import io.netty.handler.codec.MessageToByteEncoder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@RequiredArgsConstructor
public final class FallbackPacketEncoder extends MessageToByteEncoder<FallbackPacket> {
public final class SonarPacketEncoder extends MessageToByteEncoder<SonarPacket> {
private final ProtocolVersion protocolVersion;
@Getter
private FallbackPacketRegistry packetRegistry;
private FallbackPacketRegistry.ProtocolRegistry protocolRegistry;
private SonarPacketRegistry packetRegistry;
private SonarPacketRegistry.ProtocolRegistry protocolRegistry;
public void updateRegistry(final @NotNull FallbackPacketRegistry packetRegistry) {
public void updateRegistry(final @NotNull SonarPacketRegistry packetRegistry) {
this.packetRegistry = packetRegistry;
this.protocolRegistry = packetRegistry.getProtocolRegistry(FallbackPacketRegistry.Direction.CLIENTBOUND, protocolVersion);
this.protocolRegistry = packetRegistry.getProtocolRegistry(SonarPacketRegistry.Direction.CLIENTBOUND, protocolVersion);
}
@Override
protected void encode(final ChannelHandlerContext ctx,
final @NotNull FallbackPacket packet,
final @NotNull SonarPacket packet,
final @NotNull ByteBuf out) throws Exception {
final Class<? extends FallbackPacket> originalPacket = packet instanceof FallbackPacketSnapshot
? ((FallbackPacketSnapshot) packet).getOriginalPacketClass() : packet.getClass();
final Class<? extends SonarPacket> originalPacket = packet instanceof SonarPacketSnapshot
? ((SonarPacketSnapshot) packet).getOriginalPacketClass() : packet.getClass();
final int packetId = protocolRegistry.getPacketId(originalPacket);
ProtocolUtil.writeVarInt(out, packetId);
packet.encode(out, protocolVersion);
@@ -15,17 +15,17 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface FallbackPacketListener {
public interface SonarPacketListener {
/**
* Handles the incoming packet
*
* @param packet Packet to handle
*/
void handle(final @NotNull FallbackPacket packet);
void handle(final @NotNull SonarPacket packet);
}
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import lombok.experimental.UtilityClass;
import net.kyori.adventure.nbt.CompoundBinaryTag;
@@ -24,20 +24,21 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.config.SonarConfiguration;
import xyz.jonesdev.sonar.api.event.impl.CaptchaGenerationStartEvent;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.captcha.StandardCaptchaGenerator;
import xyz.jonesdev.sonar.captcha.complex.ComplexCaptchaGenerator;
import xyz.jonesdev.sonar.captcha.legacy.LegacyCaptchaGenerator;
import xyz.jonesdev.sonar.common.fallback.protocol.block.BlockType;
import xyz.jonesdev.sonar.common.fallback.protocol.block.BlockUpdate;
import xyz.jonesdev.sonar.common.fallback.protocol.dimension.DimensionRegistry;
import xyz.jonesdev.sonar.common.fallback.protocol.dimension.DimensionType;
import xyz.jonesdev.sonar.common.fallback.protocol.entity.EntityType;
import xyz.jonesdev.sonar.common.fallback.protocol.item.ItemType;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.configuration.RegistryDataPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.login.LoginSuccessPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.play.*;
import xyz.jonesdev.sonar.common.protocol.block.BlockType;
import xyz.jonesdev.sonar.common.protocol.block.BlockUpdate;
import xyz.jonesdev.sonar.common.protocol.dimension.DimensionRegistry;
import xyz.jonesdev.sonar.common.protocol.dimension.DimensionType;
import xyz.jonesdev.sonar.common.protocol.entity.EntityType;
import xyz.jonesdev.sonar.common.protocol.item.ItemType;
import xyz.jonesdev.sonar.common.protocol.packets.configuration.RegistryDataPacket;
import xyz.jonesdev.sonar.common.protocol.packets.login.LoginSuccessPacket;
import xyz.jonesdev.sonar.common.protocol.packets.play.*;
import xyz.jonesdev.sonar.common.util.ComponentHolder;
import java.io.File;
@@ -45,14 +46,14 @@ import java.util.Random;
import java.util.UUID;
@UtilityClass
public class FallbackPreparer {
public class SonarPacketPreparer {
private final Random RANDOM = new Random();
public static final int PLAYER_ENTITY_ID = RANDOM.nextInt();
public static final int VEHICLE_ENTITY_ID = RANDOM.nextInt();
public static final BlockType[] POSSIBLE_BLOCK_TYPES = BlockType.values();
public final FallbackPacket[] BLOCKS_PACKETS = new FallbackPacket[POSSIBLE_BLOCK_TYPES.length];
public final SonarPacket[] BLOCKS_PACKETS = new SonarPacket[POSSIBLE_BLOCK_TYPES.length];
public final int BLOCKS_PER_ROW = 8; // 8 * 8 = 64 (vanilla protocol maximum)
public final int SPAWN_X_POSITION = 16 / 2; // middle of the chunk
@@ -66,68 +67,69 @@ public class FallbackPreparer {
private final int MAP_SLOT = RANDOM.nextInt(9);
public static final FallbackPacket CAPTCHA_SET_CONTAINER_SLOT = new SetContainerSlotPacket(
public static final SonarPacket CAPTCHA_SET_CONTAINER_SLOT = new SetContainerSlotPacket(
0, 36 + MAP_SLOT, 1, ItemType.FILLED_MAP, CompoundBinaryTag.builder()
.put("map", IntBinaryTag.intBinaryTag(0)) // map id
.build());
public final static FallbackPacket CAPTCHA_HELD_ITEM_SLOT = new SetHeldItemPacket(MAP_SLOT);
public final FallbackPacket DEFAULT_ABILITIES = new PlayerAbilitiesPacket(0x00, 0, 0);
public final FallbackPacket NO_MOVE_ABILITIES = new PlayerAbilitiesPacket(0x02, 0, 0);
public final FallbackPacket NO_MOVE_ABILITIES_BEDROCK = new PlayerAbilitiesPacket(0x06, 0, 0);
public final FallbackPacket CAPTCHA_POSITION = new FallbackPacketSnapshot(new SetPlayerPositionRotationPacket(
public final static SonarPacket CAPTCHA_HELD_ITEM_SLOT = new SetHeldItemPacket(MAP_SLOT);
public final SonarPacket DEFAULT_ABILITIES = new PlayerAbilitiesPacket(0x00, 0, 0);
public final SonarPacket NO_MOVE_ABILITIES = new PlayerAbilitiesPacket(0x02, 0, 0);
public final SonarPacket NO_MOVE_ABILITIES_BEDROCK = new PlayerAbilitiesPacket(0x06, 0, 0);
public final SonarPacket CAPTCHA_POSITION = new SonarPacketSnapshot(new SetPlayerPositionRotationPacket(
SPAWN_X_POSITION, 10000, SPAWN_Z_POSITION, 0, 90, 0, 0, false, false, true));
// I think the people working at Microsoft are actually the *real* ultimate trolls of the internet!
public final FallbackPacket[] EMPTY_CHUNK_DATA = new FallbackPacket[]{
new FallbackPacketSnapshot(new ChunkDataPacket(0, 0)),
new FallbackPacketSnapshot(new ChunkDataPacket(0, 1)),
new FallbackPacketSnapshot(new ChunkDataPacket(0, -1)),
new FallbackPacketSnapshot(new ChunkDataPacket(1, 0)),
new FallbackPacketSnapshot(new ChunkDataPacket(1, 1)),
new FallbackPacketSnapshot(new ChunkDataPacket(1, -1)),
new FallbackPacketSnapshot(new ChunkDataPacket(-1, 0)),
new FallbackPacketSnapshot(new ChunkDataPacket(-1, 1)),
new FallbackPacketSnapshot(new ChunkDataPacket(-1, -1))
public final SonarPacket[] EMPTY_CHUNK_DATA = new SonarPacket[]{
new SonarPacketSnapshot(new ChunkDataPacket(0, 0)),
new SonarPacketSnapshot(new ChunkDataPacket(0, 1)),
new SonarPacketSnapshot(new ChunkDataPacket(0, -1)),
new SonarPacketSnapshot(new ChunkDataPacket(1, 0)),
new SonarPacketSnapshot(new ChunkDataPacket(1, 1)),
new SonarPacketSnapshot(new ChunkDataPacket(1, -1)),
new SonarPacketSnapshot(new ChunkDataPacket(-1, 0)),
new SonarPacketSnapshot(new ChunkDataPacket(-1, 1)),
new SonarPacketSnapshot(new ChunkDataPacket(-1, -1))
};
public final FallbackPacket PRE_JOIN_KEEP_ALIVE = new FallbackPacketSnapshot(new KeepAlivePacket(PRE_JOIN_KEEP_ALIVE_ID));
public final FallbackPacket[] REGISTRY_SYNC_1_20 = new FallbackPacket[] {
new FallbackPacketSnapshot(new RegistryDataPacket(DimensionRegistry.CODEC_1_20, null, null))};
public final FallbackPacket[] REGISTRY_SYNC_1_20_5 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_20_5);
public final FallbackPacket[] REGISTRY_SYNC_1_21 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21);
public final FallbackPacket[] REGISTRY_SYNC_1_21_2 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21_2);
public final FallbackPacket[] REGISTRY_SYNC_1_21_4 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21_4);
public final FallbackPacket[] REGISTRY_SYNC_1_21_5 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21_5);
public final FallbackPacket START_WRITING_CHUNKS = new GameEventPacket(13, 0);
public final static FallbackPacket INVALID_HELD_ITEM_SLOT = new SetHeldItemPacket(-1);
public final FallbackPacket RANDOM_KEEP_ALIVE = new FallbackPacketSnapshot(new KeepAlivePacket(RANDOM.nextInt()));
public static final FallbackPacket SPAWN_BOAT_ENTITY = new FallbackPacketSnapshot(new SpawnEntityPacket(
public final SonarPacket PRE_JOIN_KEEP_ALIVE = new SonarPacketSnapshot(new KeepAlivePacket(PRE_JOIN_KEEP_ALIVE_ID));
public final SonarPacket[] REGISTRY_SYNC_1_20 = new SonarPacket[] {
new SonarPacketSnapshot(new RegistryDataPacket(DimensionRegistry.CODEC_1_20, null, null))};
public final SonarPacket[] REGISTRY_SYNC_1_20_5 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_20_5);
public final SonarPacket[] REGISTRY_SYNC_1_21 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21);
public final SonarPacket[] REGISTRY_SYNC_1_21_2 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21_2);
public final SonarPacket[] REGISTRY_SYNC_1_21_4 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21_4);
public final SonarPacket[] REGISTRY_SYNC_1_21_5 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21_5);
public final SonarPacket[] REGISTRY_SYNC_1_21_11 = RegistryDataPacket.of(DimensionRegistry.CODEC_1_21_11);
public final SonarPacket START_WRITING_CHUNKS = new GameEventPacket(13, 0);
public final static SonarPacket INVALID_HELD_ITEM_SLOT = new SetHeldItemPacket(-1);
public final SonarPacket RANDOM_KEEP_ALIVE = new SonarPacketSnapshot(new KeepAlivePacket(RANDOM.nextInt()));
public static final SonarPacket SPAWN_BOAT_ENTITY = new SonarPacketSnapshot(new SpawnEntityPacket(
VEHICLE_ENTITY_ID, EntityType.BOAT, SPAWN_X_POSITION, IN_AIR_Y_POSITION, SPAWN_Z_POSITION,
0, 0, 0, 0));
public static final FallbackPacket SPAWN_MINECART_ENTITY = new FallbackPacketSnapshot(new SpawnEntityPacket(
public static final SonarPacket SPAWN_MINECART_ENTITY = new SonarPacketSnapshot(new SpawnEntityPacket(
VEHICLE_ENTITY_ID, EntityType.MINECART, SPAWN_X_POSITION, IN_AIR_Y_POSITION - 16, SPAWN_Z_POSITION,
0, 0, 0, 0));
public static final FallbackPacket REMOVE_VEHICLE = new RemoveEntitiesPacket(VEHICLE_ENTITY_ID);
public static final FallbackPacket SET_VEHICLE_PASSENGERS = new FallbackPacketSnapshot(
public static final SonarPacket REMOVE_VEHICLE = new RemoveEntitiesPacket(VEHICLE_ENTITY_ID);
public static final SonarPacket SET_VEHICLE_PASSENGERS = new SonarPacketSnapshot(
new SetPassengersPacket(VEHICLE_ENTITY_ID, PLAYER_ENTITY_ID));
public FallbackPacket[] incorrectCaptcha;
public SonarPacket[] incorrectCaptcha;
public FallbackPacket loginSuccess;
public FallbackPacket welcomeMessage;
public FallbackPacket enterCodeMessage;
public static FallbackPacket joinGame;
public FallbackPacket defaultSpawnPosition;
public FallbackPacket spawnPosition;
public FallbackPacket fallStartPosition;
public FallbackPacket fallStartPositionLegacy;
public static FallbackPacket transferToOrigin;
public FallbackPacket blacklisted;
public FallbackPacket alreadyQueued;
public FallbackPacket alreadyVerifying;
public FallbackPacket reconnectedTooFast;
public FallbackPacket protocolBlacklisted;
public FallbackPacket unsupportedVersion;
public FallbackPacket tooManyOnlinePerIP;
public FallbackPacket[] xpCountdown;
public FallbackPacket updateTime;
public SonarPacket loginSuccess;
public SonarPacket welcomeMessage;
public SonarPacket enterCodeMessage;
public static SonarPacket joinGame;
public SonarPacket defaultSpawnPosition;
public SonarPacket spawnPosition;
public SonarPacket fallStartPosition;
public SonarPacket fallStartPositionLegacy;
public static SonarPacket transferToOrigin;
public SonarPacket blacklisted;
public SonarPacket alreadyQueued;
public SonarPacket alreadyVerifying;
public SonarPacket reconnectedTooFast;
public SonarPacket protocolBlacklisted;
public SonarPacket unsupportedVersion;
public SonarPacket tooManyOnlinePerIP;
public SonarPacket[] xpCountdown;
public SonarPacket updateTime;
public static int maxMovementTick, dynamicSpawnYPosition, maxTotalPacketsSent;
@@ -135,7 +137,7 @@ public class FallbackPreparer {
// Preload the packet registry to avoid CPU/RAM issues on 1st connection
Sonar.get0().getLogger().info("Preloading all registered packets...");
//noinspection ResultOfMethodCallIgnored
FallbackPacketRegistry.values();
SonarPacketRegistry.values();
// Prepare LoginSuccess packet with capped username to 16 characters
final UUID uuid = UUID.randomUUID();
@@ -143,10 +145,10 @@ public class FallbackPreparer {
if (username.length() > 16) {
username = username.substring(0, 16);
}
loginSuccess = new FallbackPacketSnapshot(new LoginSuccessPacket(uuid, username, true));
loginSuccess = new SonarPacketSnapshot(new LoginSuccessPacket(uuid, username, true));
// Prepare JoinGame packet
joinGame = new FallbackPacketSnapshot(new JoinGamePacket(PLAYER_ENTITY_ID,
joinGame = new SonarPacketSnapshot(new JoinGamePacket(PLAYER_ENTITY_ID,
Sonar.get0().getConfig().getVerification().getGamemode().getId(),
-1, 0, 0,
RANDOM.nextInt(3), 1, 0, 0,
@@ -167,16 +169,16 @@ public class FallbackPreparer {
// Set the dynamic block and collide Y position based on the maximum fall distance
dynamicSpawnYPosition = PLATFORM_Y_POSITION + (int) Math.ceil(fallDistance);
defaultSpawnPosition = new FallbackPacketSnapshot(new SetDefaultSpawnPositionPacket(
defaultSpawnPosition = new SonarPacketSnapshot(new SetDefaultSpawnPositionPacket(
"minecraft:overworld",
SPAWN_X_POSITION, IN_AIR_Y_POSITION, SPAWN_Z_POSITION));
spawnPosition = new FallbackPacketSnapshot(new SetPlayerPositionRotationPacket(
spawnPosition = new SonarPacketSnapshot(new SetPlayerPositionRotationPacket(
SPAWN_X_POSITION, IN_AIR_Y_POSITION, SPAWN_Z_POSITION,
0, 0, FIRST_TELEPORT_ID, 0, false, false, true));
fallStartPosition = new FallbackPacketSnapshot(new SetPlayerPositionRotationPacket(
fallStartPosition = new SonarPacketSnapshot(new SetPlayerPositionRotationPacket(
SPAWN_X_POSITION, dynamicSpawnYPosition - IN_AIR_Y_POSITION, SPAWN_Z_POSITION,
0, -90, SECOND_TELEPORT_ID, 1 << 1, false, false, true));
fallStartPositionLegacy = new FallbackPacketSnapshot(new SetPlayerPositionRotationPacket(
fallStartPositionLegacy = new SonarPacketSnapshot(new SetPlayerPositionRotationPacket(
SPAWN_X_POSITION, dynamicSpawnYPosition, SPAWN_Z_POSITION,
0, -90, 0, 0, false, false, true));
@@ -193,21 +195,21 @@ public class FallbackPreparer {
blocks[index++] = new BlockUpdate(position, POSSIBLE_BLOCK_TYPES[i]);
}
}
BLOCKS_PACKETS[i] = new FallbackPacketSnapshot(new UpdateSectionBlocksPacket(0, 0, blocks));
BLOCKS_PACKETS[i] = new SonarPacketSnapshot(new UpdateSectionBlocksPacket(0, 0, blocks));
}
// Prepare disconnect packets during login
blacklisted = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getBlacklisted(), true));
alreadyVerifying = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getAlreadyVerifying(), true));
alreadyQueued = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getAlreadyQueued(), true));
protocolBlacklisted = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getProtocolBlacklisted(), true));
reconnectedTooFast = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getTooFastReconnect(), true));
unsupportedVersion = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getUnsupportedVersion(), true));
tooManyOnlinePerIP = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getTooManyOnlinePerIp(), true));
blacklisted = new SonarPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getBlacklisted(), true));
alreadyVerifying = new SonarPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getAlreadyVerifying(), true));
alreadyQueued = new SonarPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getAlreadyQueued(), true));
protocolBlacklisted = new SonarPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getProtocolBlacklisted(), true));
reconnectedTooFast = new SonarPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getTooFastReconnect(), true));
unsupportedVersion = new SonarPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getVerification().getUnsupportedVersion(), true));
tooManyOnlinePerIP = new SonarPacketSnapshot(new DisconnectPacket(Sonar.get0().getConfig().getTooManyOnlinePerIp(), true));
// Prepare transfer packet
if (Sonar.get0().getConfig().getGeneralConfig().getBoolean("verification.transfer.enabled")) {
transferToOrigin = new FallbackPacketSnapshot(new TransferPacket(
transferToOrigin = new SonarPacketSnapshot(new TransferPacket(
Sonar.get0().getConfig().getGeneralConfig().getString("verification.transfer.destination-host"),
Sonar.get0().getConfig().getGeneralConfig().getInt("verification.transfer.destination-port")));
} else {
@@ -227,59 +229,63 @@ public class FallbackPreparer {
if (welcome.isEmpty()) {
welcomeMessage = null;
} else {
welcomeMessage = new FallbackPacketSnapshot(new SystemChatPacket(new ComponentHolder(
welcomeMessage = new SonarPacketSnapshot(new SystemChatPacket(new ComponentHolder(
MiniMessage.miniMessage().deserialize(welcome,
Placeholder.component("prefix", Sonar.get0().getConfig().getPrefix())))));
}
if (Sonar.get0().getConfig().getVerification().getMap().getTiming() != SonarConfiguration.Verification.Timing.NEVER
|| Sonar.get0().getConfig().getVerification().getGravity().isCaptchaOnFail()) {
// Prepare CAPTCHA messages
enterCodeMessage = new FallbackPacketSnapshot(new SystemChatPacket(new ComponentHolder(
enterCodeMessage = new SonarPacketSnapshot(new SystemChatPacket(new ComponentHolder(
MiniMessage.miniMessage().deserialize(
Sonar.get0().getConfig().getMessagesConfig().getString("verification.captcha.enter"),
Placeholder.component("prefix", Sonar.get0().getConfig().getPrefix())))));
incorrectCaptcha = new FallbackPacket[Sonar.get0().getConfig().getVerification().getMap().getMaxTries()];
incorrectCaptcha = new SonarPacket[Sonar.get0().getConfig().getVerification().getMap().getMaxTries()];
for (int i = 0; i < incorrectCaptcha.length; i++) {
incorrectCaptcha[i] = new FallbackPacketSnapshot(new SystemChatPacket(new ComponentHolder(
incorrectCaptcha[i] = new SonarPacketSnapshot(new SystemChatPacket(new ComponentHolder(
MiniMessage.miniMessage().deserialize(
Sonar.get0().getConfig().getMessagesConfig().getString("verification.captcha.incorrect"),
Placeholder.component("prefix", Sonar.get0().getConfig().getPrefix()),
Placeholder.unparsed("attempts-left", String.valueOf(i + 1))))));
}
// Prepare countdown
xpCountdown = new FallbackPacket[Sonar.get0().getConfig().getVerification().getMap().getMaxDuration() / 1000];
xpCountdown = new SonarPacket[Sonar.get0().getConfig().getVerification().getMap().getMaxDuration() / 1000];
for (int i = 0; i < xpCountdown.length; i++) {
final float bar = (float) i / xpCountdown.length;
xpCountdown[i] = new FallbackPacketSnapshot(new SetExperiencePacket(bar, i, 0));
xpCountdown[i] = new SonarPacketSnapshot(new SetExperiencePacket(bar, i, 0));
}
// Update the CAPTCHA generator if necessary
final CaptchaGenerationStartEvent generationStartEvent = new CaptchaGenerationStartEvent(
Sonar.get0().getFallback().getCaptchaGenerator());
Sonar.get0().getAntiBot().getCaptchaGenerator());
Sonar.get0().getEventManager().publish(generationStartEvent);
if (generationStartEvent.getCaptchaGenerator() == null
|| generationStartEvent.getCaptchaGenerator() instanceof StandardCaptchaGenerator
|| generationStartEvent.getCaptchaGenerator() instanceof LegacyCaptchaGenerator) {
|| generationStartEvent.getCaptchaGenerator() instanceof LegacyCaptchaGenerator
|| generationStartEvent.getCaptchaGenerator() instanceof ComplexCaptchaGenerator) {
final File backgroundImage = Sonar.get0().getConfig().getVerification().getMap().getBackgroundImage();
final boolean useLegacyCaptchaGenerator = Sonar.get0().getConfig().getGeneralConfig()
.getString("verification.checks.map-captcha.style").equalsIgnoreCase("legacy");
Sonar.get0().getFallback().setCaptchaGenerator(useLegacyCaptchaGenerator
? new LegacyCaptchaGenerator(backgroundImage) : new StandardCaptchaGenerator(backgroundImage));
switch (Sonar.get0().getConfig().getGeneralConfig()
.getString("verification.checks.map-captcha.style").toLowerCase()) {
case "legacy":
Sonar.get0().getAntiBot().setCaptchaGenerator(new LegacyCaptchaGenerator(backgroundImage));
break;
case "complex":
Sonar.get0().getAntiBot().setCaptchaGenerator(new ComplexCaptchaGenerator(backgroundImage));
break;
default:
Sonar.get0().getAntiBot().setCaptchaGenerator(new StandardCaptchaGenerator(backgroundImage));
break;
}
} else {
Sonar.get0().getLogger().info("Custom CAPTCHA generator detected, skipping reinitialization.");
}
// Prepare CAPTCHA answers
CaptchaPreparer.prepare();
} else {
// Throw away if not needed
enterCodeMessage = null;
incorrectCaptcha = null;
xpCountdown = null;
Sonar.get0().getFallback().setCaptchaGenerator(null);
Sonar.get0().getAntiBot().setCaptchaGenerator(null);
}
maxTotalPacketsSent = maxMovementTick + 2
@@ -289,8 +295,10 @@ public class FallbackPreparer {
+ Sonar.get0().getConfig().getVerification().getMaxPacketCount();
}
public static FallbackPacket[] getRegistryPackets(final @NotNull ProtocolVersion protocolVersion) {
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_21_5)) {
public static SonarPacket[] getRegistryPackets(final @NotNull ProtocolVersion protocolVersion) {
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_21_11)) {
return REGISTRY_SYNC_1_21_11;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_21_5)) {
return REGISTRY_SYNC_1_21_5;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_21_4)) {
return REGISTRY_SYNC_1_21_4;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap;
@@ -23,14 +23,14 @@ import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.configuration.FinishConfigurationPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.configuration.RegistryDataPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.handshake.HandshakePacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.login.LoginAcknowledgedPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.login.LoginStartPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.login.LoginSuccessPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.play.*;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.packets.configuration.FinishConfigurationPacket;
import xyz.jonesdev.sonar.common.protocol.packets.configuration.RegistryDataPacket;
import xyz.jonesdev.sonar.common.protocol.packets.handshake.HandshakePacket;
import xyz.jonesdev.sonar.common.protocol.packets.login.LoginAcknowledgedPacket;
import xyz.jonesdev.sonar.common.protocol.packets.login.LoginStartPacket;
import xyz.jonesdev.sonar.common.protocol.packets.login.LoginSuccessPacket;
import xyz.jonesdev.sonar.common.protocol.packets.play.*;
import java.util.EnumMap;
import java.util.EnumSet;
@@ -38,10 +38,10 @@ import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
import static xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion.*;
import static xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion.*;
// https://github.com/PaperMC/Velocity/blob/dev/3.0.0/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
public enum FallbackPacketRegistry {
public enum SonarPacketRegistry {
HANDSHAKE {
{
serverbound.register(HandshakePacket.class, HandshakePacket::new,
@@ -712,8 +712,8 @@ public enum FallbackPacketRegistry {
CLIENTBOUND
}
public FallbackPacketRegistry.ProtocolRegistry getProtocolRegistry(final Direction direction,
final ProtocolVersion version) {
public SonarPacketRegistry.ProtocolRegistry getProtocolRegistry(final Direction direction,
final ProtocolVersion version) {
return (direction == Direction.SERVERBOUND ? serverbound : clientbound).getProtocolRegistry(version);
}
@@ -736,9 +736,9 @@ public enum FallbackPacketRegistry {
return registry;
}
private <T extends FallbackPacket> void register(final @NotNull Class<T> clazz,
final @NotNull Supplier<T> supplier,
final PacketMapping @NotNull ... mappings) {
private <T extends SonarPacket> void register(final @NotNull Class<T> clazz,
final @NotNull Supplier<T> supplier,
final PacketMapping @NotNull ... mappings) {
if (mappings.length == 0) {
throw new IllegalArgumentException("At least one mapping must be provided.");
}
@@ -783,17 +783,17 @@ public enum FallbackPacketRegistry {
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public static class ProtocolRegistry {
private final ProtocolVersion protocolVersion;
private final IntObjectMap<Supplier<? extends FallbackPacket>> packetIdToSupplier =
private final IntObjectMap<Supplier<? extends SonarPacket>> packetIdToSupplier =
new IntObjectHashMap<>(16, 0.5f);
private final Map<Class<? extends FallbackPacket>, Integer> packetClassToId =
private final Map<Class<? extends SonarPacket>, Integer> packetClassToId =
new HashMap<>(16, 0.5f);
public FallbackPacket createPacket(final int packetId) {
public SonarPacket createPacket(final int packetId) {
final var supplier = packetIdToSupplier.get(packetId);
return supplier == null ? null : supplier.get();
}
public int getPacketId(final @NotNull Class<? extends FallbackPacket> clazz) {
public int getPacketId(final @NotNull Class<? extends SonarPacket> clazz) {
final int packetId = packetClassToId.getOrDefault(clazz, -1);
if (packetId == -1) {
throw new IllegalArgumentException("Could not find packet ID for " + clazz.getSimpleName());
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol;
package xyz.jonesdev.sonar.common.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -25,20 +25,20 @@ import io.netty.util.collection.IntObjectMap;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
import static xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion.ID_TO_PROTOCOL_CONSTANT;
import static xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion.ID_TO_PROTOCOL_CONSTANT;
// https://github.com/Nan1t/NanoLimbo/blob/main/src/main/java/ua/nanit/limbo/protocol/PacketSnapshot.java
public final class FallbackPacketSnapshot implements FallbackPacket {
public final class SonarPacketSnapshot implements SonarPacket {
private final IntObjectMap<Integer> mappings = new IntObjectHashMap<>(ID_TO_PROTOCOL_CONSTANT.size());
private final IntObjectMap<byte[]> cachedBytes = new IntObjectHashMap<>(ID_TO_PROTOCOL_CONSTANT.size());
@Getter
private final Class<? extends FallbackPacket> originalPacketClass;
private final Class<? extends SonarPacket> originalPacketClass;
public FallbackPacketSnapshot(final @NotNull FallbackPacket originalPacket) {
public SonarPacketSnapshot(final @NotNull SonarPacket originalPacket) {
this.originalPacketClass = originalPacket.getClass();
final IntObjectMap<Integer> hashedData = new IntObjectHashMap<>(ID_TO_PROTOCOL_CONSTANT.size());
@@ -15,15 +15,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.block;
package xyz.jonesdev.sonar.common.protocol.block;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import java.util.function.Function;
import static xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion.*;
import static xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion.*;
// TODO: load mappings from a separate file
@Getter
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.block;
package xyz.jonesdev.sonar.common.protocol.block;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.dimension;
package xyz.jonesdev.sonar.common.protocol.dimension;
import lombok.experimental.UtilityClass;
import net.kyori.adventure.nbt.BinaryTagIO;
@@ -40,6 +40,7 @@ public final class DimensionRegistry {
public final CompoundBinaryTag CODEC_1_21_2;
public final CompoundBinaryTag CODEC_1_21_4;
public final CompoundBinaryTag CODEC_1_21_5;
public final CompoundBinaryTag CODEC_1_21_11;
static {
CODEC_1_16 = getCodec("codec_1_16.nbt");
@@ -54,6 +55,7 @@ public final class DimensionRegistry {
CODEC_1_21_2 = getCodec("codec_1_21_2.nbt");
CODEC_1_21_4 = getCodec("codec_1_21_4.nbt");
CODEC_1_21_5 = getCodec("codec_1_21_5.nbt");
CODEC_1_21_11 = getCodec("codec_1_21_11.nbt");
}
private @NotNull CompoundBinaryTag getCodec(final @NotNull String fileName) {
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.dimension;
package xyz.jonesdev.sonar.common.protocol.dimension;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -15,15 +15,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.entity;
package xyz.jonesdev.sonar.common.protocol.entity;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import java.util.function.Function;
import static xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion.*;
import static xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion.*;
// TODO: load mappings from a separate file
@Getter
@@ -64,7 +64,10 @@ public enum EntityType {
if (protocolVersion.lessThanOrEquals(MINECRAFT_1_21_7)) {
return 85;
}
return 87;
if (protocolVersion.lessThanOrEquals(MINECRAFT_1_21_9)) {
return 87;
}
return 89;
}),
MINECART(protocolVersion -> {
if (protocolVersion.lessThanOrEquals(MINECRAFT_1_13_2)) {
@@ -106,7 +109,10 @@ public enum EntityType {
if (protocolVersion.lessThanOrEquals(MINECRAFT_1_21_7)) {
return 82;
}
return 84;
if (protocolVersion.lessThanOrEquals(MINECRAFT_1_21_9)) {
return 84;
}
return 85;
});
private final Function<ProtocolVersion, Integer> id;
@@ -15,15 +15,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.item;
package xyz.jonesdev.sonar.common.protocol.item;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import java.util.function.Function;
import static xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion.*;
import static xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion.*;
// TODO: load mappings from a separate file
@Getter
@@ -90,7 +90,10 @@ public enum ItemType {
if (protocolVersion.lessThanOrEquals(MINECRAFT_1_21_4)) {
return 36;
}
return 37;
if (protocolVersion.lessThanOrEquals(MINECRAFT_1_21_9)) {
return 37;
}
return 44;
});
private final Function<ProtocolVersion, Integer> id;
@@ -15,21 +15,21 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.map;
package xyz.jonesdev.sonar.common.protocol.map;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.FallbackUser;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.play.MapDataPacket;
import xyz.jonesdev.sonar.api.antibot.SonarUser;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.packets.play.MapDataPacket;
@Getter
public final class MapCaptchaInfo {
private final String answer;
private final FallbackPacket[] legacy;
private final FallbackPacket modern;
private final SonarPacket[] legacy;
private final SonarPacket modern;
public MapCaptchaInfo(final @NotNull String answer, final byte @NotNull [] buffer) {
this.answer = answer;
@@ -39,7 +39,7 @@ public final class MapCaptchaInfo {
for (int i = 0; i < buffer.length; i++) {
grid[i & Byte.MAX_VALUE][i >> 7] = buffer[i];
}
this.legacy = new FallbackPacket[grid.length];
this.legacy = new SonarPacket[grid.length];
for (int i = 0; i < grid.length; i++) {
this.legacy[i] = new MapDataPacket(grid[i], i, 0, 0, true);
}
@@ -48,10 +48,10 @@ public final class MapCaptchaInfo {
this.modern = new MapDataPacket(buffer, 0, 0, 0, true);
}
public void delayedWrite(final @NotNull FallbackUser user) {
public void delayedWrite(final @NotNull SonarUser user) {
if (user.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_8)) {
// 1.7.2-1.7.10 needs separate packets for each axis
for (final FallbackPacket packet : legacy) {
for (final SonarPacket packet : legacy) {
user.delayedWrite(packet);
}
return;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.map;
package xyz.jonesdev.sonar.common.protocol.map;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
@@ -15,16 +15,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.configuration;
package xyz.jonesdev.sonar.common.protocol.packets.configuration;
import io.netty.buffer.ByteBuf;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class FinishConfigurationPacket implements FallbackPacket {
public final class FinishConfigurationPacket implements SonarPacket {
public static final FinishConfigurationPacket INSTANCE = new FinishConfigurationPacket();
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.configuration;
package xyz.jonesdev.sonar.common.protocol.packets.configuration;
import io.netty.buffer.ByteBuf;
import lombok.*;
@@ -23,9 +23,9 @@ import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketSnapshot;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.SonarPacketSnapshot;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import java.util.ArrayList;
@@ -34,7 +34,7 @@ import java.util.List;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public final class RegistryDataPacket implements FallbackPacket {
public final class RegistryDataPacket implements SonarPacket {
private CompoundBinaryTag tag;
private String type;
private List<RegistryDataPacket.Bundle> bundles;
@@ -66,8 +66,8 @@ public final class RegistryDataPacket implements FallbackPacket {
throw new UnsupportedOperationException();
}
public static FallbackPacket @NotNull [] of(final @NotNull CompoundBinaryTag rootTag) {
final FallbackPacket[] packets = new FallbackPacket[rootTag.size()];
public static SonarPacket @NotNull [] of(final @NotNull CompoundBinaryTag rootTag) {
final SonarPacket[] packets = new SonarPacket[rootTag.size()];
int index = 0;
for (final String type : rootTag.keySet()) {
final ArrayList<RegistryDataPacket.Bundle> bundles = new ArrayList<>();
@@ -76,7 +76,7 @@ public final class RegistryDataPacket implements FallbackPacket {
// CompoundBinaryTag#getCompound(String) will return an empty compound tag when not exist.
bundles.add(new Bundle(tag.getString("name"), tag.get("element") == null ? null : tag.getCompound("element")));
}
packets[index++] = new FallbackPacketSnapshot(new RegistryDataPacket(rootTag, type, bundles));
packets[index++] = new SonarPacketSnapshot(new RegistryDataPacket(rootTag, type, bundles));
}
return packets;
}
@@ -15,18 +15,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.handshake;
package xyz.jonesdev.sonar.common.protocol.packets.handshake;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.ToString;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString(of = {"protocolVersionId", "hostname", "port"})
public final class HandshakePacket implements FallbackPacket {
public final class HandshakePacket implements SonarPacket {
private int protocolVersionId;
private String hostname;
private int port;
@@ -15,13 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.login;
package xyz.jonesdev.sonar.common.protocol.packets.login;
import io.netty.buffer.ByteBuf;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
public final class LoginAcknowledgedPacket implements FallbackPacket {
public final class LoginAcknowledgedPacket implements SonarPacket {
@Override
public void encode(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.login;
package xyz.jonesdev.sonar.common.protocol.packets.login;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.DecoderException;
@@ -25,8 +25,8 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
@@ -36,7 +36,7 @@ import java.util.UUID;
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class LoginStartPacket implements FallbackPacket {
public final class LoginStartPacket implements SonarPacket {
private String username;
private @Nullable UUID uuid;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.login;
package xyz.jonesdev.sonar.common.protocol.packets.login;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,8 +23,8 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.FastUuidSansHyphens;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@@ -34,7 +34,7 @@ import java.util.UUID;
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class LoginSuccessPacket implements FallbackPacket {
public final class LoginSuccessPacket implements SonarPacket {
private UUID uuid;
private String username;
private boolean strictErrorHandling;
@@ -15,13 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.*;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@@ -29,7 +29,7 @@ import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@NoArgsConstructor
@AllArgsConstructor
@ToString(of = {"entityId", "hand"})
public final class AnimationPacket implements FallbackPacket {
public final class AnimationPacket implements SonarPacket {
private int entityId = -1;
private int hand = MAIN_HAND;
private LegacyAnimationType type = LegacyAnimationType.SWING_ARM;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -25,15 +25,15 @@ import lombok.ToString;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.LongArrayBinaryTag;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class ChunkDataPacket implements FallbackPacket {
public final class ChunkDataPacket implements SonarPacket {
private int sectionX, sectionZ;
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class ClientInformationPacket implements FallbackPacket {
public final class ClientInformationPacket implements SonarPacket {
private String locale;
private byte viewDistance;
private int chatVisibility;
@@ -15,13 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
public final class ClientTickEndPacket implements FallbackPacket {
public final class ClientTickEndPacket implements SonarPacket {
@Override
public void encode(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
@@ -15,22 +15,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class ConfirmTeleportationPacket implements FallbackPacket {
public final class ConfirmTeleportationPacket implements SonarPacket {
private int teleportId;
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ComponentHolder;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public final class DisconnectPacket implements FallbackPacket {
public final class DisconnectPacket implements SonarPacket {
private @NotNull ComponentHolder componentHolder;
private boolean duringLogin;
@@ -15,22 +15,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public final class EntityAnimationPacket implements FallbackPacket {
public final class EntityAnimationPacket implements SonarPacket {
private int entityId;
private Type type;
@@ -15,20 +15,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Data
@NoArgsConstructor
@AllArgsConstructor
public final class GameEventPacket implements FallbackPacket {
public final class GameEventPacket implements SonarPacket {
private int type;
private float value;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -25,10 +25,10 @@ import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.ListBinaryTag;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.dimension.DimensionRegistry;
import xyz.jonesdev.sonar.common.fallback.protocol.dimension.DimensionType;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.dimension.DimensionRegistry;
import xyz.jonesdev.sonar.common.protocol.dimension.DimensionType;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import java.util.Objects;
@@ -36,7 +36,7 @@ import java.util.Objects;
@Data
@NoArgsConstructor
@AllArgsConstructor
public final class JoinGamePacket implements FallbackPacket {
public final class JoinGamePacket implements SonarPacket {
private int entityId;
private int gamemode;
private int previousGamemode;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class KeepAlivePacket implements FallbackPacket {
public final class KeepAlivePacket implements SonarPacket {
private long id;
@Override
@@ -15,21 +15,21 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public final class MapDataPacket implements FallbackPacket {
public final class MapDataPacket implements SonarPacket {
private byte[] buffer;
private int x, y;
private int scaling;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class PaddleBoatPacket implements FallbackPacket {
public final class PaddleBoatPacket implements SonarPacket {
private boolean leftPaddle, rightPaddle;
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class PlayerAbilitiesPacket implements FallbackPacket {
public final class PlayerAbilitiesPacket implements SonarPacket {
private int encodedFlags;
private float flySpeed, walkSpeed;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class PlayerInputPacket implements FallbackPacket {
public final class PlayerInputPacket implements SonarPacket {
private float sideways, forward;
private boolean jump, sneak;
@@ -15,20 +15,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
@Getter
@ToString
public final class PluginMessagePacket implements FallbackPacket {
public final class PluginMessagePacket implements SonarPacket {
private String channel;
private byte[] data;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class RemoveEntitiesPacket implements FallbackPacket {
public final class RemoveEntitiesPacket implements SonarPacket {
private int entityId; // We only need one entityId
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -24,16 +24,16 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.item.ItemType;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.item.ItemType;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetContainerSlotPacket implements FallbackPacket {
public final class SetContainerSlotPacket implements SonarPacket {
private int windowId, slot, count;
private ItemType itemType;
private CompoundBinaryTag compoundBinaryTag;
@@ -60,10 +60,10 @@ public final class SetContainerSlotPacket implements FallbackPacket {
ProtocolUtil.writeVarInt(byteBuf, count);
}
if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_13_2)) {
byteBuf.writeShort(itemType.getId().apply(protocolVersion));
} else {
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_13_2)) {
ProtocolUtil.writeVarInt(byteBuf, itemType.getId().apply(protocolVersion));
} else {
byteBuf.writeShort(itemType.getId().apply(protocolVersion));
}
if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_20_5)) {
@@ -83,8 +83,8 @@ public final class SetContainerSlotPacket implements FallbackPacket {
} else if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_20_5)) {
ProtocolUtil.writeBinaryTag(byteBuf, protocolVersion, compoundBinaryTag);
} else {
ProtocolUtil.writeVarInt(byteBuf, 1); // component count to add
ProtocolUtil.writeVarInt(byteBuf, 0); // component count to remove
ProtocolUtil.writeVarInt(byteBuf, 1); // addedComponentCount
ProtocolUtil.writeVarInt(byteBuf, 0); // removedComponentCount
ProtocolUtil.writeVarInt(byteBuf, itemType.getComponents().apply(protocolVersion));
ProtocolUtil.writeVarInt(byteBuf, 0); // data
}
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetDefaultSpawnPositionPacket implements FallbackPacket {
public final class SetDefaultSpawnPositionPacket implements SonarPacket {
private String dimensionName;
private int x, y, z;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetExperiencePacket implements FallbackPacket {
public final class SetExperiencePacket implements SonarPacket {
private float experienceBar;
private int level;
private int totalExperience;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetHeldItemPacket implements FallbackPacket {
public final class SetHeldItemPacket implements SonarPacket {
private int slot;
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetPassengersPacket implements FallbackPacket {
public final class SetPassengersPacket implements SonarPacket {
private int entityId, passengerId;
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetPlayerOnGround implements FallbackPacket {
public final class SetPlayerOnGround implements SonarPacket {
private boolean onGround, horizontalCollision;
@Override
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetPlayerPositionPacket implements FallbackPacket {
public final class SetPlayerPositionPacket implements SonarPacket {
private double x, y, z;
private boolean onGround, horizontalCollision;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetPlayerPositionRotationPacket implements FallbackPacket {
public final class SetPlayerPositionRotationPacket implements SonarPacket {
private double x, y, z;
private float yaw, pitch;
private int teleportId, relativeMask;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SetPlayerRotationPacket implements FallbackPacket {
public final class SetPlayerRotationPacket implements SonarPacket {
private float yaw, pitch;
private boolean onGround, horizontalCollision;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,9 +23,9 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.entity.EntityType;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.entity.EntityType;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import java.util.UUID;
@@ -34,7 +34,7 @@ import java.util.UUID;
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class SpawnEntityPacket implements FallbackPacket {
public final class SpawnEntityPacket implements SonarPacket {
private int entityId;
private EntityType entityType;
private double x, y, z;
@@ -15,15 +15,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ComponentHolder;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
@@ -33,7 +33,7 @@ import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
public final class SystemChatPacket implements FallbackPacket {
public final class SystemChatPacket implements SonarPacket {
private static final int DIV_FLOOR = -Math.floorDiv(-20, 8);
private ComponentHolder componentHolder;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,14 +23,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class TransactionPacket implements FallbackPacket {
public final class TransactionPacket implements SonarPacket {
private int windowId, transactionId;
private boolean accepted;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,15 +23,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class TransferPacket implements FallbackPacket {
public final class TransferPacket implements SonarPacket {
private String destinationHost;
private int destinationPort;
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
package xyz.jonesdev.sonar.common.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
@@ -23,16 +23,16 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.block.BlockUpdate;
import xyz.jonesdev.sonar.api.antibot.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.protocol.SonarPacket;
import xyz.jonesdev.sonar.common.protocol.block.BlockUpdate;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString(exclude = {"blockUpdates"})
public final class UpdateSectionBlocksPacket implements FallbackPacket {
public final class UpdateSectionBlocksPacket implements SonarPacket {
private int sectionX, sectionZ;
private BlockUpdate[] blockUpdates;
Loaded 100 of 132 files, more files were not shown because too many files have changed in this diff. Show more