Extract BungeeCord message in dedicated classes

This commit is contained in:
games647
2018-02-17 20:32:52 +01:00
parent 06bb4b80dd
commit cff25c958d
10 changed files with 259 additions and 74 deletions

View File

@ -9,6 +9,8 @@ import com.github.games647.fastlogin.bukkit.listener.protocollib.SkinApplyListen
import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener;
import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook;
import com.github.games647.fastlogin.core.CommonUtil;
import com.github.games647.fastlogin.core.messages.ChangePremiumMessage;
import com.github.games647.fastlogin.core.messages.ChannelMessage;
import com.github.games647.fastlogin.core.mojang.MojangApiConnector;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.PlatformPlugin;
@ -120,9 +122,10 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
return core;
}
public void sendBungeeActivateMessage(CommandSender sender, String target, boolean activate) {
if (sender instanceof PluginMessageRecipient) {
notifyBungeeCord((PluginMessageRecipient) sender, target, activate, true);
public void sendBungeeActivateMessage(CommandSender invoker, String target, boolean activate) {
if (invoker instanceof PluginMessageRecipient) {
ChannelMessage message = new ChangePremiumMessage(target, activate, true);
sendPluginMessage((PluginMessageRecipient) invoker, message);
} else {
Optional<? extends Player> optPlayer = getServer().getOnlinePlayers().stream().findFirst();
@ -131,7 +134,9 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
return;
}
notifyBungeeCord(optPlayer.get(), target, activate, false);
Player sender = optPlayer.get();
ChannelMessage message = new ChangePremiumMessage(target, activate, false);
sendPluginMessage(sender, message);
}
}
@ -174,17 +179,14 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
}
}
private void notifyBungeeCord(PluginMessageRecipient sender, String target, boolean activate, boolean isPlayer) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
if (activate) {
dataOutput.writeUTF("ON");
} else {
dataOutput.writeUTF("OFF");
}
public void sendPluginMessage(PluginMessageRecipient player, ChannelMessage message) {
if (player != null) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
dataOutput.writeUTF(message.getChannelName());
dataOutput.writeUTF(target);
dataOutput.writeBoolean(isPlayer);
sender.sendPluginMessage(this, getName(), dataOutput.toByteArray());
message.writeTo(dataOutput);
player.sendPluginMessage(this, this.getName(), dataOutput.toByteArray());
}
}
@Override

View File

@ -4,6 +4,8 @@ import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.tasks.ForceLoginTask;
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import com.github.games647.fastlogin.core.messages.ForceActionMessage;
import com.github.games647.fastlogin.core.messages.ForceActionMessage.Type;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
@ -14,6 +16,7 @@ import java.nio.file.Path;
import java.util.Collections;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -48,38 +51,43 @@ public class BungeeListener implements PluginMessageListener {
ByteArrayDataInput dataInput = ByteStreams.newDataInput(message);
String subChannel = dataInput.readUTF();
plugin.getLog().debug("Received plugin message for sub channel {} from {}", subChannel, player);
if (!"FORCE_ACTION".equals(subChannel)) {
plugin.getLog().info("Unknown sub channel {}", subChannel);
return;
}
String playerName = dataInput.readUTF();
ForceActionMessage loginMessage = new ForceActionMessage();
loginMessage.readFrom(dataInput);
plugin.getLog().debug("Received plugin message {}", loginMessage);
//check if the player is still online or disconnected
Player checkedPlayer = Bukkit.getPlayerExact(playerName);
Player checkedPlayer = Bukkit.getPlayerExact(loginMessage.getPlayerName());
//fail if target player is blacklisted because already authenticated or wrong bungeecord id
if (checkedPlayer != null && !checkedPlayer.hasMetadata(plugin.getName())) {
//bungeecord UUID
long mostSignificantBits = dataInput.readLong();
long leastSignificantBits = dataInput.readLong();
UUID sourceId = new UUID(mostSignificantBits, leastSignificantBits);
plugin.getLog().debug("Received proxy id {} from {}", sourceId, player);
//fail if BungeeCord support is disabled (id = null)
UUID sourceId = loginMessage.getProxyId();
if (proxyIds.contains(sourceId)) {
readMessage(checkedPlayer, subChannel, playerName, player);
readMessage(checkedPlayer, loginMessage);
} else {
plugin.getLog().warn("Received proxy id: {} that doesn't exist in the proxy whitelist file", sourceId);
}
}
}
private void readMessage(Player checkedPlayer, String subChannel, String playerName, Player player) {
InetSocketAddress address = checkedPlayer.getAddress();
private void readMessage(Player player, ForceActionMessage message) {
String playerName = message.getPlayerName();
Type type = message.getType();
InetSocketAddress address = player.getAddress();
String id = '/' + address.getAddress().getHostAddress() + ':' + address.getPort();
if ("AUTO_LOGIN".equalsIgnoreCase(subChannel)) {
if (type == Type.LOGIN) {
BukkitLoginSession playerSession = new BukkitLoginSession(playerName, true);
playerSession.setVerified(true);
plugin.getLoginSessions().put(id, playerSession);
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new ForceLoginTask(plugin.getCore(), player), 20L);
} else if ("AUTO_REGISTER".equalsIgnoreCase(subChannel)) {
} else if (type == Type.REGISTER) {
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> {
AuthPlugin<Player> authPlugin = plugin.getCore().getAuthPluginHook();
try {
@ -104,10 +112,11 @@ public class BungeeListener implements PluginMessageListener {
Files.createFile(whitelistFile);
}
return Files.lines(whitelistFile)
.map(String::trim)
.map(UUID::fromString)
.collect(toSet());
try (Stream<String> lines = Files.lines(whitelistFile)) {
return lines.map(String::trim)
.map(UUID::fromString)
.collect(toSet());
}
} catch (IOException ex) {
plugin.getLog().error("Failed to create file for Proxy whitelist", ex);
} catch (Exception ex) {

View File

@ -2,11 +2,11 @@ package com.github.games647.fastlogin.bukkit.tasks;
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.core.messages.ChannelMessage;
import com.github.games647.fastlogin.core.messages.SuccessMessage;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.ForceLoginManagement;
import com.github.games647.fastlogin.core.shared.LoginSession;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import java.util.concurrent.ExecutionException;
@ -39,10 +39,8 @@ public class ForceLoginTask extends ForceLoginManagement<Player, CommandSender,
@Override
public void onForceActionSuccess(LoginSession session) {
if (core.getPlugin().isBungeeCord()) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
dataOutput.writeUTF("SUCCESS");
player.sendPluginMessage(core.getPlugin(), core.getPlugin().getName(), dataOutput.toByteArray());
ChannelMessage message = new SuccessMessage();
core.getPlugin().sendPluginMessage(player, message);
}
}

View File

@ -4,9 +4,12 @@ import com.github.games647.fastlogin.bungee.hooks.BungeeAuthHook;
import com.github.games647.fastlogin.bungee.listener.ConnectListener;
import com.github.games647.fastlogin.bungee.listener.MessageListener;
import com.github.games647.fastlogin.core.CommonUtil;
import com.github.games647.fastlogin.core.messages.ChannelMessage;
import com.github.games647.fastlogin.core.mojang.MojangApiConnector;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.PlatformPlugin;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.google.common.net.HostAndPort;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
@ -20,6 +23,7 @@ import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.scheduler.GroupedThreadFactory;
@ -78,6 +82,16 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
}
}
public void sendPluginMessage(Server server, ChannelMessage message) {
if (server != null) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
dataOutput.writeUTF(message.getChannelName());
message.writeTo(dataOutput);
server.sendData(core.getPlugin().getName(), dataOutput.toByteArray());
}
}
@Override
public String getName() {
return getDescription().getName();

View File

@ -4,6 +4,7 @@ import com.github.games647.fastlogin.bungee.BungeeLoginSession;
import com.github.games647.fastlogin.bungee.FastLoginBungee;
import com.github.games647.fastlogin.bungee.tasks.AsyncToggleMessage;
import com.github.games647.fastlogin.core.PlayerProfile;
import com.github.games647.fastlogin.core.messages.ChangePremiumMessage;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
@ -55,28 +56,29 @@ public class MessageListener implements Listener {
String subChannel = dataInput.readUTF();
if ("SUCCESS".equals(subChannel)) {
onSuccessMessage(forPlayer);
} else if ("ON".equals(subChannel)) {
String playerName = dataInput.readUTF();
boolean isPlayerSender = dataInput.readBoolean();
} else if ("CHANGE".equals(subChannel)) {
ChangePremiumMessage changeMessage = new ChangePremiumMessage();
changeMessage.readFrom(dataInput);
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;
String playerName = changeMessage.getPlayerName();
boolean isSourceInvoker = changeMessage.isSourceInvoker();
if (changeMessage.isWillEnable()) {
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);
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
} else {
Runnable task = new AsyncToggleMessage(core, forPlayer, playerName, false, isSourceInvoker);
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
}
core.getPendingConfirms().remove(forPlayer.getUniqueId());
Runnable task = new AsyncToggleMessage(core, forPlayer, playerName, true, isPlayerSender);
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
} else if ("OFF".equals(subChannel)) {
String playerName = dataInput.readUTF();
boolean isPlayerSender = dataInput.readBoolean();
Runnable task = new AsyncToggleMessage(core, forPlayer, playerName, false, isPlayerSender);
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
}
}
}
private void onSuccessMessage(ProxiedPlayer forPlayer) {

View File

@ -2,15 +2,16 @@ package com.github.games647.fastlogin.bungee.tasks;
import com.github.games647.fastlogin.bungee.BungeeLoginSession;
import com.github.games647.fastlogin.bungee.FastLoginBungee;
import com.github.games647.fastlogin.core.messages.ChannelMessage;
import com.github.games647.fastlogin.core.messages.ForceActionMessage;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.ForceLoginManagement;
import com.github.games647.fastlogin.core.shared.LoginSession;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import java.util.UUID;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
@ -57,25 +58,16 @@ public class ForceLoginTask
@Override
public void onForceActionSuccess(LoginSession session) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
//sub channel name
String type = "AUTO_LOGIN";
if (session.needsRegistration()) {
dataOutput.writeUTF("AUTO_REGISTER");
} else {
dataOutput.writeUTF("AUTO_LOGIN");
type = "AUTO_REGISTER";
}
//Data is sent through a random player. We have to tell the Bukkit version of this plugin the target
dataOutput.writeUTF(player.getName());
UUID proxyId = UUID.fromString(ProxyServer.getInstance().getConfig().getUuid());
ChannelMessage loginMessage = new ForceActionMessage(type, player.getName(), proxyId);
//proxy identifier to check if it's a acceptable proxy
UUID proxyId = UUID.fromString(core.getPlugin().getProxy().getConfig().getUuid());
dataOutput.writeLong(proxyId.getMostSignificantBits());
dataOutput.writeLong(proxyId.getLeastSignificantBits());
if (server != null) {
server.sendData(core.getPlugin().getName(), dataOutput.toByteArray());
}
core.getPlugin().sendPluginMessage(server, loginMessage);
}
@Override

View File

@ -0,0 +1,52 @@
package com.github.games647.fastlogin.core.messages;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
public class ChangePremiumMessage implements ChannelMessage {
private String playerName;
private boolean willEnable;
private boolean isSourceInvoker;
public ChangePremiumMessage(String playerName, boolean willEnable, boolean isSourceInvoker) {
this.playerName = playerName;
this.willEnable = willEnable;
this.isSourceInvoker = isSourceInvoker;
}
public ChangePremiumMessage() {
//reading from
}
public String getPlayerName() {
return playerName;
}
public boolean isWillEnable() {
return willEnable;
}
public boolean isSourceInvoker() {
return isSourceInvoker;
}
@Override
public String getChannelName() {
return "CHANGE";
}
@Override
public void readFrom(ByteArrayDataInput input) {
willEnable = input.readBoolean();
playerName = input.readUTF();
isSourceInvoker = input.readBoolean();
}
@Override
public void writeTo(ByteArrayDataOutput output) {
output.writeBoolean(willEnable);
output.writeUTF(playerName);
output.writeBoolean(isSourceInvoker);
}
}

View File

@ -0,0 +1,13 @@
package com.github.games647.fastlogin.core.messages;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
public interface ChannelMessage {
String getChannelName();
void readFrom(ByteArrayDataInput input);
void writeTo(ByteArrayDataOutput output);
}

View File

@ -0,0 +1,81 @@
package com.github.games647.fastlogin.core.messages;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import java.util.UUID;
public class ForceActionMessage implements ChannelMessage {
private Type type;
private String playerName;
private UUID proxyId;
public ForceActionMessage(Type type, String playerName, UUID proxyId) {
this.type = type;
this.playerName = playerName;
this.proxyId = proxyId;
}
public ForceActionMessage() {
//reading mode
}
public Type getType() {
return type;
}
public String getPlayerName() {
return playerName;
}
public UUID getProxyId() {
return proxyId;
}
@Override
public void readFrom(ByteArrayDataInput input) {
this.type = Type.valueOf(input.readUTF());
this.playerName = input.readUTF();
//bungeecord UUID
long mostSignificantBits = input.readLong();
long leastSignificantBits = input.readLong();
this.proxyId = new UUID(mostSignificantBits, leastSignificantBits);
}
@Override
public void writeTo(ByteArrayDataOutput output) {
output.writeUTF(type.name());
//Data is sent through a random player. We have to tell the Bukkit version of this plugin the target
output.writeUTF(playerName);
//proxy identifier to check if it's a acceptable proxy
output.writeLong(proxyId.getMostSignificantBits());
output.writeLong(proxyId.getLeastSignificantBits());
}
@Override
public String getChannelName() {
return "FORCE_ACTION";
}
@Override
public String toString() {
return this.getClass().getSimpleName() + '{' +
"type='" + type + '\'' +
", playerName='" + playerName + '\'' +
", proxyId=" + proxyId +
'}';
}
public enum Type {
LOGIN,
REGISTER
}
}

View File

@ -0,0 +1,22 @@
package com.github.games647.fastlogin.core.messages;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
public class SuccessMessage implements ChannelMessage {
@Override
public String getChannelName() {
return "SUCCESS";
}
@Override
public void readFrom(ByteArrayDataInput input) {
//empty
}
@Override
public void writeTo(ByteArrayDataOutput output) {
//empty
}
}