mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 14:59:20 +00:00
Removed config holder and changed a few things
This commit is contained in:
@@ -80,18 +80,7 @@ public interface FloodgateLogger {
|
|||||||
void trace(String message, Object... args);
|
void trace(String message, Object... args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables debug mode for the Floodgate logger.
|
* Returns true if debugging is enabled
|
||||||
*/
|
|
||||||
void enableDebug();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disables debug mode for the Floodgate logger. Debug messages can still be sent after running
|
|
||||||
* this method, but they will be hidden from the console.
|
|
||||||
*/
|
|
||||||
void disableDebug();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if debugging is enabled
|
|
||||||
*/
|
*/
|
||||||
boolean isDebug();
|
boolean isDebug();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ object Versions {
|
|||||||
const val configUtilsVersion = "1.0-SNAPSHOT"
|
const val configUtilsVersion = "1.0-SNAPSHOT"
|
||||||
const val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
const val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
||||||
const val fastutilVersion = "8.5.3"
|
const val fastutilVersion = "8.5.3"
|
||||||
const val guiceVersion = "5.0.1"
|
const val guiceVersion = "5.1.0"
|
||||||
const val nettyVersion = "4.1.49.Final"
|
const val nettyVersion = "4.1.49.Final"
|
||||||
const val snakeyamlVersion = "1.28"
|
const val snakeyamlVersion = "1.28"
|
||||||
const val cloudVersion = "1.5.0"
|
const val cloudVersion = "1.5.0"
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ public final class BungeePlatformModule extends AbstractModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(PlatformUtils.class).to(BungeePlatformUtils.class);
|
bind(PlatformUtils.class).to(BungeePlatformUtils.class);
|
||||||
|
bind(FloodgateLogger.class).to(JavaUtilFloodgateLogger.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -74,12 +75,6 @@ public final class BungeePlatformModule extends AbstractModule {
|
|||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public FloodgateLogger floodgateLogger(LanguageManager languageManager) {
|
|
||||||
return new JavaUtilFloodgateLogger(plugin.getLogger(), languageManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Commands / Listeners
|
Commands / Listeners
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -28,10 +28,6 @@ package org.geysermc.floodgate;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.name.Named;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import net.engio.mbassy.bus.common.PubSubSupport;
|
import net.engio.mbassy.bus.common.PubSubSupport;
|
||||||
import org.geysermc.floodgate.api.FloodgateApi;
|
import org.geysermc.floodgate.api.FloodgateApi;
|
||||||
@@ -41,12 +37,9 @@ import org.geysermc.floodgate.api.inject.PlatformInjector;
|
|||||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
import org.geysermc.floodgate.api.packet.PacketHandlers;
|
import org.geysermc.floodgate.api.packet.PacketHandlers;
|
||||||
import org.geysermc.floodgate.config.ConfigLoader;
|
|
||||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
|
||||||
import org.geysermc.floodgate.event.ShutdownEvent;
|
import org.geysermc.floodgate.event.ShutdownEvent;
|
||||||
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
||||||
import org.geysermc.floodgate.module.ConfigLoadedModule;
|
|
||||||
import org.geysermc.floodgate.module.PostInitializeModule;
|
import org.geysermc.floodgate.module.PostInitializeModule;
|
||||||
import org.geysermc.floodgate.news.NewsChecker;
|
import org.geysermc.floodgate.news.NewsChecker;
|
||||||
import org.geysermc.floodgate.util.Metrics;
|
import org.geysermc.floodgate.util.Metrics;
|
||||||
@@ -54,51 +47,16 @@ import org.geysermc.floodgate.util.PrefixCheckTask;
|
|||||||
|
|
||||||
public class FloodgatePlatform {
|
public class FloodgatePlatform {
|
||||||
private static final UUID KEY = UUID.randomUUID();
|
private static final UUID KEY = UUID.randomUUID();
|
||||||
private final FloodgateApi api;
|
@Inject private FloodgateApi api;
|
||||||
private final PlatformInjector injector;
|
@Inject private PlatformInjector injector;
|
||||||
|
|
||||||
private final FloodgateLogger logger;
|
@Inject private FloodgateLogger logger;
|
||||||
|
|
||||||
private FloodgateConfig config;
|
@Inject private FloodgateConfig config;
|
||||||
private Injector guice;
|
@Inject private Injector guice;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public FloodgatePlatform(
|
public void init(PacketHandlers packetHandlers, HandshakeHandlers handshakeHandlers) {
|
||||||
FloodgateApi api,
|
|
||||||
PlatformInjector platformInjector,
|
|
||||||
FloodgateLogger logger,
|
|
||||||
Injector guice) {
|
|
||||||
|
|
||||||
this.api = api;
|
|
||||||
this.injector = platformInjector;
|
|
||||||
this.logger = logger;
|
|
||||||
this.guice = guice;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public void init(
|
|
||||||
@Named("dataDirectory") Path dataDirectory,
|
|
||||||
ConfigLoader configLoader,
|
|
||||||
FloodgateConfigHolder configHolder,
|
|
||||||
PacketHandlers packetHandlers,
|
|
||||||
HandshakeHandlers handshakeHandlers) {
|
|
||||||
|
|
||||||
if (!Files.isDirectory(dataDirectory)) {
|
|
||||||
try {
|
|
||||||
Files.createDirectory(dataDirectory);
|
|
||||||
} catch (IOException exception) {
|
|
||||||
logger.error("Failed to create the data folder", exception);
|
|
||||||
throw new RuntimeException("Failed to create the data folder", exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config = configLoader.load();
|
|
||||||
if (config.isDebug()) {
|
|
||||||
logger.enableDebug();
|
|
||||||
}
|
|
||||||
|
|
||||||
configHolder.set(config);
|
|
||||||
guice = guice.createChildInjector(new ConfigLoadedModule(config));
|
|
||||||
PlayerLink link = guice.getInstance(PlayerLinkLoader.class).load();
|
PlayerLink link = guice.getInstance(PlayerLinkLoader.class).load();
|
||||||
|
|
||||||
InstanceHolder.set(api, link, this.injector, packetHandlers, handshakeHandlers, KEY);
|
InstanceHolder.set(api, link, this.injector, packetHandlers, handshakeHandlers, KEY);
|
||||||
@@ -131,7 +89,7 @@ public class FloodgatePlatform {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean disable() {
|
public void disable() {
|
||||||
guice.getInstance(PubSubSupport.class).publish(new ShutdownEvent());
|
guice.getInstance(PubSubSupport.class).publish(new ShutdownEvent());
|
||||||
|
|
||||||
if (injector != null && injector.canRemoveInjection()) {
|
if (injector != null && injector.canRemoveInjection()) {
|
||||||
@@ -143,7 +101,6 @@ public class FloodgatePlatform {
|
|||||||
logger.error("Failed to remove the injection!", exception);
|
logger.error("Failed to remove the injection!", exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isProxy() {
|
public boolean isProxy() {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import org.geysermc.cumulus.form.util.FormBuilder;
|
|||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||||
import org.geysermc.floodgate.api.unsafe.Unsafe;
|
import org.geysermc.floodgate.api.unsafe.Unsafe;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||||
import org.geysermc.floodgate.pluginmessage.channel.FormChannel;
|
import org.geysermc.floodgate.pluginmessage.channel.FormChannel;
|
||||||
import org.geysermc.floodgate.pluginmessage.channel.TransferChannel;
|
import org.geysermc.floodgate.pluginmessage.channel.TransferChannel;
|
||||||
@@ -58,13 +58,13 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Inject private PluginMessageManager pluginMessageManager;
|
@Inject private PluginMessageManager pluginMessageManager;
|
||||||
@Inject private FloodgateConfigHolder configHolder;
|
@Inject private FloodgateConfig config;
|
||||||
@Inject private HttpClient httpClient;
|
@Inject private HttpClient httpClient;
|
||||||
@Inject private FloodgateLogger logger;
|
@Inject private FloodgateLogger logger;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPlayerPrefix() {
|
public String getPlayerPrefix() {
|
||||||
return configHolder.get().getUsernamePrefix();
|
return config.getUsernamePrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,23 +32,16 @@ import cloud.commandframework.Command;
|
|||||||
import cloud.commandframework.Command.Builder;
|
import cloud.commandframework.Command.Builder;
|
||||||
import cloud.commandframework.CommandManager;
|
import cloud.commandframework.CommandManager;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import com.google.inject.Inject;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import org.geysermc.floodgate.command.util.Permission;
|
import org.geysermc.floodgate.command.util.Permission;
|
||||||
import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
||||||
import org.geysermc.floodgate.platform.command.FloodgateSubCommand;
|
import org.geysermc.floodgate.platform.command.FloodgateSubCommand;
|
||||||
|
import org.geysermc.floodgate.platform.command.SubCommands;
|
||||||
import org.geysermc.floodgate.player.UserAudience;
|
import org.geysermc.floodgate.player.UserAudience;
|
||||||
|
|
||||||
public final class MainCommand implements FloodgateCommand {
|
public final class MainCommand extends SubCommands implements FloodgateCommand {
|
||||||
private final List<FloodgateSubCommand> subCommands = new ArrayList<>();
|
public MainCommand() {
|
||||||
|
defineSubCommand(FirewallCheckSubcommand.class);
|
||||||
@Inject
|
|
||||||
public void createSubCommands(FirewallCheckSubcommand firewallCheckSubcommand) {
|
|
||||||
//todo move subcommand logic to a separate class
|
|
||||||
subCommands.clear();
|
|
||||||
subCommands.add(firewallCheckSubcommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -60,7 +53,7 @@ public final class MainCommand implements FloodgateCommand {
|
|||||||
.permission(Permission.COMMAND_MAIN.get())
|
.permission(Permission.COMMAND_MAIN.get())
|
||||||
.handler(this::execute);
|
.handler(this::execute);
|
||||||
|
|
||||||
for (FloodgateSubCommand subCommand : subCommands) {
|
for (FloodgateSubCommand subCommand : subCommands()) {
|
||||||
commandManager.command(builder
|
commandManager.command(builder
|
||||||
.literal(subCommand.name().toLowerCase(Locale.ROOT), subCommand.description())
|
.literal(subCommand.name().toLowerCase(Locale.ROOT), subCommand.description())
|
||||||
.permission(subCommand.permission().get())
|
.permission(subCommand.permission().get())
|
||||||
@@ -76,7 +69,7 @@ public final class MainCommand implements FloodgateCommand {
|
|||||||
public void execute(CommandContext<UserAudience> context) {
|
public void execute(CommandContext<UserAudience> context) {
|
||||||
StringBuilder helpMessage = new StringBuilder("Available subcommands are:\n");
|
StringBuilder helpMessage = new StringBuilder("Available subcommands are:\n");
|
||||||
|
|
||||||
for (FloodgateSubCommand subCommand : subCommands) {
|
for (FloodgateSubCommand subCommand : subCommands()) {
|
||||||
if (context.getSender().hasPermission(subCommand.permission().get())) {
|
if (context.getSender().hasPermission(subCommand.permission().get())) {
|
||||||
helpMessage.append('\n').append(COLOR_CHAR).append('b')
|
helpMessage.append('\n').append(COLOR_CHAR).append('b')
|
||||||
.append(subCommand.name().toLowerCase(Locale.ROOT))
|
.append(subCommand.name().toLowerCase(Locale.ROOT))
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import org.geysermc.configutils.ConfigUtilities;
|
|||||||
import org.geysermc.configutils.file.codec.PathFileCodec;
|
import org.geysermc.configutils.file.codec.PathFileCodec;
|
||||||
import org.geysermc.configutils.file.template.ResourceTemplateReader;
|
import org.geysermc.configutils.file.template.ResourceTemplateReader;
|
||||||
import org.geysermc.configutils.updater.change.Changes;
|
import org.geysermc.configutils.updater.change.Changes;
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
|
||||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||||
import org.geysermc.floodgate.crypto.KeyProducer;
|
import org.geysermc.floodgate.crypto.KeyProducer;
|
||||||
|
|
||||||
@@ -48,8 +47,6 @@ public final class ConfigLoader {
|
|||||||
private final KeyProducer keyProducer;
|
private final KeyProducer keyProducer;
|
||||||
private final FloodgateCipher cipher;
|
private final FloodgateCipher cipher;
|
||||||
|
|
||||||
private final FloodgateLogger logger;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends FloodgateConfig> T load() {
|
public <T extends FloodgateConfig> T load() {
|
||||||
String templateFile = "config.yml";
|
String templateFile = "config.yml";
|
||||||
@@ -100,21 +97,16 @@ public final class ConfigLoader {
|
|||||||
String decrypted = cipher.decryptToString(encrypted);
|
String decrypted = cipher.decryptToString(encrypted);
|
||||||
|
|
||||||
if (!test.equals(decrypted)) {
|
if (!test.equals(decrypted)) {
|
||||||
logger.error("Whoops, we tested the generated Floodgate keys but " +
|
throw new RuntimeException("Failed to decrypt test message.\n" +
|
||||||
"the decrypted test message doesn't match the original.\n" +
|
|
||||||
"Original message: " + test + "." +
|
"Original message: " + test + "." +
|
||||||
"Decrypted message: " + decrypted + ".\n" +
|
"Decrypted message: " + decrypted + ".\n" +
|
||||||
"The encrypted message itself: " + new String(encrypted)
|
"The encrypted message itself: " + new String(encrypted)
|
||||||
);
|
);
|
||||||
throw new RuntimeException(
|
|
||||||
"Tested the generated public and private key but, " +
|
|
||||||
"the decrypted message doesn't match the original!"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Files.write(keyPath, key.getEncoded());
|
Files.write(keyPath, key.getEncoded());
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
logger.error("Error while creating key", exception);
|
throw new RuntimeException("Error while creating key", exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,17 +27,23 @@ package org.geysermc.floodgate.logger;
|
|||||||
|
|
||||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.util.LanguageManager;
|
import org.geysermc.floodgate.util.LanguageManager;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public final class JavaUtilFloodgateLogger implements FloodgateLogger {
|
public final class JavaUtilFloodgateLogger implements FloodgateLogger {
|
||||||
private final Logger logger;
|
@Inject private Logger logger;
|
||||||
private final LanguageManager languageManager;
|
@Inject private LanguageManager languageManager;
|
||||||
private Level originLevel;
|
|
||||||
|
@Inject
|
||||||
|
private void init(FloodgateConfig config) {
|
||||||
|
if (config.isDebug()) {
|
||||||
|
logger.setLevel(Level.ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(String message, Object... args) {
|
public void error(String message, Object... args) {
|
||||||
@@ -74,19 +80,6 @@ public final class JavaUtilFloodgateLogger implements FloodgateLogger {
|
|||||||
logger.finer(format(message, args));
|
logger.finer(format(message, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableDebug() {
|
|
||||||
originLevel = logger.getLevel();
|
|
||||||
logger.setLevel(Level.ALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableDebug() {
|
|
||||||
if (originLevel != null) {
|
|
||||||
logger.setLevel(originLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDebug() {
|
public boolean isDebug() {
|
||||||
return logger.getLevel() == Level.ALL;
|
return logger.getLevel() == Level.ALL;
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import org.geysermc.floodgate.api.packet.PacketHandlers;
|
|||||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||||
import org.geysermc.floodgate.config.ConfigLoader;
|
import org.geysermc.floodgate.config.ConfigLoader;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
|
||||||
import org.geysermc.floodgate.crypto.AesCipher;
|
import org.geysermc.floodgate.crypto.AesCipher;
|
||||||
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
||||||
import org.geysermc.floodgate.crypto.Base64Topping;
|
import org.geysermc.floodgate.crypto.Base64Topping;
|
||||||
@@ -65,7 +64,6 @@ import org.geysermc.floodgate.skin.SkinApplier;
|
|||||||
import org.geysermc.floodgate.skin.SkinUploadManager;
|
import org.geysermc.floodgate.skin.SkinUploadManager;
|
||||||
import org.geysermc.floodgate.util.Constants;
|
import org.geysermc.floodgate.util.Constants;
|
||||||
import org.geysermc.floodgate.util.HttpClient;
|
import org.geysermc.floodgate.util.HttpClient;
|
||||||
import org.geysermc.floodgate.util.LanguageManager;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CommonModule extends AbstractModule {
|
public class CommonModule extends AbstractModule {
|
||||||
@@ -97,6 +95,12 @@ public class CommonModule extends AbstractModule {
|
|||||||
bind(NewsChecker.class).in(Singleton.class);
|
bind(NewsChecker.class).in(Singleton.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public FloodgateConfig floodgateConfig(ConfigLoader configLoader) {
|
||||||
|
return configLoader.load();
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public KeyProducer keyProducer() {
|
public KeyProducer keyProducer() {
|
||||||
@@ -116,28 +120,13 @@ public class CommonModule extends AbstractModule {
|
|||||||
return dataDirectory;
|
return dataDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public FloodgateConfigHolder configHolder() {
|
|
||||||
return new FloodgateConfigHolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public ConfigLoader configLoader(
|
public ConfigLoader configLoader(
|
||||||
@Named("configClass") Class<? extends FloodgateConfig> configClass,
|
@Named("configClass") Class<? extends FloodgateConfig> configClass,
|
||||||
KeyProducer producer,
|
KeyProducer producer,
|
||||||
FloodgateCipher cipher,
|
FloodgateCipher cipher) {
|
||||||
FloodgateLogger logger) {
|
return new ConfigLoader(dataDirectory, configClass, producer, cipher);
|
||||||
return new ConfigLoader(dataDirectory, configClass, producer, cipher, logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public LanguageManager languageLoader(
|
|
||||||
FloodgateConfigHolder configHolder,
|
|
||||||
FloodgateLogger logger) {
|
|
||||||
return new LanguageManager(configHolder, logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -146,12 +135,12 @@ public class CommonModule extends AbstractModule {
|
|||||||
HandshakeHandlersImpl handshakeHandlers,
|
HandshakeHandlersImpl handshakeHandlers,
|
||||||
SimpleFloodgateApi api,
|
SimpleFloodgateApi api,
|
||||||
FloodgateCipher cipher,
|
FloodgateCipher cipher,
|
||||||
FloodgateConfigHolder configHolder,
|
FloodgateConfig config,
|
||||||
SkinUploadManager skinUploadManager,
|
SkinUploadManager skinUploadManager,
|
||||||
@Named("playerAttribute") AttributeKey<FloodgatePlayer> playerAttribute,
|
@Named("playerAttribute") AttributeKey<FloodgatePlayer> playerAttribute,
|
||||||
FloodgateLogger logger) {
|
FloodgateLogger logger) {
|
||||||
|
|
||||||
return new FloodgateHandshakeHandler(handshakeHandlers, api, cipher, configHolder,
|
return new FloodgateHandshakeHandler(handshakeHandlers, api, cipher, config,
|
||||||
skinUploadManager, playerAttribute, logger);
|
skinUploadManager, playerAttribute, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ public final class ProxyCommonModule extends CommonModule {
|
|||||||
bind(ProxyFloodgateApi.class).in(Singleton.class);
|
bind(ProxyFloodgateApi.class).in(Singleton.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public ProxyFloodgateConfig proxyFloodgateConfig(FloodgateConfig config) {
|
||||||
|
return (ProxyFloodgateConfig) config;
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named("configClass")
|
@Named("configClass")
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public final class ServerCommonModule extends CommonModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
super.configure();
|
||||||
bind(SimpleFloodgateApi.class).in(Singleton.class);
|
bind(SimpleFloodgateApi.class).in(Singleton.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,37 +23,32 @@
|
|||||||
* @link https://github.com/GeyserMC/Floodgate
|
* @link https://github.com/GeyserMC/Floodgate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.floodgate.config;
|
package org.geysermc.floodgate.platform.command;
|
||||||
|
|
||||||
import org.geysermc.floodgate.util.FloodgateInfoHolder;
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class FloodgateConfigHolder {
|
public abstract class SubCommands {
|
||||||
private FloodgateConfig config;
|
private final Set<Class<? extends FloodgateSubCommand>> toRegister = new HashSet<>();
|
||||||
|
private Set<FloodgateSubCommand> subCommands;
|
||||||
|
|
||||||
public boolean has() {
|
public void defineSubCommand(Class<? extends FloodgateSubCommand> subCommandClass) {
|
||||||
return config != null;
|
toRegister.add(subCommandClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isProxy() {
|
@Inject
|
||||||
return config instanceof ProxyFloodgateConfig;
|
public void registerSubCommands(Injector injector) {
|
||||||
|
Set<FloodgateSubCommand> subCommandSet = new HashSet<>();
|
||||||
|
for (Class<? extends FloodgateSubCommand> subCommand : toRegister) {
|
||||||
|
subCommandSet.add(injector.getInstance(subCommand));
|
||||||
|
}
|
||||||
|
subCommands = Collections.unmodifiableSet(subCommandSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FloodgateConfig get() {
|
protected Set<FloodgateSubCommand> subCommands() {
|
||||||
return config;
|
return subCommands;
|
||||||
}
|
|
||||||
|
|
||||||
public ProxyFloodgateConfig getAsProxy() {
|
|
||||||
return getAs();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T extends FloodgateConfig> T getAs() {
|
|
||||||
return (T) config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(FloodgateConfig config) {
|
|
||||||
this.config = config;
|
|
||||||
// for Geyser dump
|
|
||||||
FloodgateInfoHolder.setConfig(config);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ import org.geysermc.floodgate.api.handshake.HandshakeData;
|
|||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||||
import org.geysermc.floodgate.api.player.PropertyKey;
|
import org.geysermc.floodgate.api.player.PropertyKey;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||||
import org.geysermc.floodgate.skin.SkinUploadManager;
|
import org.geysermc.floodgate.skin.SkinUploadManager;
|
||||||
import org.geysermc.floodgate.util.BedrockData;
|
import org.geysermc.floodgate.util.BedrockData;
|
||||||
@@ -60,7 +60,7 @@ public final class FloodgateHandshakeHandler {
|
|||||||
private final HandshakeHandlersImpl handshakeHandlers;
|
private final HandshakeHandlersImpl handshakeHandlers;
|
||||||
private final SimpleFloodgateApi api;
|
private final SimpleFloodgateApi api;
|
||||||
private final FloodgateCipher cipher;
|
private final FloodgateCipher cipher;
|
||||||
private final FloodgateConfigHolder configHolder;
|
private final FloodgateConfig config;
|
||||||
private final SkinUploadManager skinUploadManager;
|
private final SkinUploadManager skinUploadManager;
|
||||||
private final AttributeKey<FloodgatePlayer> playerAttribute;
|
private final AttributeKey<FloodgatePlayer> playerAttribute;
|
||||||
private final FloodgateLogger logger;
|
private final FloodgateLogger logger;
|
||||||
@@ -69,7 +69,7 @@ public final class FloodgateHandshakeHandler {
|
|||||||
HandshakeHandlersImpl handshakeHandlers,
|
HandshakeHandlersImpl handshakeHandlers,
|
||||||
SimpleFloodgateApi api,
|
SimpleFloodgateApi api,
|
||||||
FloodgateCipher cipher,
|
FloodgateCipher cipher,
|
||||||
FloodgateConfigHolder configHolder,
|
FloodgateConfig config,
|
||||||
SkinUploadManager skinUploadManager,
|
SkinUploadManager skinUploadManager,
|
||||||
AttributeKey<FloodgatePlayer> playerAttribute,
|
AttributeKey<FloodgatePlayer> playerAttribute,
|
||||||
FloodgateLogger logger) {
|
FloodgateLogger logger) {
|
||||||
@@ -77,7 +77,7 @@ public final class FloodgateHandshakeHandler {
|
|||||||
this.handshakeHandlers = handshakeHandlers;
|
this.handshakeHandlers = handshakeHandlers;
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.cipher = cipher;
|
this.cipher = cipher;
|
||||||
this.configHolder = configHolder;
|
this.config = config;
|
||||||
this.skinUploadManager = skinUploadManager;
|
this.skinUploadManager = skinUploadManager;
|
||||||
this.playerAttribute = playerAttribute;
|
this.playerAttribute = playerAttribute;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
@@ -134,7 +134,7 @@ public final class FloodgateHandshakeHandler {
|
|||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// all the other exceptions are caused by invalid/tempered Floodgate data
|
// all the other exceptions are caused by invalid/tempered Floodgate data
|
||||||
if (configHolder.get().isDebug()) {
|
if (config.isDebug()) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,10 +207,10 @@ public final class FloodgateHandshakeHandler {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
HandshakeData handshakeData = new HandshakeDataImpl(
|
HandshakeData handshakeData = new HandshakeDataImpl(
|
||||||
channel, true, bedrockData.clone(), configHolder.get(),
|
channel, true, bedrockData.clone(), config,
|
||||||
linkedPlayer != null ? linkedPlayer.clone() : null, hostname);
|
linkedPlayer != null ? linkedPlayer.clone() : null, hostname);
|
||||||
|
|
||||||
if (configHolder.get().getPlayerLink().isRequireLink() && linkedPlayer == null) {
|
if (config.getPlayerLink().isRequireLink() && linkedPlayer == null) {
|
||||||
handshakeData.setDisconnectReason("floodgate.core.not_linked");
|
handshakeData.setDisconnectReason("floodgate.core.not_linked");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ public final class FloodgateHandshakeHandler {
|
|||||||
String hostname) {
|
String hostname) {
|
||||||
|
|
||||||
HandshakeData handshakeData = new HandshakeDataImpl(channel, bedrockData != null,
|
HandshakeData handshakeData = new HandshakeDataImpl(channel, bedrockData != null,
|
||||||
bedrockData, configHolder.get(), null, hostname);
|
bedrockData, config, null, hostname);
|
||||||
handshakeHandlers.callHandshakeHandlers(handshakeData);
|
handshakeHandlers.callHandshakeHandlers(handshakeData);
|
||||||
|
|
||||||
return new HandshakeResult(resultType, handshakeData, bedrockData, null);
|
return new HandshakeResult(resultType, handshakeData, bedrockData, null);
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
package org.geysermc.floodgate.util;
|
package org.geysermc.floodgate.util;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
@@ -37,19 +39,18 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages translations for strings in Floodgate
|
* Manages translations for strings in Floodgate
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor
|
@Singleton
|
||||||
public final class LanguageManager {
|
public final class LanguageManager {
|
||||||
private final Map<String, Properties> localeMappings = new HashMap<>();
|
private final Map<String, Properties> localeMappings = new HashMap<>();
|
||||||
private final FloodgateConfigHolder configHolder;
|
|
||||||
private final FloodgateLogger logger;
|
@Inject private FloodgateConfig config;
|
||||||
|
@Inject private FloodgateLogger logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The locale used in console and as a fallback
|
* The locale used in console and as a fallback
|
||||||
@@ -71,24 +72,15 @@ public final class LanguageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLoaded() {
|
|
||||||
return logger != null && defaultLocale != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to load the log's locale file once a string has been requested
|
* Tries to load the log's locale file once a string has been requested
|
||||||
*/
|
*/
|
||||||
|
@Inject
|
||||||
private void init() {
|
private void init() {
|
||||||
if (!loadLocale("en_US")) {// Fallback
|
if (!loadLocale("en_US")) {// Fallback
|
||||||
logger.error("Failed to load the fallback language. This will likely cause errors!");
|
logger.error("Failed to load the fallback language. This will likely cause errors!");
|
||||||
}
|
}
|
||||||
|
|
||||||
FloodgateConfig config = configHolder.get();
|
|
||||||
if (config == null) {
|
|
||||||
// :thonk:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultLocale = formatLocale(config.getDefaultLocale());
|
defaultLocale = formatLocale(config.getDefaultLocale());
|
||||||
|
|
||||||
if (isValidLanguage(defaultLocale)) {
|
if (isValidLanguage(defaultLocale)) {
|
||||||
@@ -167,14 +159,6 @@ public final class LanguageManager {
|
|||||||
* @return translated string or "key arg1, arg2 (etc.)" if it was not found in the given locale
|
* @return translated string or "key arg1, arg2 (etc.)" if it was not found in the given locale
|
||||||
*/
|
*/
|
||||||
public String getString(String key, String locale, Object... values) {
|
public String getString(String key, String locale, Object... values) {
|
||||||
if (!isLoaded()) {
|
|
||||||
init();
|
|
||||||
// we can skip everything if the LanguageManager can't be loaded yet
|
|
||||||
if (!isLoaded()) {
|
|
||||||
return formatNotFound(key, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties properties = localeMappings.get(locale);
|
Properties properties = localeMappings.get(locale);
|
||||||
String formatString = null;
|
String formatString = null;
|
||||||
|
|
||||||
|
|||||||
@@ -26,23 +26,13 @@
|
|||||||
package org.geysermc.floodgate;
|
package org.geysermc.floodgate;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.geysermc.floodgate.api.FloodgateApi;
|
|
||||||
import org.geysermc.floodgate.api.inject.PlatformInjector;
|
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
|
||||||
|
|
||||||
public final class SpigotPlatform extends FloodgatePlatform {
|
public final class SpigotPlatform extends FloodgatePlatform {
|
||||||
@Inject private JavaPlugin plugin;
|
@Inject private JavaPlugin plugin;
|
||||||
|
|
||||||
@Inject
|
|
||||||
public SpigotPlatform(FloodgateApi api, PlatformInjector platformInjector,
|
|
||||||
FloodgateLogger logger, Injector injector) {
|
|
||||||
super(api, platformInjector, logger, injector);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean enable(Module... postInitializeModules) {
|
public boolean enable(Module... postInitializeModules) {
|
||||||
boolean success = super.enable(postInitializeModules);
|
boolean success = super.enable(postInitializeModules);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ public final class SpigotPlatformModule extends AbstractModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(PlatformUtils.class).to(SpigotPlatformUtils.class);
|
bind(PlatformUtils.class).to(SpigotPlatformUtils.class);
|
||||||
|
bind(FloodgateLogger.class).to(JavaUtilFloodgateLogger.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -68,12 +69,6 @@ public final class SpigotPlatformModule extends AbstractModule {
|
|||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public FloodgateLogger floodgateLogger(LanguageManager languageManager) {
|
|
||||||
return new JavaUtilFloodgateLogger(plugin.getLogger(), languageManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Commands / Listeners
|
Commands / Listeners
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -27,17 +27,26 @@ package org.geysermc.floodgate.logger;
|
|||||||
|
|
||||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.core.config.Configurator;
|
import org.apache.logging.log4j.core.config.Configurator;
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.util.LanguageManager;
|
import org.geysermc.floodgate.util.LanguageManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@Singleton
|
||||||
public final class Slf4jFloodgateLogger implements FloodgateLogger {
|
public final class Slf4jFloodgateLogger implements FloodgateLogger {
|
||||||
private final Logger logger;
|
@Inject private Logger logger;
|
||||||
private final LanguageManager languageManager;
|
@Inject private LanguageManager languageManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private void init(FloodgateConfig config) {
|
||||||
|
if (config.isDebug() && !logger.isDebugEnabled()) {
|
||||||
|
Configurator.setLevel(logger.getName(), Level.DEBUG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(String message, Object... args) {
|
public void error(String message, Object... args) {
|
||||||
@@ -74,20 +83,6 @@ public final class Slf4jFloodgateLogger implements FloodgateLogger {
|
|||||||
logger.trace(message, args);
|
logger.trace(message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableDebug() {
|
|
||||||
if (!logger.isDebugEnabled()) {
|
|
||||||
Configurator.setLevel(logger.getName(), Level.DEBUG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableDebug() {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
Configurator.setLevel(logger.getName(), Level.INFO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDebug() {
|
public boolean isDebug() {
|
||||||
return logger.isDebugEnabled();
|
return logger.isDebugEnabled();
|
||||||
|
|||||||
@@ -56,11 +56,9 @@ import org.geysermc.floodgate.pluginmessage.PluginMessageRegistration;
|
|||||||
import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageRegistration;
|
import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageRegistration;
|
||||||
import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageUtils;
|
import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageUtils;
|
||||||
import org.geysermc.floodgate.skin.SkinApplier;
|
import org.geysermc.floodgate.skin.SkinApplier;
|
||||||
import org.geysermc.floodgate.util.LanguageManager;
|
|
||||||
import org.geysermc.floodgate.util.VelocityCommandUtil;
|
import org.geysermc.floodgate.util.VelocityCommandUtil;
|
||||||
import org.geysermc.floodgate.util.VelocityPlatformUtils;
|
import org.geysermc.floodgate.util.VelocityPlatformUtils;
|
||||||
import org.geysermc.floodgate.util.VelocitySkinApplier;
|
import org.geysermc.floodgate.util.VelocitySkinApplier;
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public final class VelocityPlatformModule extends AbstractModule {
|
public final class VelocityPlatformModule extends AbstractModule {
|
||||||
@@ -70,6 +68,7 @@ public final class VelocityPlatformModule extends AbstractModule {
|
|||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(CommandUtil.class).to(VelocityCommandUtil.class);
|
bind(CommandUtil.class).to(VelocityCommandUtil.class);
|
||||||
bind(PlatformUtils.class).to(VelocityPlatformUtils.class);
|
bind(PlatformUtils.class).to(VelocityPlatformUtils.class);
|
||||||
|
bind(FloodgateLogger.class).to(Slf4jFloodgateLogger.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -89,12 +88,6 @@ public final class VelocityPlatformModule extends AbstractModule {
|
|||||||
return commandManager;
|
return commandManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public FloodgateLogger floodgateLogger(Logger logger, LanguageManager languageManager) {
|
|
||||||
return new Slf4jFloodgateLogger(logger, languageManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Commands / Listeners
|
Commands / Listeners
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user