Trying to get better inventory protection. Doesn't work atm.

This commit is contained in:
samo_lego 2020-03-17 22:59:01 +01:00
parent 52687dac54
commit 2c16cb8318
10 changed files with 199 additions and 39 deletions

View File

@ -17,7 +17,7 @@ dependencies {
//to change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"

View File

@ -2,12 +2,12 @@
org.gradle.jvmargs=-Xmx1G
# Fabric properties
minecraft_version=20w10a
yarn_mappings=20w10a+build.16
minecraft_version=20w11a
yarn_mappings=20w11a+build.6
loader_version=0.7.8+build.187
#Fabric api
fabric_version=0.5.1+build.305-1.16
fabric_version=0.5.3+build.308-1.16
# Mod Properties
mod_version = 1.2.0

View File

@ -4,7 +4,10 @@ import net.fabricmc.api.DedicatedServerModInitializer;
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.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import org.apache.logging.log4j.LogManager;
@ -19,16 +22,24 @@ import org.samo_lego.simpleauth.event.item.DropItemCallback;
import org.samo_lego.simpleauth.utils.AuthConfig;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
public class SimpleAuth implements DedicatedServerModInitializer {
private static final Logger LOGGER = LogManager.getLogger();
public static SimpleAuthDatabase db = new SimpleAuthDatabase();
// HashSet of players that are not authenticated
// Rather than storing all the authenticated players, we just store ones that are not authenticated
public static HashSet<PlayerEntity> deauthenticatedUsers = new HashSet<>();
public static HashMap<PlayerEntity, Integer> deauthenticatedUsers = new HashMap<>();
// Boolean for easier checking if player is authenticated
public static boolean isAuthenticated(ServerPlayerEntity player) { return !deauthenticatedUsers.contains(player); }
public static boolean isAuthenticated(ServerPlayerEntity player) {
return !deauthenticatedUsers.containsKey(player);
}
// Getting game directory
public static final File gameDirectory = FabricLoader.getInstance().getGameDirectory();
// Mod config
public static AuthConfig config;
@ -40,11 +51,11 @@ public class SimpleAuth implements DedicatedServerModInitializer {
LOGGER.info("[SimpleAuth] This mod wouldn't exist without the awesome Fabric Community. TYSM guys!");
// Creating data directory (database and config files are stored there)
File file = new File("./mods/SimpleAuth");
File file = new File(gameDirectory + "/mods/SimpleAuth");
if (!file.exists() && !file.mkdir())
LOGGER.error("[SimpleAuth] Error creating directory!");
// Loading config
config = AuthConfig.load(new File("./mods/SimpleAuth/config.json"));
config = AuthConfig.load(new File(gameDirectory + "/mods/SimpleAuth/config.json"));
// Connecting to db
db.openConnection();
// Making a table in the database
@ -77,7 +88,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
db.close();
}
public static void authenticatePlayer(ServerPlayerEntity player, Text msg) {
SimpleAuth.deauthenticatedUsers.remove(player);
deauthenticatedUsers.remove(player);
// Player no longer needs to be invisible and invulnerable
player.setInvulnerable(false);
player.setInvisible(false);

View File

@ -2,6 +2,7 @@ package org.samo_lego.simpleauth.database;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.samo_lego.simpleauth.SimpleAuth;
import java.sql.*;
@ -18,7 +19,7 @@ public class SimpleAuthDatabase {
public void openConnection() {
// SQLite connection string
String url = "jdbc:sqlite:mods/SimpleAuth/players.db";
String url = "jdbc:sqlite:" + SimpleAuth.gameDirectory + "/mods/SimpleAuth/players.db";
try {
conn = DriverManager.getConnection(url);
} catch (SQLException e) {

View File

@ -29,7 +29,7 @@ public class AuthEventHandler {
// Player joining the server
public static void onPlayerJoin(ServerPlayerEntity player) {
SimpleAuth.deauthenticatedUsers.add(player);
SimpleAuth.deauthenticatedUsers.put(player, 0);
/*CompoundTag loginTries = new CompoundTag();
loginTries.putInt("loginTries", 0);
player.saveToTag(loginTries);

View File

@ -1,30 +1,88 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerSpawnPositionS2CPacket;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback;
import org.samo_lego.simpleauth.event.item.DropItemCallback;
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;
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity {
// Thanks to PR https://github.com/FabricMC/fabric/pull/260 and AbusedLib https://github.com/abused/AbusedLib
@Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At("INVOKE"), cancellable = true)
private void dropItem(ItemStack stack, boolean dropAtFeet, boolean saveThrower, CallbackInfoReturnable<ItemEntity> cir) {
@Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At("HEAD"), cancellable = true)
private void dropItem(ItemStack stack, boolean throwRandomly, boolean retainOwnership, CallbackInfoReturnable<ItemEntity> cir) {
// Defining player
ServerPlayerEntity player = (ServerPlayerEntity) (Object) this;
// Getting action result from auth event handler
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.inventory.insertStack(stack);
player.networkHandler.sendPacket(
new ScreenHandlerSlotUpdateS2CPacket(
-2,
player.inventory.selectedSlot,
player.inventory.getInvStack(player.inventory.selectedSlot))
);
// Packet for mouse-dropping inventory update
player.currentScreenHandler.sendContentUpdates();
//player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-1, -1, player.inventory.getCursorStack()));
cir.cancel();
}
}
// Player item dropping
@Inject(method = "dropSelectedItem(Z)Z", at = @At("HEAD"), cancellable = true)
private void dropSelectedItem(boolean dropEntireStack, CallbackInfoReturnable<Boolean> cir) {
//Testing purposes - todo - doesn't delete armor, but allows mouse dropping
ServerPlayerEntity player = (ServerPlayerEntity) (Object) this;
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.giveItemStack(stack);
player.inventory.updateItems();
cir.cancel();
player.networkHandler.sendPacket(
new ScreenHandlerSlotUpdateS2CPacket(
-2,
player.inventory.selectedSlot,
player.inventory.getInvStack(player.inventory.selectedSlot))
);
player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-1, -1, player.inventory.getCursorStack()));
cir.setReturnValue(false);
}
}
// Player movement
@Inject(method = "travel(Lnet/minecraft/util/math/Vec3d;)V", at = @At("HEAD"), cancellable = true)
private void travel(Vec3d movementInput, CallbackInfo ci) {
ServerPlayerEntity player = (ServerPlayerEntity) (Object) this;
ActionResult result = PlayerMoveCallback.EVENT.invoker().onPlayerMove(player);
if (result == ActionResult.FAIL) {
// A bit ugly, I know. (we need to update player position)
player.teleport(player.getX(), player.getY(), player.getZ());
ci.cancel();
}
}
}

View File

@ -0,0 +1,67 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import org.samo_lego.simpleauth.SimpleAuth;
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 org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.List;
@Mixin(PlayerInventory.class)
public abstract class MixinPlayerInventory {
@Final
@Shadow
public PlayerEntity player;
@Inject(method="setInvStack(ILnet/minecraft/item/ItemStack;)V", at = @At(value = "HEAD"), cancellable = true)
private void setInvStack(int slot, ItemStack stack, CallbackInfo ci) {
/*ServerPlayerEntity player = (ServerPlayerEntity) this.player;
ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player);
if (result == ActionResult.FAIL) {
player.inventory
player.networkHandler.sendPacket(
new ScreenHandlerSlotUpdateS2CPacket(
-2,
player.inventory.selectedSlot,
player.inventory.getInvStack(player.inventory.selectedSlot))
);
// Packet for mouse-dropping inventory update
player.currentScreenHandler.sendContentUpdates();
ci.cancel();
}*/
System.out.println("Setting inv stack: " + slot + "(slot) " + stack.getCount()+ "(amount)" + stack.getItem().getTranslationKey() + "(item)");
}
// Thank you Giselbaer for the help provided!
@Inject(method = "takeInvStack(II)Lnet/minecraft/item/ItemStack;", at = @At(value = "RETURN"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
private void takeInvStack(int slot, int amount, CallbackInfoReturnable<ItemStack> cir, List<ItemStack> list) {
if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player)) {
// Getting back the default item count
int initialCount = player.inventory.getInvStack(slot).getCount() + amount;
// Getting itemstack that would be returned
ItemStack stack = list != null && !list.get(slot).isEmpty() ? Inventories.splitStack(list, slot, amount) : ItemStack.EMPTY;
System.out.println("takeInvStack: " + slot + "(slot) " + amount + "(amount)" + stack.getItem().getTranslationKey() + "(item)");
// Setting stack value back to default (before it was taken or dropped)
stack.setCount(initialCount);
// Setting the stack back to inventory
player.inventory.setInvStack(slot, stack);
cir.setReturnValue(stack);
}
}
}

View File

@ -1,10 +1,10 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.network.packet.c2s.play.*;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import org.samo_lego.simpleauth.SimpleAuth;
import org.samo_lego.simpleauth.event.entity.player.ChatCallback;
import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback;
import org.spongepowered.asm.mixin.Mixin;
@ -28,30 +28,11 @@ public abstract class MixinServerPlayNetworkHandler {
),
cancellable = true
)
// todo: redirect packets to off-thread packet manager?
private void onChatMessage(ChatMessageC2SPacket chatMessageC2SPacket_1, CallbackInfo ci) {
ActionResult result = ChatCallback.EVENT.invoker().onPlayerChat(player, chatMessageC2SPacket_1);
if (result == ActionResult.FAIL) {
ci.cancel();
}
}
@Inject(
method="onPlayerMove(Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;)V",
at = @At(
value = "INVOKE",
// Thanks to Liach for helping me out!
target = "net/minecraft/network/NetworkThreadUtils.forceMainThread(Lnet/minecraft/network/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/server/world/ServerWorld;)V",
shift = At.Shift.AFTER
),
cancellable = true
)
private void onPlayerMove(PlayerMoveC2SPacket playerMoveC2SPacket_1, CallbackInfo ci) {
ActionResult result = PlayerMoveCallback.EVENT.invoker().onPlayerMove(player);
if (result == ActionResult.FAIL) {
// A bit ugly, I know. (we need to update player position)
player.teleport(player.getX(), player.getY(), player.getZ());
ci.cancel();
}
}
// onClickWindow, onPickFromInventory todo*/
}

View File

@ -0,0 +1,40 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import org.samo_lego.simpleauth.SimpleAuth;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayerEntity.class)
public abstract class MixinServerPlayerEntity {
@Inject(method = "onSlotUpdate(Lnet/minecraft/screen/ScreenHandler;ILnet/minecraft/item/ItemStack;)V", at = @At("HEAD"), cancellable = true)
private void onSlotUpdate(ScreenHandler handler, int slotId, ItemStack stack, CallbackInfo ci) {
ServerPlayerEntity player = (ServerPlayerEntity) (Object) this;
/*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.inventory.insertStack(stack);
player.networkHandler.sendPacket(
new ScreenHandlerSlotUpdateS2CPacket(
-2,
player.inventory.selectedSlot,
player.inventory.getInvStack(player.inventory.selectedSlot))
);
// Packet for mouse-dropping inventory update
player.currentScreenHandler.sendContentUpdates();
}*/
//player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-1, -1, player.inventory.getCursorStack()));
if(!SimpleAuth.isAuthenticated(player)) {
System.out.println("onSlotUpdate: " + stack.getItem().getTranslationKey());
//player.inventory.setInvStack(slotId, stack);
//ci.cancel();
}
}
}

View File

@ -7,7 +7,9 @@
"server": [
"MixinServerPlayNetworkHandler",
"MixinPlayerManager",
"MixinPlayerEntity"
"MixinPlayerEntity",
"MixinServerPlayerEntity",
"MixinPlayerInventory"
],
"injectors": {
"defaultRequire": 1