forked from sorceress/EasyAuth
Starting with player position protection. RN throws NPE when leaving server
This commit is contained in:
parent
eb927bbf37
commit
f5d7de0b41
|
@ -6,9 +6,11 @@ import net.fabricmc.fabric.api.event.server.ServerStopCallback;
|
|||
import net.fabricmc.fabric.api.registry.CommandRegistry;
|
||||
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.world.dimension.DimensionType;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.samo_lego.simpleauth.commands.*;
|
||||
|
@ -109,7 +111,11 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
|||
|
||||
// Authenticates player and sends the message
|
||||
public static void authenticatePlayer(ServerPlayerEntity player, Text msg) {
|
||||
// Teleporting player back
|
||||
teleportPlayer(player, false);
|
||||
|
||||
deauthenticatedUsers.remove(convertUuid(player));
|
||||
|
||||
// Player no longer needs to be invisible and invulnerable
|
||||
player.setInvulnerable(false);
|
||||
player.setInvisible(false);
|
||||
|
@ -120,9 +126,12 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
|||
public static void deauthenticatePlayer(ServerPlayerEntity player) {
|
||||
if(db.isClosed())
|
||||
return;
|
||||
|
||||
// Marking player as not authenticated, (re)setting login tries to zero
|
||||
String uuid = convertUuid(player);
|
||||
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, player.getIp()));
|
||||
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, player));
|
||||
// Teleporting player to spawn to hide its position
|
||||
teleportPlayer(player, true);
|
||||
|
||||
// Player is now not authenticated
|
||||
player.sendMessage(notAuthenticated(), false);
|
||||
|
@ -144,4 +153,33 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
|||
// 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
|
||||
public static void teleportPlayer(ServerPlayerEntity player, boolean toSpawn) {
|
||||
if(config.main.spawnOnJoin) {
|
||||
MinecraftServer server = player.getServer();
|
||||
assert server != null;
|
||||
if (toSpawn) {
|
||||
// Teleports player to spawn
|
||||
player.teleport(
|
||||
server.getWorld(DimensionType.byRawId(config.worldSpawn.dimensionId)),
|
||||
config.worldSpawn.x,
|
||||
config.worldSpawn.y,
|
||||
config.worldSpawn.z,
|
||||
0,
|
||||
0
|
||||
);
|
||||
return;
|
||||
}
|
||||
PlayerCache cache = deauthenticatedUsers.get(convertUuid(player));
|
||||
// Puts player to last cached position
|
||||
player.setWorld(server.getWorld(DimensionType.byRawId(cache.lastDimId)));
|
||||
player.setPos(
|
||||
cache.lastX,
|
||||
cache.lastY,
|
||||
cache.lastZ
|
||||
);
|
||||
player.updateNeeded = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,19 +15,24 @@ import org.samo_lego.simpleauth.storage.PlayerCache;
|
|||
import org.samo_lego.simpleauth.utils.AuthHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.word;
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
import static org.samo_lego.simpleauth.SimpleAuth.config;
|
||||
import static org.samo_lego.simpleauth.SimpleAuth.db;
|
||||
|
||||
public class AuthCommand {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private static Text userdataDeleted = new LiteralText(SimpleAuth.config.lang.userdataDeleted);
|
||||
private static Text userdataUpdated = new LiteralText(SimpleAuth.config.lang.userdataUpdated);
|
||||
private static Text configurationReloaded = new LiteralText(SimpleAuth.config.lang.configurationReloaded);
|
||||
private static Text globalPasswordSet = new LiteralText(SimpleAuth.config.lang.globalPasswordSet);
|
||||
private static Text userdataDeleted = new LiteralText(config.lang.userdataDeleted);
|
||||
private static Text userdataUpdated = new LiteralText(config.lang.userdataUpdated);
|
||||
private static Text configurationReloaded = new LiteralText(config.lang.configurationReloaded);
|
||||
private static Text globalPasswordSet = new LiteralText(config.lang.globalPasswordSet);
|
||||
|
||||
public static void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
// Registering the "/auth" command
|
||||
|
@ -44,6 +49,32 @@ public class AuthCommand {
|
|||
))
|
||||
)
|
||||
)
|
||||
.then(literal("setSpawn")
|
||||
.then(argument("here", word())
|
||||
.executes( ctx -> setSpawn(
|
||||
ctx.getSource(),
|
||||
Objects.requireNonNull(ctx.getSource().getEntity()).dimension.getRawId(),
|
||||
ctx.getSource().getEntity().getX(),
|
||||
ctx.getSource().getEntity().getY(),
|
||||
ctx.getSource().getEntity().getZ()
|
||||
))
|
||||
)
|
||||
.then(argument("dimensionId", integer())
|
||||
.then(argument("x", integer())
|
||||
.then(argument("y", integer())
|
||||
.then(argument("z", integer())
|
||||
.executes( ctx -> setSpawn(
|
||||
ctx.getSource(),
|
||||
getInteger(ctx, "dimensionId"),
|
||||
getInteger(ctx, "x"),
|
||||
getInteger(ctx, "y"),
|
||||
getInteger(ctx, "z")
|
||||
))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.then(literal("remove")
|
||||
.then(argument("uuid", word())
|
||||
.executes( ctx -> removeAccount(
|
||||
|
@ -80,12 +111,12 @@ public class AuthCommand {
|
|||
// Reloading the config
|
||||
private static int reloadConfig(ServerCommandSource source) {
|
||||
Entity sender = source.getEntity();
|
||||
SimpleAuth.config = AuthConfig.load(new File("./mods/SimpleAuth/config.json"));
|
||||
config = AuthConfig.load(new File("./mods/SimpleAuth/config.json"));
|
||||
|
||||
if(sender != null)
|
||||
((PlayerEntity) sender).sendMessage(configurationReloaded, false);
|
||||
else
|
||||
LOGGER.info(SimpleAuth.config.lang.configurationReloaded);
|
||||
LOGGER.info(config.lang.configurationReloaded);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -94,27 +125,41 @@ public class AuthCommand {
|
|||
// Getting the player who send the command
|
||||
Entity sender = source.getEntity();
|
||||
// Writing the global pass to config
|
||||
SimpleAuth.config.main.globalPassword = AuthHelper.hashPass(pass.toCharArray());
|
||||
SimpleAuth.config.main.enableGlobalPassword = true;
|
||||
SimpleAuth.config.save(new File("./mods/SimpleAuth/config.json"));
|
||||
config.main.globalPassword = AuthHelper.hashPass(pass.toCharArray());
|
||||
config.main.enableGlobalPassword = true;
|
||||
config.save(new File("./mods/SimpleAuth/config.json"));
|
||||
|
||||
if(sender != null)
|
||||
((PlayerEntity) sender).sendMessage(globalPasswordSet, false);
|
||||
else
|
||||
LOGGER.info(SimpleAuth.config.lang.globalPasswordSet);
|
||||
LOGGER.info(config.lang.globalPasswordSet);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
private static int setSpawn(ServerCommandSource source, int dimensionId, double x, double y, double z) {
|
||||
config.worldSpawn.dimensionId = dimensionId;
|
||||
config.worldSpawn.x = x;
|
||||
config.worldSpawn.y = y;
|
||||
config.worldSpawn.z = z;
|
||||
Entity sender = source.getEntity();
|
||||
if(sender != null)
|
||||
sender.sendSystemMessage(new LiteralText(config.lang.worldSpawnSet));
|
||||
else
|
||||
LOGGER.info(config.lang.worldSpawnSet);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Deleting (unregistering) user's account
|
||||
private static int removeAccount(ServerCommandSource source, String uuid) {
|
||||
Entity sender = source.getEntity();
|
||||
SimpleAuth.db.deleteUserData(uuid);
|
||||
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, ""));
|
||||
db.deleteUserData(uuid);
|
||||
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, null));
|
||||
|
||||
if(sender != null)
|
||||
((PlayerEntity) sender).sendMessage(userdataDeleted, false);
|
||||
else
|
||||
LOGGER.info(SimpleAuth.config.lang.userdataDeleted);
|
||||
LOGGER.info(config.lang.userdataDeleted);
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
|
@ -128,11 +173,11 @@ public class AuthCommand {
|
|||
String hash = AuthHelper.hashPass(password.toCharArray());
|
||||
playerdata.addProperty("password", hash);
|
||||
|
||||
if(SimpleAuth.db.registerUser(uuid, playerdata.toString())) {
|
||||
if(db.registerUser(uuid, playerdata.toString())) {
|
||||
if(sender != null)
|
||||
((PlayerEntity) sender).sendMessage(userdataUpdated, false);
|
||||
else
|
||||
LOGGER.info(SimpleAuth.config.lang.userdataUpdated);
|
||||
LOGGER.info(config.lang.userdataUpdated);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -148,11 +193,11 @@ public class AuthCommand {
|
|||
String hash = AuthHelper.hashPass(password.toCharArray());
|
||||
playerdata.addProperty("password", hash);
|
||||
|
||||
SimpleAuth.db.updateUserData(uuid, playerdata.toString());
|
||||
db.updateUserData(uuid, playerdata.toString());
|
||||
if(sender != null)
|
||||
((PlayerEntity) sender).sendMessage(userdataUpdated, false);
|
||||
else
|
||||
LOGGER.info(SimpleAuth.config.lang.userdataUpdated);
|
||||
LOGGER.info(config.lang.userdataUpdated);
|
||||
return 1;
|
||||
}
|
||||
// todo PlayerEntity.getOfflinePlayerUuid("")
|
||||
|
|
|
@ -71,6 +71,7 @@ public class AuthEventHandler {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Player joining the server
|
||||
public static void onPlayerJoin(ServerPlayerEntity player) {
|
||||
// If player is fake auth is not needed
|
||||
|
@ -89,8 +90,7 @@ public class AuthEventHandler {
|
|||
deauthenticatedUsers.remove(uuid); // Makes player authenticated
|
||||
return;
|
||||
}
|
||||
else
|
||||
deauthenticatePlayer(player);
|
||||
deauthenticatePlayer(player);
|
||||
|
||||
// Tries to rescue player from nether portal
|
||||
if(config.main.tryPortalRescue && player.getBlockState().getBlock().equals(Blocks.NETHER_PORTAL)) {
|
||||
|
@ -163,11 +163,13 @@ public class AuthEventHandler {
|
|||
}
|
||||
|
||||
public static void onPlayerLeave(ServerPlayerEntity player) {
|
||||
if(
|
||||
!isAuthenticated(player) ||
|
||||
config.main.sessionTimeoutTime == -1 ||
|
||||
isPlayerFake(player)
|
||||
)
|
||||
if(isPlayerFake(player))
|
||||
return;
|
||||
|
||||
// Teleporting player back
|
||||
teleportPlayer(player, false);
|
||||
|
||||
if(!isAuthenticated(player) || config.main.sessionTimeoutTime == -1)
|
||||
return;
|
||||
|
||||
// Starting session
|
||||
|
|
|
@ -40,7 +40,7 @@ public class AuthConfig {
|
|||
// Disables registering and forces logging in with global password
|
||||
// Visit https://github.com/samolego/SimpleAuth/wiki/Locking-server-with-global-password for more info
|
||||
public boolean enableGlobalPassword = false;
|
||||
public String globalPassword = null;
|
||||
public String globalPassword;
|
||||
// Tries to rescue players if they are stuck inside a portal on logging in
|
||||
// Visit https://github.com/samolego/SimpleAuth/wiki/Portal-Rescue for more info
|
||||
public boolean tryPortalRescue = true;
|
||||
|
@ -54,6 +54,14 @@ public class AuthConfig {
|
|||
// Set to -1 to disable
|
||||
// Visit https://github.com/samolego/SimpleAuth/wiki/Sessions for more info
|
||||
public int sessionTimeoutTime = 60;
|
||||
|
||||
public boolean spawnOnJoin = false;
|
||||
public static class WorldSpawn {
|
||||
public int dimensionId;
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
};
|
||||
}
|
||||
public static class LangConfig {
|
||||
public String enterPassword = "§6You need to enter your password!";
|
||||
|
@ -83,6 +91,7 @@ public class AuthConfig {
|
|||
public String minPasswordChars = "§6Password needs to be at least %d characters long!";
|
||||
public String disallowedUsername = "§6Invalid username characters! Allowed character regex: %s";
|
||||
public String playerAlreadyOnline = "§cPlayer %s is already online!";
|
||||
public String worldSpawnSet = "";
|
||||
}
|
||||
public static class ExperimentalConfig {
|
||||
// Prevents player being kicked because another player with the same name has joined the server
|
||||
|
@ -114,6 +123,7 @@ public class AuthConfig {
|
|||
.create();
|
||||
|
||||
public MainConfig main = new MainConfig();
|
||||
public MainConfig.WorldSpawn worldSpawn = new MainConfig.WorldSpawn();
|
||||
public LangConfig lang = new LangConfig();
|
||||
public ExperimentalConfig experimental = new ExperimentalConfig();
|
||||
|
||||
|
|
|
@ -2,7 +2,10 @@ package org.samo_lego.simpleauth.storage;
|
|||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.samo_lego.simpleauth.SimpleAuth;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
import static org.samo_lego.simpleauth.SimpleAuth.config;
|
||||
import static org.samo_lego.simpleauth.SimpleAuth.db;
|
||||
|
||||
public class PlayerCache {
|
||||
public boolean isRegistered;
|
||||
|
@ -11,15 +14,40 @@ public class PlayerCache {
|
|||
public int loginTries;
|
||||
public String lastIp;
|
||||
public long validUntil;
|
||||
|
||||
public int lastDimId;
|
||||
public double lastX;
|
||||
public double lastY;
|
||||
public double lastZ;
|
||||
|
||||
private static final JsonParser parser = new JsonParser();
|
||||
|
||||
|
||||
public PlayerCache(String uuid, String ip) {
|
||||
SimpleAuthDatabase db = SimpleAuth.db;
|
||||
public PlayerCache(String uuid, ServerPlayerEntity player) {
|
||||
if(db.isClosed())
|
||||
return;
|
||||
if(player != null) {
|
||||
this.lastIp = player.getIp();
|
||||
|
||||
// Setting last coordinates
|
||||
this.lastDimId = player.dimension.getRawId();
|
||||
this.lastX = player.getX();
|
||||
this.lastY = player.getY();
|
||||
this.lastZ = player.getZ();
|
||||
}
|
||||
else {
|
||||
this.lastIp = "";
|
||||
|
||||
// Setting last coordinates
|
||||
this.lastDimId = config.worldSpawn.dimensionId;
|
||||
this.lastX = config.worldSpawn.x;
|
||||
this.lastY = config.worldSpawn.y;
|
||||
this.lastZ = config.worldSpawn.z;
|
||||
}
|
||||
|
||||
this.wasAuthenticated = false;
|
||||
this.loginTries = 0;
|
||||
this.lastIp = ip;
|
||||
|
||||
|
||||
if(db.isUserRegistered(uuid)) {
|
||||
this.isRegistered = true;
|
||||
|
|
Loading…
Reference in New Issue