Core refactor

This commit is contained in:
samo_lego 2020-08-28 09:50:25 +02:00
parent 327d9ad81c
commit 584c7cdc64
15 changed files with 163 additions and 129 deletions

View File

@ -17,7 +17,7 @@ sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
archivesBaseName = project.archives_base_name archivesBaseName = project.archives_base_name
version = project.mod_version version = "${project.mod_version}-${project.minecraft_version}"
group = project.maven_group group = project.maven_group
minecraft { minecraft {
@ -116,3 +116,4 @@ publishing {
mavenCentral() mavenCentral()
} }
} }

View File

@ -10,7 +10,7 @@ loader_version=0.9.1+build.205
fabric_version=0.17.2+build.396-1.16 fabric_version=0.17.2+build.396-1.16
# Mod Properties # Mod Properties
mod_version = 1.5.1 mod_version = 1.5.2
maven_group = org.samo_lego maven_group = org.samo_lego
archives_base_name = simpleauth archives_base_name = simpleauth

View File

@ -52,10 +52,11 @@ public class SimpleAuth implements DedicatedServerModInitializer {
private static final Timer TIMER = new Timer(); private static final Timer TIMER = new Timer();
/** /**
* HashMap of non-authenticated players. * HashMap of players that have joined the server.
* It's cleared on server stop in order to save some interactions with database during runtime.
* Stores their data as {@link org.samo_lego.simpleauth.storage.PlayerCache PlayerCache} object * Stores their data as {@link org.samo_lego.simpleauth.storage.PlayerCache PlayerCache} object
*/ */
public static HashMap<String, PlayerCache> deauthenticatedUsers = new HashMap<>(); public static HashMap<String, PlayerCache> playerCacheMap = new HashMap<>();
/** /**
* Checks whether player is authenticated. * Checks whether player is authenticated.
@ -66,7 +67,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
*/ */
public static boolean isAuthenticated(ServerPlayerEntity player) { public static boolean isAuthenticated(ServerPlayerEntity player) {
String uuid = convertUuid(player); String uuid = convertUuid(player);
return !deauthenticatedUsers.containsKey(uuid) || deauthenticatedUsers.get(uuid).wasAuthenticated; return playerCacheMap.containsKey(uuid) && playerCacheMap.get(uuid).isAuthenticated;
} }
// Getting game directory // Getting game directory
@ -136,8 +137,8 @@ public class SimpleAuth implements DedicatedServerModInitializer {
logInfo("Shutting down SimpleAuth."); logInfo("Shutting down SimpleAuth.");
WriteBatch batch = DB.getLevelDBStore().createWriteBatch(); WriteBatch batch = DB.getLevelDBStore().createWriteBatch();
// Writing coordinates of de-authenticated players to database // Updating player data.
deauthenticatedUsers.forEach((uuid, playerCache) -> { playerCacheMap.forEach((uuid, playerCache) -> {
JsonObject data = new JsonObject(); JsonObject data = new JsonObject();
data.addProperty("password", playerCache.password); data.addProperty("password", playerCache.password);
@ -171,7 +172,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
* @return LiteralText with appropriate string (login or register) * @return LiteralText with appropriate string (login or register)
*/ */
public static LiteralText notAuthenticated(PlayerEntity player) { public static LiteralText notAuthenticated(PlayerEntity player) {
final PlayerCache cache = deauthenticatedUsers.get(convertUuid(player)); final PlayerCache cache = playerCacheMap.get(convertUuid(player));
if(SimpleAuth.config.main.enableGlobalPassword || cache.isRegistered) if(SimpleAuth.config.main.enableGlobalPassword || cache.isRegistered)
return new LiteralText( return new LiteralText(
SimpleAuth.config.lang.notAuthenticated + "\n" + SimpleAuth.config.lang.loginRequired SimpleAuth.config.lang.notAuthenticated + "\n" + SimpleAuth.config.lang.loginRequired
@ -188,7 +189,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
* @param msg message to be send to the player * @param msg message to be send to the player
*/ */
public static void authenticatePlayer(ServerPlayerEntity player, Text msg) { public static void authenticatePlayer(ServerPlayerEntity player, Text msg) {
PlayerCache playerCache = deauthenticatedUsers.get(convertUuid(player)); PlayerCache playerCache = playerCacheMap.get(convertUuid(player));
// Teleporting player back // Teleporting player back
if(config.main.spawnOnJoin) if(config.main.spawnOnJoin)
teleportPlayer(player, false); teleportPlayer(player, false);
@ -212,7 +213,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
if(!playerCache.wasOnFire) if(!playerCache.wasOnFire)
player.setFireTicks(0); player.setFireTicks(0);
deauthenticatedUsers.remove(convertUuid(player)); playerCache.isAuthenticated = true;
// Player no longer needs to be invisible and invulnerable // Player no longer needs to be invisible and invulnerable
player.setInvulnerable(false); player.setInvulnerable(false);
@ -231,7 +232,8 @@ public class SimpleAuth implements DedicatedServerModInitializer {
// Marking player as not authenticated // Marking player as not authenticated
String uuid = convertUuid(player); String uuid = convertUuid(player);
deauthenticatedUsers.put(uuid, new PlayerCache(uuid, player)); playerCacheMap.put(uuid, new PlayerCache(uuid, player));
playerCacheMap.get(uuid).isAuthenticated = false;
// Teleporting player to spawn to hide its position // Teleporting player to spawn to hide its position
if(config.main.spawnOnJoin) if(config.main.spawnOnJoin)
@ -244,16 +246,15 @@ public class SimpleAuth implements DedicatedServerModInitializer {
player.setInvulnerable(SimpleAuth.config.experimental.playerInvulnerable); player.setInvulnerable(SimpleAuth.config.experimental.playerInvulnerable);
player.setInvisible(SimpleAuth.config.experimental.playerInvisible); player.setInvisible(SimpleAuth.config.experimental.playerInvisible);
// Timer should start only if player has joined, not left the server (in case os session) // Kicks player after a certain amount of time if not authenticated
if(player.networkHandler.getConnection().isOpen()) TIMER.schedule(new TimerTask() {
TIMER.schedule(new TimerTask() { @Override
@Override public void run() {
public void run() { // Kicking player if not authenticated
// Kicking player if not authenticated if(!isAuthenticated(player) && player.networkHandler.getConnection().isOpen())
if(!isAuthenticated(player) && player.networkHandler.getConnection().isOpen()) player.networkHandler.disconnect(new LiteralText(SimpleAuth.config.lang.timeExpired));
player.networkHandler.disconnect(new LiteralText(SimpleAuth.config.lang.timeExpired)); }
} }, SimpleAuth.config.main.kickTime * 1000);
}, SimpleAuth.config.main.kickTime * 1000);
} }
/** /**
@ -291,7 +292,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
); );
return; return;
} }
PlayerCache cache = deauthenticatedUsers.get(convertUuid(player)); PlayerCache cache = playerCacheMap.get(convertUuid(player));
// Puts player to last cached position // Puts player to last cached position
try { try {
player.teleport( player.teleport(

View File

@ -1,6 +1,5 @@
package org.samo_lego.simpleauth.commands; package org.samo_lego.simpleauth.commands;
import com.google.gson.JsonObject;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
@ -13,8 +12,7 @@ import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.word; import static com.mojang.brigadier.arguments.StringArgumentType.word;
import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal; import static net.minecraft.server.command.CommandManager.literal;
import static org.samo_lego.simpleauth.SimpleAuth.THREADPOOL; import static org.samo_lego.simpleauth.SimpleAuth.*;
import static org.samo_lego.simpleauth.SimpleAuth.config;
import static org.samo_lego.simpleauth.utils.UuidConverter.convertUuid; import static org.samo_lego.simpleauth.utils.UuidConverter.convertUuid;
public class AccountCommand { public class AccountCommand {
@ -75,7 +73,7 @@ public class AccountCommand {
// Different thread to avoid lag spikes // Different thread to avoid lag spikes
THREADPOOL.submit(() -> { THREADPOOL.submit(() -> {
if (AuthHelper.checkPass(convertUuid(player), pass.toCharArray()) == 1) { if (AuthHelper.checkPass(convertUuid(player), pass.toCharArray()) == 1) {
SimpleAuth.DB.deleteUserData(convertUuid(player)); DB.deleteUserData(convertUuid(player));
player.sendMessage( player.sendMessage(
new LiteralText(config.lang.accountDeleted), new LiteralText(config.lang.accountDeleted),
false false
@ -118,12 +116,8 @@ public class AccountCommand {
), false); ), false);
return; return;
} }
// JSON object holding password (may hold some other info in the future) // Changing password in playercache
JsonObject playerdata = new JsonObject(); playerCacheMap.get(convertUuid(player)).password = AuthHelper.hashPassword(newPass.toCharArray());
String hash = AuthHelper.hashPassword(newPass.toCharArray());
playerdata.addProperty("password", hash);
SimpleAuth.DB.updateUserData(convertUuid(player), playerdata.toString());
player.sendMessage( player.sendMessage(
new LiteralText(config.lang.passwordUpdated), new LiteralText(config.lang.passwordUpdated),
false false

View File

@ -1,6 +1,5 @@
package org.samo_lego.simpleauth.commands; package org.samo_lego.simpleauth.commands;
import com.google.gson.JsonObject;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.command.argument.BlockPosArgumentType; import net.minecraft.command.argument.BlockPosArgumentType;
import net.minecraft.command.argument.DimensionArgumentType; import net.minecraft.command.argument.DimensionArgumentType;
@ -25,8 +24,11 @@ import static org.samo_lego.simpleauth.utils.SimpleLogger.logInfo;
public class AuthCommand { public class AuthCommand {
/**
* Registers the "/auth" command
* @param dispatcher
*/
public static void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher) { public static void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher) {
// Registering the "/auth" command
dispatcher.register(literal("auth") dispatcher.register(literal("auth")
.requires(source -> source.hasPermissionLevel(4)) .requires(source -> source.hasPermissionLevel(4))
.then(literal("reload") .then(literal("reload")
@ -95,7 +97,12 @@ public class AuthCommand {
); );
} }
// Reloading the config /**
* Reloads the config file.
*
* @param sender executioner of the command
* @return 0
*/
public static int reloadConfig(Entity sender) { public static int reloadConfig(Entity sender) {
config = AuthConfig.load(new File("./mods/SimpleAuth/config.json")); config = AuthConfig.load(new File("./mods/SimpleAuth/config.json"));
@ -106,14 +113,20 @@ public class AuthCommand {
return 1; return 1;
} }
// Setting global password /**
private static int setGlobalPassword(ServerCommandSource source, String pass) { * Sets global password.
*
* @param source executioner of the command
* @param password password that will be set
* @return 0
*/
private static int setGlobalPassword(ServerCommandSource source, String password) {
// Getting the player who send the command // Getting the player who send the command
Entity sender = source.getEntity(); Entity sender = source.getEntity();
// Different thread to avoid lag spikes // Different thread to avoid lag spikes
THREADPOOL.submit(() -> { THREADPOOL.submit(() -> {
// Writing the global pass to config // Writing the global pass to config
config.main.globalPassword = AuthHelper.hashPassword(pass.toCharArray()); config.main.globalPassword = AuthHelper.hashPassword(password.toCharArray());
config.main.enableGlobalPassword = true; config.main.enableGlobalPassword = true;
config.save(new File("./mods/SimpleAuth/config.json")); config.save(new File("./mods/SimpleAuth/config.json"));
}); });
@ -125,7 +138,16 @@ public class AuthCommand {
return 1; return 1;
} }
// /**
* Sets {@link org.samo_lego.simpleauth.storage.AuthConfig.MainConfig.WorldSpawn global spawn}.
*
* @param source executioner of the command
* @param world world id of global spawn
* @param x x coordinate of the global spawn
* @param y y coordinate of the global spawn
* @param z z coordinate of the global spawn
* @return 0
*/
private static int setSpawn(ServerCommandSource source, Identifier world, double x, double y, double z) { private static int setSpawn(ServerCommandSource source, Identifier world, double x, double y, double z) {
// Setting config values and saving // Setting config values and saving
config.worldSpawn.dimension = String.valueOf(world); config.worldSpawn.dimension = String.valueOf(world);
@ -144,12 +166,18 @@ public class AuthCommand {
return 1; return 1;
} }
// Deleting (unregistering) user's account /**
* Deletes (unregisters) player's account.
*
* @param source executioner of the command
* @param uuid uuid of the player to delete account for
* @return 0
*/
private static int removeAccount(ServerCommandSource source, String uuid) { private static int removeAccount(ServerCommandSource source, String uuid) {
Entity sender = source.getEntity(); Entity sender = source.getEntity();
THREADPOOL.submit(() -> { THREADPOOL.submit(() -> {
DB.deleteUserData(uuid); DB.deleteUserData(uuid);
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, null)); SimpleAuth.playerCacheMap.put(uuid, new PlayerCache(uuid, null));
}); });
if(sender != null) if(sender != null)
@ -159,39 +187,70 @@ public class AuthCommand {
return 1; // Success return 1; // Success
} }
// Creating account for user /**
* Creates account for player.
*
* @param source executioner of the command
* @param uuid uuid of the player to create account for
* @param password new password for the player account
* @return 0
*/
private static int registerUser(ServerCommandSource source, String uuid, String password) { private static int registerUser(ServerCommandSource source, String uuid, String password) {
// Getting the player who send the command // Getting the player who send the command
Entity sender = source.getEntity(); Entity sender = source.getEntity();
THREADPOOL.submit(() -> { THREADPOOL.submit(() -> {
// JSON object holding password (may hold some other info in the future) PlayerCache playerCache;
JsonObject playerdata = new JsonObject(); if(playerCacheMap.containsKey(uuid)) {
String hash = AuthHelper.hashPassword(password.toCharArray()); playerCache = playerCacheMap.get(uuid);
playerdata.addProperty("password", hash);
if (DB.registerUser(uuid, playerdata.toString())) {
if (sender != null)
((PlayerEntity) sender).sendMessage(new LiteralText(config.lang.userdataUpdated), false);
else
logInfo(config.lang.userdataUpdated);
} }
else {
playerCache = new PlayerCache(uuid, null);
}
playerCacheMap.put(uuid, playerCache);
playerCacheMap.get(uuid).password = AuthHelper.hashPassword(password.toCharArray());
playerCacheMap.get(uuid).isRegistered = true;
if (sender != null)
((PlayerEntity) sender).sendMessage(new LiteralText(config.lang.userdataUpdated), false);
else
logInfo(config.lang.userdataUpdated);
}); });
return 0; return 0;
} }
// Force-updating the user's password /**
* Force-updates the player's password.
*
* @param source executioner of the command
* @param uuid uuid of the player to update data for
* @param password new password for the player
* @return 0
*/
private static int updatePass(ServerCommandSource source, String uuid, String password) { private static int updatePass(ServerCommandSource source, String uuid, String password) {
// Getting the player who send the command // Getting the player who send the command
Entity sender = source.getEntity(); Entity sender = source.getEntity();
THREADPOOL.submit(() -> { THREADPOOL.submit(() -> {
// JSON object holding password (may hold some other info in the future) PlayerCache playerCache;
JsonObject playerdata = new JsonObject(); if(playerCacheMap.containsKey(uuid)) {
String hash = AuthHelper.hashPassword(password.toCharArray()); playerCache = playerCacheMap.get(uuid);
playerdata.addProperty("password", hash); }
else {
playerCache = new PlayerCache(uuid, null);
}
playerCacheMap.put(uuid, playerCache);
if(!playerCacheMap.get(uuid).isRegistered) {
if (sender != null)
((PlayerEntity) sender).sendMessage(new LiteralText(config.lang.userNotRegistered), false);
else
logInfo(config.lang.userNotRegistered);
return;
}
playerCacheMap.get(uuid).password = AuthHelper.hashPassword(password.toCharArray());
DB.updateUserData(uuid, playerdata.toString());
if (sender != null) if (sender != null)
((PlayerEntity) sender).sendMessage(new LiteralText(config.lang.userdataUpdated), false); ((PlayerEntity) sender).sendMessage(new LiteralText(config.lang.userdataUpdated), false);
else else

View File

@ -5,15 +5,13 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import org.samo_lego.simpleauth.SimpleAuth;
import org.samo_lego.simpleauth.utils.AuthHelper; import org.samo_lego.simpleauth.utils.AuthHelper;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.word; import static com.mojang.brigadier.arguments.StringArgumentType.word;
import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal; import static net.minecraft.server.command.CommandManager.literal;
import static org.samo_lego.simpleauth.SimpleAuth.THREADPOOL; import static org.samo_lego.simpleauth.SimpleAuth.*;
import static org.samo_lego.simpleauth.SimpleAuth.config;
import static org.samo_lego.simpleauth.utils.UuidConverter.convertUuid; import static org.samo_lego.simpleauth.utils.UuidConverter.convertUuid;
public class LoginCommand { public class LoginCommand {
@ -35,7 +33,7 @@ public class LoginCommand {
// Getting the player who send the command // Getting the player who send the command
ServerPlayerEntity player = source.getPlayer(); ServerPlayerEntity player = source.getPlayer();
String uuid = convertUuid(player); String uuid = convertUuid(player);
if (SimpleAuth.isAuthenticated(player)) { if (isAuthenticated(player)) {
player.sendMessage(new LiteralText(config.lang.alreadyAuthenticated), false); player.sendMessage(new LiteralText(config.lang.alreadyAuthenticated), false);
return 0; return 0;
} }
@ -44,12 +42,12 @@ public class LoginCommand {
int maxLoginTries = config.main.maxLoginTries; int maxLoginTries = config.main.maxLoginTries;
int passwordResult = AuthHelper.checkPass(uuid, pass.toCharArray()); int passwordResult = AuthHelper.checkPass(uuid, pass.toCharArray());
if(SimpleAuth.deauthenticatedUsers.get(uuid).loginTries >= maxLoginTries && maxLoginTries != -1) { if(playerCacheMap.get(uuid).loginTries >= maxLoginTries && maxLoginTries != -1) {
player.networkHandler.disconnect(new LiteralText(config.lang.loginTriesExceeded)); player.networkHandler.disconnect(new LiteralText(config.lang.loginTriesExceeded));
return; return;
} }
else if(passwordResult == 1) { else if(passwordResult == 1) {
SimpleAuth.authenticatePlayer(player, new LiteralText(config.lang.successfullyAuthenticated)); authenticatePlayer(player, new LiteralText(config.lang.successfullyAuthenticated));
return; return;
} }
else if(passwordResult == -1) { else if(passwordResult == -1) {
@ -64,7 +62,7 @@ public class LoginCommand {
// Sending wrong pass message // Sending wrong pass message
player.sendMessage(new LiteralText(config.lang.wrongPassword), false); player.sendMessage(new LiteralText(config.lang.wrongPassword), false);
// ++ the login tries // ++ the login tries
SimpleAuth.deauthenticatedUsers.get(uuid).loginTries += 1; playerCacheMap.get(uuid).loginTries += 1;
}); });
return 0; return 0;
} }

View File

@ -5,23 +5,23 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import org.samo_lego.simpleauth.SimpleAuth;
import static net.minecraft.server.command.CommandManager.literal; import static net.minecraft.server.command.CommandManager.literal;
import static org.samo_lego.simpleauth.SimpleAuth.config; import static org.samo_lego.simpleauth.SimpleAuth.config;
import static org.samo_lego.simpleauth.SimpleAuth.deauthenticatePlayer;
public class LogoutCommand { public class LogoutCommand {
public static void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher) { public static void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher) {
// Registering the "/logout" command // Registering the "/logout" command
dispatcher.register(literal("logout") dispatcher.register(literal("logout")
.executes(ctx -> logout(ctx.getSource())) // Tries to deauthenticate user .executes(ctx -> logout(ctx.getSource())) // Tries to de-authenticate the user
); );
} }
private static int logout(ServerCommandSource serverCommandSource) throws CommandSyntaxException { private static int logout(ServerCommandSource serverCommandSource) throws CommandSyntaxException {
ServerPlayerEntity player = serverCommandSource.getPlayer(); ServerPlayerEntity player = serverCommandSource.getPlayer();
SimpleAuth.deauthenticatePlayer(player); deauthenticatePlayer(player);
player.sendMessage(new LiteralText(config.lang.successfulLogout), false); player.sendMessage(new LiteralText(config.lang.successfulLogout), false);
return 1; return 1;
} }

View File

@ -1,20 +1,18 @@
package org.samo_lego.simpleauth.commands; package org.samo_lego.simpleauth.commands;
import com.google.gson.JsonObject;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.storage.PlayerCache;
import org.samo_lego.simpleauth.utils.AuthHelper;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.word; import static com.mojang.brigadier.arguments.StringArgumentType.word;
import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal; import static net.minecraft.server.command.CommandManager.literal;
import static org.samo_lego.simpleauth.SimpleAuth.THREADPOOL; import static org.samo_lego.simpleauth.SimpleAuth.*;
import static org.samo_lego.simpleauth.SimpleAuth.config; import static org.samo_lego.simpleauth.utils.AuthHelper.hashPassword;
import static org.samo_lego.simpleauth.utils.UuidConverter.convertUuid; import static org.samo_lego.simpleauth.utils.UuidConverter.convertUuid;
@ -41,7 +39,7 @@ public class RegisterCommand {
player.sendMessage(new LiteralText(config.lang.loginRequired), false); player.sendMessage(new LiteralText(config.lang.loginRequired), false);
return 0; return 0;
} }
else if(SimpleAuth.isAuthenticated(player)) { else if(isAuthenticated(player)) {
player.sendMessage(new LiteralText(config.lang.alreadyAuthenticated), false); player.sendMessage(new LiteralText(config.lang.alreadyAuthenticated), false);
return 0; return 0;
} }
@ -63,13 +61,12 @@ public class RegisterCommand {
), false); ), false);
return; return;
} }
String hash = AuthHelper.hashPassword(pass1.toCharArray());
// JSON object holding password (may hold some other info in the future)
JsonObject playerdata = new JsonObject();
playerdata.addProperty("password", hash);
if (SimpleAuth.DB.registerUser(convertUuid(player), playerdata.toString())) { PlayerCache playerCache = playerCacheMap.get(convertUuid(player));
SimpleAuth.authenticatePlayer(player, new LiteralText(config.lang.registerSuccess)); if (!playerCache.isRegistered) {
authenticatePlayer(player, new LiteralText(config.lang.registerSuccess));
playerCache.password = hashPassword(pass1.toCharArray());
playerCache.isRegistered = true;
return; return;
} }
player.sendMessage(new LiteralText(config.lang.alreadyRegistered), false); player.sendMessage(new LiteralText(config.lang.alreadyRegistered), false);

View File

@ -12,7 +12,6 @@ import net.minecraft.text.LiteralText;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.TypedActionResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import org.samo_lego.simpleauth.mixin.BlockUpdateS2CPacketAccessor;
import org.samo_lego.simpleauth.storage.PlayerCache; import org.samo_lego.simpleauth.storage.PlayerCache;
import java.net.SocketAddress; import java.net.SocketAddress;
@ -68,28 +67,27 @@ public class AuthEventHandler {
return; return;
// Checking if session is still valid // Checking if session is still valid
String uuid = convertUuid(player); String uuid = convertUuid(player);
PlayerCache playerCache = deauthenticatedUsers.getOrDefault(uuid, null); PlayerCache playerCache = playerCacheMap.getOrDefault(uuid, null);
if (playerCache != null) { if (playerCache != null) {
if ( if (
playerCache.wasAuthenticated && playerCache.isAuthenticated &&
playerCache.validUntil >= System.currentTimeMillis() && playerCache.validUntil >= System.currentTimeMillis() &&
player.getIp().equals(playerCache.lastIp) player.getIp().equals(playerCache.lastIp)
) { ) {
authenticatePlayer(player, null); // Makes player authenticated authenticatePlayer(player, null); // Makes player authenticated
return; return;
} }
// Ugly fix for #13
player.setInvulnerable(config.experimental.playerInvulnerable); player.setInvulnerable(config.experimental.playerInvulnerable);
player.setInvisible(config.experimental.playerInvisible); player.setInvisible(config.experimental.playerInvisible);
// Invalidating session // Invalidating session
playerCache.wasAuthenticated = false; playerCache.isAuthenticated = false;
player.sendMessage(notAuthenticated(player), false); player.sendMessage(notAuthenticated(player), false);
} }
else { else {
deauthenticatePlayer(player); deauthenticatePlayer(player);
playerCache = deauthenticatedUsers.get(uuid); playerCache = playerCacheMap.get(uuid);
playerCache.wasOnFire = false; playerCache.wasOnFire = false;
} }
@ -102,14 +100,10 @@ public class AuthEventHandler {
BlockPos pos = player.getBlockPos(); BlockPos pos = player.getBlockPos();
// Faking portal blocks to be air // Faking portal blocks to be air
BlockUpdateS2CPacket feetPacket = new BlockUpdateS2CPacket(); BlockUpdateS2CPacket feetPacket = new BlockUpdateS2CPacket(pos, Blocks.AIR.getDefaultState());
((BlockUpdateS2CPacketAccessor) feetPacket).setState(Blocks.AIR.getDefaultState());
((BlockUpdateS2CPacketAccessor) feetPacket).setBlockPos(pos);
player.networkHandler.sendPacket(feetPacket); player.networkHandler.sendPacket(feetPacket);
BlockUpdateS2CPacket headPacket = new BlockUpdateS2CPacket(); BlockUpdateS2CPacket headPacket = new BlockUpdateS2CPacket(pos.up(), Blocks.AIR.getDefaultState());
((BlockUpdateS2CPacketAccessor) headPacket).setState(Blocks.AIR.getDefaultState());
((BlockUpdateS2CPacketAccessor) headPacket).setBlockPos(pos.up());
player.networkHandler.sendPacket(headPacket); player.networkHandler.sendPacket(headPacket);
// Teleporting player to the middle of the block // Teleporting player to the middle of the block
@ -118,21 +112,21 @@ public class AuthEventHandler {
} }
public static void onPlayerLeave(ServerPlayerEntity player) { public static void onPlayerLeave(ServerPlayerEntity player) {
if(isPlayerFake(player) || !isAuthenticated(player) || config.main.sessionTimeoutTime == -1) String uuid = convertUuid(player);
return; PlayerCache playerCache = playerCacheMap.get(uuid);
// Starting session playerCache.lastIp = player.getIp();
// Putting player to deauthenticated player map playerCache.lastAir = player.getAir();
deauthenticatePlayer(player); playerCache.wasOnFire = player.isOnFire();
playerCache.wasInPortal = player.getBlockState().getBlock().equals(Blocks.NETHER_PORTAL);
// Setting that player was actually authenticated before leaving playerCache.lastDim = String.valueOf(player.getEntityWorld().getRegistryKey().getValue());
PlayerCache playerCache = deauthenticatedUsers.get(convertUuid(player)); playerCache.lastX = player.getX();
if(playerCache == null) playerCache.lastY = player.getY();
return; playerCache.lastZ = player.getZ();
playerCache.wasAuthenticated = true;
// Setting the session expire time // Setting the session expire time
playerCache.validUntil = System.currentTimeMillis() + config.main.sessionTimeoutTime * 1000; if(!isPlayerFake(player) && isAuthenticated(player) && config.main.sessionTimeoutTime != -1)
playerCache.validUntil = System.currentTimeMillis() + config.main.sessionTimeoutTime * 1000;
} }
// Player chatting // Player chatting

View File

@ -1,16 +0,0 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.block.BlockState;
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(BlockUpdateS2CPacket.class)
public interface BlockUpdateS2CPacketAccessor {
@Accessor("state")
void setState(BlockState state);
@Accessor("pos")
void setBlockPos(BlockPos pos);
}

View File

@ -133,6 +133,7 @@ public class AuthConfig {
public String playerAlreadyOnline = "§cPlayer %s is already online!"; public String playerAlreadyOnline = "§cPlayer %s is already online!";
public String worldSpawnSet = "§aSpawn for logging in was set successfully."; public String worldSpawnSet = "§aSpawn for logging in was set successfully.";
public String corruptedPlayerData = "§cYour data is probably corrupted. Please contact admin."; public String corruptedPlayerData = "§cYour data is probably corrupted. Please contact admin.";
public String userNotRegistered = "§cThis player is not registered!";
} }
public static class ExperimentalConfig { public static class ExperimentalConfig {
/** /**

View File

@ -17,10 +17,10 @@ public class PlayerCache {
*/ */
public boolean isRegistered; public boolean isRegistered;
/** /**
* Whether player was authenticated after leaving. * Whether player is authenticated.
* Used for {@link org.samo_lego.simpleauth.event.AuthEventHandler#onPlayerJoin(ServerPlayerEntity) session validation}. * Used for {@link org.samo_lego.simpleauth.event.AuthEventHandler#onPlayerJoin(ServerPlayerEntity) session validation}.
*/ */
public boolean wasAuthenticated; public boolean isAuthenticated;
/** /**
* Hashed password of player. * Hashed password of player.
*/ */
@ -125,7 +125,7 @@ public class PlayerCache {
this.isRegistered = false; this.isRegistered = false;
this.password = ""; this.password = "";
} }
this.wasAuthenticated = false; this.isAuthenticated = false;
this.loginTries = 0; this.loginTries = 0;
} }
} }

View File

@ -119,13 +119,18 @@ public class SimpleAuthDatabase {
} }
} }
// Gets the hashed password from DB /**
* Gets the hashed password from DB.
*
* @param uuid uuid of the player to get data for.
* @return data as string if player has it, otherwise empty string.
*/
public String getData(String uuid){ public String getData(String uuid){
try { try {
if(this.isUserRegistered(uuid)) // Gets password from db and removes "data:" prefix from it if(this.isUserRegistered(uuid)) // Gets password from db and removes "data:" prefix from it
return new String(levelDBStore.get(bytes("UUID:" + uuid))).substring(5); return new String(levelDBStore.get(bytes("UUID:" + uuid))).substring(5);
} catch (Error e) { } catch (Error e) {
logError("Error getting password: " + e.getMessage()); logError("Error getting data: " + e.getMessage());
} }
return ""; return "";
} }

View File

@ -9,6 +9,7 @@ import org.samo_lego.simpleauth.utils.hashing.HasherArgon2;
import org.samo_lego.simpleauth.utils.hashing.HasherBCrypt; import org.samo_lego.simpleauth.utils.hashing.HasherBCrypt;
import static org.samo_lego.simpleauth.SimpleAuth.config; import static org.samo_lego.simpleauth.SimpleAuth.config;
import static org.samo_lego.simpleauth.SimpleAuth.playerCacheMap;
public class AuthHelper { public class AuthHelper {
// Json parser // Json parser
@ -29,8 +30,8 @@ public class AuthHelper {
else { else {
String hashed; String hashed;
// Password from cache // Password from cache
if(SimpleAuth.deauthenticatedUsers.containsKey(uuid)) if(playerCacheMap.containsKey(uuid))
hashed = SimpleAuth.deauthenticatedUsers.get(uuid).password; hashed = playerCacheMap.get(uuid).password;
// Hashed password from DB // Hashed password from DB
else { else {
@ -45,7 +46,7 @@ public class AuthHelper {
} }
} }
if(hashed.equals("")) if(hashed == null)
return -1; // User is not yet registered return -1; // User is not yet registered
// Verify password // Verify password

View File

@ -4,7 +4,6 @@
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [], "mixins": [],
"server": [ "server": [
"BlockUpdateS2CPacketAccessor",
"MixinPlayerEntity", "MixinPlayerEntity",
"MixinPlayerManager", "MixinPlayerManager",
"MixinServerPlayNetworkHandler", "MixinServerPlayNetworkHandler",