Fixed NPE that could occur when stopping server.
This commit is contained in:
parent
898ed03e26
commit
27cdcf324d
|
@ -5,6 +5,7 @@ import net.fabricmc.fabric.api.event.player.*;
|
||||||
import net.fabricmc.fabric.api.event.server.ServerStopCallback;
|
import net.fabricmc.fabric.api.event.server.ServerStopCallback;
|
||||||
import net.fabricmc.fabric.api.registry.CommandRegistry;
|
import net.fabricmc.fabric.api.registry.CommandRegistry;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
@ -12,10 +13,7 @@ import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.samo_lego.simpleauth.commands.*;
|
import org.samo_lego.simpleauth.commands.*;
|
||||||
import org.samo_lego.simpleauth.event.AuthEventHandler;
|
import org.samo_lego.simpleauth.event.AuthEventHandler;
|
||||||
import org.samo_lego.simpleauth.event.entity.player.ChatCallback;
|
import org.samo_lego.simpleauth.event.entity.player.*;
|
||||||
import org.samo_lego.simpleauth.event.entity.player.PlayerJoinServerCallback;
|
|
||||||
import org.samo_lego.simpleauth.event.entity.player.PlayerLeaveServerCallback;
|
|
||||||
import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback;
|
|
||||||
import org.samo_lego.simpleauth.event.item.DropItemCallback;
|
import org.samo_lego.simpleauth.event.item.DropItemCallback;
|
||||||
import org.samo_lego.simpleauth.event.item.TakeItemCallback;
|
import org.samo_lego.simpleauth.event.item.TakeItemCallback;
|
||||||
import org.samo_lego.simpleauth.storage.AuthConfig;
|
import org.samo_lego.simpleauth.storage.AuthConfig;
|
||||||
|
@ -75,6 +73,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Registering the events
|
// Registering the events
|
||||||
|
PrePlayerJoinCallback.EVENT.register(AuthEventHandler::checkCanPlayerJoinServer);
|
||||||
PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin);
|
PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin);
|
||||||
PlayerLeaveServerCallback.EVENT.register(AuthEventHandler::onPlayerLeave);
|
PlayerLeaveServerCallback.EVENT.register(AuthEventHandler::onPlayerLeave);
|
||||||
DropItemCallback.EVENT.register(AuthEventHandler::onDropItem);
|
DropItemCallback.EVENT.register(AuthEventHandler::onDropItem);
|
||||||
|
@ -115,6 +114,8 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
||||||
|
|
||||||
// De-authenticates player
|
// De-authenticates player
|
||||||
public static void deauthenticatePlayer(ServerPlayerEntity player) {
|
public static void deauthenticatePlayer(ServerPlayerEntity player) {
|
||||||
|
if(db.isClosed())
|
||||||
|
return;
|
||||||
// Marking player as not authenticated, (re)setting login tries to zero
|
// Marking player as not authenticated, (re)setting login tries to zero
|
||||||
String uuid = player.getUuidAsString();
|
String uuid = player.getUuidAsString();
|
||||||
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, player.getIp()));
|
SimpleAuth.deauthenticatedUsers.put(uuid, new PlayerCache(uuid, player.getIp()));
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class AuthCommand {
|
||||||
SimpleAuth.config.save(new File("./mods/SimpleAuth/config.json"));
|
SimpleAuth.config.save(new File("./mods/SimpleAuth/config.json"));
|
||||||
|
|
||||||
if(sender != null)
|
if(sender != null)
|
||||||
sender.sendSystemMessage(globalPasswordSet);
|
((PlayerEntity) sender).sendMessage(globalPasswordSet, false);
|
||||||
else
|
else
|
||||||
LOGGER.info(SimpleAuth.config.lang.globalPasswordSet);
|
LOGGER.info(SimpleAuth.config.lang.globalPasswordSet);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package org.samo_lego.simpleauth.event;
|
package org.samo_lego.simpleauth.event;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
|
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
|
||||||
|
import net.minecraft.server.PlayerManager;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
@ -14,6 +16,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import org.samo_lego.simpleauth.storage.PlayerCache;
|
import org.samo_lego.simpleauth.storage.PlayerCache;
|
||||||
|
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -35,18 +38,40 @@ public class AuthEventHandler {
|
||||||
|
|
||||||
private static Text successfulPortalRescue = new LiteralText(config.lang.successfulPortalRescue);
|
private static Text successfulPortalRescue = new LiteralText(config.lang.successfulPortalRescue);
|
||||||
|
|
||||||
// Player joining the server
|
// Player pre-join
|
||||||
public static void onPlayerJoin(ServerPlayerEntity player) {
|
// Returns text as a reason for disconnect or null to pass
|
||||||
|
public static LiteralText checkCanPlayerJoinServer(SocketAddress socketAddress, GameProfile profile, PlayerManager manager) {
|
||||||
|
// Getting the player
|
||||||
|
String incomingPlayerUsername = profile.getName();
|
||||||
|
PlayerEntity onlinePlayer = manager.getPlayer(incomingPlayerUsername);
|
||||||
|
|
||||||
// Checking if player username is valid
|
// Checking if player username is valid
|
||||||
String regex = config.main.usernameRegex;
|
String regex = config.main.usernameRegex;
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile(regex);
|
Pattern pattern = Pattern.compile(regex);
|
||||||
Matcher matcher = pattern.matcher(player.getName().getString());
|
Matcher matcher = pattern.matcher(incomingPlayerUsername);
|
||||||
if (!matcher.matches()) {
|
|
||||||
player.networkHandler.disconnect(new LiteralText(String.format(config.lang.disallowedUsername, regex)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(onlinePlayer != null && config.experimental.disableAnotherLocationKick) {
|
||||||
|
// Player needs to be kicked, since there's already a player with that name
|
||||||
|
// playing on the server
|
||||||
|
return new LiteralText(
|
||||||
|
String.format(
|
||||||
|
config.lang.playerAlreadyOnline, onlinePlayer.getName().asString()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(!matcher.matches()) {
|
||||||
|
return new LiteralText(
|
||||||
|
String.format(
|
||||||
|
config.lang.disallowedUsername, regex
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Player joining the server
|
||||||
|
public static void onPlayerJoin(ServerPlayerEntity player) {
|
||||||
// Checking if session is still valid
|
// Checking if session is still valid
|
||||||
String uuid = player.getUuidAsString();
|
String uuid = player.getUuidAsString();
|
||||||
PlayerCache playerCache = deauthenticatedUsers.getOrDefault(uuid, null);
|
PlayerCache playerCache = deauthenticatedUsers.getOrDefault(uuid, null);
|
||||||
|
@ -143,8 +168,8 @@ public class AuthEventHandler {
|
||||||
// Setting that player was actually authenticated before leaving
|
// Setting that player was actually authenticated before leaving
|
||||||
PlayerCache playerCache = deauthenticatedUsers.get(player.getUuidAsString());
|
PlayerCache playerCache = deauthenticatedUsers.get(player.getUuidAsString());
|
||||||
playerCache.wasAuthenticated = true;
|
playerCache.wasAuthenticated = true;
|
||||||
|
// Setting the session expire time
|
||||||
playerCache.validUntil = System.currentTimeMillis() + config.main.sessionTimeoutTime * 1000;
|
playerCache.validUntil = System.currentTimeMillis() + config.main.sessionTimeoutTime * 1000;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Player chatting
|
// Player chatting
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.samo_lego.simpleauth.event.entity.player;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.fabricmc.fabric.api.event.Event;
|
||||||
|
import net.fabricmc.fabric.api.event.EventFactory;
|
||||||
|
import net.minecraft.server.PlayerManager;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
public interface PrePlayerJoinCallback {
|
||||||
|
Event<PrePlayerJoinCallback> EVENT = EventFactory.createArrayBacked(
|
||||||
|
PrePlayerJoinCallback.class, listeners -> (
|
||||||
|
socketAddress, profile, manager
|
||||||
|
) -> {
|
||||||
|
for (PrePlayerJoinCallback event : listeners) {
|
||||||
|
|
||||||
|
LiteralText returnText = event.checkCanPlayerJoinServer(socketAddress, profile, manager);
|
||||||
|
|
||||||
|
if (returnText != null) {
|
||||||
|
return returnText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
LiteralText checkCanPlayerJoinServer(SocketAddress socketAddress, GameProfile profile, PlayerManager manager);
|
||||||
|
}
|
|
@ -1,14 +1,24 @@
|
||||||
package org.samo_lego.simpleauth.mixin;
|
package org.samo_lego.simpleauth.mixin;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import net.minecraft.network.ClientConnection;
|
import net.minecraft.network.ClientConnection;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.PlayerManager;
|
import net.minecraft.server.PlayerManager;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import org.samo_lego.simpleauth.event.entity.player.PlayerJoinServerCallback;
|
import org.samo_lego.simpleauth.event.entity.player.PlayerJoinServerCallback;
|
||||||
import org.samo_lego.simpleauth.event.entity.player.PlayerLeaveServerCallback;
|
import org.samo_lego.simpleauth.event.entity.player.PlayerLeaveServerCallback;
|
||||||
|
import org.samo_lego.simpleauth.event.entity.player.PrePlayerJoinCallback;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
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.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
@Mixin(PlayerManager.class)
|
@Mixin(PlayerManager.class)
|
||||||
public abstract class MixinPlayerManager {
|
public abstract class MixinPlayerManager {
|
||||||
|
@ -22,4 +32,18 @@ public abstract class MixinPlayerManager {
|
||||||
private void onPlayerLeave(ServerPlayerEntity serverPlayerEntity, CallbackInfo ci) {
|
private void onPlayerLeave(ServerPlayerEntity serverPlayerEntity, CallbackInfo ci) {
|
||||||
PlayerLeaveServerCallback.EVENT.invoker().onPlayerLeave(serverPlayerEntity);
|
PlayerLeaveServerCallback.EVENT.invoker().onPlayerLeave(serverPlayerEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method for kicking player for
|
||||||
|
@Inject(method = "checkCanJoin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/text/Text;", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void checkCanJoin(SocketAddress socketAddress, GameProfile profile, CallbackInfoReturnable<Text> cir) {
|
||||||
|
// Getting the player that is trying to join the server
|
||||||
|
PlayerManager manager = (PlayerManager) (Object) this;
|
||||||
|
|
||||||
|
LiteralText returnText = PrePlayerJoinCallback.EVENT.invoker().checkCanPlayerJoinServer(socketAddress, profile, manager);
|
||||||
|
|
||||||
|
if(returnText != null) {
|
||||||
|
// Canceling player joining with the returnText message
|
||||||
|
cir.setReturnValue(returnText);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package org.samo_lego.simpleauth.mixin;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.network.ServerLoginNetworkHandler;
|
|
||||||
import net.minecraft.text.LiteralText;
|
|
||||||
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.config;
|
|
||||||
|
|
||||||
|
|
||||||
@Mixin(ServerLoginNetworkHandler.class)
|
|
||||||
public abstract class MixinServerLoginNetworkHandler {
|
|
||||||
|
|
||||||
@Shadow @Final
|
|
||||||
private MinecraftServer server;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private GameProfile profile;
|
|
||||||
|
|
||||||
@Inject(method = "acceptPlayer()V", at = @At("HEAD"), cancellable = true)
|
|
||||||
private void acceptPlayer(CallbackInfo ci) {
|
|
||||||
// Player pre-join event, we don't do standard callback, since
|
|
||||||
// there are lots of variables that would need to be passed over
|
|
||||||
PlayerEntity onlinePlayer = this.server.getPlayerManager().getPlayer(this.profile.getName());
|
|
||||||
|
|
||||||
// Getting network handler
|
|
||||||
ServerLoginNetworkHandler handler = (ServerLoginNetworkHandler) (Object) this;
|
|
||||||
|
|
||||||
if (config.experimental.disableAnotherLocationKick && onlinePlayer != null) {
|
|
||||||
// Player needs to be kicked, since there's already a player with that name
|
|
||||||
// playing on the server
|
|
||||||
handler.disconnect(new LiteralText(String.format(config.lang.playerAlreadyOnline, onlinePlayer.getName().asString())));
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -39,6 +39,12 @@ public class SimpleAuthDatabase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tells whether db connection is closed
|
||||||
|
public boolean isClosed() {
|
||||||
|
return levelDBStore != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// When player registers, we insert the data into DB
|
// When player registers, we insert the data into DB
|
||||||
public boolean registerUser(String uuid, String data) {
|
public boolean registerUser(String uuid, String data) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
"server": [
|
"server": [
|
||||||
"MixinPlayerEntity",
|
"MixinPlayerEntity",
|
||||||
"MixinPlayerManager",
|
"MixinPlayerManager",
|
||||||
"MixinServerLoginNetworkHandler",
|
|
||||||
"MixinServerPlayNetworkHandler",
|
"MixinServerPlayNetworkHandler",
|
||||||
"MixinSlot"
|
"MixinSlot"
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue