diff --git a/build.gradle b/build.gradle index d79725c..1f3a759 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.4.29' + id 'fabric-loom' version '0.4-SNAPSHOT' id 'maven-publish' } diff --git a/gradle.properties b/gradle.properties index 9b29aa0..ab93115 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ loader_version=0.9.0+build.204 fabric_version=0.16.1+build.387-1.16 # Mod Properties -mod_version = 1.5.0 +mod_version = 1.5.1 maven_group = org.samo_lego archives_base_name = simpleauth diff --git a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java index b6a60e2..05d4e9a 100644 --- a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java +++ b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java @@ -56,7 +56,13 @@ public class SimpleAuth implements DedicatedServerModInitializer { // It stores some data as well, e.g. login tries and user password public static HashMap deauthenticatedUsers = new HashMap<>(); - // Boolean for easier checking if player is authenticated + /** + * Checks whether player is authenticated + * Fake players always count as authenticated + * + * @param player player that needs to be checked + * @return false if player is de-authenticated, otherwise false + */ public static boolean isAuthenticated(ServerPlayerEntity player) { String uuid = convertUuid(player); return !deauthenticatedUsers.containsKey(uuid) || deauthenticatedUsers.get(uuid).wasAuthenticated; @@ -152,7 +158,13 @@ public class SimpleAuth implements DedicatedServerModInitializer { DB.close(); } - // Getting not authenticated text + /** + * Gets the text which tells the player + * to login or register, depending on account status + * + * @param player player who will get the message + * @return LiteralText with appropriate string (login or register) + */ public static LiteralText notAuthenticated(PlayerEntity player) { final PlayerCache cache = deauthenticatedUsers.get(convertUuid(player)); if(SimpleAuth.config.main.enableGlobalPassword || cache.isRegistered) @@ -164,7 +176,12 @@ public class SimpleAuth implements DedicatedServerModInitializer { ); } - // Authenticates player and sends the message + /** + * Authenticates player and sends the success message + * + * @param player player that needs to be authenticated + * @param msg message to be send to the player + */ public static void authenticatePlayer(ServerPlayerEntity player, Text msg) { PlayerCache playerCache = deauthenticatedUsers.get(convertUuid(player)); // Teleporting player back @@ -198,7 +215,11 @@ public class SimpleAuth implements DedicatedServerModInitializer { player.sendMessage(msg, false); } - // De-authenticates player + /** + * De-authenticates the player + * + * @param player player that needs to be de-authenticated + */ public static void deauthenticatePlayer(ServerPlayerEntity player) { if(DB.isClosed()) return; @@ -230,13 +251,24 @@ public class SimpleAuth implements DedicatedServerModInitializer { }, SimpleAuth.config.main.delay * 1000); } - // Checking is player is a fake (carpetmod) player + /** + * Checks whether player is a fake player (from CarpetMod) + * + * @param player player that needs to be checked + * @return true if player is fake, otherwise false + */ public static boolean isPlayerFake(PlayerEntity player) { // We ask CarpetHelper class since it has the imports needed return FabricLoader.getInstance().isModLoaded("carpet") && isPlayerCarpetFake(player); } - // Teleports player to spawn or last location when authenticating + /** + * Teleports player to spawn or last location that is recorded + * Last location means the location before de-authentication + * + * @param player player that needs to be teleported + * @param toSpawn whether to teleport player to spawn (provided in config) or last recorded position + */ public static void teleportPlayer(ServerPlayerEntity player, boolean toSpawn) { MinecraftServer server = player.getServer(); if(server == null || config.worldSpawn.dimension == null) diff --git a/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java b/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java index 3934c70..ddd536c 100644 --- a/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java +++ b/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java @@ -114,7 +114,6 @@ public class AuthEventHandler { // Teleporting player to the middle of the block player.teleport(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); - playerCache.wasInPortal = true; } } @@ -154,7 +153,17 @@ public class AuthEventHandler { // Player movement public static ActionResult onPlayerMove(PlayerEntity player) { - if(!isAuthenticated((ServerPlayerEntity) player) && !config.experimental.allowMovement) { + // Player will fall if enabled (prevent fly kick) + boolean auth = isAuthenticated((ServerPlayerEntity) player); + if(!auth && config.main.allowFalling && !player.isOnGround() && !player.isInsideWaterOrBubbleColumn()) { + if(player.isInvulnerable()) + player.setInvulnerable(false); + return ActionResult.PASS; + } + // Otherwise movement should be disabled + else if(!auth && !config.experimental.allowMovement) { + if(!player.isInvulnerable()) + player.setInvulnerable(true); return ActionResult.FAIL; } return ActionResult.PASS; diff --git a/src/main/java/org/samo_lego/simpleauth/storage/AuthConfig.java b/src/main/java/org/samo_lego/simpleauth/storage/AuthConfig.java index 3a0e2d2..3b6542e 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/AuthConfig.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/AuthConfig.java @@ -53,8 +53,13 @@ public class AuthConfig { // Visit https://github.com/samolego/SimpleAuth/wiki/Sessions for more info public int sessionTimeoutTime = 60; + // Should deauthenticated players fall if the login mid-air? + public boolean allowFalling = false; + // Whether to tp player to spawn when joining (to hide coordinates) public boolean spawnOnJoin = false; + + // Data for spawn (where deauthenticated players are teleported) public static class WorldSpawn { public String dimension; public double x; diff --git a/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java b/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java index 1e6301f..a4a87bc 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java @@ -1,32 +1,42 @@ package org.samo_lego.simpleauth.storage; import com.google.gson.*; +import net.minecraft.block.Blocks; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.LiteralText; import static org.samo_lego.simpleauth.SimpleAuth.DB; import static org.samo_lego.simpleauth.SimpleAuth.config; +/** + * Class used for storing the deauthenticated player's cache + */ public class PlayerCache { + // Whether player is registered public boolean isRegistered; // If player from another location (different IP) joins, session is invalidated using this boolean public boolean wasAuthenticated; + // Hashed password of player public String password; + // How many times player has tried to login public int loginTries; + // Last IP of player, used for sessions public String lastIp; + // Time until session is valid public long validUntil; - public int lastAir = 300; + // Player stats before de-authenticating + public int lastAir; public boolean wasOnFire; + public boolean wasInPortal; + // Last recorded position before de-authenticating public String lastDim; public double lastX; public double lastY; public double lastZ; private static final Gson gson = new Gson(); - public boolean wasInPortal; - public PlayerCache(String uuid, ServerPlayerEntity player) { if(DB.isClosed()) @@ -40,12 +50,15 @@ public class PlayerCache { // Setting position cache this.lastDim = String.valueOf(player.getEntityWorld().getRegistryKey().getValue()); + this.wasInPortal = player.getBlockState().getBlock().equals(Blocks.NETHER_PORTAL); this.lastX = player.getX(); this.lastY = player.getY(); this.lastZ = player.getZ(); } else { this.wasOnFire = false; + this.wasInPortal = false; + this.lastAir = 300; } if(DB.isUserRegistered(uuid)) { @@ -96,6 +109,5 @@ public class PlayerCache { } this.wasAuthenticated = false; this.loginTries = 0; - this.wasInPortal = false; } } diff --git a/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java b/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java index 9ad0d3f..0397d37 100644 --- a/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java +++ b/src/main/java/org/samo_lego/simpleauth/utils/AuthHelper.java @@ -12,12 +12,17 @@ public class AuthHelper { // Json parser private static final JsonParser parser = new JsonParser(); - // Returns 1 if password is correct, 0 if not - // and -1 if user is not registered yet - public static int checkPass(String uuid, char[] pass) { + /** + * Checks password of user + * + * @param uuid uuid of player, stored in database + * @param password password that needs to be checked + * @return 1 for pass, 0 if password is false, -1 if user is not yet registered + */ + public static int checkPass(String uuid, char[] password) { if(config.main.enableGlobalPassword) { // We have global password enabled - return verifyPassword(pass, config.main.globalPassword) ? 1 : 0; + return verifyPassword(password, config.main.globalPassword) ? 1 : 0; } else { String hashed; @@ -35,18 +40,23 @@ public class AuthHelper { return -1; // User is not yet registered // Verify password - return verifyPassword(pass, hashed) ? 1 : 0; + return verifyPassword(password, hashed) ? 1 : 0; } } - public static String hashPassword(char[] pass) { + /** + * Hashes password with algorithm, depending on config + * + * @param password character array of password string + * @return hashed password as string + */ + public static String hashPassword(char[] password) { if(config.experimental.useBCryptLibrary) - return HasherBCrypt.hash(pass); + return HasherBCrypt.hash(password); else - return HasherArgon2.hash(pass); + return HasherArgon2.hash(password); } - private static boolean verifyPassword(char[] pass, String hashed) { if(config.experimental.useBCryptLibrary) return HasherBCrypt.verify(pass, hashed); diff --git a/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherArgon2.java b/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherArgon2.java index ed32931..726643e 100644 --- a/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherArgon2.java +++ b/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherArgon2.java @@ -10,23 +10,35 @@ public class HasherArgon2 { // Creating the instance private static final Argon2 HASHER = Argon2Factory.create(); - public static boolean verify(char[] pass, String hashed) { + /** + * Verifies password + * + * @param password character array of password string + * @param hashed hashed password + * @return true if password was correct + */ + public static boolean verify(char[] password, String hashed) { try { - return HASHER.verify(hashed, pass); + return HASHER.verify(hashed, password); } catch (Error e) { logError("Argon2 password verification error: " + e); return false; } finally { // Wipe confidential data - HASHER.wipeArray(pass); + HASHER.wipeArray(password); } } - // Hashing the password with the Argon2 power - public static String hash(char[] pass) { + /** + * Hashes the password + * + * @param password character array of password string that needs to be hashed + * @return string + */ + public static String hash(char[] password) { try { - return HASHER.hash(10, 65536, 1, pass); + return HASHER.hash(10, 65536, 1, password); } catch (Error e) { logError("Argon2 password hashing error: " + e); } diff --git a/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherBCrypt.java b/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherBCrypt.java index afdf72d..f04db2a 100644 --- a/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherBCrypt.java +++ b/src/main/java/org/samo_lego/simpleauth/utils/hashing/HasherBCrypt.java @@ -6,9 +6,16 @@ import static org.samo_lego.simpleauth.utils.SimpleLogger.logError; public class HasherBCrypt { - public static boolean verify(char[] pass, String hashed) { + /** + * Verifies password + * + * @param password character array of password string + * @param hashed hashed password + * @return true if password was correct + */ + public static boolean verify(char[] password, String hashed) { try { - return BCrypt.verifyer().verify(pass, hashed).verified; + return BCrypt.verifyer().verify(password, hashed).verified; } catch (Error e) { logError("BCrypt password verification error: " + e); @@ -16,10 +23,15 @@ public class HasherBCrypt { } } - // Hashing the password with the Argon2 power - public static String hash(char[] pass) { + /** + * Hashes the password + * + * @param password character array of password string that needs to be hashed + * @return string + */ + public static String hash(char[] password) { try { - return BCrypt.withDefaults().hashToString(12, pass); + return BCrypt.withDefaults().hashToString(12, password); } catch (Error e) { logError("BCrypt password hashing error: " + e); }