1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2025-12-19 14:59:20 +00:00

Changed how post-enable messages work internally + minor other changes

This commit is contained in:
Tim203
2022-07-11 11:13:37 +02:00
parent 904c584a2a
commit 41de3673a7
10 changed files with 221 additions and 171 deletions

View File

@@ -35,23 +35,21 @@ import org.geysermc.floodgate.api.InstanceHolder;
import org.geysermc.floodgate.api.handshake.HandshakeHandlers;
import org.geysermc.floodgate.api.inject.PlatformInjector;
import org.geysermc.floodgate.api.link.PlayerLink;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.api.packet.PacketHandlers;
import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.event.PostEnableEvent;
import org.geysermc.floodgate.event.ShutdownEvent;
import org.geysermc.floodgate.link.PlayerLinkLoader;
import org.geysermc.floodgate.module.PostInitializeModule;
import org.geysermc.floodgate.news.NewsChecker;
import org.geysermc.floodgate.util.Metrics;
import org.geysermc.floodgate.util.PrefixCheckTask;
import org.geysermc.floodgate.util.PostEnableMessages;
public class FloodgatePlatform {
private static final UUID KEY = UUID.randomUUID();
@Inject private FloodgateApi api;
@Inject private PlatformInjector injector;
@Inject private FloodgateLogger logger;
@Inject private FloodgateConfig config;
@Inject private Injector guice;
@@ -77,9 +75,11 @@ public class FloodgatePlatform {
this.guice = guice.createChildInjector(new PostInitializeModule(postInitializeModules));
PrefixCheckTask.checkAndExecuteDelayed(config, logger);
//todo add some kind of auto-load, as this looks kinda weird
guice.getInstance(PostEnableMessages.class);
guice.getInstance(Metrics.class);
guice.getInstance(PubSubSupport.class).publish(new PostEnableEvent());
}
public void disable() {

View File

@@ -41,7 +41,7 @@ import org.geysermc.floodgate.crypto.KeyProducer;
@Getter
@RequiredArgsConstructor
public final class ConfigLoader {
private final Path dataFolder;
private final Path dataDirectory;
private final Class<? extends FloodgateConfig> configClass;
private final KeyProducer keyProducer;
@@ -62,7 +62,7 @@ public final class ConfigLoader {
ConfigUtilities utilities =
ConfigUtilities.builder()
.fileCodec(PathFileCodec.of(dataFolder))
.fileCodec(PathFileCodec.of(dataDirectory))
.configFile("config.yml")
.templateReader(ResourceTemplateReader.of(getClass()))
.template(templateFile)

View File

@@ -52,7 +52,9 @@ public class FloodgateConfig implements GenericPostInitializeCallback<ConfigLoad
private boolean debug;
private int configVersion;
private Key key;
private String rawUsernamePrefix;
public boolean isProxy() {
return this instanceof ProxyFloodgateConfig;
@@ -60,7 +62,7 @@ public class FloodgateConfig implements GenericPostInitializeCallback<ConfigLoad
@Override
public CallbackResult postInitialize(ConfigLoader loader) {
Path keyPath = loader.getDataFolder().resolve(getKeyFileName());
Path keyPath = loader.getDataDirectory().resolve(getKeyFileName());
// don't assume that the key always exists with the existence of a config
if (!Files.exists(keyPath)) {
@@ -74,6 +76,14 @@ public class FloodgateConfig implements GenericPostInitializeCallback<ConfigLoad
} catch (IOException exception) {
return CallbackResult.failed(exception.getMessage());
}
rawUsernamePrefix = usernamePrefix;
// Java usernames can't be longer than 16 chars
if (usernamePrefix.length() >= 16) {
usernamePrefix = ".";
}
return CallbackResult.ok();
}

View File

@@ -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 PostEnableEvent {
}

View File

@@ -28,11 +28,7 @@ package org.geysermc.floodgate.util;
import com.google.common.base.Joiner;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
@@ -117,21 +113,11 @@ public final class LanguageManager {
return true;
}
InputStream localeStream = LanguageManager.class.getClassLoader().getResourceAsStream(
"languages/texts/" + formatLocale + ".properties");
Properties properties =
Utils.readProperties("languages/texts/" + formatLocale + ".properties");
// load the locale
if (localeStream != null) {
Properties localeProp = new Properties();
try (Reader reader = new InputStreamReader(localeStream, StandardCharsets.UTF_8)) {
localeProp.load(reader);
} catch (Exception e) {
throw new AssertionError("Failed to load Floodgate locale", e);
}
// insert the locale into the mappings
localeMappings.put(formatLocale, localeProp);
if (properties != null) {
localeMappings.put(formatLocale, properties);
return true;
}

View File

@@ -0,0 +1,105 @@
/*
* 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.util;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import net.engio.mbassy.listener.Handler;
import net.engio.mbassy.listener.Listener;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.event.PostEnableEvent;
@Listener
public final class PostEnableMessages {
private final List<String> messages = new ArrayList<>();
@Inject private FloodgateConfig config;
@Inject private FloodgateLogger logger;
public void add(String[] message, Object... args) {
StringBuilder builder = new StringBuilder();
builder.append("\n**********************************\n");
for (String part : message) {
builder.append("* ").append(part).append('\n');
}
builder.append("**********************************");
messages.add(MessageFormatter.format(builder.toString(), args));
}
@Inject
private void init() {
registerPrefixMessages();
}
private void registerPrefixMessages() {
String prefix = config.getRawUsernamePrefix();
if (prefix.isEmpty()) {
add(new String[]{
"You specified an empty prefix in your Floodgate config for Bedrock players!",
"Should a Java player join and a Bedrock player join with the same username, unwanted results and conflicts will happen!",
"We strongly recommend using . as the prefix, but other alternatives that will not conflict include: +, - and *"
});
} else if (!Utils.isUniquePrefix(prefix)) {
add(new String[]{
"The prefix you entered in your Floodgate config ({}) could lead to username conflicts!",
"Should a Java player join with the username {}Notch, and a Bedrock player join as Notch (who will be given the name {}Notch), unwanted results will happen!",
"We strongly recommend using . as the prefix, but other alternatives that will not conflict include: +, - and *"
}, prefix, prefix, prefix, prefix);
}
if (prefix.length() >= 16) {
add(new String[]{
"The prefix you entered in your Floodgate config ({}) is longer than a Java username can be!",
"Because of this, we reset the prefix to the default Floodgate prefix (.)"
}, prefix);
} else if (prefix.length() > 2) {
// we only have to warn them if we haven't replaced the prefix
add(new String[]{
"The prefix you entered in your Floodgate config ({}) is long! ({} characters)",
"A prefix is there to prevent username conflicts. However, a long prefix makes the chance of username conflicts higher.",
"We strongly recommend using . as the prefix, but other alternatives that will not conflict include: +, - and *"
}, prefix, prefix.length());
}
}
@Handler
public void onPostEnable(PostEnableEvent ignored) {
new Thread(() -> {
// normally proxies don't have a lot of plugins, so proxies don't need to sleep as long
try {
Thread.sleep(config.isProxy() ? 2000 : 5000);
} catch (InterruptedException ignored1) {
}
messages.forEach(logger::warn);
}).start();
}
}

View File

@@ -1,65 +0,0 @@
/*
* 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.util;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.config.FloodgateConfig;
public final class PrefixCheckTask {
public static void checkAndExecuteDelayed(FloodgateConfig config, FloodgateLogger logger) {
if (Utils.isUniquePrefix(config.getUsernamePrefix())) {
return;
}
new Thread(() -> {
// normally proxies don't have a lot of plugins, so proxies don't need to sleep as long
try {
Thread.sleep(config.isProxy() ? 1000 : 2000);
} catch (InterruptedException ignored) {
}
if (config.getUsernamePrefix().isEmpty()) {
logger.warn("\n" +
"**********************************\n" +
"* You specified an empty prefix in your Floodgate config for Bedrock players!\n" +
"* Should a Java player join and a Bedrock player join with the same username, unwanted results and conflicts will happen!\n" +
"* We strongly recommend using . as the prefix, but other alternatives that will not conflict include: +, - and *\n" +
"**********************************");
return;
}
logger.warn(
"\n" +
"**********************************\n" +
"* The prefix you entered in your Floodgate config ({}) could lead to username conflicts!\n" +
"* Should a Java player join with the username {}Notch, and a Bedrock player join as Notch (who will be given the name {}Notch), unwanted results will happen!\n" +
"* We strongly recommend using . as the prefix, but other alternatives that will not conflict include: +, - and *\n" +
"**********************************",
config.getUsernamePrefix(), config.getUsernamePrefix(),
config.getUsernamePrefix(), config.getUsernamePrefix());
}).start();
}
}

View File

@@ -28,18 +28,10 @@ package org.geysermc.floodgate.util;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelPipeline;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.UUID;
@@ -47,7 +39,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.regex.Pattern;
public class Utils {
private static final Pattern NON_UNIQUE_PREFIX = Pattern.compile("^[a-zA-Z0-9_]{0,16}$");
private static final Pattern NON_UNIQUE_PREFIX = Pattern.compile("^\\w{0,16}$");
private static final Pattern DATABASE_NAME = Pattern.compile(Constants.DATABASE_NAME_FORMAT);
/**
@@ -66,33 +58,21 @@ public class Utils {
}
}
public static List<String> readAllLines(String resourcePath) throws IOException {
InputStream stream = Utils.class.getClassLoader().getResourceAsStream(resourcePath);
try (BufferedReader reader = newBufferedReader(stream, StandardCharsets.UTF_8)) {
List<String> result = new ArrayList<>();
for (; ; ) {
String line = reader.readLine();
if (line == null) {
break;
}
result.add(line);
}
return result;
}
}
public static BufferedReader newBufferedReader(InputStream inputStream, Charset charset) {
CharsetDecoder decoder = charset.newDecoder();
Reader reader = new InputStreamReader(inputStream, decoder);
return new BufferedReader(reader);
}
/**
* Reads a properties resource file
* @param resourceFile the resource file to read
* @return the properties file if the resource exists, otherwise null
* @throws AssertionError if something went wrong while readin the resource file
*/
public static Properties readProperties(String resourceFile) {
Properties properties = new Properties();
try (InputStream is = Utils.class.getClassLoader().getResourceAsStream(resourceFile)) {
if (is == null) {
return null;
}
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
throw new AssertionError("Failed to read properties file", e);
}
return properties;
}