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.registry.CommandRegistry;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
@ -12,10 +13,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import org.samo_lego.simpleauth.commands.*;
|
||||
import org.samo_lego.simpleauth.event.AuthEventHandler;
|
||||
import org.samo_lego.simpleauth.event.entity.player.ChatCallback;
|
||||
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.entity.player.*;
|
||||
import org.samo_lego.simpleauth.event.item.DropItemCallback;
|
||||
import org.samo_lego.simpleauth.event.item.TakeItemCallback;
|
||||
import org.samo_lego.simpleauth.storage.AuthConfig;
|
||||
|
@ -75,6 +73,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
|||
});
|
||||
|
||||
// Registering the events
|
||||
PrePlayerJoinCallback.EVENT.register(AuthEventHandler::checkCanPlayerJoinServer);
|
||||
PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin);
|
||||
PlayerLeaveServerCallback.EVENT.register(AuthEventHandler::onPlayerLeave);
|
||||
DropItemCallback.EVENT.register(AuthEventHandler::onDropItem);
|
||||
|
@ -115,6 +114,8 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
|||
|
||||
// De-authenticates player
|
||||
public static void deauthenticatePlayer(ServerPlayerEntity player) {
|
||||
if(db.isClosed())
|
||||
return;
|
||||
// Marking player as not authenticated, (re)setting login tries to zero
|
||||
String uuid = player.getUuidAsString();
|
||||
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"));
|
||||
|
||||
if(sender != null)
|
||||
sender.sendSystemMessage(globalPasswordSet);
|
||||
((PlayerEntity) sender).sendMessage(globalPasswordSet, false);
|
||||
else
|
||||
LOGGER.info(SimpleAuth.config.lang.globalPasswordSet);
|
||||
return 1;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package org.samo_lego.simpleauth.event;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
@ -14,6 +16,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.World;
|
||||
import org.samo_lego.simpleauth.storage.PlayerCache;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -35,18 +38,40 @@ public class AuthEventHandler {
|
|||
|
||||
private static Text successfulPortalRescue = new LiteralText(config.lang.successfulPortalRescue);
|
||||
|
||||
// Player joining the server
|
||||
public static void onPlayerJoin(ServerPlayerEntity player) {
|
||||
// Player pre-join
|
||||
// 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
|
||||
String regex = config.main.usernameRegex;
|
||||
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(player.getName().getString());
|
||||
if (!matcher.matches()) {
|
||||
player.networkHandler.disconnect(new LiteralText(String.format(config.lang.disallowedUsername, regex)));
|
||||
return;
|
||||
}
|
||||
Matcher matcher = pattern.matcher(incomingPlayerUsername);
|
||||
|
||||
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
|
||||
String uuid = player.getUuidAsString();
|
||||
PlayerCache playerCache = deauthenticatedUsers.getOrDefault(uuid, null);
|
||||
|
@ -143,8 +168,8 @@ public class AuthEventHandler {
|
|||
// Setting that player was actually authenticated before leaving
|
||||
PlayerCache playerCache = deauthenticatedUsers.get(player.getUuidAsString());
|
||||
playerCache.wasAuthenticated = true;
|
||||
// Setting the session expire time
|
||||
playerCache.validUntil = System.currentTimeMillis() + config.main.sessionTimeoutTime * 1000;
|
||||
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
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.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.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 java.net.SocketAddress;
|
||||
|
||||
@Mixin(PlayerManager.class)
|
||||
public abstract class MixinPlayerManager {
|
||||
|
@ -22,4 +32,18 @@ public abstract class MixinPlayerManager {
|
|||
private void onPlayerLeave(ServerPlayerEntity serverPlayerEntity, CallbackInfo ci) {
|
||||
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
|
||||
public boolean registerUser(String uuid, String data) {
|
||||
try {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"server": [
|
||||
"MixinPlayerEntity",
|
||||
"MixinPlayerManager",
|
||||
"MixinServerLoginNetworkHandler",
|
||||
"MixinServerPlayNetworkHandler",
|
||||
"MixinSlot"
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue