Fix thread-safety in async forcelogin task

This commit is contained in:
games647
2016-05-05 12:00:22 +02:00
parent 96fe190cac
commit d56a0f9ff1
7 changed files with 1480 additions and 1443 deletions

View File

@ -4,8 +4,12 @@ import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
@ -13,7 +17,7 @@ import org.bukkit.metadata.FixedMetadataValue;
public class ForceLoginTask implements Runnable {
protected final FastLoginBukkit plugin;
private final Player player;
protected final Player player;
public ForceLoginTask(FastLoginBukkit plugin, Player player) {
this.plugin = plugin;
@ -22,7 +26,7 @@ public class ForceLoginTask implements Runnable {
@Override
public void run() {
if (!player.isOnline()) {
if (!isOnlineThreadSafe()) {
return;
}
@ -56,7 +60,7 @@ public class ForceLoginTask implements Runnable {
sendSuccessNotification();
} else {
boolean success = false;
if (session.isVerified()) {
if (isOnlineThreadSafe() && session.isVerified()) {
if (session.needsRegistration()) {
success = forceRegister(authPlugin, player);
} else {
@ -104,4 +108,21 @@ public class ForceLoginTask implements Runnable {
player.sendPluginMessage(plugin, plugin.getName(), dataOutput.toByteArray());
}
}
private boolean isOnlineThreadSafe() {
//the playerlist isn't thread-safe
Future<Boolean> onlineFuture = Bukkit.getScheduler().callSyncMethod(plugin, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return player.isOnline();
}
});
try {
return onlineFuture.get();
} catch (InterruptedException | ExecutionException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to perform thread-safe online check", ex);
return false;
}
}
}

View File

@ -68,7 +68,7 @@ public class CrazyLoginHook implements BukkitAuthPlugin {
try {
LoginPlayerData result = future.get();
if (result != null) {
if (result != null && result.isLoggedIn()) {
//SQL-Queries should run async
crazyLoginPlugin.getCrazyDatabase().saveWithoutPassword(result);
return true;
@ -88,7 +88,7 @@ public class CrazyLoginHook implements BukkitAuthPlugin {
@Override
public boolean forceRegister(final Player player, String password) {
final CrazyLoginDataDatabase crazyDatabase = crazyLoginPlugin.getCrazyDatabase();
CrazyLoginDataDatabase crazyDatabase = crazyLoginPlugin.getCrazyDatabase();
//this executes a sql query and accesses only thread safe collections so we can run it async
LoginPlayerData playerData = crazyLoginPlugin.getPlayerData(player.getName());

File diff suppressed because it is too large Load Diff

View File

@ -81,6 +81,12 @@ public class LoginSecurityHook implements BukkitAuthPlugin {
//this executes a sql query without interacting with other parts so we can run it async.
dataManager.register(uuidString, passwordHash, securityPlugin.hasher.getTypeId(), ipAddress.toString());
return forceLogin(player);
String storedPassword = dataManager.getPassword(uuidString);
if (storedPassword != null && storedPassword.equals(passwordHash)) {
//the register method silents any excpetion so check if our entry was saved
return forceLogin(player);
}
return false;
}
}

View File

@ -34,7 +34,7 @@ public class RoyalAuthHook implements BukkitAuthPlugin {
//not thread-safe
authPlayer.login();
return true;
return authPlayer.isLoggedIn();
}
});

View File

@ -32,11 +32,10 @@ public class xAuthHook implements BukkitAuthPlugin {
xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player);
if (xAuthPlayer != null) {
//we checked that the player is premium (paid account)
//unprotect the inventory, op status...
xAuthPlayer.setPremium(true);
xAuthPlugin.getPlayerManager().doLogin(xAuthPlayer);
return true;
//unprotect the inventory, op status...
return xAuthPlugin.getPlayerManager().doLogin(xAuthPlayer);
}
return false;