Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UPDATE #2

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.14
1.1.18
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

setGroup("net.elytrium")
setVersion("1.1.14")
setVersion("1.1.19")

compileJava {
getOptions().setEncoding("UTF-8")
Expand All @@ -29,7 +29,7 @@ repositories {
}
maven {
setName("papermc-repo")
setUrl("https://papermc.io/repo/repository/maven-public/")
setUrl("https://repo.papermc.io/repository/maven-public/")
}
maven() {
setName("sonatype-snapshots-repo")
Expand Down
2 changes: 1 addition & 1 deletion config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

<module name="LineLength">
<property name="fileExtensions" value="java"/>
<property name="max" value="155"/>
<property name="max" value="205"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>

Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
limboapiVersion=1.1.14
velocityVersion=3.3.0-SNAPSHOT
limboapiVersion=1.1.27
velocityVersion=3.4.0-SNAPSHOT
nettyVersion=4.1.86.Final
fastutilVersion=8.5.11
log4jVersion=2.19.0
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/net/elytrium/limbofilter/LimboFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,23 @@ public void reload() {
(float) captchaCoords.CAPTCHA_YAW, (float) captchaCoords.CAPTCHA_PITCH
);

// Make LimboAPI preload parent to captcha chunks to ensure that Sodium can properly render captcha.
if (Settings.IMP.MAIN.FRAMED_CAPTCHA.FRAMED_CAPTCHA_ENABLED) {
Settings.MAIN.FRAMED_CAPTCHA settings = Settings.IMP.MAIN.FRAMED_CAPTCHA;
for (int x = 0; x < settings.WIDTH; x++) {
this.filterWorld.getChunkOrNew(settings.COORDS.X + x, settings.COORDS.Z);
}

for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
this.filterWorld.getChunkOrNew(
(int) captchaCoords.CAPTCHA_X + (x * 16),
(int) captchaCoords.CAPTCHA_Z + (z * 16)
);
}
}
}

if (Settings.IMP.MAIN.LOAD_WORLD) {
try {
Path path = this.dataDirectory.resolve(Settings.IMP.MAIN.WORLD_FILE_PATH);
Expand Down Expand Up @@ -279,6 +296,8 @@ public void reload() {
new PacketMapping(0x10, ProtocolVersion.MINECRAFT_1_19_4, false),
new PacketMapping(0x12, ProtocolVersion.MINECRAFT_1_20_2, false),
new PacketMapping(0x13, ProtocolVersion.MINECRAFT_1_20_3, false),
new PacketMapping(0x16, ProtocolVersion.MINECRAFT_1_20_5, false),
new PacketMapping(0x18, ProtocolVersion.MINECRAFT_1_21_2, false),
})
.registerPacket(PacketDirection.CLIENTBOUND, SetEntityMetadata.class, SetEntityMetadata::new, new PacketMapping[]{
new PacketMapping(0x1C, ProtocolVersion.MINIMUM_VERSION, true),
Expand All @@ -294,6 +313,8 @@ public void reload() {
new PacketMapping(0x52, ProtocolVersion.MINECRAFT_1_19_4, true),
new PacketMapping(0x54, ProtocolVersion.MINECRAFT_1_20_2, true),
new PacketMapping(0x56, ProtocolVersion.MINECRAFT_1_20_3, true),
new PacketMapping(0x58, ProtocolVersion.MINECRAFT_1_20_5, true),
new PacketMapping(0x5D, ProtocolVersion.MINECRAFT_1_21_2, true),
})
.registerPacket(PacketDirection.CLIENTBOUND, SpawnEntity.class, SpawnEntity::new, new PacketMapping[]{
new PacketMapping(0x0E, ProtocolVersion.MINIMUM_VERSION, true),
Expand Down Expand Up @@ -379,6 +400,10 @@ public boolean shouldCheck(Player player) {
return false;
}

if (player.getRemoteAddress().getPort() == 0 && !this.checkCpsLimit(Settings.IMP.MAIN.FILTER_AUTO_TOGGLE.GEYSER_BYPASS)) {
return false;
}

return this.shouldCheck(player.getUsername(), player.getRemoteAddress().getAddress());
}

Expand Down
31 changes: 20 additions & 11 deletions src/main/java/net/elytrium/limbofilter/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static class MAIN {
public boolean CHECK_CLIENT_SETTINGS = true;
@Comment("Check if player's Minecraft client has a brand.")
public boolean CHECK_CLIENT_BRAND = true;
@Comment("If player's Minecraft client brand (e.g. fabric or forge) is set here, then this player will be kicked.")
@Comment("If a player's Minecraft client brand (e.g., fabric or forge) is set here, then that player will be kicked.")
public List<String> BLOCKED_CLIENT_BRANDS = List.of("brand1", "brand2");
@Comment("Time in milliseconds, how frequently will the cache list with verified players be reset. Before that time, verified players can join the server without passing antibot checks.")
public long PURGE_CACHE_MILLIS = 3600000;
Expand Down Expand Up @@ -98,7 +98,7 @@ public static class MAIN {

public boolean LOAD_WORLD = false;
@Comment({
"World file type:",
"World file types:",
" SCHEMATIC (MCEdit .schematic, 1.12.2 and lower, not recommended)",
" STRUCTURE (structure block .nbt, any Minecraft version is supported, but the latest one is recommended).",
" WORLDEDIT_SCHEM (WorldEdit .schem, any Minecraft version is supported, but the latest one is recommended)."
Expand All @@ -118,7 +118,13 @@ public static class MAIN {
@Comment("Available: ADVENTURE, CREATIVE, SURVIVAL, SPECTATOR")
public GameMode GAME_MODE = GameMode.ADVENTURE;

@Comment("Unit of time in seconds for the Auto Toggles the Statistics.")
@Comment({
"Should we prevent the player from falling after passing the fall check, or after they join the game when the ONLY_CAPTCHA mode is enabled",
"This might be useful when using a world schema to allow players to walk in that world"
})
public boolean DISABLE_FALLING_ON_CAPTCHA = true;

@Comment("Unit of time in seconds for the Auto Toggles and Statistics.")
public int UNIT_OF_TIME_CPS = 300;

@Comment("Unit of time in seconds for the Auto Toggles and the Statistics.")
Expand Down Expand Up @@ -170,6 +176,9 @@ public static class FILTER_AUTO_TOGGLE {
})
public int ONLINE_MODE_BYPASS = 49;

@Comment("Geyser players will bypass all anti-bot checks.")
public int GEYSER_BYPASS = 0;

@Comment({
"Verify Online Mode connection before AntiBot.",
"If connections per unit of time amount is bigger than the limit: online mode players will need to reconnect.",
Expand All @@ -186,7 +195,7 @@ public static class FILTER_AUTO_TOGGLE {
})
public int CHECK_STATE_TOGGLE = 0;

@Comment("The player will need to reconnect after passing AntiBot check.")
@Comment("The player will need to reconnect after passing the AntiBot check.")
public int NEED_TO_RECONNECT = 129;

@Comment("Picture in the MOTD Server Ping packet will be disabled.")
Expand Down Expand Up @@ -251,7 +260,7 @@ public static class CAPTCHA_GENERATOR {
public boolean NUMBER_SPELLING = false;
@Comment({
"Set to true if you want to verify the number spelling configuration.",
"The results will be saved to the number_spelling.txt file."
"Results will be saved to the number_spelling.txt file."
})
public boolean SAVE_NUMBER_SPELLING_OUTPUT = false;
public boolean EACH_WORD_ON_SEPARATE_LINE = true;
Expand Down Expand Up @@ -424,26 +433,26 @@ public static class STRINGS {
public String CHECKING_SUBTITLE = "&aPlease wait..";

public String CHECKING_CAPTCHA_CHAT = "{PRFX} &aPlease, solve the captcha, you have &6{0} &aattempts.";
public String CHECKING_WRONG_CAPTCHA_CHAT = "{PRFX} &cYou entered the captcha incorrectly, you have &6{0} &cattempts left.";
public String CHECKING_WRONG_CAPTCHA_CHAT = "{PRFX} &cYou have entered the captcha incorrectly, you have &6{0} &cattempts left.";
public String CHECKING_CAPTCHA_TITLE = "&aPlease solve the captcha.";
public String CHECKING_CAPTCHA_SUBTITLE = "&aYou have &6{0} &aattempts.";

public String SUCCESSFUL_CRACKED = "{PRFX} &aSuccessfully passed Bot-Filter check.";
public String SUCCESSFUL_CRACKED = "{PRFX} &aSuccessfully passed the Bot-Filter check.";
public String SUCCESSFUL_PREMIUM_KICK = "{PRFX}{NL}&aSuccessfully passed Bot-Filter check.{NL}&6Please, rejoin the server!";

public String CAPTCHA_FAILED_KICK = "{PRFX}{NL}&cYou've mistaken in captcha check.{NL}&6Please, rejoin the server.";
public String FALLING_CHECK_FAILED_KICK = "{PRFX}{NL}&cFalling Check was failed.{NL}&6Please, rejoin the server.";
public String TIMES_UP = "{PRFX}{NL}&cYou have exceeded the maximum Bot-Filter check time.{NL}&6Please, rejoin the server.";

public String STATS_FORMAT = "&c&lTotal Blocked: &6&l{0} &c&l| Connections: &6&l{1}s &c&l| Pings: &6&l{2}s &c&l| Total Connections: &6&l{3} &c&l| L7 Ping: &6&l{4} &c&l| L4 Ping: &6&l{5}";
public String STATS_ENABLED = "{PRFX} &aNow you see statistics in your action bar.";
public String STATS_DISABLED = "{PRFX} &cYou're no longer see statistics in your action bar.";
public String STATS_ENABLED = "{PRFX} &aNow you may see statistics in your action bar.";
public String STATS_DISABLED = "{PRFX} &cYou can no longer see statistics in your action bar.";

public String SEND_PLAYER_SUCCESSFUL = "{PRFX} Successfully sent {0} to the filter limbo.";
public String SEND_SERVER_SUCCESSFUL = "{PRFX} Successfully sent {0} players from {1} to the filter limbo.";
public String SEND_SERVER_SUCCESSFUL = "{PRFX} Successfully sent {0} players from {1} to filter limbo.";
public String SEND_FAILED = "{PRFX} There is no registered servers or connected players named {0}.";

public String CAPTCHA_NOT_READY_YET = "{PRFX} Captcha is not ready yet. Try again in a few seconds";
public String CAPTCHA_NOT_READY_YET = "{PRFX} The captcha is not ready yet. Try again in a few seconds.";
}
}
}
56 changes: 41 additions & 15 deletions src/main/java/net/elytrium/limbofilter/cache/CachedPackets.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.protocol.StateRegistry;
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
import com.velocitypowered.proxy.protocol.packet.chat.ChatType;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import com.velocitypowered.proxy.protocol.packet.chat.SystemChat;
import com.velocitypowered.proxy.protocol.packet.chat.legacy.LegacyChat;
import com.velocitypowered.proxy.protocol.packet.chat.SystemChatPacket;
import com.velocitypowered.proxy.protocol.packet.chat.legacy.LegacyChatPacket;
import com.velocitypowered.proxy.protocol.packet.title.GenericTitlePacket;
import java.text.MessageFormat;
import java.util.UUID;
Expand All @@ -35,6 +36,7 @@
import net.elytrium.limboapi.api.material.Item;
import net.elytrium.limboapi.api.material.VirtualItem;
import net.elytrium.limboapi.api.protocol.PreparedPacket;
import net.elytrium.limboapi.api.protocol.item.ItemComponentMap;
import net.elytrium.limboapi.api.protocol.packets.PacketFactory;
import net.elytrium.limbofilter.LimboFilter;
import net.elytrium.limbofilter.Settings;
Expand All @@ -58,6 +60,7 @@ public class CachedPackets {
private PreparedPacket kickProxyCheck;
private PreparedPacket successfulBotFilterChat;
private PreparedPacket successfulBotFilterDisconnect;
private PreparedPacket fallingCheckChunkUnload;
private PreparedPacket noAbilities;
private PreparedPacket[] experience;
private PreparedPacket captchaNotReadyYet;
Expand Down Expand Up @@ -97,6 +100,7 @@ public void createPackets(LimboFactory limboFactory, PacketFactory packetFactory

this.successfulBotFilterDisconnect = this.createDisconnectPacket(limboFactory, strings.SUCCESSFUL_PREMIUM_KICK);

this.fallingCheckChunkUnload = this.createFallingCheckChunkUnloadPacket(limboFactory, packetFactory);
this.noAbilities = this.createAbilitiesPacket(limboFactory, packetFactory);
this.experience = this.createExpPackets(limboFactory, packetFactory);

Expand Down Expand Up @@ -169,7 +173,12 @@ private PreparedPacket[] createCaptchaAttemptsPacket(LimboFactory limboFactory,
this.createSetSlotPacketModern(
packetFactory, limboFactory.getItem(Item.FILLED_MAP), 1,
CompoundBinaryTag.builder().put("map", IntBinaryTag.intBinaryTag(0)).build()
), ProtocolVersion.MINECRAFT_1_17
), ProtocolVersion.MINECRAFT_1_17, ProtocolVersion.MINECRAFT_1_20_3
).prepare(
this.createSetSlotPacketComponent(
packetFactory, limboFactory.getItem(Item.FILLED_MAP), 1,
limboFactory.createItemComponentMap().add(ProtocolVersion.MINECRAFT_1_20_5, "minecraft:map_id", 0)
), ProtocolVersion.MINECRAFT_1_20_5
);
}
packets[i] = packet.build();
Expand All @@ -190,7 +199,12 @@ private PreparedPacket[] createCaptchaAttemptsPacket(LimboFactory limboFactory,
this.createSetSlotPacketModern(
packetFactory, limboFactory.getItem(Item.FILLED_MAP), 1,
CompoundBinaryTag.builder().put("map", IntBinaryTag.intBinaryTag(0)).build()
), ProtocolVersion.MINECRAFT_1_17
), ProtocolVersion.MINECRAFT_1_17, ProtocolVersion.MINECRAFT_1_20_3
).prepare(
this.createSetSlotPacketComponent(
packetFactory, limboFactory.getItem(Item.FILLED_MAP), 1,
limboFactory.createItemComponentMap().add(ProtocolVersion.MINECRAFT_1_20_5, "minecraft:map_id", 0)
), ProtocolVersion.MINECRAFT_1_20_5
);
}
packets[Settings.IMP.MAIN.CAPTCHA_ATTEMPTS].build();
Expand Down Expand Up @@ -294,18 +308,21 @@ private MinecraftPacket createUpdateViewPosition(PacketFactory factory, int x, i
return (MinecraftPacket) factory.createUpdateViewPositionPacket(x >> 4, z >> 4);
}

private PreparedPacket createFallingCheckChunkUnloadPacket(LimboFactory limboFactory, PacketFactory packetFactory) {
Settings.MAIN.FALLING_COORDS coords = Settings.IMP.MAIN.FALLING_COORDS;
return limboFactory.createPreparedPacket().prepare(packetFactory.createChunkUnloadPacket(coords.X >> 4, coords.Z >> 4), ProtocolVersion.MINECRAFT_1_21_2).build();
}

private PreparedPacket createAbilitiesPacket(LimboFactory limboFactory, PacketFactory packetFactory) {
return limboFactory.createPreparedPacket().prepare(packetFactory.createPlayerAbilitiesPacket((byte) 6, 0f, 0f)).build();
}

private PreparedPacket[] createExpPackets(LimboFactory limboFactory, PacketFactory packetFactory) {
int ticks = Settings.IMP.MAIN.FALLING_CHECK_TICKS;
PreparedPacket[] packets = new PreparedPacket[ticks];
float expInterval = 0.01F;
final int ticksM1 = ticks - 1;
for (int i = 0; i < ticks; ++i) {
int percentage = i * 100 / ticks;
packets[i] =
limboFactory.createPreparedPacket().prepare(packetFactory.createSetExperiencePacket(percentage * expInterval, percentage, 0)).build();
packets[i] = limboFactory.createPreparedPacket().prepare(packetFactory.createSetExperiencePacket((float) i / ticksM1, (i * 100) / ticksM1, 0)).build();
}

return packets;
Expand All @@ -319,25 +336,30 @@ private MinecraftPacket createSetSlotPacketModern(PacketFactory packetFactory, V
return (MinecraftPacket) packetFactory.createSetSlotPacket(0, Settings.IMP.MAIN.CAPTCHA_LEFT_HAND ? 45 : 36, item, count, 0, nbt);
}

private MinecraftPacket createSetSlotPacketComponent(PacketFactory packetFactory, VirtualItem item, int count, ItemComponentMap map) {
return (MinecraftPacket) packetFactory.createSetSlotPacket(0, Settings.IMP.MAIN.CAPTCHA_LEFT_HAND ? 45 : 36, item, count, 0, map);
}

public void createChatPacket(PreparedPacket packet, String text) {
packet
.prepare(new LegacyChat(
.prepare(new LegacyChatPacket(
ProtocolUtils.getJsonChatSerializer(ProtocolVersion.MINIMUM_VERSION).serialize(
LimboFilter.getSerializer().deserialize(text)
), LegacyChat.CHAT_TYPE, null
), LegacyChatPacket.CHAT_TYPE, null
), ProtocolVersion.MINIMUM_VERSION, ProtocolVersion.MINECRAFT_1_15_2)
.prepare(new LegacyChat(
.prepare(new LegacyChatPacket(
ProtocolUtils.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_16).serialize(
LimboFilter.getSerializer().deserialize(text)
), LegacyChat.CHAT_TYPE, null
), LegacyChatPacket.CHAT_TYPE, null
), ProtocolVersion.MINECRAFT_1_16, ProtocolVersion.MINECRAFT_1_18_2)
.prepare(version -> new SystemChat(
.prepare(version -> new SystemChatPacket(
new ComponentHolder(version, LimboFilter.getSerializer().deserialize(text)), ChatType.SYSTEM
), ProtocolVersion.MINECRAFT_1_19);
}

private PreparedPacket createDisconnectPacket(LimboFactory factory, String message) {
return factory.createPreparedPacket().prepare(version -> Disconnect.create(LimboFilter.getSerializer().deserialize(message), version, false)).build();
return factory.createPreparedPacket().prepare(version ->
DisconnectPacket.create(LimboFilter.getSerializer().deserialize(message), version, StateRegistry.PLAY)).build();
}

public void createTitlePacket(PreparedPacket preparedPacket, String title, String subtitle) {
Expand Down Expand Up @@ -402,6 +424,10 @@ public PreparedPacket getSuccessfulBotFilterDisconnect() {
return this.successfulBotFilterDisconnect;
}

public PreparedPacket getFallingCheckChunkUnload() {
return this.fallingCheckChunkUnload;
}

public PreparedPacket getNoAbilities() {
return this.noAbilities;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.proxy.protocol.packet.ClientSettings;
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -191,9 +191,9 @@ public void onMove(double x, double y, double z) {
this.fallingCheckFailed("Non-valid X, Z or Velocity");
return;
}
PreparedPacket expBuf = this.plugin.getPackets().getExperience(this.ticks);
if (expBuf != null) {
this.player.writePacketAndFlush(expBuf);
PreparedPacket experience = this.plugin.getPackets().getExperience(this.ticks);
if (experience != null) {
this.player.writePacketAndFlush(experience);
}

++this.ticks;
Expand Down Expand Up @@ -272,16 +272,16 @@ private boolean equalsCaptchaAnswer(String message) {

@Override
public void onGeneric(Object packet) {
if (packet instanceof PluginMessage) {
PluginMessage pluginMessage = (PluginMessage) packet;
if (packet instanceof PluginMessagePacket) {
PluginMessagePacket pluginMessage = (PluginMessagePacket) packet;
if (PluginMessageUtil.isMcBrand(pluginMessage) && !this.checkedByBrand) {
String brand = PluginMessageUtil.readBrandMessage(pluginMessage.content());
LimboFilter.getLogger().info("{} has client brand {}", this.proxyPlayer, brand);
if (!Settings.IMP.MAIN.BLOCKED_CLIENT_BRANDS.contains(brand)) {
this.checkedByBrand = true;
}
}
} else if (packet instanceof ClientSettings) {
} else if (packet instanceof ClientSettingsPacket) {
if (Settings.IMP.MAIN.CHECK_CLIENT_SETTINGS && !this.checkedBySettings) {
this.checkedBySettings = true;
}
Expand Down Expand Up @@ -366,9 +366,15 @@ private boolean checkPing() {
}

private void changeStateToCaptcha() {
if (this.state != CheckState.ONLY_CAPTCHA && this.version.noLessThan(ProtocolVersion.MINECRAFT_1_21_2)) {
this.player.writePacket(this.plugin.getPackets().getFallingCheckChunkUnload());
}

this.state = CheckState.ONLY_CAPTCHA;
this.server.respawnPlayer(this.proxyPlayer);
this.player.writePacketAndFlush(this.plugin.getPackets().getNoAbilities());
if (Settings.IMP.MAIN.DISABLE_FALLING_ON_CAPTCHA) {
this.player.writePacketAndFlush(this.plugin.getPackets().getNoAbilities());
}

this.waitingTeleportId = this.validTeleportId;
if (this.captchaAnswer == null) {
Expand Down
Loading