diff --git a/src/main/java/org/samo_lego/simpleauth/commands/LogoutCommand.java b/src/main/java/org/samo_lego/simpleauth/commands/LogoutCommand.java index 4266829..7e975f9 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/LogoutCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/LogoutCommand.java @@ -9,6 +9,7 @@ import org.samo_lego.simpleauth.utils.PlayerAuth; import static net.minecraft.server.command.CommandManager.literal; import static org.samo_lego.simpleauth.SimpleAuth.config; +import static org.samo_lego.simpleauth.SimpleAuth.mojangAccountNamesCache; public class LogoutCommand { @@ -22,8 +23,12 @@ public class LogoutCommand { private static int logout(ServerCommandSource serverCommandSource) throws CommandSyntaxException { ServerPlayerEntity player = serverCommandSource.getPlayer(); - ((PlayerAuth) player).setAuthenticated(false); - player.sendMessage(new LiteralText(config.lang.successfulLogout), false); + if(mojangAccountNamesCache.contains(player.getGameProfile().getName().toLowerCase())) { + ((PlayerAuth) player).setAuthenticated(false); + player.sendMessage(new LiteralText(config.lang.successfulLogout), false); + } + else + player.sendMessage(new LiteralText(config.lang.cannotLogout), false); return 1; } } 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 a20be4e..580999f 100644 --- a/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java +++ b/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java @@ -63,7 +63,6 @@ public class AuthEventHandler { // Player joining the server public static void onPlayerJoin(ServerPlayerEntity player) { - // If player is fake auth is not needed if (((PlayerAuth) player).canSkipAuth()) return; // Checking if session is still valid @@ -76,22 +75,12 @@ public class AuthEventHandler { playerCache.validUntil >= System.currentTimeMillis() && player.getIp().equals(playerCache.lastIp) ) { + // Valid session ((PlayerAuth) player).setAuthenticated(true); return; } - player.setInvulnerable(config.experimental.playerInvulnerable); - player.setInvisible(config.experimental.playerInvisible); - - // Invalidating session - playerCache.isAuthenticated = false; - if(config.main.spawnOnJoin) - ((PlayerAuth) player).hidePosition(true); - } - else { - ((PlayerAuth) player).setAuthenticated(false); - playerCache = playerCacheMap.get(uuid); - playerCache.wasOnFire = false; } + ((PlayerAuth) player).setAuthenticated(false); // Tries to rescue player from nether portal @@ -116,10 +105,8 @@ public class AuthEventHandler { String uuid = ((PlayerAuth) player).getFakeUuid(); PlayerCache playerCache = playerCacheMap.get(uuid); - if(((PlayerAuth) player).isAuthenticated()) { + if(playerCache.isAuthenticated) { playerCache.lastIp = player.getIp(); - playerCache.lastAir = player.getAir(); - playerCache.wasOnFire = player.isOnFire(); playerCache.wasInPortal = player.getBlockState().getBlock().equals(Blocks.NETHER_PORTAL); // Setting the session expire time @@ -151,13 +138,8 @@ public class AuthEventHandler { public static ActionResult onPlayerMove(PlayerEntity player) { // Player will fall if enabled (prevent fly kick) boolean auth = ((PlayerAuth) player).isAuthenticated(); - 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(!auth && !config.experimental.allowMovement) { if(!player.isInvulnerable()) player.setInvulnerable(true); return ActionResult.FAIL; diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java index 2b46435..73655f2 100644 --- a/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java @@ -1,231 +1,17 @@ package org.samo_lego.simpleauth.mixin; -import com.mojang.authlib.GameProfile; -import net.fabricmc.loader.api.FabricLoader; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; import net.minecraft.util.ActionResult; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryKey; -import net.minecraft.world.World; -import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.event.item.DropItemCallback; -import org.samo_lego.simpleauth.storage.PlayerCache; -import org.samo_lego.simpleauth.utils.PlayerAuth; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import static org.samo_lego.simpleauth.SimpleAuth.config; -import static org.samo_lego.simpleauth.SimpleAuth.playerCacheMap; -import static org.samo_lego.simpleauth.utils.CarpetHelper.isPlayerCarpetFake; -import static org.samo_lego.simpleauth.utils.SimpleLogger.logInfo; - @Mixin(PlayerEntity.class) -public abstract class MixinPlayerEntity implements PlayerAuth { +public class MixinPlayerEntity { - @Shadow @Final private GameProfile gameProfile; - private final ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - - // * 20 for 20 ticks in second - private int kickTimer = config.main.kickTime * 20; - - private final boolean isRunningCarpet = FabricLoader.getInstance().isModLoaded("carpet"); - - private final MinecraftServer server = player.getServer(); - - /** - * Teleports player to spawn or last location that is recorded. - * Last location means the location before de-authentication. - * - * @param hide whether to teleport player to spawn (provided in config) or last recorded position - */ - @Override - public void hidePosition(boolean hide) { - assert server != null; - - PlayerCache cache = playerCacheMap.get(this.getFakeUuid()); - if(config.main.spawnOnJoin) - logInfo("Teleporting " + player.getName().asString() + (hide ? " to spawn." : " to original position.")); - if (hide) { - // Saving position - cache.lastLocation.dimension = player.getServerWorld(); - cache.lastLocation.position = player.getPos(); - cache.lastLocation.yaw = player.yaw; - cache.lastLocation.pitch = player.pitch; - - // Teleports player to spawn - player.teleport( - server.getWorld(RegistryKey.of(Registry.DIMENSION, new Identifier(config.worldSpawn.dimension))), - config.worldSpawn.x, - config.worldSpawn.y, - config.worldSpawn.z, - config.worldSpawn.yaw, - config.worldSpawn.pitch - ); - return; - } - // Puts player to last cached position - player.teleport( - cache.lastLocation.dimension, - cache.lastLocation.position.getX(), - cache.lastLocation.position.getY(), - cache.lastLocation.position.getZ(), - cache.lastLocation.yaw, - cache.lastLocation.pitch - ); - } - - /** - * Converts player uuid, to ensure player with "nAmE" and "NamE" get same uuid. - * Both players are not allowed to play, since mod mimics Mojang behaviour. - * of not allowing accounts with same names but different capitalization. - * - * @return converted UUID as string - */ - @Override - public String getFakeUuid() { - // If server is in online mode online-mode UUIDs should be used - assert server != null; - if(server.isOnlineMode() && this.isUsingMojangAccount()) - return player.getUuidAsString(); - /* - Lower case is used for Player and PlAyEr to get same UUID (for password storing) - Mimicking Mojang behaviour, where players cannot set their name to - ExAmple if Example is already taken. - */ - // Getting player+s name via GameProfile, in order to be compatible with Drogtor mod - String playername = player.getGameProfile().getName().toLowerCase(); - return PlayerEntity.getOfflinePlayerUuid(playername).toString(); - - } - - /** - * Sets the authentication status of the player. - * - * @param authenticated whether player should be authenticated - */ - @Override - public void setAuthenticated(boolean authenticated) { - PlayerCache playerCache; - - if(!playerCacheMap.containsKey(this.getFakeUuid())) { - // First join - playerCache = new PlayerCache(this.getFakeUuid(), player); - playerCacheMap.put(this.getFakeUuid(), playerCache); - } - else { - playerCache = playerCacheMap.get(this.getFakeUuid()); - if(this.isAuthenticated() == authenticated) - return; - playerCache.isAuthenticated = authenticated; - } - - player.setInvulnerable(!authenticated && config.experimental.playerInvulnerable); - player.setInvisible(!authenticated && config.experimental.playerInvisible); - - // Teleporting player (hiding / restoring position) - if(config.main.spawnOnJoin) - this.hidePosition(!authenticated); - - if(authenticated) { - kickTimer = config.main.kickTime * 20; - // Updating blocks if needed (if portal rescue action happened) - if(playerCache.wasInPortal) { - World world = player.getEntityWorld(); - BlockPos pos = player.getBlockPos(); - - // Sending updates to portal blocks - // This is technically not needed, but it cleans the "messed portal" on the client - world.updateListeners(pos, world.getBlockState(pos), world.getBlockState(pos), 3); - world.updateListeners(pos.up(), world.getBlockState(pos.up()), world.getBlockState(pos.up()), 3); - } - - // Setting last air to player - if(player.isSubmergedInWater()) - player.setAir(playerCache.lastAir); - - // In case player is in lava during authentication proccess - if(!playerCache.wasOnFire) - player.setFireTicks(0); - } - } - - /** - * Gets the text which tells the player - * to login or register, depending on account status. - * - * @return LiteralText with appropriate string (login or register) - */ - @Override - public Text getAuthMessage() { - final PlayerCache cache = playerCacheMap.get(((PlayerAuth) player).getFakeUuid()); - if(SimpleAuth.config.main.enableGlobalPassword || cache.isRegistered) - return new LiteralText( - SimpleAuth.config.lang.notAuthenticated + "\n" + SimpleAuth.config.lang.loginRequired - ); - return new LiteralText( - SimpleAuth.config.lang.notAuthenticated+ "\n" + SimpleAuth.config.lang.registerRequired - ); - } - - /** - * Checks whether player can skip authentication process. - * - * @return true if can skip authentication process, otherwise false - */ - @Override - public boolean canSkipAuth() { - // We ask CarpetHelper class since it has the imports needed - return (this.isRunningCarpet && isPlayerCarpetFake(this.player)) || (isUsingMojangAccount() && config.experimental.premiumAutologin); - } - - /** - * Whether the player is using the mojang account. - * @return true if paid, otherwise false - */ - @Override - public boolean isUsingMojangAccount() { - return !gameProfile.getId().equals(PlayerEntity.getOfflinePlayerUuid(gameProfile.getName())); - } - - /** - * Checks whether player is authenticated. - * - * @return false if player is not authenticated, otherwise true. - */ - @Override - public boolean isAuthenticated() { - String uuid = ((PlayerAuth) player).getFakeUuid(); - return this.canSkipAuth() || (playerCacheMap.containsKey(uuid) && playerCacheMap.get(uuid).isAuthenticated); - } - - @Inject(method = "tick()V", at = @At("HEAD"), cancellable = true) - private void tick(CallbackInfo ci) { - if(!this.isAuthenticated()) { - // Checking player timer - if(kickTimer <= 0 && player.networkHandler.getConnection().isOpen()) { - player.networkHandler.disconnect(new LiteralText(config.lang.timeExpired)); - } - else { - // Sending authentication prompt every 10 seconds - if(kickTimer % 200 == 0) - player.sendMessage(this.getAuthMessage(), false); - kickTimer--; - } - ci.cancel(); - } - } // Player item dropping @Inject(method = "dropSelectedItem(Z)Z", at = @At("HEAD"), cancellable = true) @@ -234,14 +20,6 @@ public abstract class MixinPlayerEntity implements PlayerAuth { ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player); if (result == ActionResult.FAIL) { - // Canceling the item drop, as well as giving the items back to player (and updating inv with packet) - player.networkHandler.sendPacket( - new ScreenHandlerSlotUpdateS2CPacket( - -2, - player.inventory.selectedSlot, - player.inventory.getStack(player.inventory.selectedSlot)) - ); - player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-1, -1, player.inventory.getCursorStack())); cir.setReturnValue(false); } } diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java new file mode 100644 index 0000000..753db51 --- /dev/null +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java @@ -0,0 +1,216 @@ +package org.samo_lego.simpleauth.mixin; + +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.registry.RegistryKey; +import net.minecraft.world.World; +import org.samo_lego.simpleauth.SimpleAuth; +import org.samo_lego.simpleauth.storage.PlayerCache; +import org.samo_lego.simpleauth.utils.PlayerAuth; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static org.samo_lego.simpleauth.SimpleAuth.*; +import static org.samo_lego.simpleauth.utils.CarpetHelper.isPlayerCarpetFake; +import static org.samo_lego.simpleauth.utils.SimpleLogger.logInfo; + +@Mixin(ServerPlayerEntity.class) +public class MixinServerPlayerEntity implements PlayerAuth { + + private final ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; + + // * 20 for 20 ticks in second + private int kickTimer = config.main.kickTime * 20; + + private final boolean isRunningCarpet = FabricLoader.getInstance().isModLoaded("carpet"); + + @Final + @Shadow + public MinecraftServer server; + + /** + * Teleports player to spawn or last location that is recorded. + * Last location means the location before de-authentication. + * + * @param hide whether to teleport player to spawn (provided in config) or last recorded position + */ + @Override + public void hidePosition(boolean hide) { + assert server != null; + + PlayerCache cache = playerCacheMap.get(this.getFakeUuid()); + if(config.main.spawnOnJoin) + logInfo("Teleporting " + player.getName().asString() + (hide ? " to spawn." : " to original position.")); + if (hide) { + // Saving position + cache.lastLocation.dimension = player.getServerWorld(); + cache.lastLocation.position = player.getPos(); + cache.lastLocation.yaw = player.yaw; + cache.lastLocation.pitch = player.pitch; + + // Teleports player to spawn + player.teleport( + server.getWorld(RegistryKey.of(Registry.DIMENSION, new Identifier(config.worldSpawn.dimension))), + config.worldSpawn.x, + config.worldSpawn.y, + config.worldSpawn.z, + config.worldSpawn.yaw, + config.worldSpawn.pitch + ); + return; + } + // Puts player to last cached position + player.teleport( + cache.lastLocation.dimension, + cache.lastLocation.position.getX(), + cache.lastLocation.position.getY(), + cache.lastLocation.position.getZ(), + cache.lastLocation.yaw, + cache.lastLocation.pitch + ); + } + + /** + * Converts player uuid, to ensure player with "nAmE" and "NamE" get same uuid. + * Both players are not allowed to play, since mod mimics Mojang behaviour. + * of not allowing accounts with same names but different capitalization. + * + * @return converted UUID as string + */ + @Override + public String getFakeUuid() { + // If server is in online mode online-mode UUIDs should be used + assert server != null; + if(server.isOnlineMode() && this.isUsingMojangAccount()) + return player.getUuidAsString(); + /* + Lower case is used for Player and PlAyEr to get same UUID (for password storing) + Mimicking Mojang behaviour, where players cannot set their name to + ExAmple if Example is already taken. + */ + // Getting player+s name via GameProfile, in order to be compatible with Drogtor mod + String playername = player.getGameProfile().getName().toLowerCase(); + return PlayerEntity.getOfflinePlayerUuid(playername).toString(); + + } + + /** + * Sets the authentication status of the player. + * + * @param authenticated whether player should be authenticated + */ + @Override + public void setAuthenticated(boolean authenticated) { + PlayerCache playerCache; + + if(!playerCacheMap.containsKey(this.getFakeUuid())) { + // First join + playerCache = new PlayerCache(this.getFakeUuid(), player); + playerCacheMap.put(this.getFakeUuid(), playerCache); + } + else { + playerCache = playerCacheMap.get(this.getFakeUuid()); + if(this.isAuthenticated() == authenticated) + return; + playerCache.isAuthenticated = authenticated; + } + + player.setInvulnerable(!authenticated && config.experimental.playerInvulnerable); + player.setInvisible(!authenticated && config.experimental.playerInvisible); + + // Teleporting player (hiding / restoring position) + if(config.main.spawnOnJoin) + this.hidePosition(!authenticated); + + if(authenticated) { + kickTimer = config.main.kickTime * 20; + // Updating blocks if needed (if portal rescue action happened) + if(playerCache.wasInPortal) { + World world = player.getEntityWorld(); + BlockPos pos = player.getBlockPos(); + + // Sending updates to portal blocks + // This is technically not needed, but it cleans the "messed portal" on the client + world.updateListeners(pos, world.getBlockState(pos), world.getBlockState(pos), 3); + world.updateListeners(pos.up(), world.getBlockState(pos.up()), world.getBlockState(pos.up()), 3); + } + } + } + + /** + * Gets the text which tells the player + * to login or register, depending on account status. + * + * @return LiteralText with appropriate string (login or register) + */ + @Override + public Text getAuthMessage() { + final PlayerCache cache = playerCacheMap.get(((PlayerAuth) player).getFakeUuid()); + if(SimpleAuth.config.main.enableGlobalPassword || cache.isRegistered) + return new LiteralText( + SimpleAuth.config.lang.notAuthenticated + "\n" + SimpleAuth.config.lang.loginRequired + ); + return new LiteralText( + SimpleAuth.config.lang.notAuthenticated+ "\n" + SimpleAuth.config.lang.registerRequired + ); + } + + /** + * Checks whether player can skip authentication process. + * + * @return true if can skip authentication process, otherwise false + */ + @Override + public boolean canSkipAuth() { + // We ask CarpetHelper class since it has the imports needed + return (this.isRunningCarpet && isPlayerCarpetFake(this.player)) || (isUsingMojangAccount() && config.experimental.premiumAutologin); + } + + /** + * Whether the player is using the mojang account. + * @return true if paid, otherwise false + */ + @Override + public boolean isUsingMojangAccount() { + return mojangAccountNamesCache.contains(player.getGameProfile().getName().toLowerCase()); + } + + /** + * Checks whether player is authenticated. + * + * @return false if player is not authenticated, otherwise true. + */ + @Override + public boolean isAuthenticated() { + String uuid = ((PlayerAuth) player).getFakeUuid(); + return this.canSkipAuth() || (playerCacheMap.containsKey(uuid) && playerCacheMap.get(uuid).isAuthenticated); + } + + @Inject(method = "playerTick()V", at = @At("HEAD"), cancellable = true) + private void playerTick(CallbackInfo ci) { + if(!this.isAuthenticated()) { + // Checking player timer + if(kickTimer <= 0 && player.networkHandler.getConnection().isOpen()) { + player.networkHandler.disconnect(new LiteralText(config.lang.timeExpired)); + } + else { + // Sending authentication prompt every 10 seconds + if(kickTimer % 200 == 0) + player.sendMessage(this.getAuthMessage(), false); + --kickTimer; + } + ci.cancel(); + } + } +} \ No newline at end of file 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 34af65a..34b5647 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/AuthConfig.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/AuthConfig.java @@ -81,11 +81,6 @@ public class AuthConfig { */ 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 original player coordinates) */ @@ -125,7 +120,7 @@ public class AuthConfig { public String timeExpired = "§cTime for authentication has expired."; public String registerRequired = "§6Type /register to claim this account."; public String alreadyRegistered = "§6This account name is already registered!"; - public String registerSuccess = "§aYou are now authenticated."; + public String registerSuccess = "§aAccount was created."; public String userdataDeleted = "§aUserdata deleted."; public String userdataUpdated = "§aUserdata updated."; public String accountDeleted = "§aYour account was successfully deleted!"; @@ -137,6 +132,7 @@ public class AuthConfig { public String worldSpawnSet = "§aSpawn for logging in was set successfully."; public String corruptedPlayerData = "§cYour data is probably corrupted. Please contact admin."; public String userNotRegistered = "§cThis player is not registered!"; + public String cannotLogout = "§cYou cannot logout!"; } public static class ExperimentalConfig { /** 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 c814558..0c5b17b 100644 --- a/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java +++ b/src/main/java/org/samo_lego/simpleauth/storage/PlayerCache.java @@ -1,16 +1,14 @@ package org.samo_lego.simpleauth.storage; -import com.google.gson.*; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; import net.minecraft.block.Blocks; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.LiteralText; -import net.minecraft.util.Identifier; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.registry.RegistryKey; - -import java.util.Objects; import static org.samo_lego.simpleauth.SimpleAuth.DB; import static org.samo_lego.simpleauth.SimpleAuth.config; @@ -50,8 +48,6 @@ public class PlayerCache { /** * Player stats before de-authentication. */ - public int lastAir; - public boolean wasOnFire; public boolean wasInPortal; /** @@ -78,9 +74,6 @@ public class PlayerCache { logInfo("Creating cache for " + player.getName().asString()); this.lastIp = player.getIp(); - this.lastAir = player.getAir(); - this.wasOnFire = player.isOnFire(); - // Setting position cache this.lastLocation.dimension = player.getServerWorld(); this.lastLocation.position = player.getPos(); @@ -90,9 +83,7 @@ public class PlayerCache { this.wasInPortal = player.getBlockState().getBlock().equals(Blocks.NETHER_PORTAL); } else { - this.wasOnFire = false; this.wasInPortal = false; - this.lastAir = 300; } String data = DB.getData(uuid); @@ -114,32 +105,6 @@ public class PlayerCache { this.password = passwordElement.getAsString(); this.isRegistered = !this.password.isEmpty(); } - - - // DEPRECATED, UGLY - if(config.main.spawnOnJoin) { - try { - JsonElement lastLoc = json.get("lastLocation"); - if (lastLoc != null) { - // Getting DB coords - JsonObject lastLocation = gson.fromJson(lastLoc.getAsString(), JsonObject.class); - assert player != null; - this.lastLocation.dimension = Objects.requireNonNull(player.getServer()).getWorld(RegistryKey.of(Registry.DIMENSION, new Identifier( - lastLocation.get("dim").isJsonNull() ? config.worldSpawn.dimension : lastLocation.get("dim").getAsString()))); - - this.lastLocation.position = new Vec3d( - lastLocation.get("x").isJsonNull() ? config.worldSpawn.x : lastLocation.get("x").getAsDouble(), - lastLocation.get("y").isJsonNull() ? config.worldSpawn.y : lastLocation.get("y").getAsDouble(), - lastLocation.get("z").isJsonNull() ? config.worldSpawn.z : lastLocation.get("z").getAsDouble() - ); - this.lastLocation.yaw = lastLocation.get("yaw") == null ? 90 : lastLocation.get("yaw").getAsFloat(); - this.lastLocation.pitch = lastLocation.get("pitch") == null ? 0 : lastLocation.get("pitch").getAsFloat(); - - } - } catch (JsonSyntaxException ignored) { - // Player didn't have any coords in db to tp to - } - } } else { this.isRegistered = false; diff --git a/src/main/resources/mixins.simpleauth.json b/src/main/resources/mixins.simpleauth.json index 0539766..d1b281d 100644 --- a/src/main/resources/mixins.simpleauth.json +++ b/src/main/resources/mixins.simpleauth.json @@ -7,6 +7,7 @@ "MixinPlayerEntity", "MixinPlayerManager", "MixinServerLoginNetworkHandler", + "MixinServerPlayerEntity", "MixinServerPlayNetworkHandler", "MixinSlot", "MixinWorldSaveHandler"