diff --git a/pom.xml b/pom.xml
index 95c8b79..d0bebd1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.lielamar
2fa
- 1.5.4
+ 1.5.5
UTF-8
@@ -42,7 +42,7 @@
1.4.200
8.0.26
2.7.3
- 42.2.23
+ 42.3.1
3.12.10
2.0.0-alpha5
@@ -153,7 +153,7 @@
org.json
json
- 20200518
+ 20210307
compile
@@ -168,7 +168,7 @@
net.md-5
bungeecord-api
- 1.16-R0.4-SNAPSHOT
+ 1.16-R0.4
jar
provided
diff --git a/src/main/java/com/lielamar/auth/bukkit/handlers/AuthHandler.java b/src/main/java/com/lielamar/auth/bukkit/handlers/AuthHandler.java
index a00a5c3..9e007cb 100644
--- a/src/main/java/com/lielamar/auth/bukkit/handlers/AuthHandler.java
+++ b/src/main/java/com/lielamar/auth/bukkit/handlers/AuthHandler.java
@@ -12,10 +12,7 @@
import com.lielamar.lielsutils.ColorUtils;
import com.lielamar.lielsutils.SpigotUtils;
import net.md_5.bungee.api.chat.*;
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.Material;
-import org.bukkit.World;
+import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -110,23 +107,32 @@ public boolean approveKey(UUID uuid, Integer code) {
public void playerJoin(UUID uuid) {
super.playerJoin(uuid);
- // If no player has joined the server yet, meaning there was no opportunity to check if the server is using bungeecord
- // * we check if the server is using bungeecord by sending a message to bungeecord and expecting a response. Once we get a response we know the server is using bungeecord
- // then we want to firstly send the #loadBungeecord message to bungeecord, and only then load the player.
- // If bungeecord was already loaded (we know this through loadedBungeecord, which changes to true after the initial load), we only want to load the player because we already know whether
- // the server is using bungeecord or not.
+ // Loads the player whenever they join the server.
+ //
+ // If bungeecord was not loaded yet, we want to try to load it. What it generally means is - we send a request called
+ // "LOAD_BUNGEECORD" to bungeecord. If we get a response, it means bungeecord exists, and then we set the value of
+ // isBungeecordEnabled to true, so we know to use bungeecord for future requests.
+ // In case bungeecord was loaded successfully, we provide a callback to re-load the joined player, since when we loaded
+ // them, we did so locally on the spigot instance and not in bungeecord.
+ //
+ // This way, if a player was online and then joined a spigot instance that was just booted, it would load their data and ask
+ // them to authenticate, but straight after that, it'd load bungeecord and then re-load the player and auto-authenticate them.
+
+ handlePlayerJoin(uuid);
+
if(!loadedBungeecord) {
loadedBungeecord = true;
- Bukkit.getScheduler().runTaskLater(this.main, () -> this.main.getPluginMessageListener().loadBungeecord(uuid, null), 1L);
+ long timeMillis = System.currentTimeMillis();
+ Bukkit.getScheduler().runTaskLater(this.main, () -> this.main.getPluginMessageListener().loadBungeecord(uuid, new Callback() {
+ public void execute() { handlePlayerJoin(uuid); }
+ public long getExecutionStamp() { return timeMillis; }
+ }), 1L);
}
-
- // Loading the player, only after the above code is done executing (since it's not async).
- handlePlayerJoin(uuid);
}
/**
- * A util method to handle the player join event. It removes the map copies from their inventory, loads their auth state (from either spigot/bungeecord), etc.
+ * A method to handle the player join event. It removes the map copies from their inventory, loads their auth state (from either spigot/bungeecord), etc.
*
* @param uuid UUID of the player to handle
*/
@@ -135,9 +141,8 @@ private void handlePlayerJoin(UUID uuid) {
Bukkit.getScheduler().runTaskLater(this.main, () -> {
Player player = Bukkit.getPlayer(uuid);
- if(player == null || !player.isOnline()) {
+ if(player == null || !player.isOnline())
return;
- }
// Removing previous QR codes
for(ItemStack item : player.getInventory().getContents()) {
@@ -200,7 +205,6 @@ public void changeState(UUID uuid, AuthState authState, boolean updateBungeecord
PlayerStateChangeEvent event = new PlayerStateChangeEvent(player, authStates.get(uuid), authState);
Bukkit.getPluginManager().callEvent(event);
-
if(event.isCancelled())
return;
diff --git a/src/main/java/com/lielamar/auth/bukkit/handlers/BungeecordMessageHandler.java b/src/main/java/com/lielamar/auth/bukkit/handlers/BungeecordMessageHandler.java
index 73782b9..f8cd8d7 100644
--- a/src/main/java/com/lielamar/auth/bukkit/handlers/BungeecordMessageHandler.java
+++ b/src/main/java/com/lielamar/auth/bukkit/handlers/BungeecordMessageHandler.java
@@ -15,7 +15,6 @@
import java.io.*;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
@@ -23,41 +22,30 @@
public class BungeecordMessageHandler extends PluginMessagingHandler implements PluginMessageListener {
private final TwoFactorAuthentication main;
- private final Map callbackFunctions;
+ private final Map callbacks;
public BungeecordMessageHandler(TwoFactorAuthentication main) {
this.main = main;
- this.callbackFunctions = new HashMap<>();
+ this.callbacks = new HashMap<>();
- // Looping over the callbacks, if it's been more than 15 seconds cancel the callback
+ // Removes all callbacks that were set more than 5 seconds ago, since they're most-likely invalid by now
Bukkit.getScheduler().runTaskTimerAsynchronously(main, () -> {
long currentTimestamp = System.currentTimeMillis();
-
- Iterator iterator = callbackFunctions.keySet().iterator();
- UUID key;
- Callback value;
- while(iterator.hasNext()) {
- key = iterator.next();
- value = callbackFunctions.get(key);
-
- if(value != null) {
- if((currentTimestamp - value.getExecutionStamp())/1000 > 15)
- iterator.remove();
- }
- }
- }, 300L, 300L);
+ callbacks.entrySet().removeIf(entry -> (currentTimestamp - entry.getValue().getExecutionStamp())/1000 > 5);
+ }, 100L, 100L);
}
+
/**
* Sets the header of a message
*
- * @param msg Message Stream
- * @param uuid UUID of the player attached to the message
- * @param callback Callback function to call once a response is received
+ * @param msg Message Stream
+ * @param uuid UUID of the player attached to the message
+ * @param callbackUUID UUID of the callback function to call once a response is received
*/
- public void setMessageHeader(ByteArrayDataOutput msg, UUID uuid, Callback callback) {
+ public void setMessageHeader(ByteArrayDataOutput msg, UUID uuid, UUID callbackUUID) {
msg.writeUTF(super.subChannelName); // Setting the SubChannel of the message
- msg.writeUTF(attachCallbackFunction(callback).toString()); // Setting the Message UUID
+ msg.writeUTF(callbackUUID.toString()); // Setting the Message UUID
msg.writeUTF(uuid.toString()); // Setting the UUID of the player
}
@@ -91,6 +79,20 @@ public void applyMessageBody(ByteArrayDataOutput msg, ByteArrayOutputStream msgB
msg.write(msgBody.toByteArray()); // Setting the body data
}
+ /**
+ * Generates a random UUID for the message and attaches the callback function to call it later when a response is made
+ *
+ * @param callback Callback function to save
+ * @return Random generated UUID
+ */
+ public UUID registerCallback(Callback callback) {
+ UUID randomUUID = UUID.randomUUID();
+
+ if(callback != null)
+ this.callbacks.put(randomUUID, callback);
+ return randomUUID;
+ }
+
/**
* Sends the message to bungeecord
*
@@ -105,20 +107,6 @@ public void sendMessage(UUID uuid, ByteArrayDataOutput msg) {
}
- /**
- * Generates a random UUID for the message and attaches the callback function to call it later when a response is made
- *
- * @param callback Callback function to save
- * @return Random generated UUID
- */
- public UUID attachCallbackFunction(Callback callback) {
- UUID randomUUID = UUID.randomUUID();
- if(callback != null)
- this.callbackFunctions.put(randomUUID, callback);
- return randomUUID;
- }
-
-
/**
* Communicates with BungeeCord and sets the player authentication state to {authenticated}
*
@@ -128,7 +116,7 @@ public UUID attachCallbackFunction(Callback callback) {
*/
public void setBungeeCordAuthState(UUID uuid, AuthHandler.AuthState state, Callback callback) {
ByteArrayDataOutput msg = ByteStreams.newDataOutput();
- this.setMessageHeader(msg, uuid, callback);
+ this.setMessageHeader(msg, uuid, registerCallback(callback));
ByteArrayOutputStream msgBody = new ByteArrayOutputStream();
this.setMessageBody(msgBody, MessageAction.SET_STATE, state.name());
@@ -150,7 +138,7 @@ public void setBungeeCordAuthState(UUID uuid, AuthHandler.AuthState state) {
*/
public void getBungeeCordAuthState(UUID uuid, AuthHandler.AuthState defaultState, Callback callback) {
ByteArrayDataOutput msg = ByteStreams.newDataOutput();
- this.setMessageHeader(msg, uuid, callback);
+ this.setMessageHeader(msg, uuid, registerCallback(callback));
ByteArrayOutputStream msgBody = new ByteArrayOutputStream();
this.setMessageBody(msgBody, MessageAction.GET_STATE, defaultState.name());
@@ -163,10 +151,15 @@ public void getBungeeCordAuthState(UUID uuid, AuthHandler.AuthState defaultState
this.getBungeeCordAuthState(uuid, defaultState, null);
}
-
+ /**
+ * Loads Bungeecord (checks if bungeecord exists in the server)
+ *
+ * @param uuid UUID of the player to use to load the bungeecord
+ * @param callback A callback function to call whenever a response for the message is received
+ */
public void loadBungeecord(UUID uuid, Callback callback) {
ByteArrayDataOutput msg = ByteStreams.newDataOutput();
- this.setMessageHeader(msg, uuid, callback);
+ this.setMessageHeader(msg, uuid, registerCallback(callback));
ByteArrayOutputStream msgBody = new ByteArrayOutputStream();
this.setMessageBody(msgBody, MessageAction.LOAD_BUNGEECORD);
@@ -213,7 +206,7 @@ public void onPluginMessageReceived(String channel, @NotNull Player player, @Not
main.getAuthHandler().changeState(playerUUID, state, false);
}
- Callback callback = this.callbackFunctions.getOrDefault(messageUUID, null);
+ Callback callback = this.callbacks.getOrDefault(messageUUID, null);
if(callback != null) callback.execute();
} catch (IOException | IllegalArgumentException exception) {
exception.printStackTrace();
diff --git a/src/main/java/com/lielamar/auth/bukkit/handlers/DependencyHandler.java b/src/main/java/com/lielamar/auth/bukkit/handlers/DependencyHandler.java
index ab3690f..acbe3bd 100644
--- a/src/main/java/com/lielamar/auth/bukkit/handlers/DependencyHandler.java
+++ b/src/main/java/com/lielamar/auth/bukkit/handlers/DependencyHandler.java
@@ -26,8 +26,6 @@ public DependencyHandler(Plugin plugin) {
} catch(Exception exception) {
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "[2FA] 2FA detected that you are using Java 16 without the --add-opens java.base/java.lang=ALL-UNNAMED or the --add-opens java.base/java.net=ALL-UNNAMED flags!");
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "[2FA] If you want the plugin to support all features, most significantly Remote Databases, please add this flag to your startup script");
-// Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "[2FA] Disabling plugin...");
-// Bukkit.getPluginManager().disablePlugin(plugin);
}
}
@@ -63,7 +61,7 @@ private void loadDependencies(Plugin plugin, Properties properties) {
String h2Version = properties.getProperty("version_h2", "1.4.200");
String mysqlVersion = properties.getProperty("version_mysql", "8.0.26");
String mariaDBVersion = properties.getProperty("version_maria_db", "2.7.3");
- String postgresVersion = properties.getProperty("version_postgres", "42.2.23");
+ String postgresVersion = properties.getProperty("version_postgres", "42.3.1");
String mongoDBVersion = properties.getProperty("version_mongo_db", "3.12.10");
String slf4jVersion = properties.getProperty("version_slf4j", "2.0.0-alpha5");
diff --git a/src/main/resources/bungee.yml b/src/main/resources/bungee.yml
index 10dbf9b..3828c56 100644
--- a/src/main/resources/bungee.yml
+++ b/src/main/resources/bungee.yml
@@ -1,5 +1,5 @@
name: 2FA
-version: "1.5.4"
+version: "1.5.5"
author: "LielAmar"
main: com.lielamar.auth.bungee.TwoFactorAuthentication
description: Add another layer of protection to your server
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 7da8cb3..d79cfdc 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,5 +1,5 @@
name: 2FA
-version: "1.5.4"
+version: "1.5.5"
authors: [LielAmar, SadGhost]
main: com.lielamar.auth.bukkit.TwoFactorAuthentication
description: Add another layer of protection to your server
@@ -12,7 +12,7 @@ libraries:
- com.h2database:h2:1.4.200
- mysql:mysql-connector-java:8.0.26
- org.mariadb.jdbc:mariadb-java-client:2.7.3
- - org.postgresql:postgresql:42.2.23
+ - org.postgresql:postgresql:42.3.1
- org.mongodb:mongo-java-driver:3.12.10
- org.slf4j:slf4j-api:2.0.0-alpha5