Finally! Better inventory protection.
This commit is contained in:
parent
1f274c3034
commit
0112004457
|
@ -2,12 +2,12 @@
|
|||
org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric properties
|
||||
minecraft_version=20w11a
|
||||
yarn_mappings=20w11a+build.6
|
||||
loader_version=0.7.8+build.187
|
||||
minecraft_version=20w13a
|
||||
yarn_mappings=20w13a+build.5
|
||||
loader_version=0.7.8+build.189
|
||||
|
||||
#Fabric api
|
||||
fabric_version=0.5.3+build.308-1.16
|
||||
fabric_version=0.5.6+build.313-1.16
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.2.0
|
||||
|
|
|
@ -19,6 +19,7 @@ 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.PlayerMoveCallback;
|
||||
import org.samo_lego.simpleauth.event.item.DropItemCallback;
|
||||
import org.samo_lego.simpleauth.event.item.TakeItemCallback;
|
||||
import org.samo_lego.simpleauth.utils.AuthConfig;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -73,6 +74,7 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
|||
// Registering the events
|
||||
PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin);
|
||||
DropItemCallback.EVENT.register(AuthEventHandler::onDropItem);
|
||||
TakeItemCallback.EVENT.register(AuthEventHandler::onTakeItem);
|
||||
ChatCallback.EVENT.register(AuthEventHandler::onPlayerChat);
|
||||
PlayerMoveCallback.EVENT.register(AuthEventHandler::onPlayerMove);
|
||||
// From Fabric API
|
||||
|
|
|
@ -42,9 +42,10 @@ public class LoginCommand {
|
|||
player.sendMessage(alreadyAuthenticated);
|
||||
return 0;
|
||||
}
|
||||
else if(SimpleAuth.deauthenticatedUsers.get(player) >= maxLoginTries && maxLoginTries != -1)
|
||||
else if(SimpleAuth.deauthenticatedUsers.get(player) >= maxLoginTries && maxLoginTries != -1) {
|
||||
player.networkHandler.disconnect(loginTriesExceeded);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if(SimpleAuth.config.main.enableGlobalPassword) {
|
||||
if (AuthHelper.checkPass("globalPass", pass.toCharArray())) {
|
||||
SimpleAuth.authenticatePlayer(player, successfullyAuthenticated);
|
||||
|
@ -55,11 +56,19 @@ public class LoginCommand {
|
|||
SimpleAuth.authenticatePlayer(player, successfullyAuthenticated);
|
||||
return 1;
|
||||
}
|
||||
else if(maxLoginTries == 1)
|
||||
// Kicking the player out
|
||||
else if(maxLoginTries == 1) {
|
||||
player.networkHandler.disconnect(wrongPassword);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sending wrong pass message
|
||||
player.sendMessage(wrongPassword);
|
||||
SimpleAuth.deauthenticatedUsers.replace(player, SimpleAuth.deauthenticatedUsers.get(player) + 1);
|
||||
// ++ the login tries
|
||||
SimpleAuth.deauthenticatedUsers.replace(
|
||||
player,
|
||||
SimpleAuth.deauthenticatedUsers.getOrDefault(player, 0) + 1
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,7 @@ public class AuthEventHandler {
|
|||
public static void onPlayerJoin(ServerPlayerEntity player) {
|
||||
// Marking player as not authenticated, (re)setting login tries to zero
|
||||
SimpleAuth.deauthenticatedUsers.put(player, 0);
|
||||
/*CompoundTag loginTries = new CompoundTag();
|
||||
loginTries.putInt("loginTries", 0);
|
||||
player.saveToTag(loginTries);
|
||||
player.writeCustomDataToTag(loginTries);*/
|
||||
|
||||
// Player not authenticated
|
||||
// If clause actually not needed, since we add player to deauthenticated hashset above
|
||||
if (!SimpleAuth.isAuthenticated(player)) {
|
||||
|
@ -68,6 +65,7 @@ public class AuthEventHandler {
|
|||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
// Player movement
|
||||
public static ActionResult onPlayerMove(PlayerEntity player) {
|
||||
if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player) && !SimpleAuth.config.main.allowMovement) {
|
||||
|
@ -111,6 +109,15 @@ public class AuthEventHandler {
|
|||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
// Changing inventory (item moving etc.)
|
||||
public static ActionResult onTakeItem(PlayerEntity player) {
|
||||
if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player) && !SimpleAuth.config.main.allowItemMoving) {
|
||||
player.sendMessage(notAuthenticated());
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
// Attacking an entity
|
||||
public static ActionResult onAttackEntity(PlayerEntity player) {
|
||||
if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player) && !SimpleAuth.config.main.allowEntityPunch) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package org.samo_lego.simpleauth.event.item;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
|
||||
public interface TakeItemCallback {
|
||||
Event<TakeItemCallback> EVENT = EventFactory.createArrayBacked(TakeItemCallback.class, listeners -> (player) -> {
|
||||
for (TakeItemCallback event : listeners) {
|
||||
ActionResult result = event.onTakeItem(player);
|
||||
if (result != ActionResult.PASS) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
});
|
||||
|
||||
ActionResult onTakeItem(PlayerEntity player);
|
||||
}
|
|
@ -1,61 +1,20 @@
|
|||
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("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);
|
||||
|
||||
|
@ -71,18 +30,4 @@ public abstract class MixinPlayerEntity {
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ 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;
|
||||
|
@ -34,5 +33,23 @@ public abstract class MixinServerPlayNetworkHandler {
|
|||
ci.cancel();
|
||||
}
|
||||
}
|
||||
// onClickWindow, onPickFromInventory todo*/
|
||||
// onClickWindow, onPickFromInventory todo
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.samo_lego.simpleauth.mixin;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import org.samo_lego.simpleauth.event.item.TakeItemCallback;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Slot.class)
|
||||
public abstract class MixinSlot {
|
||||
// Denying item moving etc.
|
||||
@Inject(method = "canTakeItems(Lnet/minecraft/entity/player/PlayerEntity;)Z", at = @At(value = "HEAD"), cancellable = true)
|
||||
private void canTakeItems(PlayerEntity playerEntity, CallbackInfoReturnable<Boolean> cir) {
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) playerEntity;
|
||||
ActionResult result = TakeItemCallback.EVENT.invoker().onTakeItem(player);
|
||||
|
||||
if (result == ActionResult.FAIL) {
|
||||
// Canceling the item taking
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,6 +40,8 @@ public class AuthConfig {
|
|||
public boolean allowBlockPunch = false;
|
||||
// Allows dropping items from inventory
|
||||
public boolean allowItemDrop = false;
|
||||
// Allows moving item through inventory
|
||||
public boolean allowItemMoving = false;
|
||||
// Allows item "use" - right click function (e.g. using a bow)
|
||||
public boolean allowItemUse = false;
|
||||
// Allows attacking mobs
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
"MixinServerPlayNetworkHandler",
|
||||
"MixinPlayerManager",
|
||||
"MixinPlayerEntity",
|
||||
"MixinServerPlayerEntity",
|
||||
"MixinPlayerInventory"
|
||||
"MixinSlot"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
Loading…
Reference in New Issue