From ed57b22b9bae1cabd74f9dd91ebe83389d6223ee Mon Sep 17 00:00:00 2001 From: Juan Cruz Linsalata Date: Mon, 12 Oct 2020 15:40:53 -0300 Subject: [PATCH] FlameCord General Patch diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/FlameCord.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/FlameCord.java new file mode 100644 index 00000000..fd889644 --- /dev/null +++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/FlameCord.java @@ -0,0 +1,68 @@ +package dev._2lstudios.flamecord; + +import java.util.Collection; +import java.util.logging.Logger; + +import dev._2lstudios.flamecord.configuration.FlameCordConfiguration; +import dev._2lstudios.flamecord.configuration.MessagesConfiguration; +import dev._2lstudios.flamecord.configuration.ModulesConfiguration; +import dev._2lstudios.flamecord.firewall.FirewallManager; +import lombok.Getter; +import net.md_5.bungee.config.ConfigurationProvider; +import net.md_5.bungee.config.YamlConfiguration; + +public class FlameCord { + @Getter + private static FlameCord instance; + @Getter + private final FirewallManager firewallManager; + @Getter + private final FlameCordConfiguration flameCordConfiguration; + @Getter + private final ModulesConfiguration modulesConfiguration; + @Getter + private final MessagesConfiguration messagesConfiguration; + @Getter + private final Thread thread; + private boolean running = true; + + public static void renew(final Logger logger, final Collection whitelistedAddresses) { + if (FlameCord.instance != null) { + FlameCord.instance.running = false; + } + + final FlameCord instance = new FlameCord(logger, whitelistedAddresses); + + FlameCord.instance = instance; + } + + private FlameCord(final Logger logger, final Collection whitelistedAddresses) { + final ConfigurationProvider configurationProvider = ConfigurationProvider.getProvider(YamlConfiguration.class); + + this.flameCordConfiguration = new FlameCordConfiguration(configurationProvider); + this.firewallManager = new FirewallManager(logger, whitelistedAddresses, + flameCordConfiguration.getFirewallSeconds()); + this.modulesConfiguration = new ModulesConfiguration(configurationProvider); + this.messagesConfiguration = new MessagesConfiguration(logger, configurationProvider); + this.thread = new Thread() { + @Override + public void run() { + while (running) { + try { + sleep(1000L); + + if (!running) { + return; + } + + firewallManager.tick(); + } catch (final Exception e) { + // Ignored + } + } + } + }; + + this.thread.start(); + } +} \ No newline at end of file diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java new file mode 100644 index 00000000..b7268e1d --- /dev/null +++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java @@ -0,0 +1,81 @@ +package dev._2lstudios.flamecord.configuration; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; + +import lombok.Getter; +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.config.ConfigurationProvider; + +public class FlameCordConfiguration { + @Getter + private boolean loggerInitialhandler = false, loggerExceptions = false, loggerDump = false, firewallNotify = true, + firewallEnabled = true; + @Getter + private int firewallSeconds = 60; + @Getter + private Collection firewallNames = new HashSet<>(Arrays.asList(new String[] { "mcspam" })); + + public FlameCordConfiguration(final ConfigurationProvider configurationProvider) { + try { + final String fileName = "./flamecord.yml"; + final File configurationFile = new File(fileName); + final Configuration configuration; + final boolean configurationExists = configurationFile.exists(); + + if (!configurationExists) { + configuration = new Configuration(); + } else { + configuration = configurationProvider.load(configurationFile); + } + + this.loggerInitialhandler = setIfUnexistant("logger.initialhandler", this.loggerInitialhandler, + configuration); + this.loggerExceptions = setIfUnexistant("logger.exceptions", this.loggerExceptions, configuration); + this.loggerDump = setIfUnexistant("logger.dump", this.loggerDump, configuration); + this.firewallEnabled = setIfUnexistant("firewall.enabled", this.firewallEnabled, configuration); + this.firewallNotify = setIfUnexistant("firewall.notify", this.firewallNotify, configuration); + this.firewallSeconds = setIfUnexistant("firewall.seconds", this.firewallSeconds, configuration); + this.firewallNames = setIfUnexistant("firewall.names", this.firewallNames, configuration); + + if (!configurationExists) { + configurationProvider.save(configuration, configurationFile); + } + } catch (final IOException e) { + e.printStackTrace(); + } + } + + private int setIfUnexistant(final String arg1, final int arg2, final Configuration configuration) { + return (int) setIfUnexistant(arg1, (Object) arg2, configuration); + } + + private boolean setIfUnexistant(final String arg1, final boolean arg2, final Configuration configuration) { + return (boolean) setIfUnexistant(arg1, (Object) arg2, configuration); + } + + private Object setIfUnexistant(final String arg1, final Object arg2, final Configuration configuration) { + if (!configuration.contains(arg1)) { + configuration.set(arg1, arg2); + + return arg2; + } else { + return configuration.get(arg1); + } + } + + private Collection setIfUnexistant(final String arg1, final Collection arg2, + final Configuration configuration) { + if (!configuration.contains(arg1)) { + configuration.set(arg1, new ArrayList<>(arg2)); + + return arg2; + } else { + return new HashSet<>(configuration.getStringList(arg1)); + } + } +} diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java new file mode 100644 index 00000000..c88077ad --- /dev/null +++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java @@ -0,0 +1,129 @@ +package dev._2lstudios.flamecord.configuration; + +import java.io.File; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.config.ConfigurationProvider; + +public class MessagesConfiguration { + private final Logger logger; + private final Map messages = new HashMap<>(); + + public MessagesConfiguration(final Logger logger, final ConfigurationProvider configurationProvider) { + this.logger = logger; + + try { + final String fileName = "./messages.yml"; + final File configurationFile = new File(fileName); + final Configuration configuration; + final boolean configurationExists = configurationFile.exists(); + + if (!configurationExists) { + configuration = new Configuration(); + } else { + configuration = configurationProvider.load(configurationFile); + } + + // BungeeCord + setIfUnexistant("alert", "&8[&4Alert&8]&r ", configuration); + setIfUnexistant("already_connected", "&cYou are already connected to this server!", configuration); + setIfUnexistant("already_connected_proxy", "&cYou are already connected to this proxy!", configuration); + setIfUnexistant("already_connecting", "&cAlready connecting to this server!", configuration); + setIfUnexistant("command_list", "&a[{0}] &e({1}): &r{2}", configuration); + setIfUnexistant("connect_kick", "&cKicked whilst connecting to {0}: {1}", configuration); + setIfUnexistant("current_server", "&6You are currently connected to {0}.", configuration); + setIfUnexistant("fallback_kick", + "&cCould not connect to a default or fallback server, please try again later: {0}", configuration); + setIfUnexistant("fallback_lobby", + "&cCould not connect to target server, you have been moved to a fallback server.", configuration); + setIfUnexistant("lost_connection", "[Proxy] Lost connection to server.", configuration); + setIfUnexistant("mojang_fail", "Error occurred while contacting login servers, are they down?", + configuration); + setIfUnexistant("no_permission", "&cYou do not have permission to execute this command!", configuration); + setIfUnexistant("no_server", "&cThe specified server does not exist.", configuration); + setIfUnexistant("no_server_permission", "&cYou don't have permission to access this server.", + configuration); + setIfUnexistant("outdated_client", "Outdated client! Please use {0}", configuration); + setIfUnexistant("outdated_server", "Outdated server! I'm still on {0}", configuration); + setIfUnexistant("proxy_full", "Server is full!", configuration); + setIfUnexistant("restart", "[Proxy] Proxy restarting.", configuration); + setIfUnexistant("server_kick", "[Kicked] ", configuration); + setIfUnexistant("server_list", "&6You may connect to the following servers at this time: ", configuration); + setIfUnexistant("server_went_down", + "&cThe server you were previously on went down, you have been connected to a fallback server", + configuration); + setIfUnexistant("total_players", "Total players online: {0}", configuration); + setIfUnexistant("name_too_long", "Cannot have username longer than 16 characters", configuration); + setIfUnexistant("name_invalid", "Username contains invalid characters.", configuration); + setIfUnexistant("ping_cannot_connect", "&c[Bungee] Can't connect to server.", configuration); + setIfUnexistant("offline_mode_player", "Not authenticated with Minecraft.net", configuration); + setIfUnexistant("message_needed", "&cYou must supply a message.", configuration); + setIfUnexistant("error_occurred_player", + "&cAn error occurred while parsing your message. (Hover for details)", configuration); + setIfUnexistant("error_occurred_console", "&cAn error occurred while parsing your message: {0}", + configuration); + setIfUnexistant("click_to_connect", "Click to connect to the server", configuration); + setIfUnexistant("username_needed", "&cPlease follow this command by a user name.", configuration); + setIfUnexistant("user_not_online", "&cThat user is not online.", configuration); + setIfUnexistant("user_online_at", "&a{0} &ris online at {1}", configuration); + setIfUnexistant("send_cmd_usage", + "&cNot enough arguments, usage: /send ", configuration); + setIfUnexistant("player_only", "&cOnly in game players can use this command", configuration); + setIfUnexistant("successfully_summoned", "&aSuccessfully summoned player(s)", configuration); + setIfUnexistant("you_got_summoned", "&6Summoned to {0} by {1}", configuration); + setIfUnexistant("command_perms_groups", "&6You have the following groups: {0}", configuration); + setIfUnexistant("command_perms_permission", "&9- {0}", configuration); + setIfUnexistant("command_ip", "&9IP of {0} is {1}", configuration); + + // FlameCord + setIfUnexistant("firewall_added", "&e{0}&c had been firewalled from the proxy!", configuration); + setIfUnexistant("firewall_blocked", "&e{0}&c is firewalled from the proxy, request blocked!", + configuration); + setIfUnexistant("firewall_info", + "&aThere are&b {0} &aaddresses firewalled!\n&aThe firewall will clear in &b{1} &aseconds!", + configuration); + setIfUnexistant("firewall_cleared", "&b{0}&a addresses had been automatically removed from the firewall!", + configuration); + setIfUnexistant("flamecord_reload", "&aAll files had been successfully reloaded!", configuration); + setIfUnexistant("flamecord_help", + "&aFlameCord&b {0}&a by&b LinsaFTW&a &&b Sammwy&r\n&e /flamecord reload&7 >&b Reloads FlameCord files!\n&e /flamecord firewall&7 >&b Shows information about the Firewall!\n&e /flamecord help&7 >&b Shows this message!", + configuration); + setIfUnexistant("flamecord_nopermission", "&cYou don't have permission to do this!", configuration); + + if (!configurationExists) { + configurationProvider.save(configuration, configurationFile); + } + + for (final String key : configuration.getKeys()) { + final Object value = configuration.get(key); + + if (value instanceof String) { + this.messages.put(key, ChatColor.translateAlternateColorCodes('&', (String) value)); + } + } + } catch (final IOException e) { + e.printStackTrace(); + } + } + + public String getTranslation(final String name, final Object... args) { + if (!messages.containsKey(name)) { + logger.warning("[FlameCord] Tried to get translation '" + name + + "' from messages.yml file but wasn't found. Please try resetting this file or report to a developer."); + } + + return MessageFormat.format(messages.getOrDefault(name, ""), args); + } + + private void setIfUnexistant(final String arg1, final Object arg2, final Configuration configuration) { + if (!configuration.contains(arg1)) { + configuration.set(arg1, arg2); + } + } +} \ No newline at end of file diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/ModulesConfiguration.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/ModulesConfiguration.java new file mode 100644 index 00000000..e82c4844 --- /dev/null +++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/ModulesConfiguration.java @@ -0,0 +1,94 @@ +package dev._2lstudios.flamecord.configuration; + +import java.io.File; +import java.io.IOException; + +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.config.ConfigurationProvider; + +public class ModulesConfiguration { + // Reconnect Module + public boolean reconnectEnabled = false; + + // Alert Module + public boolean alertEnabled = true; + + // Find Module + public boolean findEnabled = true; + + // IP Module + public boolean ipEnabled = true; + + // List Module + public boolean listEnabled = true; + + // Perms Module + public boolean permsEnabled = true; + + // Reload Module + public boolean reloadEnabled = true; + + // Send Module + public boolean sendEnabled = true; + + // Server + public boolean serverEnabled = true; + + public ModulesConfiguration(final ConfigurationProvider configurationProvider) { + try { + final String fileName = "./modules.yml"; + final File configurationFile = new File(fileName); + final Configuration configuration; + final boolean configurationExists = configurationFile.exists(); + + if (!configurationExists) { + configuration = new Configuration(); + } else { + configuration = configurationProvider.load(configurationFile); + } + + this.alertEnabled = setIfUnexistant("alert.enabled", this.alertEnabled, configuration); + + this.findEnabled = setIfUnexistant("find.enabled", this.findEnabled, configuration); + + this.ipEnabled = setIfUnexistant("ip.enabled", this.ipEnabled, configuration); + + this.listEnabled = setIfUnexistant("list.enabled", this.listEnabled, configuration); + + this.permsEnabled = setIfUnexistant("perms.enabled", this.permsEnabled, configuration); + + this.reloadEnabled = setIfUnexistant("reload.enabled", this.reloadEnabled, configuration); + + this.sendEnabled = setIfUnexistant("send.enabled", this.sendEnabled, configuration); + + this.serverEnabled = setIfUnexistant("server.enabled", this.serverEnabled, configuration); + + this.reconnectEnabled = setIfUnexistant("reconnect.enabled", this.reconnectEnabled, + configuration); + + if (!configurationExists) { + configurationProvider.save(configuration, configurationFile); + } + } catch (final IOException e) { + e.printStackTrace(); + } + } + + private String setIfUnexistant(final String arg1, final String arg2, final Configuration configuration) { + return (String) setIfUnexistant(arg1, (Object) arg2, configuration); + } + + private boolean setIfUnexistant(final String arg1, final boolean arg2, final Configuration configuration) { + return (boolean) setIfUnexistant(arg1, (Object) arg2, configuration); + } + + private Object setIfUnexistant(final String arg1, final Object arg2, final Configuration configuration) { + if (!configuration.contains(arg1)) { + configuration.set(arg1, arg2); + + return arg2; + } else { + return configuration.get(arg1); + } + } +} diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallException.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallException.java new file mode 100644 index 00000000..6a661898 --- /dev/null +++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallException.java @@ -0,0 +1,30 @@ +package dev._2lstudios.flamecord.firewall; + +import java.net.SocketAddress; + +public class FirewallException extends Exception { + private static final long serialVersionUID = 1L; + + public FirewallException(final SocketAddress address) { + super("The address " + address + " is blocked from the server!"); + } + + public FirewallException(final String string) { + super(string); + } + + public FirewallException(final String string, final Throwable throwable) { + super(string, throwable); + } + + @Override + public synchronized Throwable initCause(final Throwable cause) + { + return this; + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} \ No newline at end of file diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallManager.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallManager.java new file mode 100644 index 00000000..8a474758 --- /dev/null +++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallManager.java @@ -0,0 +1,116 @@ +package dev._2lstudios.flamecord.firewall; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Collection; +import java.util.HashSet; +import java.util.logging.Logger; + +import dev._2lstudios.flamecord.FlameCord; +import dev._2lstudios.flamecord.configuration.FlameCordConfiguration; +import lombok.Getter; + +public class FirewallManager { + private final Logger logger; + private final Collection whitelistedAddresses; + private final Collection firewalled; + private final int defaultSeconds; + @Getter + private int seconds; + + public FirewallManager(final Logger logger, final Collection whitelistedAddresses, + final int defaultSeconds) { + this.logger = logger; + this.whitelistedAddresses = whitelistedAddresses; + this.firewalled = new HashSet<>(); + this.defaultSeconds = defaultSeconds; + this.seconds = defaultSeconds; + } + + public boolean isWhitelisted(final SocketAddress address) { + final String addressString = address.toString(); + + for (final String whitelistedAddressString : whitelistedAddresses) { + if (addressString.endsWith(whitelistedAddressString)) { + return true; + } + } + + return false; + } + + public void addFirewalled(final SocketAddress address) { + if (FlameCord.getInstance().getFlameCordConfiguration().isFirewallEnabled() && !isWhitelisted(address)) { + final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address; + final String hostString = iNetSocketAddress.getHostString(); + + if (!this.firewalled.contains(hostString)) { + this.firewalled.add(hostString); + logAdded(address); + } + } + } + + public void logAdded(final SocketAddress address) { + final FlameCord flameCord = FlameCord.getInstance(); + final FlameCordConfiguration flameCordConfiguration = flameCord.getFlameCordConfiguration(); + + if (flameCordConfiguration.isFirewallNotify()) { + final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address; + final String hostString = iNetSocketAddress.getHostString(); + + this.logger.info(flameCord.getMessagesConfiguration().getTranslation("firewall_added", hostString)); + } + } + + public void logBlocked(final SocketAddress address) { + final FlameCord flameCord = FlameCord.getInstance(); + final FlameCordConfiguration flameCordConfiguration = flameCord.getFlameCordConfiguration(); + + if (flameCordConfiguration.isFirewallNotify()) { + final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address; + final String hostString = iNetSocketAddress.getHostString(); + + this.logger.info(flameCord.getMessagesConfiguration().getTranslation("firewall_blocked", hostString)); + } + } + + public Collection getFirewalled() { + return this.firewalled; + } + + public boolean isFirewalled(final SocketAddress address) { + final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address; + + return this.firewalled.contains(iNetSocketAddress.getHostString()); + } + + public boolean isFirewalled(final String name) { + final String nameLowerCase = name.toLowerCase(); + + for (final String string : FlameCord.getInstance().getFlameCordConfiguration().getFirewallNames()) { + if (nameLowerCase.contains(string)) { + return true; + } + } + + return false; + } + + public void tick() { + if (--seconds <= 0) { + final FlameCord flameCord = FlameCord.getInstance(); + final int size = this.firewalled.size(); + + if (size > 0) { + if (flameCord.getFlameCordConfiguration().isFirewallNotify()) { + this.logger.info(flameCord.getMessagesConfiguration().getTranslation("firewall_cleared", size)); + } + + this.firewalled.clear(); + } + + this.seconds = defaultSeconds; + } + } +} \ No newline at end of file diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java index d4729244..dd089abd 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol; +import dev._2lstudios.flamecord.FlameCord; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandlerContext; @@ -102,7 +103,14 @@ public class MinecraftDecoder extends MessageToMessageDecoder } else { packetTypeStr = "unknown"; } - throw new FastDecoderException("Error decoding packet " + packetTypeStr + " with contents:\n" + ByteBufUtil.prettyHexDump(slice), e); // Waterfall + + // FlameCord - Toggle Dumping packet info + // FlameCord - Change from FastDecoderException to DecoderException + if (FlameCord.getInstance().getFlameCordConfiguration().isLoggerDump()) { + throw new FastDecoderException( "Error decoding packet " + packetTypeStr + " with contents:\n" + ByteBufUtil.prettyHexDump(slice), e ); // Waterfall + } else { + throw new FastDecoderException( "Error decoding packet " + packetTypeStr, e ); + } } finally { if ( slice != null ) diff --git a/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java b/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java new file mode 100644 index 00000000..fa0b59c2 --- /dev/null +++ b/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java @@ -0,0 +1,71 @@ +package dev._2lstudios.flamecord.commands; + +import java.util.Collection; +import java.util.HashSet; + +import dev._2lstudios.flamecord.FlameCord; +import dev._2lstudios.flamecord.configuration.MessagesConfiguration; +import dev._2lstudios.flamecord.firewall.FirewallManager; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.plugin.Command; + +public class FlameCordCommand extends Command { +private final BungeeCord bungeeCord; + + public FlameCordCommand(final BungeeCord bungeeCord) { + super("flamecord"); + + this.bungeeCord = bungeeCord; + } + + @Override + public void execute(final CommandSender sender, final String[] args) { + final FlameCord flameCord = FlameCord.getInstance(); + final MessagesConfiguration messagesConfiguration = flameCord.getMessagesConfiguration(); + + if (sender.hasPermission("flamecord.usage")) { + if (args.length > 0) { + final String arg0 = args[0]; + + switch (arg0) { + case "firewall": { + final FirewallManager firewallManager = flameCord.getFirewallManager(); + final int amount = firewallManager.getFirewalled().size(), + seconds = firewallManager.getSeconds(); + + sender.sendMessage(TextComponent.fromLegacyText( + messagesConfiguration.getTranslation("firewall_info", amount, seconds))); + break; + } + case "reload": { + // FlameCord - Collect ips from servers + final Collection whitelistedAddresses = new HashSet<>(); + + for (final ServerInfo serverInfo : bungeeCord.getServers().values()) { + whitelistedAddresses.add(serverInfo.getSocketAddress().toString()); + } + + FlameCord.renew(bungeeCord.getLogger(), whitelistedAddresses); + sender.sendMessage(TextComponent + .fromLegacyText(messagesConfiguration.getTranslation("flamecord_reload"))); + break; + } + default: { + sender.sendMessage(TextComponent.fromLegacyText( + messagesConfiguration.getTranslation("flamecord_help", bungeeCord.getVersion()))); + break; + } + } + } else { + sender.sendMessage(TextComponent + .fromLegacyText(messagesConfiguration.getTranslation("flamecord_help", bungeeCord.getVersion()))); + } + } else { + sender.sendMessage(TextComponent + .fromLegacyText(messagesConfiguration.getTranslation("flamecord_nopermission"))); + } + } +} diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index 3e4ebfc5..316790ee 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -9,6 +9,10 @@ import com.google.common.collect.Sets; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + +import dev._2lstudios.flamecord.FlameCord; +import dev._2lstudios.flamecord.commands.FlameCordCommand; +import dev._2lstudios.flamecord.configuration.ModulesConfiguration; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.github.waterfallmc.waterfall.conf.WaterfallConfiguration; import io.github.waterfallmc.waterfall.event.ProxyExceptionEvent; @@ -86,6 +90,12 @@ import net.md_5.bungee.conf.Configuration; import net.md_5.bungee.conf.YamlConfig; import net.md_5.bungee.forge.ForgeConstants; import net.md_5.bungee.module.ModuleManager; +import net.md_5.bungee.module.cmd.alert.CommandAlert; +import net.md_5.bungee.module.cmd.find.CommandFind; +import net.md_5.bungee.module.cmd.list.CommandList; +import net.md_5.bungee.module.cmd.send.CommandSend; +import net.md_5.bungee.module.cmd.server.CommandServer; +import net.md_5.bungee.module.reconnect.yaml.YamlReconnectHandler; import net.md_5.bungee.netty.PipelineUtils; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.ProtocolConstants; @@ -232,11 +242,12 @@ public class BungeeCord extends ProxyServer // Waterfall end pluginManager = new PluginManager( this ); - getPluginManager().registerCommand( null, new CommandReload() ); - getPluginManager().registerCommand( null, new CommandEnd() ); - getPluginManager().registerCommand( null, new CommandIP() ); - getPluginManager().registerCommand( null, new CommandBungee() ); - getPluginManager().registerCommand( null, new CommandPerms() ); + // FlameCord - We register commands in our new method + //getPluginManager().registerCommand( null, new CommandReload() ); + //getPluginManager().registerCommand( null, new CommandEnd() ); + //getPluginManager().registerCommand( null, new CommandIP() ); + //getPluginManager().registerCommand( null, new CommandBungee() ); + //getPluginManager().registerCommand( null, new CommandPerms() ); if ( !Boolean.getBoolean( "net.md_5.bungee.native.disable" ) ) { @@ -275,9 +286,10 @@ public class BungeeCord extends ProxyServer bossEventLoopGroup = PipelineUtils.newEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty Boss IO Thread #%1$d" ).build() ); workerEventLoopGroup = PipelineUtils.newEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty Worker IO Thread #%1$d" ).build() ); - File moduleDirectory = new File( "modules" ); + // FlameCord - Use own module system + /* File moduleDirectory = new File( "modules" ); moduleManager.load( this, moduleDirectory ); - pluginManager.detectPlugins( moduleDirectory ); + pluginManager.detectPlugins( moduleDirectory ); */ pluginsFolder.mkdir(); pluginManager.detectPlugins( pluginsFolder ); @@ -285,6 +297,16 @@ public class BungeeCord extends ProxyServer pluginManager.loadPlugins(); config.load(); + // FlameCord - Renew and register modules + final Collection whitelistedAddresses = new HashSet<>(); + + for (final ServerInfo serverInfo : getServers().values()) { + whitelistedAddresses.add(serverInfo.getSocketAddress().toString()); + } + + FlameCord.renew(logger, whitelistedAddresses); + registerModules(); + if ( config.isForgeSupport() ) { registerChannel( ForgeConstants.FML_TAG ); @@ -573,16 +595,8 @@ public class BungeeCord extends ProxyServer @Override public String getTranslation(String name, Object... args) { - String translation = ""; - try - { - final String string = customBundle != null && customBundle.containsKey( name ) ? customBundle.getString( name ) : baseBundle.getString( name ); - - translation = ( args.length == 0 ) ? string : MessageFormat.format( string, args ); - } catch ( MissingResourceException ex ) - { - } - return translation; + // FlameCord - Use own translation system + return FlameCord.getInstance().getMessagesConfiguration().getTranslation(name, args); } @Override @@ -815,4 +829,56 @@ public class BungeeCord extends ProxyServer { return new BungeeTitle(); } + + // FlameCord - Method to simplify module registering + public void registerModules() { + final ModulesConfiguration modulesConfiguration = FlameCord.getInstance().getModulesConfiguration(); + + // Bungeecord Commands + pluginManager.registerCommand(null, new CommandEnd()); + pluginManager.registerCommand(null, new CommandBungee()); + + if (modulesConfiguration.reloadEnabled) { + pluginManager.registerCommand(null, new CommandReload()); + } + if (modulesConfiguration.ipEnabled) { + pluginManager.registerCommand(null, new CommandIP()); + } + if (modulesConfiguration.permsEnabled) { + pluginManager.registerCommand(null, new CommandPerms()); + } + + // Modules Commands + if (modulesConfiguration.alertEnabled) { + pluginManager.registerCommand(null, new CommandAlert()); + } + if (modulesConfiguration.findEnabled) { + pluginManager.registerCommand(null, new CommandFind()); + } + if (modulesConfiguration.listEnabled) { + pluginManager.registerCommand(null, new CommandList()); + } + if (modulesConfiguration.sendEnabled) { + pluginManager.registerCommand(null, new CommandSend()); + } + if (modulesConfiguration.serverEnabled) { + pluginManager.registerCommand(null, new CommandServer()); + } + + try { + if (modulesConfiguration.reconnectEnabled) { + for (ListenerInfo info : getConfig().getListeners()) { + if (!info.isForceDefault() && getReconnectHandler() == null) { + setReconnectHandler(new YamlReconnectHandler()); + break; + } + } + } + } catch (final Exception exception) { + logger.warning("Reconnect module is not able to work on FlameCord!"); + } + + // Flamecord - Commands (Had to make it like this because of maven limitations) + pluginManager.registerCommand(null, new FlameCordCommand(this)); + } } diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java index e90237ac..3cfef373 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -1,6 +1,8 @@ package net.md_5.bungee; import com.google.common.base.Preconditions; + +import dev._2lstudios.flamecord.FlameCord; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import java.net.InetSocketAddress; @@ -34,6 +36,7 @@ import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.HandlerBoss; import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.netty.PipelineUtils; +import net.md_5.bungee.protocol.BadPacketException; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.MinecraftDecoder; import net.md_5.bungee.protocol.PacketWrapper; @@ -161,7 +164,13 @@ public class ServerConnector extends PacketHandler { if ( packet.packet == null ) { - throw new QuietException( "Unexpected packet received during server login process!\n" + BufUtil.dump( packet.buf, 16 ) ); + // FlameCord - Toggle Dumping packet info + // FlameCord - Change from QuietException to BadPacketException + if (FlameCord.getInstance().getFlameCordConfiguration().isLoggerDump()) { + throw new BadPacketException( "Unexpected packet received during server connector process!\n" + BufUtil.dump(packet.buf, 16) ); + } else { + throw new BadPacketException( "Unexpected packet received during server connector process!" ); + } } } diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 159119c1..7c4c8f8a 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -35,6 +35,7 @@ import net.md_5.bungee.api.SkinConfiguration; import net.md_5.bungee.api.Title; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.config.ListenerInfo; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.PermissionCheckEvent; @@ -65,6 +66,7 @@ import net.md_5.bungee.tab.ServerUnique; import net.md_5.bungee.tab.TabList; import net.md_5.bungee.util.CaseInsensitiveSet; import net.md_5.bungee.util.ChatComponentTransformer; +import net.md_5.bungee.util.QuietException; @RequiredArgsConstructor public final class UserConnection implements ProxiedPlayer @@ -387,9 +389,11 @@ public final class UserConnection implements ProxiedPlayer .option( ChannelOption.CONNECT_TIMEOUT_MILLIS, request.getConnectTimeout() ) .remoteAddress( target.getAddress() ); // Windows is bugged, multi homed users will just have to live with random connecting IPs - if ( getPendingConnection().getListener().isSetLocalAddress() && !PlatformDependent.isWindows() && getPendingConnection().getListener().getSocketAddress() instanceof InetSocketAddress ) + // FlameCord - Use listenerInfo + final ListenerInfo listenerInfo = getPendingConnection().getListener(); + if ( listenerInfo.isSetLocalAddress() && !PlatformDependent.isWindows() && listenerInfo.getSocketAddress() instanceof InetSocketAddress ) { - b.localAddress( getPendingConnection().getListener().getHost().getHostString(), 0 ); + b.localAddress( listenerInfo.getHost().getHostString(), 0 ); } b.connect().addListener( listener ); } diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index e7542b1c..47a9c74d 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -16,6 +16,8 @@ import java.util.logging.Level; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; +import dev._2lstudios.flamecord.FlameCord; + import lombok.Getter; import lombok.RequiredArgsConstructor; import net.md_5.bungee.BungeeCord; @@ -49,6 +51,7 @@ import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.netty.PipelineUtils; import net.md_5.bungee.netty.cipher.CipherDecoder; import net.md_5.bungee.netty.cipher.CipherEncoder; +import net.md_5.bungee.protocol.BadPacketException; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; @@ -152,7 +155,13 @@ public class InitialHandler extends PacketHandler implements PendingConnection { if ( packet.packet == null ) { - throw new QuietException( "Unexpected packet received during login process! " + BufUtil.dump( packet.buf, 16 ) ); + // FlameCord - Toggle Dumping packet info + // FlameCord - Change from QuietException to BadPacketException + if (FlameCord.getInstance().getFlameCordConfiguration().isLoggerDump()) { + throw new BadPacketException( "Unexpected packet received during server login process!\n" + BufUtil.dump(packet.buf, 16) ); + } else { + throw new BadPacketException( "Unexpected packet received during server login process!" ); + } } } @@ -365,7 +374,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection { case 1: // Ping - if ( bungee.getConfig().isLogPings() ) + // FlameCord - Toggle for initialhandler logger + if ( bungee.getConfig().isLogPings() && FlameCord.getInstance().getFlameCordConfiguration().isLoggerInitialhandler() ) { bungee.getLogger().log( Level.INFO, "{0} has pinged", this ); } @@ -374,7 +384,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection break; case 2: // Login - if (BungeeCord.getInstance().getConfig().isLogInitialHandlerConnections() ) // Waterfall + // FlameCord - Toggle for initialhandler logger + if (BungeeCord.getInstance().getConfig().isLogInitialHandlerConnections() && FlameCord.getInstance().getFlameCordConfiguration().isLoggerInitialhandler() ) // Waterfall { bungee.getLogger().log( Level.INFO, "{0} has connected", this ); } diff --git a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java index 6cd71071..09909bd9 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java @@ -1,6 +1,8 @@ package net.md_5.bungee.connection; import com.google.gson.Gson; + +import dev._2lstudios.flamecord.FlameCord; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import lombok.RequiredArgsConstructor; import net.md_5.bungee.BungeeCord; @@ -12,6 +14,7 @@ import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.netty.PipelineUtils; +import net.md_5.bungee.protocol.BadPacketException; import net.md_5.bungee.protocol.MinecraftDecoder; import net.md_5.bungee.protocol.MinecraftEncoder; import net.md_5.bungee.protocol.PacketWrapper; @@ -58,7 +61,13 @@ public class PingHandler extends PacketHandler { if ( packet.packet == null ) { - throw new QuietException( "Unexpected packet received during ping process! " + BufUtil.dump( packet.buf, 16 ) ); + // FlameCord - Toggle dumping packet info + // FlameCord - Change from QuietException to BadPacketException + if (FlameCord.getInstance().getFlameCordConfiguration().isLoggerDump()) { + throw new BadPacketException( "Unexpected packet received during ping process! " + BufUtil.dump( packet.buf, 16 ) ); + } else { + throw new BadPacketException( "Unexpected packet received during ping process!" ); + } } } diff --git a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java index d68cc2ce..46e338ca 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java @@ -1,6 +1,9 @@ package net.md_5.bungee.netty; import com.google.common.base.Preconditions; + +import dev._2lstudios.flamecord.FlameCord; +import dev._2lstudios.flamecord.firewall.FirewallException; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.CorruptedFrameException; @@ -9,6 +12,7 @@ import io.netty.handler.codec.haproxy.HAProxyMessage; import io.netty.handler.timeout.ReadTimeoutException; import java.io.IOException; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.util.logging.Level; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.connection.CancelSendSignal; @@ -39,12 +43,20 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { + // FlameCord - Firewall system + final SocketAddress remoteAddress = ctx.channel().remoteAddress(); + + if (remoteAddress != null && FlameCord.getInstance().getFirewallManager().isFirewalled(remoteAddress)) { + throw new FirewallException(remoteAddress); + } + if ( handler != null ) { channel = new ChannelWrapper( ctx ); handler.connected( channel ); - if ( !( handler instanceof InitialHandler || handler instanceof PingHandler ) ) + // FlameCord - Added isLoggerInitialhandler boolean + if ( !( handler instanceof InitialHandler || handler instanceof PingHandler ) && FlameCord.getInstance().getFlameCordConfiguration().isLoggerInitialhandler() ) { ProxyServer.getInstance().getLogger().log( Level.INFO, "{0} has connected", handler ); } @@ -60,7 +72,8 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter channel.close(); handler.disconnected( channel ); - if ( !( handler instanceof InitialHandler || handler instanceof PingHandler ) ) + // FlameCord - Added isLoggerInitialhandler boolean + if ( !( handler instanceof InitialHandler || handler instanceof PingHandler ) && FlameCord.getInstance().getFlameCordConfiguration().isLoggerInitialhandler() ) { ProxyServer.getInstance().getLogger().log( Level.INFO, "{0} has disconnected", handler ); } @@ -130,7 +143,24 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter { if ( ctx.channel().isActive() ) { - boolean logExceptions = !( handler instanceof PingHandler ); + // FlameCord - Use flamecord + final FlameCord flameCord = FlameCord.getInstance(); + // FlameCord - log exceptions based on FlameCord configuration and FirewallException + boolean logExceptions = flameCord.getFlameCordConfiguration().isLoggerExceptions() && !(cause instanceof FirewallException); + + // FlameCord - Firewall system + if (cause instanceof DecoderException || cause instanceof IllegalStateException || cause instanceof BadPacketException) { + final SocketAddress remoteAddress = ctx.channel().remoteAddress(); + + if (remoteAddress != null) { + flameCord.getFirewallManager().addFirewalled(remoteAddress); + } + } + + // FlameCord - Handle firewall exceptions + if (cause instanceof FirewallException) { + flameCord.getFirewallManager().logBlocked(ctx.channel().remoteAddress()); + } if ( logExceptions ) { diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java index a54da9c3..84302b32 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java @@ -1,6 +1,9 @@ package net.md_5.bungee.netty; import com.google.common.base.Preconditions; + +import dev._2lstudios.flamecord.FlameCord; +import dev._2lstudios.flamecord.firewall.FirewallException; import io.github.waterfallmc.waterfall.event.ConnectionInitEvent; import io.netty.buffer.PooledByteBufAllocator; import io.netty.channel.Channel; @@ -61,6 +64,11 @@ public class PipelineUtils { SocketAddress remoteAddress = ( ch.remoteAddress() == null ) ? ch.parent().localAddress() : ch.remoteAddress(); + // FlameCord - Firewall system + if (remoteAddress != null && FlameCord.getInstance().getFirewallManager().isFirewalled(remoteAddress)) { + throw new FirewallException(remoteAddress); + } + if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( remoteAddress ) ) { ch.close(); @@ -107,7 +115,9 @@ public class PipelineUtils // FlameCord - Close on exception caught @Override public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception { + if (FlameCord.getInstance().getFlameCordConfiguration().isLoggerExceptions()) { cause.printStackTrace(); + } ctx.close(); } -- 2.20.1