mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 14:59:20 +00:00
Started using plugin messages internally. Started subcommand refactor
This commit is contained in:
@@ -34,6 +34,7 @@ object Versions {
|
||||
const val snakeyamlVersion = "1.28"
|
||||
const val cloudVersion = "1.5.0"
|
||||
const val bstatsVersion = "3.0.0"
|
||||
const val mbassadorVersion = "1.3.2"
|
||||
|
||||
const val javaWebsocketVersion = "1.5.2"
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ dependencies {
|
||||
api("cloud.commandframework", "cloud-core", Versions.cloudVersion)
|
||||
api("org.yaml", "snakeyaml", Versions.snakeyamlVersion)
|
||||
api("org.bstats", "bstats-base", Versions.bstatsVersion)
|
||||
api("net.engio", "mbassador", Versions.mbassadorVersion)
|
||||
}
|
||||
|
||||
// present on all platforms
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.UUID;
|
||||
import net.engio.mbassy.bus.common.PubSubSupport;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.InstanceHolder;
|
||||
import org.geysermc.floodgate.api.handshake.HandshakeHandlers;
|
||||
@@ -43,6 +44,7 @@ import org.geysermc.floodgate.api.packet.PacketHandlers;
|
||||
import org.geysermc.floodgate.config.ConfigLoader;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
||||
import org.geysermc.floodgate.event.ShutdownEvent;
|
||||
import org.geysermc.floodgate.link.PlayerLinkLoader;
|
||||
import org.geysermc.floodgate.module.ConfigLoadedModule;
|
||||
import org.geysermc.floodgate.module.PostInitializeModule;
|
||||
@@ -130,6 +132,8 @@ public class FloodgatePlatform {
|
||||
}
|
||||
|
||||
public boolean disable() {
|
||||
guice.getInstance(PubSubSupport.class).publish(new ShutdownEvent());
|
||||
|
||||
if (injector != null && injector.canRemoveInjection()) {
|
||||
try {
|
||||
if (!injector.removeInjection()) {
|
||||
@@ -139,9 +143,6 @@ public class FloodgatePlatform {
|
||||
logger.error("Failed to remove the injection!", exception);
|
||||
}
|
||||
}
|
||||
|
||||
guice.getInstance(NewsChecker.class).shutdown();
|
||||
api.getPlayerLink().stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,24 +25,14 @@
|
||||
|
||||
package org.geysermc.floodgate.api;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
import org.geysermc.floodgate.util.BedrockData;
|
||||
|
||||
public final class ProxyFloodgateApi extends SimpleFloodgateApi {
|
||||
private final FloodgateCipher cipher;
|
||||
|
||||
public ProxyFloodgateApi(
|
||||
PluginMessageManager pluginMessageManager,
|
||||
FloodgateConfigHolder configHolder,
|
||||
FloodgateLogger logger,
|
||||
FloodgateCipher cipher) {
|
||||
super(pluginMessageManager, configHolder, logger);
|
||||
this.cipher = cipher;
|
||||
}
|
||||
@Inject
|
||||
private FloodgateCipher cipher;
|
||||
|
||||
public byte[] createEncryptedData(BedrockData bedrockData) {
|
||||
try {
|
||||
|
||||
@@ -30,13 +30,13 @@ import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.cumulus.form.Form;
|
||||
import org.geysermc.cumulus.form.util.FormBuilder;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
@@ -47,10 +47,9 @@ import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
import org.geysermc.floodgate.pluginmessage.channel.FormChannel;
|
||||
import org.geysermc.floodgate.pluginmessage.channel.TransferChannel;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpUtils;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.geysermc.floodgate.util.Utils;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SimpleFloodgateApi implements FloodgateApi {
|
||||
private final Map<UUID, FloodgatePlayer> players = new HashMap<>();
|
||||
private final Cache<UUID, FloodgatePlayer> pendingRemove =
|
||||
@@ -58,9 +57,10 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
.expireAfterWrite(20, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
private final PluginMessageManager pluginMessageManager;
|
||||
private final FloodgateConfigHolder configHolder;
|
||||
private final FloodgateLogger logger;
|
||||
@Inject private PluginMessageManager pluginMessageManager;
|
||||
@Inject private FloodgateConfigHolder configHolder;
|
||||
@Inject private HttpClient httpClient;
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
@Override
|
||||
public String getPlayerPrefix() {
|
||||
@@ -148,7 +148,7 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
return Utils.failedFuture(new IllegalStateException("Received an invalid gamertag"));
|
||||
}
|
||||
|
||||
return HttpUtils.asyncGet(Constants.GET_XUID_URL + gamertag)
|
||||
return httpClient.asyncGet(Constants.GET_XUID_URL + gamertag)
|
||||
.thenApply(result -> {
|
||||
JsonObject response = result.getResponse();
|
||||
|
||||
@@ -163,7 +163,7 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getGamertagFor(long xuid) {
|
||||
return HttpUtils.asyncGet(Constants.GET_GAMERTAG_URL + xuid)
|
||||
return httpClient.asyncGet(Constants.GET_GAMERTAG_URL + xuid)
|
||||
.thenApply(result -> {
|
||||
JsonObject response = result.getResponse();
|
||||
|
||||
|
||||
@@ -49,10 +49,11 @@ import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.audience.ProfileAudience;
|
||||
import org.geysermc.floodgate.player.audience.ProfileAudienceArgument;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpUtils;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
|
||||
public class WhitelistCommand implements FloodgateCommand {
|
||||
@Inject private FloodgateConfig config;
|
||||
@Inject private HttpClient httpClient;
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
@Override
|
||||
@@ -128,7 +129,7 @@ public class WhitelistCommand implements FloodgateCommand {
|
||||
final String strippedName = name;
|
||||
|
||||
// We need to get the UUID of the player if it's not manually specified
|
||||
HttpUtils.asyncGet(Constants.GET_XUID_URL + name)
|
||||
httpClient.asyncGet(Constants.GET_XUID_URL + name)
|
||||
.whenComplete((result, error) -> {
|
||||
if (error != null) {
|
||||
sender.sendMessage(Message.API_UNAVAILABLE);
|
||||
|
||||
@@ -29,20 +29,40 @@ import static org.geysermc.floodgate.util.Constants.COLOR_CHAR;
|
||||
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.inject.Inject;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.platform.command.FloodgateSubCommand;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpUtils;
|
||||
import org.geysermc.floodgate.util.HttpUtils.HttpResponse;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.geysermc.floodgate.util.HttpClient.HttpResponse;
|
||||
import org.geysermc.floodgate.util.Utils;
|
||||
|
||||
final class FirewallCheckSubcommand {
|
||||
private FirewallCheckSubcommand() {}
|
||||
final class FirewallCheckSubcommand extends FloodgateSubCommand {
|
||||
@Inject
|
||||
private HttpClient httpClient;
|
||||
|
||||
static void executeFirewall(CommandContext<UserAudience> context) {
|
||||
@Override
|
||||
public String name() {
|
||||
return "firewall";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Check if your outgoing firewall allows Floodgate to work properly";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission permission() {
|
||||
return Permission.COMMAND_MAIN_FIREWALL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
UserAudience sender = context.getSender();
|
||||
executeChecks(
|
||||
globalApiCheck(sender)
|
||||
@@ -54,12 +74,12 @@ final class FirewallCheckSubcommand {
|
||||
);
|
||||
}
|
||||
|
||||
private static BooleanSupplier globalApiCheck(UserAudience sender) {
|
||||
private BooleanSupplier globalApiCheck(UserAudience sender) {
|
||||
return executeFirewallText(
|
||||
sender, "global api",
|
||||
() -> {
|
||||
HttpResponse<JsonElement> response =
|
||||
HttpUtils.get(Constants.HEALTH_URL, JsonElement.class);
|
||||
httpClient.get(Constants.HEALTH_URL, JsonElement.class);
|
||||
|
||||
if (!response.isCodeOk()) {
|
||||
throw new IllegalStateException(String.format(
|
||||
@@ -70,7 +90,7 @@ final class FirewallCheckSubcommand {
|
||||
});
|
||||
}
|
||||
|
||||
private static BooleanSupplier executeFirewallText(
|
||||
private BooleanSupplier executeFirewallText(
|
||||
UserAudience sender, String name, Runnable runnable) {
|
||||
return () -> {
|
||||
sender.sendMessage(COLOR_CHAR + "eTesting " + name + "...");
|
||||
@@ -86,9 +106,7 @@ final class FirewallCheckSubcommand {
|
||||
};
|
||||
}
|
||||
|
||||
private static CompletableFuture<Pair<Integer, Integer>> executeChecks(
|
||||
BooleanSupplier... checks) {
|
||||
|
||||
private CompletableFuture<Pair<Integer, Integer>> executeChecks(BooleanSupplier... checks) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
AtomicInteger okCount = new AtomicInteger();
|
||||
AtomicInteger failCount = new AtomicInteger();
|
||||
|
||||
@@ -32,14 +32,25 @@ import cloud.commandframework.Command;
|
||||
import cloud.commandframework.Command.Builder;
|
||||
import cloud.commandframework.CommandManager;
|
||||
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.function.Consumer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
||||
import org.geysermc.floodgate.platform.command.FloodgateSubCommand;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
|
||||
public final class MainCommand implements FloodgateCommand {
|
||||
private final List<FloodgateSubCommand> subCommands = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
public void createSubCommands(FirewallCheckSubcommand firewallCheckSubcommand) {
|
||||
//todo move subcommand logic to a separate class
|
||||
subCommands.clear();
|
||||
subCommands.add(firewallCheckSubcommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command<UserAudience> buildCommand(CommandManager<UserAudience> commandManager) {
|
||||
Builder<UserAudience> builder = commandManager.commandBuilder(
|
||||
@@ -49,11 +60,11 @@ public final class MainCommand implements FloodgateCommand {
|
||||
.permission(Permission.COMMAND_MAIN.get())
|
||||
.handler(this::execute);
|
||||
|
||||
for (SubCommand subCommand : SubCommand.VALUES) {
|
||||
for (FloodgateSubCommand subCommand : subCommands) {
|
||||
commandManager.command(builder
|
||||
.literal(subCommand.name().toLowerCase(Locale.ROOT), subCommand.description)
|
||||
.permission(subCommand.permission.get())
|
||||
.handler(subCommand.executor::accept)
|
||||
.literal(subCommand.name().toLowerCase(Locale.ROOT), subCommand.description())
|
||||
.permission(subCommand.permission().get())
|
||||
.handler(subCommand::execute)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -65,27 +76,15 @@ public final class MainCommand implements FloodgateCommand {
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
StringBuilder helpMessage = new StringBuilder("Available subcommands are:\n");
|
||||
|
||||
for (SubCommand subCommand : SubCommand.VALUES) {
|
||||
if (context.getSender().hasPermission(subCommand.permission.get())) {
|
||||
for (FloodgateSubCommand subCommand : subCommands) {
|
||||
if (context.getSender().hasPermission(subCommand.permission().get())) {
|
||||
helpMessage.append('\n').append(COLOR_CHAR).append('b')
|
||||
.append(subCommand.name().toLowerCase(Locale.ROOT))
|
||||
.append(COLOR_CHAR).append("f - ").append(COLOR_CHAR).append('7')
|
||||
.append(subCommand.description);
|
||||
.append(subCommand.description());
|
||||
}
|
||||
}
|
||||
|
||||
context.getSender().sendMessage(helpMessage.toString());
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
enum SubCommand {
|
||||
FIREWALL("Check if your outgoing firewall allows Floodgate to work properly",
|
||||
Permission.COMMAND_MAIN_FIREWALL, FirewallCheckSubcommand::executeFirewall);
|
||||
|
||||
static final SubCommand[] VALUES = values();
|
||||
|
||||
final String description;
|
||||
final Permission permission;
|
||||
final Consumer<CommandContext<UserAudience>> executor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.event;
|
||||
|
||||
public class ShutdownEvent {
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.event.util;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.matcher.AbstractMatcher;
|
||||
import net.engio.mbassy.listener.Listener;
|
||||
|
||||
public class ListenerAnnotationMatcher extends AbstractMatcher<TypeLiteral<?>> {
|
||||
@Override
|
||||
public boolean matches(TypeLiteral<?> typeLiteral) {
|
||||
Class<?> rawType = typeLiteral.getRawType();
|
||||
return rawType.isAnnotationPresent(Listener.class);
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.engio.mbassy.listener.Handler;
|
||||
import net.engio.mbassy.listener.Listener;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.link.LinkRequest;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
@@ -41,8 +43,10 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.database.config.DatabaseConfig;
|
||||
import org.geysermc.floodgate.database.config.DatabaseConfigLoader;
|
||||
import org.geysermc.floodgate.event.ShutdownEvent;
|
||||
import org.geysermc.floodgate.util.InjectorHolder;
|
||||
|
||||
@Listener
|
||||
public abstract class CommonPlayerLink implements PlayerLink {
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final ExecutorService executorService = Executors.newFixedThreadPool(11);
|
||||
@@ -102,4 +106,9 @@ public abstract class CommonPlayerLink implements PlayerLink {
|
||||
public void stop() {
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
@Handler
|
||||
public void onShutdown(ShutdownEvent ignored) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,19 +29,23 @@ import static org.geysermc.floodgate.util.Constants.GET_BEDROCK_LINK;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.api.link.LinkRequestResult;
|
||||
import org.geysermc.floodgate.api.link.PlayerLink;
|
||||
import org.geysermc.floodgate.util.HttpUtils;
|
||||
import org.geysermc.floodgate.util.HttpUtils.DefaultHttpResponse;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.geysermc.floodgate.util.HttpClient.DefaultHttpResponse;
|
||||
import org.geysermc.floodgate.util.LinkedPlayer;
|
||||
import org.geysermc.floodgate.util.Utils;
|
||||
|
||||
@Getter
|
||||
public class GlobalPlayerLinking extends CommonPlayerLink {
|
||||
@Inject
|
||||
private HttpClient httpClient;
|
||||
|
||||
private PlayerLink databaseImpl;
|
||||
|
||||
public void setDatabaseImpl(PlayerLink databaseImpl) {
|
||||
@@ -94,7 +98,7 @@ public class GlobalPlayerLinking extends CommonPlayerLink {
|
||||
return CompletableFuture.supplyAsync(
|
||||
() -> {
|
||||
DefaultHttpResponse response =
|
||||
HttpUtils.get(GET_BEDROCK_LINK + bedrockId.getLeastSignificantBits());
|
||||
httpClient.get(GET_BEDROCK_LINK + bedrockId.getLeastSignificantBits());
|
||||
|
||||
// either the global api is down or it failed to return link
|
||||
if (!response.isCodeOk()) {
|
||||
@@ -144,7 +148,7 @@ public class GlobalPlayerLinking extends CommonPlayerLink {
|
||||
return CompletableFuture.supplyAsync(
|
||||
() -> {
|
||||
DefaultHttpResponse response =
|
||||
HttpUtils.get(GET_BEDROCK_LINK + bedrockId.getLeastSignificantBits());
|
||||
httpClient.get(GET_BEDROCK_LINK + bedrockId.getLeastSignificantBits());
|
||||
|
||||
if (!response.isCodeOk()) {
|
||||
getLogger().error(
|
||||
|
||||
@@ -28,10 +28,17 @@ package org.geysermc.floodgate.module;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Named;
|
||||
import com.google.inject.spi.InjectionListener;
|
||||
import com.google.inject.spi.TypeEncounter;
|
||||
import com.google.inject.spi.TypeListener;
|
||||
import io.netty.util.AttributeKey;
|
||||
import java.nio.file.Path;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.engio.mbassy.bus.MBassador;
|
||||
import net.engio.mbassy.bus.common.PubSubSupport;
|
||||
import net.engio.mbassy.bus.error.IPublicationErrorHandler.ConsoleLogger;
|
||||
import org.geysermc.floodgate.addon.data.HandshakeHandlersImpl;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
||||
@@ -48,29 +55,46 @@ import org.geysermc.floodgate.crypto.AesKeyProducer;
|
||||
import org.geysermc.floodgate.crypto.Base64Topping;
|
||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.crypto.KeyProducer;
|
||||
import org.geysermc.floodgate.event.util.ListenerAnnotationMatcher;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.news.NewsChecker;
|
||||
import org.geysermc.floodgate.packet.PacketHandlersImpl;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.player.FloodgateHandshakeHandler;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
import org.geysermc.floodgate.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.skin.SkinUploadManager;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CommonModule extends AbstractModule {
|
||||
private final PubSubSupport<Object> eventBus = new MBassador<>(new ConsoleLogger(true));
|
||||
private final Path dataDirectory;
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(PubSubSupport.class).toInstance(eventBus);
|
||||
// register every class that has the Listener annotation
|
||||
bindListener(new ListenerAnnotationMatcher(), new TypeListener() {
|
||||
@Override
|
||||
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
|
||||
encounter.register((InjectionListener<I>) eventBus::subscribe);
|
||||
}
|
||||
});
|
||||
|
||||
bind(HttpClient.class).in(Singleton.class);
|
||||
|
||||
bind(FloodgateApi.class).to(SimpleFloodgateApi.class);
|
||||
bind(PlatformInjector.class).to(CommonPlatformInjector.class);
|
||||
|
||||
bind(HandshakeHandlers.class).to(HandshakeHandlersImpl.class);
|
||||
bind(HandshakeHandlersImpl.class).in(Singleton.class);
|
||||
|
||||
bind(PacketHandlers.class).to(PacketHandlersImpl.class);
|
||||
bind(PacketHandlersImpl.class).asEagerSingleton();
|
||||
|
||||
bind(NewsChecker.class).in(Singleton.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -116,12 +140,6 @@ public class CommonModule extends AbstractModule {
|
||||
return new LanguageManager(configHolder, logger);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public HandshakeHandlersImpl handshakeHandlers() {
|
||||
return new HandshakeHandlersImpl();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public FloodgateHandshakeHandler handshakeHandler(
|
||||
@@ -154,8 +172,16 @@ public class CommonModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public NewsChecker newsChecker(CommandUtil commandUtil, FloodgateLogger logger) {
|
||||
return new NewsChecker(commandUtil, logger, Constants.GIT_BRANCH, Constants.BUILD_NUMBER);
|
||||
@Named("gitBranch")
|
||||
public String gitBranch() {
|
||||
return Constants.GIT_BRANCH;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("buildNumber")
|
||||
public int buildNumber() {
|
||||
return Constants.BUILD_NUMBER;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -31,12 +31,8 @@ import com.google.inject.name.Named;
|
||||
import java.nio.file.Path;
|
||||
import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
||||
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
|
||||
public final class ProxyCommonModule extends CommonModule {
|
||||
public ProxyCommonModule(Path dataDirectory) {
|
||||
@@ -46,7 +42,9 @@ public final class ProxyCommonModule extends CommonModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
|
||||
bind(SimpleFloodgateApi.class).to(ProxyFloodgateApi.class);
|
||||
bind(ProxyFloodgateApi.class).in(Singleton.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -55,14 +53,4 @@ public final class ProxyCommonModule extends CommonModule {
|
||||
public Class<? extends FloodgateConfig> floodgateConfigClass() {
|
||||
return ProxyFloodgateConfig.class;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public ProxyFloodgateApi proxyFloodgateApi(
|
||||
PluginMessageManager pluginMessageManager,
|
||||
FloodgateConfigHolder configHolder,
|
||||
FloodgateLogger logger,
|
||||
FloodgateCipher cipher) {
|
||||
return new ProxyFloodgateApi(pluginMessageManager, configHolder, logger, cipher);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,29 +30,22 @@ import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import java.nio.file.Path;
|
||||
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
|
||||
public final class ServerCommonModule extends CommonModule {
|
||||
public ServerCommonModule(Path dataDirectory) {
|
||||
super(dataDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(SimpleFloodgateApi.class).in(Singleton.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("configClass")
|
||||
public Class<? extends FloodgateConfig> floodgateConfigClass() {
|
||||
return FloodgateConfig.class;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public SimpleFloodgateApi floodgateApi(
|
||||
PluginMessageManager pluginMessageManager,
|
||||
FloodgateConfigHolder configHolder,
|
||||
FloodgateLogger logger) {
|
||||
return new SimpleFloodgateApi(pluginMessageManager, configHolder, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ package org.geysermc.floodgate.news;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -35,34 +37,40 @@ import java.util.Map;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.engio.mbassy.listener.Handler;
|
||||
import net.engio.mbassy.listener.Listener;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.event.ShutdownEvent;
|
||||
import org.geysermc.floodgate.news.data.AnnouncementData;
|
||||
import org.geysermc.floodgate.news.data.BuildSpecificData;
|
||||
import org.geysermc.floodgate.news.data.CheckAfterData;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpUtils;
|
||||
import org.geysermc.floodgate.util.HttpUtils.HttpResponse;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.geysermc.floodgate.util.HttpClient.HttpResponse;
|
||||
|
||||
@Listener
|
||||
public class NewsChecker {
|
||||
private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
|
||||
private final CommandUtil commandUtil;
|
||||
private final FloodgateLogger logger;
|
||||
|
||||
private final Map<Integer, NewsItem> activeNewsItems = new HashMap<>();
|
||||
private final String branch;
|
||||
private final int build;
|
||||
|
||||
@Inject
|
||||
private CommandUtil commandUtil;
|
||||
@Inject
|
||||
private HttpClient httpClient;
|
||||
@Inject
|
||||
private FloodgateLogger logger;
|
||||
|
||||
@Inject
|
||||
@Named("gitBranch")
|
||||
private String branch;
|
||||
@Inject
|
||||
@Named("buildNumber")
|
||||
private int build;
|
||||
|
||||
private boolean firstCheck;
|
||||
|
||||
public NewsChecker(CommandUtil commandUtil, FloodgateLogger logger, String branch, int build) {
|
||||
this.commandUtil = commandUtil;
|
||||
this.logger = logger;
|
||||
this.branch = branch;
|
||||
this.build = build;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
executorService.scheduleWithFixedDelay(this::checkNews, 0, 30, TimeUnit.MINUTES);
|
||||
}
|
||||
@@ -72,10 +80,10 @@ public class NewsChecker {
|
||||
}
|
||||
|
||||
private void checkNews() {
|
||||
HttpResponse<JsonArray> response =
|
||||
HttpUtils.getSilent(
|
||||
HttpResponse<JsonArray> response = httpClient.getSilent(
|
||||
Constants.NEWS_OVERVIEW_URL + Constants.NEWS_PROJECT_NAME,
|
||||
JsonArray.class);
|
||||
JsonArray.class
|
||||
);
|
||||
|
||||
JsonArray array = response.getResponse();
|
||||
|
||||
@@ -197,4 +205,9 @@ public class NewsChecker {
|
||||
public void shutdown() {
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
@Handler
|
||||
public void onShutdown(ShutdownEvent ignored) {
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.platform.command;
|
||||
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
|
||||
public abstract class FloodgateSubCommand {
|
||||
public abstract String name();
|
||||
|
||||
public abstract String description();
|
||||
|
||||
public abstract Permission permission();
|
||||
|
||||
public abstract void execute(CommandContext<UserAudience> context);
|
||||
}
|
||||
@@ -37,34 +37,38 @@ import java.util.concurrent.Executors;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.engio.mbassy.listener.Handler;
|
||||
import net.engio.mbassy.listener.Listener;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.floodgate.event.ShutdownEvent;
|
||||
|
||||
// resources are properly closed and ignoring the original stack trace is intended
|
||||
@SuppressWarnings({"PMD.CloseResource", "PMD.PreserveStackTrace"})
|
||||
public class HttpUtils {
|
||||
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
@Listener
|
||||
public class HttpClient {
|
||||
private static final String USER_AGENT = "GeyserMC/Floodgate";
|
||||
|
||||
public static CompletableFuture<DefaultHttpResponse> asyncGet(String urlString) {
|
||||
return CompletableFuture.supplyAsync(() -> get(urlString), EXECUTOR_SERVICE);
|
||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public CompletableFuture<DefaultHttpResponse> asyncGet(String urlString) {
|
||||
return CompletableFuture.supplyAsync(() -> get(urlString), executorService);
|
||||
}
|
||||
|
||||
public static DefaultHttpResponse get(String urlString) {
|
||||
public DefaultHttpResponse get(String urlString) {
|
||||
return readDefaultResponse(request(urlString));
|
||||
}
|
||||
|
||||
public static <T> HttpResponse<T> get(String urlString, Class<T> clazz) {
|
||||
public <T> HttpResponse<T> get(String urlString, Class<T> clazz) {
|
||||
return readResponse(request(urlString), clazz);
|
||||
}
|
||||
|
||||
public static <T> HttpResponse<T> getSilent(String urlString, Class<T> clazz) {
|
||||
public <T> HttpResponse<T> getSilent(String urlString, Class<T> clazz) {
|
||||
return readResponseSilent(request(urlString), clazz);
|
||||
}
|
||||
|
||||
private static HttpURLConnection request(String urlString) {
|
||||
private HttpURLConnection request(String urlString) {
|
||||
HttpURLConnection connection;
|
||||
|
||||
try {
|
||||
@@ -88,7 +92,7 @@ public class HttpUtils {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static <T> HttpResponse<T> readResponse(HttpURLConnection connection, Class<T> clazz) {
|
||||
private <T> HttpResponse<T> readResponse(HttpURLConnection connection, Class<T> clazz) {
|
||||
InputStreamReader streamReader = createReader(connection);
|
||||
if (streamReader == null) {
|
||||
return new HttpResponse<>(-1, null);
|
||||
@@ -96,7 +100,7 @@ public class HttpUtils {
|
||||
|
||||
try {
|
||||
int responseCode = connection.getResponseCode();
|
||||
T response = GSON.fromJson(streamReader, clazz);
|
||||
T response = gson.fromJson(streamReader, clazz);
|
||||
return new HttpResponse<>(responseCode, response);
|
||||
} catch (Exception ignored) {
|
||||
return new HttpResponse<>(-1, null);
|
||||
@@ -109,9 +113,7 @@ public class HttpUtils {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static <T> HttpResponse<T> readResponseSilent(
|
||||
HttpURLConnection connection,
|
||||
Class<T> clazz) {
|
||||
private <T> HttpResponse<T> readResponseSilent(HttpURLConnection connection, Class<T> clazz) {
|
||||
try {
|
||||
return readResponse(connection, clazz);
|
||||
} catch (Exception ignored) {
|
||||
@@ -120,7 +122,7 @@ public class HttpUtils {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static DefaultHttpResponse readDefaultResponse(HttpURLConnection connection) {
|
||||
private DefaultHttpResponse readDefaultResponse(HttpURLConnection connection) {
|
||||
InputStreamReader streamReader = createReader(connection);
|
||||
if (streamReader == null) {
|
||||
return new DefaultHttpResponse(-1, null);
|
||||
@@ -128,7 +130,7 @@ public class HttpUtils {
|
||||
|
||||
try {
|
||||
int responseCode = connection.getResponseCode();
|
||||
JsonObject response = GSON.fromJson(streamReader, JsonObject.class);
|
||||
JsonObject response = gson.fromJson(streamReader, JsonObject.class);
|
||||
return new DefaultHttpResponse(responseCode, response);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException("Failed to read response", exception);
|
||||
@@ -141,7 +143,7 @@ public class HttpUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static InputStreamReader createReader(HttpURLConnection connection) {
|
||||
private InputStreamReader createReader(HttpURLConnection connection) {
|
||||
InputStream stream;
|
||||
try {
|
||||
stream = connection.getInputStream();
|
||||
@@ -160,6 +162,11 @@ public class HttpUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Handler
|
||||
public void onShutdown(ShutdownEvent ignored) {
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public static class HttpResponse<T> {
|
||||
@@ -29,6 +29,7 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import java.nio.file.Path;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
@@ -69,4 +70,9 @@ public final class VelocityPlugin {
|
||||
new PluginMessageModule()
|
||||
);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onProxyShutdown(ProxyShutdownEvent event) {
|
||||
platform.disable();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user