Compare commits

..
11 Commits
Author SHA1 Message Date
Jones cc52289500 Release 2.0.14 (#149) 2024-01-06 14:55:30 +01:00
Jones ac1f6d616b Reword and simplify the README (#148) 2024-01-02 21:26:04 +01:00
Jones bdd941171e Use correct security contact email (#147) 2024-01-02 21:09:25 +01:00
Jones 1e18a29d1e Update license year to 2023-2024 (#146) 2024-01-02 18:17:20 +01:00
Jones 5671c2029e Change default color scheme in messages (#145) 2024-01-01 23:55:33 +01:00
Jones 32aeee4f06 Fix license link in README (#144) 2023-12-31 18:10:28 +01:00
Jones 7b5ce41420 Show server uptime in statistics (#143)
* style: small code clean up

* feat: add server uptime to statistics
2023-12-30 21:44:16 +01:00
Jones a66f60f177 Recode Velocity injection (#142)
* feat(bungee): implement empty hostname check

* feat: recode Velocity injection

* feat: recode action bar counters

* fix(bungee): make sure the connection is open
2023-12-30 21:24:53 +01:00
Jones 326a1ecc07 Release 2.0.13 (#140) 2023-12-30 15:57:53 +01:00
Jones 6af5a9fc4b Make sure the workflow uses Java 17 (#139) 2023-12-30 01:17:55 +01:00
Jones ac78d88721 Bump Velocity API from 3.2.0 to 3.3.0 (#138) 2023-12-30 01:12:27 +01:00
138 changed files with 732 additions and 1007 deletions

No files matched your search

+14 -23
View File
@@ -25,7 +25,7 @@
|
[Discord](https://jonesdev.xyz/discord)
|
[License](https://github.com/jonesdevelopment/sonar/blob/main/README.md#license)
[License](https://github.com/jonesdevelopment/sonar/?tab=readme-ov-file#license)
</div>
## Design and Goal
@@ -33,27 +33,25 @@
* Effective, lightweight, and easy-to-use
* No unnecessary features and clean code
* Protection against all kinds of bot attacks
* No player should be annoyed by any sort of captcha
* No player should be annoyed by any sort of [CAPTCHA](https://en.wikipedia.org/wiki/CAPTCHA)
* No sort of checking for VPNs or proxies
* Multi-platform support (Velocity, BungeeCord, and Bukkit)
* Multi-platform support (See [supported versions](https://docs.jonesdev.xyz/sonar/supported-versions))
## Checks
- New player logins are queued to prevent spam login attacks.
- [Fallback](https://github.com/jonesdevelopment/sonar#fallback) is Sonar's main component designed to prevent
all types of bots.
- Spigot & BungeeCord
- Duplicate login/status packet spam fix
- Run server ping handling asynchronously
- [Fallback](https://github.com/jonesdevelopment/sonar#fallback) is Sonar's main anti-bot component
- Sonar queues new player logins to prevent spam login attacks
- Sonar checks the handshake packets for legitimacy
- Protective components only on BungeeCord:
- Sonar validates the login/server ping packets
- Sonar handles all server pings asynchronously
- The Varint decoder is updated to Velocity's
improved [MinecraftVarintFrameDecoder](https://github.com/PaperMC/Velocity/blob/dev/3.0.0/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftVarintFrameDecoder.java).
### Fallback
Fallback analyzes a player's behavior before joining the actual server, therefore stopping malicious traffic from ever
reaching the backend.
It is supposed to be an instant, powerful, and invisible method of verification that should prevent all typical and
advanced types of bots.
Fallback analyzes a player's behavior before joining the actual server, therefore stopping malicious traffic from ever reaching the backend.
It is supposed to be an instant, powerful, and invisible method of verification that should prevent all typical and advanced types of bots.
* Sends the player to a lightweight fake server when they connect for the first time.
* Analyzes if the player is sending the necessary packets.
@@ -61,16 +59,11 @@ advanced types of bots.
* Checks if the player is obeying client gravity.
* Checks if the player is colliding with blocks correctly.
Fallback also protects from huge spambot attacks since it queues the incoming connections, therefore making it
technically impossible to have a ton of bots join the server at the same time.
Fallback also protects against huge spambot attacks since it queues the incoming connections, therefore making it technically impossible to have a ton of bots join the server at the same time.
### False positives
Fallback is unlikely to ever falsely prevent a player from joining the server since Minecraft uses the TCP protocol which means that packets are always sent in the correct order. Therefore, lag or ping should not affect the bot check.
However, there are some edge cases where Fallback might not receive packets within the necessary time period. In this case, Sonar tries to account for these edge cases in order to prevent false positives. For example, some higher Minecraft versions have a bug where the client sometimes sends a packet out of order. Sonar accounts for that and does not falsely blacklist clients.
If you or one of your players experiences a false positive, make sure to report it by opening
a [GitHub issue](https://github.com/jonesdevelopment/sonar/issues) or a ticket
on [Discord](https://jonesdev.xyz/discord/).
Fallback is unlikely to ever falsely prevent a player from joining the server since Minecraft uses the TCP protocol, which means that packets are always sent in the correct order. Therefore, lag or ping should not affect the bot check. However, there are some edge cases where Fallback might not receive packets within the necessary time period. In this case, Sonar tries to account for these edge cases in order to prevent false positives. If you or one of your players experiences a false positive, make sure to report it by opening a [GitHub issue](https://github.com/jonesdevelopment/sonar/issues) or a ticket on [Discord](https://jonesdev.xyz/discord/).
## Building
@@ -80,9 +73,7 @@ You can also take a look at the [gradle documentation](https://docs.gradle.org/c
## Contributing
If you are interested in contributing, you can check out
the [Contributing Guidelines](https://github.com/jonesdevelopment/sonar/blob/main/.github/CONTRIBUTING.md) for detailed
instructions.
If you are interested in contributing, you can check out the [Contributing Guidelines](https://github.com/jonesdevelopment/sonar/blob/main/.github/CONTRIBUTING.md) for detailed instructions.
## License
+3 -7
View File
@@ -13,13 +13,9 @@ If you discover a security vulnerability within Sonar, please follow these steps
## Contact
If you have any questions or concerns regarding the security of this project, please open a ticket on Discord or contact me via email at admin@jonesdev.xyz.
If you have any questions or concerns regarding the security of this project, please open a ticket on Discord or contact me via email at contact@jonesdev.xyz.
## Acknowledgments
Special thanks to the following people for their contributions:
- [xism4](https://github.com/xism4)
- fixed serious issues with packet decode logic on BungeeCord [#5](https://github.com/jonesdevelopment/sonar-legacy/pull/5) (Severity: medium)
- fixed a false blacklisting issue when a player looses connection [#9](https://github.com/jonesdevelopment/sonar-legacy/pull/9) (Severity: low)
- [NoGodHenry](https://github.com/NoGodHenry)
- fixed a ConcurrentModificationException in the configuration [#3](https://github.com/jonesdevelopment/sonar-legacy/pull/3) (Severity: low)
- Special thanks to the [contributors of Sonar](https://github.com/jonesdevelopment/sonar/graphs/contributors),
and also those who reported security issues or bugs.
+2 -2
View File
@@ -22,10 +22,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '11'
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
+1 -1
View File
@@ -1,3 +1,3 @@
group=xyz.jonesdev.sonar
version=2.0.12
version=2.0.14
description=Effective Anti-bot plugin for Velocity, BungeeCord, and Bukkit (1.7-latest)
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -27,6 +27,7 @@ import xyz.jonesdev.sonar.api.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.timer.SystemTimer;
import xyz.jonesdev.sonar.api.verbose.Verbose;
import java.io.File;
@@ -60,6 +61,8 @@ public interface Sonar {
@NotNull Verbose getVerboseHandler();
@NotNull SystemTimer getLaunchTimer();
/**
* Set a custom verbose handler
*/
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -24,6 +24,7 @@ import xyz.jonesdev.sonar.api.config.SonarConfiguration;
import xyz.jonesdev.sonar.api.event.impl.AttackDetectedEvent;
import xyz.jonesdev.sonar.api.event.impl.AttackMitigatedEvent;
import xyz.jonesdev.sonar.api.profiler.JVMProfiler;
import xyz.jonesdev.sonar.api.statistics.Counters;
import xyz.jonesdev.sonar.api.statistics.Statistics;
import xyz.jonesdev.sonar.api.timer.SystemTimer;
@@ -43,6 +44,7 @@ public final class AttackTracker implements JVMProfiler {
private final SystemTimer duration = new SystemTimer();
private final SystemTimer timer = new SystemTimer();
private int peakJoinsPerSecond;
private int peakConnectionsPerSecond;
private double peakProcessCPUUsage;
private long peakProcessMemoryUsage;
// Calculate during-attack-statistics using their deltas
@@ -50,7 +52,7 @@ public final class AttackTracker implements JVMProfiler {
}
public void checkIfUnderAttack() {
final int joinsPerSecond = Sonar.get().getVerboseHandler().getLoginsPerSecond().estimatedSize();
final int joinsPerSecond = Counters.LOGINS_PER_SECOND.estimatedSize();
final int verifyingPlayers = Sonar.get().getFallback().getConnected().size();
final int queuedPlayers = Sonar.get().getFallback().getQueue().getQueuedPlayers().size();
final int minPlayers = Sonar.get().getConfig().getMinPlayersForAttack();
@@ -77,6 +79,11 @@ public final class AttackTracker implements JVMProfiler {
// Update joins per second peak if necessary
currentAttack.peakJoinsPerSecond = joinsPerSecond;
}
final int connectionsPerSecond = Counters.CONNECTIONS_PER_SECOND.estimatedSize();
if (connectionsPerSecond > currentAttack.peakConnectionsPerSecond) {
// Update connections per second peak if necessary
currentAttack.peakConnectionsPerSecond = connectionsPerSecond;
}
final double processCPUUsage = getProcessCPUUsage();
if (processCPUUsage > currentAttack.peakProcessCPUUsage) {
// Update cpu usage peak if necessary
@@ -99,6 +106,7 @@ public final class AttackTracker implements JVMProfiler {
final String peakCPU = Sonar.DECIMAL_FORMAT.format(currentAttack.peakProcessCPUUsage);
final String peakMem = formatMemory(currentAttack.peakProcessMemoryUsage);
final String peakBPS = Sonar.DECIMAL_FORMAT.format(currentAttack.peakJoinsPerSecond);
final String peakCPS = Sonar.DECIMAL_FORMAT.format(currentAttack.peakConnectionsPerSecond);
final long minutes = deltaInMillis / (60 * 1000); // Convert milliseconds to minutes
final double seconds = (deltaInMillis % (60 * 1000)) / 1000D; // Convert remaining milliseconds to seconds
final String formattedDuration = String.format("%d minutes, %.0f seconds", minutes, seconds);
@@ -121,6 +129,7 @@ public final class AttackTracker implements JVMProfiler {
.replace("%peak-cpu%", peakCPU)
.replace("%peak-memory%", peakMem)
.replace("%peak-bps%", peakBPS)
.replace("%peak-cps%", peakCPS)
.replace("%total-blacklisted%", Sonar.DECIMAL_FORMAT.format(blacklisted))
.replace("%total-failed%", Sonar.DECIMAL_FORMAT.format(failed))
.replace("%total-success%", Sonar.DECIMAL_FORMAT.format(verified));
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -340,7 +340,8 @@ public final class SonarConfiguration {
messagesConfig.getYaml().setComment("prefix",
"Placeholder for every '%prefix%' in this configuration file");
prefix = formatString(messagesConfig.getString("prefix", "<yellow><bold>Sonar<reset> <gray>» <white>"));
prefix = formatString(messagesConfig.getString("prefix",
"<b><yellow>Sonar</b> <gray>» <white>"));
messagesConfig.getYaml().setComment("support-url",
"Placeholder for every '%support-url%' in this configuration file");
@@ -641,8 +642,8 @@ public final class SonarConfiguration {
"Placeholder for every '%header%' in this configuration file");
header = fromList(messagesConfig.getStringList("header",
Arrays.asList(
"<yellow><bold>Sonar<reset>",
"<reset>"
"<b><yellow>Sonar</b><reset>",
""
)));
messagesConfig.getYaml().setComment("footer",
@@ -708,15 +709,15 @@ public final class SonarConfiguration {
"Informational message that is shown above everything when running the main command");
commands.helpHeader = messagesConfig.getStringList("commands.main.header",
Arrays.asList(
"<yellow>Running Sonar %version% on %platform%.",
"<yellow>(C) %copyright_year% Jones Development and Sonar Contributors",
"<green><click:open_url:'https://github.com/jonesdevelopment/sonar'>https://github.com/jonesdevelopment/sonar",
"<yellow>Running <b>Sonar</b> %version% on %platform%.",
"<gray><click:open_url:'https://github.com/jonesdevelopment/sonar'>(C) %copyright_year% Jones Development and" +
" Sonar Contributors</click>",
"",
"<yellow>Need help or have any questions?",
"<yellow><click:open_url:'https://jonesdev.xyz/discord/'><hover:show_text:'(Click to open Discord)'>Open a " +
"ticket on the Discord </hover></click></yellow><yellow><click:open_url:'https://github" +
".com/jonesdevelopment/sonar/issues'><hover:show_text:'(Click to open GitHub)'>or open a new issue on " +
"GitHub.",
"<gray>Need help or have any questions?",
"<white><click:open_url:'https://jonesdev.xyz/discord/'><hover:show_text:'(Click to open Discord)'>Open a " +
"ticket on the Discord </hover></click><click:open_url:'https://github" +
".com/jonesdevelopment/sonar/issues'><hover:show_text:'(Click to open GitHub)'>or open a new issue on" +
" GitHub.",
""
));
messagesConfig.getYaml().setComment("commands.main.subcommands",
@@ -724,8 +725,8 @@ public final class SonarConfiguration {
commands.helpSubcommands = formatString(messagesConfig.getString("commands.main.subcommands",
"<click:suggest_command:'/sonar %subcommand% '><hover:show_text:'<gray>Only players: " +
"</gray>%only_players%<br><gray>Require console: </gray>%require_console%<br><gray>Permission: " +
"</gray><white>%permission%<br><gray>Aliases: </gray>%aliases%'><gray> ▪ </gray><green>/sonar " +
"%subcommand%</green><gray> - </gray><white>%description%"));
"</gray><white>%permission%<br><gray>Aliases: </gray>%aliases%'><dark_aqua> ▪ <gray>/sonar " +
"%subcommand% <white>%description%"));
SonarCommand.prepareCachedMessages();
@@ -833,7 +834,7 @@ public final class SonarConfiguration {
messagesConfig.getYaml().setComment("commands.statistics.header",
"Informational message that is shown above everything when viewing the statistics");
commands.statisticsHeader = formatString(messagesConfig.getString("commands.statistics.header",
"%prefix%<yellow>Showing %type% statistics for this session:"));
"%prefix%Showing %type% statistics for this session:"));
messagesConfig.getYaml().setComment("commands.statistics.unknown-type",
"Message that is shown when a player tries viewing an unknown statistic");
@@ -844,45 +845,46 @@ public final class SonarConfiguration {
"Format of the general statistics message");
commands.generalStatistics = formatString(fromList(messagesConfig.getStringList("commands.statistics.general",
Arrays.asList(
" <gray>▪ <green>Verified IP addresses: <white>%verified%",
" <gray>▪ <green>Verifying IP addresses: <white>%verifying%",
" <gray>▪ <green>Blacklisted IP addresses: <white>%blacklisted%",
" <gray>▪ <green>Currently queued logins: <white>%queued%",
" <gray>▪ <green>Total non-unique joins: <white>%total_joins%",
" <gray>▪ <green>Total verification attempts: <white>%total_attempts%",
" <gray>▪ <green>Total failed verifications: <white>%total_failed%"
" <dark_aqua>▪ <gray>Verified IP addresses: <white>%verified%",
" <dark_aqua>▪ <gray>Verifying IP addresses: <white>%verifying%",
" <dark_aqua>▪ <gray>Blacklisted IP addresses: <white>%blacklisted%",
" <dark_aqua>▪ <gray>Currently queued logins: <white>%queued%",
" <dark_aqua>▪ <gray>Total non-unique joins: <white>%total_joins%",
" <dark_aqua>▪ <gray>Total verification attempts: <white>%total_attempts%",
" <dark_aqua>▪ <gray>Total failed verifications: <white>%total_failed%",
" <dark_aqua>▪ <gray>Server uptime: <white>%uptime%"
))));
messagesConfig.getYaml().setComment("commands.statistics.cpu",
"Format of the CPU statistics message");
commands.cpuStatistics = formatString(fromList(messagesConfig.getStringList("commands.statistics.cpu",
Arrays.asList(
" <gray>▪ <green>Process CPU usage right now: <white>%process_cpu%%",
" <gray>▪ <green>System CPU usage right now: <white>%system_cpu%%",
" <gray>▪ <green>Per-core process CPU usage: <white>%average_process_cpu%%",
" <gray>▪ <green>Per-core system CPU usage: <white>%average_system_cpu%%",
" <gray>▪ <green>General system load average: <white>%load_average%%",
" <gray>▪ <green>Total amount of virtual cpus: <white>%virtual_cores%"
" <dark_aqua>▪ <gray>Process CPU usage right now: <white>%process_cpu%%",
" <dark_aqua>▪ <gray>System CPU usage right now: <white>%system_cpu%%",
" <dark_aqua>▪ <gray>Per-core process CPU usage: <white>%average_process_cpu%%",
" <dark_aqua>▪ <gray>Per-core system CPU usage: <white>%average_system_cpu%%",
" <dark_aqua>▪ <gray>General system load average: <white>%load_average%%",
" <dark_aqua>▪ <gray>Total amount of virtual cpus: <white>%virtual_cores%"
))));
messagesConfig.getYaml().setComment("commands.statistics.memory",
"Format of the memory statistics message");
commands.memoryStatistics = formatString(fromList(messagesConfig.getStringList("commands.statistics.memory",
Arrays.asList(
" <gray>▪ <green>Total free memory: <white>%free_memory%",
" <gray>▪ <green>Total used memory: <white>%used_memory%",
" <gray>▪ <green>Total maximum memory: <white>%max_memory%",
" <gray>▪ <green>Total allocated memory: <white>%total_memory%"
" <dark_aqua>▪ <gray>Total free memory: <white>%free_memory%",
" <dark_aqua>▪ <gray>Total used memory: <white>%used_memory%",
" <dark_aqua>▪ <gray>Total maximum memory: <white>%max_memory%",
" <dark_aqua>▪ <gray>Total allocated memory: <white>%total_memory%"
))));
messagesConfig.getYaml().setComment("commands.statistics.network",
"Format of the network statistics message");
commands.networkStatistics = formatString(fromList(messagesConfig.getStringList("commands.statistics.network",
Arrays.asList(
" <gray>▪ <green>Current incoming used bandwidth: <white>%incoming%",
" <gray>▪ <green>Current outgoing used bandwidth: <white>%outgoing%",
" <gray>▪ <green>Total incoming used bandwidth: <white>%ttl_incoming%",
" <gray>▪ <green>Total outgoing used bandwidth: <white>%ttl_outgoing%"
" <dark_aqua>▪ <gray>Current incoming used bandwidth: <white>%incoming%",
" <dark_aqua>▪ <gray>Current outgoing used bandwidth: <white>%outgoing%",
" <dark_aqua>▪ <gray>Total incoming used bandwidth: <white>%ttl_incoming%",
" <dark_aqua>▪ <gray>Total outgoing used bandwidth: <white>%ttl_outgoing%"
))));
messagesConfig.getYaml().setComment("verification",
@@ -1063,6 +1065,7 @@ public final class SonarConfiguration {
+ LINE_SEPARATOR + "- '%verify-success%' Number of verified IP addresses"
+ LINE_SEPARATOR + "- '%verify-failed%' Number of failed verifications"
+ LINE_SEPARATOR + "- '%logins-per-second%' Number of logins per second"
+ LINE_SEPARATOR + "- '%connections-per-second%' Number of connections per second"
+ LINE_SEPARATOR + "- '%attack-duration%' Duration of the current attack"
+ LINE_SEPARATOR + "- '%incoming-traffic%' Incoming bandwidth usage per second"
+ LINE_SEPARATOR + "- '%outgoing-traffic%' Outgoing bandwidth usage per second"
@@ -1076,24 +1079,22 @@ public final class SonarConfiguration {
+ LINE_SEPARATOR + "Translations for Sonar's normal verbose output");
verbose.actionBarLayout = formatString(messagesConfig.getString("verbose.layout.normal",
String.join(" <dark_aqua>╺ ", Arrays.asList(
"%prefix%<gray>Queued <white>%queued%",
"<gray>Verifying <white>%verifying%",
"<gray>Blacklisted <white>%blacklisted%" +
" <dark_aqua>| <green>⬆ <white>%outgoing-traffic%/s <red>⬇ <white>%incoming-traffic%/s" +
" <green><bold>%animation%<reset>"
))));
"%prefix%<gray>CPS <white>%connections-per-second%",
"<gray>Logins/s <white>%logins-per-second%",
"<gray>Verifying <white>%verifying%"
+ " <dark_aqua>| <green>⬆ <white>%outgoing-traffic%/s <red>⬇ <white>%incoming-traffic%/s"
+ " <green><bold>%animation%<reset>"))));
messagesConfig.getYaml().setComment("verbose.layout.attack",
"Translations for Sonar's verbose output during an active attack");
verbose.actionBarLayoutDuringAttack = formatString(messagesConfig.getString("verbose.layout.attack",
String.join(" <dark_aqua>╺ ", Arrays.asList(
"%prefix%<gray>BPS <white>%logins-per-second%",
"<gray>Queued <white>%queued%",
"%prefix%<gray>CPS <white>%connections-per-second%",
"<gray>Logins/s <white>%logins-per-second%",
"<gray>Queue <white>%queued%",
"<gray>Verifying <white>%verifying%",
"<gray>Blacklisted <white>%blacklisted%",
"<gray>Duration <white>%attack-duration%" +
" <dark_aqua>| <green>⬆ <white>%outgoing-traffic%/s <red>⬇ <white>%incoming-traffic%/s" +
" <green><bold>%animation%<reset>"
))));
"<gray>Duration <white>%attack-duration%"
+ " <dark_aqua>| <green>⬆ <white>%outgoing-traffic%/s <red>⬇ <white>%incoming-traffic%/s"
+ " <green><bold>%animation%<reset>"))));
messagesConfig.getYaml().setComment("verbose.animation", "Animation for the action bar"
+ LINE_SEPARATOR + "Alternatives:"
+ LINE_SEPARATOR + "- ▙, ▛, ▜, ▟"
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -31,5 +31,5 @@ import xyz.jonesdev.sonar.api.fallback.FallbackUser;
@RequiredArgsConstructor
public final class UserBlacklistedEvent implements SonarEvent {
@ApiStatus.Experimental
private final FallbackUser<?, ?> user;
private final FallbackUser<?> user;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -30,11 +30,11 @@ import java.util.Optional;
@ToString
@EqualsAndHashCode
public final class UserVerifyFailedEvent implements SonarEvent {
private final FallbackUser<?, ?> user;
private final FallbackUser<?> user;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private final Optional<String> reason;
public UserVerifyFailedEvent(final FallbackUser<?, ?> user, final @Nullable String reason) {
public UserVerifyFailedEvent(final FallbackUser<?> user, final @Nullable String reason) {
this.user = user;
this.reason = Optional.ofNullable(reason);
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -30,5 +30,5 @@ import xyz.jonesdev.sonar.api.fallback.FallbackUser;
@RequiredArgsConstructor
public final class UserVerifyJoinEvent implements SonarEvent {
private final String username;
private final FallbackUser<?, ?> user;
private final FallbackUser<?> user;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -33,6 +33,6 @@ import java.util.UUID;
public final class UserVerifySuccessEvent implements SonarEvent {
private final String username;
private final UUID offlineUuid;
private final FallbackUser<?, ?> user;
private final FallbackUser<?> user;
private final long timeTakenToVerify;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -33,12 +33,10 @@ import xyz.jonesdev.sonar.api.statistics.Statistics;
import java.net.InetAddress;
import java.util.concurrent.TimeUnit;
public interface FallbackUser<X, Y> {
public interface FallbackUser<T> {
@NotNull Fallback getFallback();
@NotNull X getPlayer();
@NotNull Y getConnection();
@NotNull T getConnection();
@NotNull Channel getChannel();
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2023-2024 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.api.statistics;
import xyz.jonesdev.cappuccino.Cappuccino;
import xyz.jonesdev.cappuccino.ExpiringCache;
import java.util.concurrent.TimeUnit;
public interface Counters {
ExpiringCache<Long> LOGINS_PER_SECOND = Cappuccino.buildExpiring(1L, TimeUnit.SECONDS);
ExpiringCache<Long> CONNECTIONS_PER_SECOND = Cappuccino.buildExpiring(1L, TimeUnit.SECONDS);
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -23,11 +23,10 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.cappuccino.Cappuccino;
import xyz.jonesdev.cappuccino.ExpiringCache;
import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.attack.AttackTracker;
import xyz.jonesdev.sonar.api.profiler.JVMProfiler;
import xyz.jonesdev.sonar.api.statistics.Counters;
import xyz.jonesdev.sonar.api.statistics.Statistics;
import xyz.jonesdev.sonar.api.timer.SystemTimer;
@@ -35,24 +34,24 @@ import java.util.Collection;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import static xyz.jonesdev.sonar.api.Sonar.DECIMAL_FORMAT;
import static xyz.jonesdev.sonar.api.fallback.traffic.TrafficCounter.INCOMING;
import static xyz.jonesdev.sonar.api.fallback.traffic.TrafficCounter.OUTGOING;
@Getter
public final class Verbose implements JVMProfiler {
public final class Verbose implements JVMProfiler, Counters {
private final @NotNull Collection<String> subscribers = new Vector<>(0);
private final @NotNull Map<String, Audience> audiences = new ConcurrentHashMap<>();
private int animationIndex;
private final ExpiringCache<Long> loginsPerSecond = Cappuccino.buildExpiring(1L, TimeUnit.SECONDS);
// Run action bar verbose
public void update() {
// Clean up all blacklisted IPs
Sonar.get().getFallback().getBlacklisted().cleanUp(false);
loginsPerSecond.cleanUp(false);
// Clean up all counters
LOGINS_PER_SECOND.cleanUp(false);
CONNECTIONS_PER_SECOND.cleanUp(false);
// Don't prepare component if there are no subscribers
if (subscribers.isEmpty()) return;
@@ -78,7 +77,8 @@ public final class Verbose implements JVMProfiler {
.replace("%blacklisted%",
DECIMAL_FORMAT.format(Sonar.get().getFallback().getBlacklisted().estimatedSize()))
.replace("%total-joins%", DECIMAL_FORMAT.format(Statistics.TOTAL_TRAFFIC.get()))
.replace("%logins-per-second%", DECIMAL_FORMAT.format(loginsPerSecond.estimatedSize()))
.replace("%logins-per-second%", DECIMAL_FORMAT.format(LOGINS_PER_SECOND.estimatedSize()))
.replace("%connections-per-second%", DECIMAL_FORMAT.format(CONNECTIONS_PER_SECOND.estimatedSize()))
.replace("%verify-total%", DECIMAL_FORMAT.format(Statistics.REAL_TRAFFIC.get()))
.replace("%verify-success%",
DECIMAL_FORMAT.format(Sonar.get().getVerifiedPlayerController().estimatedSize()))
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -33,6 +33,7 @@ import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.connection.InitialHandler;
import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.protocol.PlayerPublicKey;
import net.md_5.bungee.protocol.packet.Handshake;
import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.protocol.packet.LoginRequest;
import net.md_5.bungee.protocol.packet.StatusRequest;
@@ -43,6 +44,7 @@ import xyz.jonesdev.sonar.api.Sonar;
import xyz.jonesdev.sonar.api.event.impl.UserVerifyJoinEvent;
import xyz.jonesdev.sonar.api.fallback.Fallback;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.api.statistics.Counters;
import xyz.jonesdev.sonar.api.statistics.Statistics;
import xyz.jonesdev.sonar.common.fallback.FallbackChannelHandler;
import xyz.jonesdev.sonar.common.fallback.FallbackTimeoutHandler;
@@ -75,7 +77,6 @@ public final class FallbackInitialHandler extends InitialHandler {
this.bungee = bungee;
}
private static final @NotNull Fallback FALLBACK = Objects.requireNonNull(Sonar.get().getFallback());
@Getter
private ChannelWrapper channelWrapper;
private final @NotNull BungeeCord bungee;
@@ -85,10 +86,23 @@ public final class FallbackInitialHandler extends InitialHandler {
private boolean receivedLoginPacket;
private boolean receivedStatusPacket;
private static final @NotNull Fallback FALLBACK = Objects.requireNonNull(Sonar.get().getFallback());
@Override
public void connected(final ChannelWrapper channelWrapper) throws Exception {
this.channelWrapper = channelWrapper;
super.connected(channelWrapper);
// Increase connections per second for the action bar verbose
Counters.CONNECTIONS_PER_SECOND.put(System.nanoTime());
}
@Override
public void handle(final @NotNull Handshake handshake) throws Exception {
// Check if the host is invalid
if (handshake.getHost().isEmpty()) {
throw new CorruptedFrameException("Hostname is empty");
}
super.handle(handshake);
}
@Override
@@ -116,7 +130,7 @@ public final class FallbackInitialHandler extends InitialHandler {
@Override
public void handle(final LoginRequest loginRequest) throws Exception {
// Increase joins per second for the action bar verbose
Sonar.get().getVerboseHandler().getLoginsPerSecond().put(System.nanoTime());
Counters.LOGINS_PER_SECOND.put(System.nanoTime());
// Fix login packet spam exploit
if (receivedLoginPacket || user != null) {
@@ -130,7 +144,12 @@ public final class FallbackInitialHandler extends InitialHandler {
// Run in the channel's event loop
channel.eventLoop().execute(() -> {
// Do not continue if the connection is closed or marked as disconnected
if (channelWrapper.isClosed() || channelWrapper.isClosing()) return;
try {
// Hook the custom traffic pipeline, so we can count the incoming and outgoing traffic
final ChannelPipeline pipeline = channel.pipeline();
TrafficChannelHooker.hook(pipeline, PACKET_DECODER, PACKET_ENCODER);
@@ -179,8 +198,8 @@ public final class FallbackInitialHandler extends InitialHandler {
// Create wrapped Fallback user
user = new FallbackUserWrapper(
FALLBACK, channelWrapper, this,
channel, channel.pipeline(), inetAddress, protocolVersion
FALLBACK, this, channel, channel.pipeline(),
inetAddress, protocolVersion
);
// Perform default BungeeCord checks
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -23,7 +23,6 @@ import io.netty.util.ReferenceCountUtil;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import net.md_5.bungee.netty.ChannelWrapper;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.Fallback;
import xyz.jonesdev.sonar.api.fallback.FallbackUser;
@@ -34,9 +33,8 @@ import java.net.InetAddress;
@Getter
@RequiredArgsConstructor
public final class FallbackUserWrapper implements FallbackUser<ChannelWrapper, FallbackInitialHandler> {
public final class FallbackUserWrapper implements FallbackUser<FallbackInitialHandler> {
private final Fallback fallback;
private final ChannelWrapper player;
private final FallbackInitialHandler connection;
private final Channel channel;
private final ChannelPipeline pipeline;
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -53,7 +53,7 @@ public final class FallbackVerificationHandler implements FallbackPacketListener
// General
private final SystemTimer login = new SystemTimer();
private final @NotNull FallbackUser<?, ?> user;
private final @NotNull FallbackUser<?> user;
private final String username;
private final UUID playerUuid;
private @NotNull State state = State.LOGIN_ACK; // 1.20.2
@@ -87,7 +87,7 @@ public final class FallbackVerificationHandler implements FallbackPacketListener
SUCCESS
}
public FallbackVerificationHandler(final @NotNull FallbackUser<?, ?> user,
public FallbackVerificationHandler(final @NotNull FallbackUser<?> user,
final @NotNull String username,
final @NotNull UUID playerUuid) {
this.user = user;
@@ -212,14 +212,14 @@ public final class FallbackVerificationHandler implements FallbackPacketListener
}
}
private static boolean validateClientLocale(final @SuppressWarnings("unused") @NotNull FallbackUser<?, ?> user,
private static boolean validateClientLocale(final @SuppressWarnings("unused") @NotNull FallbackUser<?> user,
final String locale) {
// Check the client locale by performing a simple regex check on it
final Pattern pattern = Sonar.get().getConfig().getVerification().getValidLocaleRegex();
return pattern.matcher(locale).matches(); // Disallow non-ascii characters (by default)
}
private static boolean validateClientBrand(final @NotNull FallbackUser<?, ?> user, final ByteBuf content) {
private static boolean validateClientBrand(final @NotNull FallbackUser<?> user, final ByteBuf content) {
// We have to catch every DecoderException, so we can fail and punish
// the player instead of only disconnecting them due to an exception.
try {
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -31,11 +31,11 @@ import static xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketRegistry
import static xyz.jonesdev.sonar.common.utility.protocol.VarIntUtil.readVarInt;
public final class FallbackPacketDecoder extends ChannelInboundHandlerAdapter {
private final FallbackUser<?, ?> user;
private final FallbackUser<?> user;
private final FallbackPacketListener listener;
private FallbackPacketRegistry.ProtocolRegistry registry;
public FallbackPacketDecoder(final @NotNull FallbackUser<?, ?> user,
public FallbackPacketDecoder(final @NotNull FallbackUser<?> user,
final @NotNull FallbackPacketListener listener) {
this.user = user;
this.listener = listener;
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -222,7 +222,8 @@ public class MapInfoPreparer {
final int index = y * image.getWidth() + x;
if (pixel == -16777216 && RANDOM.nextInt(100) < 97) continue;
// Set color of pixel to random color from the palette
final byte color = (byte) (pixel == -16777216 ? RANDOM.nextInt(100) < 75 ? 14 : RANDOM.nextInt(Byte.MAX_VALUE)
final byte color = (byte) (pixel == -16777216 ? RANDOM.nextInt(100) < 75 ? 14 :
RANDOM.nextInt(Byte.MAX_VALUE)
: pixel != -65536 ? colorPalette[RANDOM.nextInt(colorPalette.length)]
: nextColorPalette[RANDOM.nextInt(nextColorPalette.length)]);
// Write pixel color to buffer
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -53,7 +53,7 @@ public final class PreparedMapInfo {
this.modern = new MapData(info);
}
public void write(final @NotNull FallbackUser<?, ?> user) {
public void write(final @NotNull FallbackUser<?> user) {
if (user.getProtocolVersion().compareTo(MINECRAFT_1_8) < 0) {
for (final MapData data : legacy) {
user.delayedWrite(data);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Sonar Contributors
* Copyright (C) 2023-2024 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
Loaded 100 of 138 files, more files were not shown because too many files have changed in this diff. Show more