Only print premium warning on command sender site

This commit is contained in:
games647
2024-05-21 21:53:30 +02:00
parent c7254034bb
commit 9a400f5ae1
20 changed files with 59 additions and 86 deletions

View File

@ -53,6 +53,8 @@ import org.slf4j.Logger;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@ -75,6 +77,9 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
private final BukkitScheduler scheduler;
@Getter
private final Collection<UUID> pendingConfirms = new HashSet<>();
@Getter
private FastLoginCore<Player, CommandSender, FastLoginBukkit> core;
@ -84,6 +89,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
private PremiumPlaceholder premiumPlaceholder;
@Getter
private AuthenticationBackend backend;
@Getter
@ -289,6 +295,10 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
initialized = true;
}
public ProxyAuthentication getBungeeManager() {
return (ProxyAuthentication) backend;
}
@Override
public BedrockService<?> getBedrockService() {
if (floodgateService != null) {

View File

@ -94,7 +94,7 @@ public class ConnectionListener implements Listener {
public void onPlayerQuit(PlayerQuitEvent quitEvent) {
Player player = quitEvent.getPlayer();
plugin.getCore().getPendingConfirms().remove(player.getUniqueId());
plugin.getPendingConfirms().remove(player.getUniqueId());
plugin.getPremiumPlayers().remove(player.getUniqueId());
}
}

View File

@ -80,7 +80,7 @@ public class ForceLoginTask extends ForceLoginManagement<Player, CommandSender,
@Override
public void onForceActionSuccess(LoginSession session) {
if (core.getPlugin().getBungeeManager().isEnabled()) {
if (core.getPlugin().getBungeeManager().isAvailable()) {
core.getPlugin().getBungeeManager().sendPluginMessage(player, new SuccessMessage());
}
}

View File

@ -48,7 +48,7 @@ public abstract class LocalAuthentication implements AuthenticationBackend {
// if server is using paper - we need to add one more listener to correct the user cache usage
if (isPaper()) {
pluginManager.registerEvents(new PaperCacheListener(this), this);
pluginManager.registerEvents(new PaperCacheListener(plugin), plugin);
} else if (plugin.getConfig().getBoolean("forwardSkin")) {
//if server is using paper - we need to set the skin at pre login anyway, so no need for this listener
pluginManager.registerEvents(new SkinApplyListener(plugin), plugin);

View File

@ -110,7 +110,7 @@ public class ProtocolLibListener extends PacketAdapter {
public void onPacketReceiving(PacketEvent packetEvent) {
if (packetEvent.isCancelled()
|| plugin.getCore().getAuthPluginHook() == null
|| !plugin.isServerFullyStarted()) {
|| !plugin.isInitialized()) {
return;
}
@ -204,7 +204,7 @@ public class ProtocolLibListener extends PacketAdapter {
Either<byte[], ?> either = packet.getSpecificModifier(Either.class).read(0);
if (clientPublicKey == null) {
Optional<byte[]> left = either.left();
if (left.isEmpty()) {
if (!left.isPresent()) {
plugin.getLog().error("No verify token sent if requested without player signed key {}", sender);
return false;
}
@ -212,7 +212,7 @@ public class ProtocolLibListener extends PacketAdapter {
return EncryptionUtil.verifyNonce(expectedToken, keyPair.getPrivate(), left.get());
} else {
Optional<?> optSignatureData = either.right();
if (optSignatureData.isEmpty()) {
if (!optSignatureData.isPresent()) {
plugin.getLog().error("No signature given to sent player signing key {}", sender);
return false;
}

View File

@ -27,11 +27,15 @@ package com.github.games647.fastlogin.bukkit.auth.proxy;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.auth.AuthenticationBackend;
import com.github.games647.fastlogin.core.message.ChannelMessage;
import com.github.games647.fastlogin.core.message.LoginActionMessage;
import com.github.games647.fastlogin.core.message.NamespaceKey;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.messaging.PluginMessageRecipient;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@ -138,4 +142,14 @@ public class ProxyAuthentication implements AuthenticationBackend {
return false;
}
public void sendPluginMessage(PluginMessageRecipient player, ChannelMessage message) {
if (player != null) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
message.writeTo(dataOutput);
NamespaceKey channel = new NamespaceKey(plugin.getName(), message.getChannelName());
player.sendPluginMessage(plugin, channel.getCombinedName(), dataOutput.toByteArray());
}
}
}

View File

@ -26,13 +26,8 @@
package com.github.games647.fastlogin.bukkit.auth.proxy;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.core.message.ChannelMessage;
import com.github.games647.fastlogin.core.message.NamespaceKey;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageRecipient;
import java.io.IOException;
import java.nio.file.Files;
@ -67,16 +62,6 @@ public class ProxyVerifier {
Bukkit.getOnlinePlayers().forEach(player -> player.removeMetadata(plugin.getName(), plugin));
}
public void sendPluginMessage(PluginMessageRecipient player, ChannelMessage message) {
if (player != null) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
message.writeTo(dataOutput);
NamespaceKey channel = new NamespaceKey(plugin.getName(), message.getChannelName());
player.sendPluginMessage(plugin, channel.getCombinedName(), dataOutput.toByteArray());
}
}
public void loadSecrets() {
proxyIds = loadBungeeCordIds();
if (proxyIds.isEmpty()) {

View File

@ -64,18 +64,18 @@ public class PremiumCommand extends ToggleCommand {
return;
}
UUID id = ((Player) sender).getUniqueId();
if (plugin.getConfig().getBoolean("premium-warning") && !plugin.getPendingConfirms().contains(id)) {
sender.sendMessage(plugin.getCore().getMessage("premium-warning"));
plugin.getPendingConfirms().add(id);
return;
}
if (forwardPremiumCommand(sender, sender.getName())) {
return;
}
UUID id = ((Player) sender).getUniqueId();
if (plugin.getConfig().getBoolean("premium-warning") && !plugin.getCore().getPendingConfirms().contains(id)) {
sender.sendMessage(plugin.getCore().getMessage("premium-warning"));
plugin.getCore().getPendingConfirms().add(id);
return;
}
plugin.getCore().getPendingConfirms().remove(id);
plugin.getPendingConfirms().remove(id);
//todo: load async
StoredProfile profile = plugin.getCore().getStorage().loadProfile(sender.getName());
if (profile.isOnlinemodePreferred()) {

View File

@ -26,6 +26,7 @@
package com.github.games647.fastlogin.bukkit.command;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.auth.proxy.ProxyAuthentication;
import com.github.games647.fastlogin.core.message.ChangePremiumMessage;
import com.github.games647.fastlogin.core.message.ChannelMessage;
import org.bukkit.Bukkit;
@ -55,7 +56,7 @@ public abstract class ToggleCommand implements CommandExecutor {
}
protected boolean forwardBungeeCommand(CommandSender sender, String target, boolean activate) {
if (plugin.getBungeeManager().isEnabled()) {
if (plugin.getBackend() instanceof ProxyAuthentication) {
sendBungeeActivateMessage(sender, target, activate);
plugin.getCore().sendLocaleMessage("wait-on-proxy", sender);
return true;
@ -80,7 +81,7 @@ public abstract class ToggleCommand implements CommandExecutor {
plugin.getBungeeManager().sendPluginMessage((PluginMessageRecipient) invoker, message);
} else {
Optional<? extends Player> optPlayer = Bukkit.getServer().getOnlinePlayers().stream().findFirst();
if (optPlayer.isEmpty()) {
if (!optPlayer.isPresent()) {
plugin.getLog().info("No player online to send a plugin message to the proxy");
return;
}

View File

@ -23,7 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit.listener.protocollib;
package com.github.games647.fastlogin.bukkit.auth.protocollib;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;

View File

@ -23,11 +23,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit.listener.protocollib;
package com.github.games647.fastlogin.bukkit.auth.protocollib;
import com.github.games647.fastlogin.bukkit.auth.protocollib.SignatureTestData.SignatureData;
import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey;
import com.github.games647.fastlogin.bukkit.auth.protocollib.protocollib.EncryptionUtil;
import com.github.games647.fastlogin.bukkit.listener.protocollib.SignatureTestData.SignatureData;
import com.google.common.hash.Hashing;
import lombok.val;
import org.junit.jupiter.api.Test;
@ -89,7 +88,7 @@ class EncryptionUtilTest {
@Test
void testExpiredClientKey() throws Exception {
val clientKey = ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
val clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
// Client expires at the exact second mentioned, so use it for verification
val expiredTimestamp = clientKey.expiry();
@ -106,7 +105,7 @@ class EncryptionUtilTest {
"client_keys/invalid_wrong_signature.json"
})
void testInvalidClientKey(String clientKeySource) throws Exception {
val clientKey = ResourceLoader.loadClientKey(clientKeySource);
val clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey(clientKeySource);
Instant expireTimestamp = clientKey.expiry().minus(5, ChronoUnit.HOURS);
assertFalse(EncryptionUtil.verifyClientKey(clientKey, expireTimestamp, null));
@ -114,7 +113,7 @@ class EncryptionUtilTest {
@Test
void testValidClientKey() throws Exception {
val clientKey = ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
val clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
val verificationTimestamp = clientKey.expiry().minus(5, ChronoUnit.HOURS);
assertTrue(EncryptionUtil.verifyClientKey(clientKey, verificationTimestamp, null));
@ -122,7 +121,7 @@ class EncryptionUtilTest {
@Test
void testValid191ClientKey() throws Exception {
val clientKey = ResourceLoader.loadClientKey("client_keys/valid_public_key_19_1.json");
val clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key_19_1.json");
val verificationTimestamp = clientKey.expiry().minus(5, ChronoUnit.HOURS);
val ownerPremiumId = UUID.fromString("0aaa2c13-922a-411b-b655-9b8c08404695");
@ -131,7 +130,7 @@ class EncryptionUtilTest {
@Test
void testIncorrect191ClientOwner() throws Exception {
val clientKey = ResourceLoader.loadClientKey("client_keys/valid_public_key_19_1.json");
val clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key_19_1.json");
val verificationTimestamp = clientKey.expiry().minus(5, ChronoUnit.HOURS);
val ownerPremiumId = UUID.fromString("61699b2e-d327-4a01-9f1e-0ea8c3f06bc6");
@ -171,7 +170,7 @@ class EncryptionUtilTest {
void testServerIdHash() throws Exception {
val serverId = "";
val sharedSecret = generateSharedKey();
val serverPK = ResourceLoader.loadClientKey("client_keys/valid_public_key.json").key();
val serverPK = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key.json").key();
String sessionHash = getServerHash(serverId, sharedSecret, serverPK);
assertEquals(EncryptionUtil.getServerIdHashString(serverId, sharedSecret, serverPK), sessionHash);
@ -201,7 +200,7 @@ class EncryptionUtilTest {
void testServerIdHashWrongSecret() throws Exception {
val serverId = "";
val sharedSecret = generateSharedKey();
val serverPK = ResourceLoader.loadClientKey("client_keys/valid_public_key.json").key();
val serverPK = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key.json").key();
String sessionHash = getServerHash(serverId, sharedSecret, serverPK);
assertNotEquals(EncryptionUtil.getServerIdHashString("", generateSharedKey(), serverPK), sessionHash);
@ -220,7 +219,7 @@ class EncryptionUtilTest {
@Test
void testValidSignedNonce() throws Exception {
ClientPublicKey clientKey = ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
ClientPublicKey clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
SignatureTestData testData = SignatureTestData.fromResource("signature/valid_signature.json");
assertTrue(verifySignedNonce(testData, clientKey));
}
@ -232,7 +231,7 @@ class EncryptionUtilTest {
"signature/incorrect_signature.json",
})
void testIncorrectNonce(String signatureSource) throws Exception {
ClientPublicKey clientKey = ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
ClientPublicKey clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/valid_public_key.json");
SignatureTestData testData = SignatureTestData.fromResource(signatureSource);
assertFalse(verifySignedNonce(testData, clientKey));
}
@ -240,7 +239,7 @@ class EncryptionUtilTest {
@Test
void testWrongPublicKeySigned() throws Exception {
// load a different public key
ClientPublicKey clientKey = ResourceLoader.loadClientKey("client_keys/invalid_wrong_key.json");
ClientPublicKey clientKey = com.github.games647.fastlogin.bukkit.auth.protocollib.ResourceLoader.loadClientKey("client_keys/invalid_wrong_key.json");
SignatureTestData testData = SignatureTestData.fromResource("signature/valid_signature.json");
assertFalse(verifySignedNonce(testData, clientKey));
}

View File

@ -23,7 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit.listener.protocollib;
package com.github.games647.fastlogin.bukkit.auth.protocollib;
import com.github.games647.fastlogin.bukkit.auth.protocollib.packet.ClientPublicKey;
import com.google.common.io.Resources;

View File

@ -23,7 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit.listener.protocollib;
package com.github.games647.fastlogin.bukkit.auth.protocollib;
import com.google.common.io.Resources;
import com.google.gson.Gson;

View File

@ -23,7 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit.listener.protocollib;
package com.github.games647.fastlogin.bukkit.auth.protocollib;
import com.comphenix.protocol.injector.packet.PacketRegistry;
import com.comphenix.protocol.reflect.accessors.Accessors;

View File

@ -23,9 +23,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit.task;
package com.github.games647.fastlogin.bukkit.hook;
import com.github.games647.fastlogin.bukkit.hook.DelayedAuthHook;
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import lombok.val;
import org.bukkit.entity.Player;

View File

@ -244,6 +244,5 @@ public class ConnectListener implements Listener {
public void onDisconnect(PlayerDisconnectEvent disconnectEvent) {
ProxiedPlayer player = disconnectEvent.getPlayer();
plugin.getSession().remove(player.getPendingConnection());
plugin.getCore().getPendingConfirms().remove(player.getUniqueId());
}
}

View File

@ -37,7 +37,6 @@ import com.github.games647.fastlogin.core.storage.StoredProfile;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.event.PluginMessageEvent;
@ -96,15 +95,6 @@ public class PluginMessageListener implements Listener {
String playerName = changeMessage.getPlayerName();
boolean isSourceInvoker = changeMessage.isSourceInvoker();
if (changeMessage.shouldEnable()) {
if (playerName.equals(forPlayer.getName()) && plugin.getCore().getConfig().get("premium-warning", true)
&& !core.getPendingConfirms().contains(forPlayer.getUniqueId())) {
String message = core.getMessage("premium-warning");
forPlayer.sendMessage(TextComponent.fromLegacyText(message));
core.getPendingConfirms().add(forPlayer.getUniqueId());
return;
}
core.getPendingConfirms().remove(forPlayer.getUniqueId());
Runnable task = new AsyncToggleMessage(core, forPlayer, playerName, true, isSourceInvoker);
plugin.getScheduler().runAsync(task);
} else {

View File

@ -61,7 +61,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -83,7 +82,6 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
Duration.ofMinutes(5), -1
);
private final Collection<UUID> pendingConfirms = new HashSet<>();
private final T plugin;
private MojangResolver resolver;
@ -123,7 +121,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
// Initialize the resolver based on the config parameter
this.resolver = this.config.getBoolean("useProxyAgnosticResolver", false)
? new ProxyAgnosticMojangResolver() : new MojangResolver();
? new ProxyAgnosticMojangResolver() : new MojangResolver();
antiBot = createAntiBotService(config.getSection("anti-bot"));
Set<Proxy> proxies = config.getStringList("proxies")
@ -287,10 +285,6 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
return pendingLogin.remove(ip + username) != null;
}
public Collection<UUID> getPendingConfirms() {
return pendingConfirms;
}
public AuthPlugin<P> getAuthPluginHook() {
return authPlugin;
}

View File

@ -38,7 +38,6 @@ import com.github.games647.fastlogin.velocity.task.FloodgateAuthTask;
import com.github.games647.fastlogin.velocity.task.ForceLoginTask;
import com.velocitypowered.api.event.EventTask;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.connection.PreLoginEvent;
import com.velocitypowered.api.event.connection.PreLoginEvent.PreLoginComponentResult;
import com.velocitypowered.api.event.player.GameProfileRequestEvent;
@ -170,10 +169,4 @@ public class ConnectListener {
// Delay at least one second, otherwise the login command can be missed
plugin.getScheduler().runAsyncDelayed(loginTask, Duration.ofSeconds(1));
}
@Subscribe
public void onDisconnect(DisconnectEvent disconnectEvent) {
Player player = disconnectEvent.getPlayer();
plugin.getCore().getPendingConfirms().remove(player.getUniqueId());
}
}

View File

@ -42,7 +42,6 @@ import com.velocitypowered.api.event.connection.PluginMessageEvent.ForwardResult
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.Arrays;
@ -97,16 +96,6 @@ public class PluginMessageListener {
String playerName = changeMessage.getPlayerName();
boolean isSourceInvoker = changeMessage.isSourceInvoker();
if (changeMessage.shouldEnable()) {
Boolean premiumWarning = plugin.getCore().getConfig().get("premium-warning", true);
if (playerName.equals(forPlayer.getUsername()) && premiumWarning
&& !core.getPendingConfirms().contains(forPlayer.getUniqueId())) {
String message = core.getMessage("premium-warning");
forPlayer.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(message));
core.getPendingConfirms().add(forPlayer.getUniqueId());
return;
}
core.getPendingConfirms().remove(forPlayer.getUniqueId());
Runnable task = new AsyncToggleMessage(core, forPlayer, playerName, true, isSourceInvoker);
plugin.getScheduler().runAsync(task);
} else {