Moved to Fabric API events

As well as fixed some bugs and did some changes to /auth
This commit is contained in:
samo_lego 2019-11-17 20:07:54 +01:00
parent c51fdc7c0a
commit 8054a8fa6d
13 changed files with 126 additions and 187 deletions

View File

@ -1,8 +1,9 @@
package org.samo_lego.simpleauth; package org.samo_lego.simpleauth;
import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback; import net.fabricmc.fabric.api.event.player.*;
import net.fabricmc.fabric.api.registry.CommandRegistry; import net.fabricmc.fabric.api.registry.CommandRegistry;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -12,12 +13,9 @@ import org.samo_lego.simpleauth.commands.LoginCommand;
import org.samo_lego.simpleauth.commands.RegisterCommand; import org.samo_lego.simpleauth.commands.RegisterCommand;
import org.samo_lego.simpleauth.database.SimpleAuthDatabase; import org.samo_lego.simpleauth.database.SimpleAuthDatabase;
import org.samo_lego.simpleauth.event.AuthEventHandler; import org.samo_lego.simpleauth.event.AuthEventHandler;
import org.samo_lego.simpleauth.event.block.BreakBlockCallback;
import org.samo_lego.simpleauth.event.block.InteractBlockCallback;
import org.samo_lego.simpleauth.event.item.DropItemCallback;
import org.samo_lego.simpleauth.event.item.InteractItemCallback;
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.item.DropItemCallback;
import java.io.File; import java.io.File;
import java.util.HashSet; import java.util.HashSet;
@ -48,18 +46,20 @@ public class SimpleAuth implements DedicatedServerModInitializer {
}); });
// Registering the events // Registering the events
InteractBlockCallback.EVENT.register(AuthEventHandler::onInteractBlock);
BreakBlockCallback.EVENT.register((world, pos, state, player) -> AuthEventHandler.onBlockBroken(player));
InteractItemCallback.EVENT.register(AuthEventHandler::onInteractItem);
DropItemCallback.EVENT.register(AuthEventHandler::onDropItem);
PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin); PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin);
PlayerLeaveServerCallback.EVENT.register(AuthEventHandler::onPlayerLeave); PlayerLeaveServerCallback.EVENT.register(AuthEventHandler::onPlayerLeave);
DropItemCallback.EVENT.register(player -> AuthEventHandler.onDropItem(player));
// From Fabric API // From Fabric API
AttackBlockCallback.EVENT.register((playerEntity, world, hand, blockPos, direction) -> AuthEventHandler.onAttackBlock(playerEntity)); AttackBlockCallback.EVENT.register((playerEntity, world, hand, blockPos, direction) -> AuthEventHandler.onAttackBlock(playerEntity));
UseBlockCallback.EVENT.register((player, world, hand, blockHitResult) -> AuthEventHandler.onUseBlock(player));
UseItemCallback.EVENT.register((player, world, hand) -> AuthEventHandler.onUseItem(player));
AttackEntityCallback.EVENT.register((player, world, hand, entity, entityHitResult) -> AuthEventHandler.onAttackEntity(player));
UseEntityCallback.EVENT.register((player, world, hand, entity, entityHitResult) -> AuthEventHandler.onUseEntity(player));
// Making a table in database
db.makeTable(); db.makeTable();
} }
public static HashSet<ServerPlayerEntity> authenticatedUsers = new HashSet<>(); public static HashSet<PlayerEntity> authenticatedUsers = new HashSet<>();
public static boolean isAuthenticated(ServerPlayerEntity player) { return authenticatedUsers.contains(player); } public static boolean isAuthenticated(ServerPlayerEntity player) { return authenticatedUsers.contains(player); }

View File

@ -5,6 +5,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import de.mkammerer.argon2.Argon2; import de.mkammerer.argon2.Argon2;
import de.mkammerer.argon2.Argon2Factory; import de.mkammerer.argon2.Argon2Factory;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
@ -17,6 +18,8 @@ import org.samo_lego.simpleauth.SimpleAuth;
import static com.mojang.brigadier.arguments.StringArgumentType.*; import static com.mojang.brigadier.arguments.StringArgumentType.*;
import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal; import static net.minecraft.server.command.CommandManager.literal;
import static org.samo_lego.simpleauth.SimpleAuth.authenticatedUsers;
import static org.samo_lego.simpleauth.SimpleAuth.isAuthenticated;
public class AuthCommand { public class AuthCommand {
private static final Logger LOGGER = LogManager.getLogger(); private static final Logger LOGGER = LogManager.getLogger();
@ -29,43 +32,68 @@ public class AuthCommand {
dispatcher.register(literal("auth") dispatcher.register(literal("auth")
.requires(source -> source.hasPermissionLevel(4)) .requires(source -> source.hasPermissionLevel(4))
.then(literal("update") .then(literal("update")
.then(literal("byUuid")
.then(argument("uuid", word()) .then(argument("uuid", word())
.then(argument("password", word()) .then(argument("password", word())
.executes( ctx -> updatePass( .executes( ctx -> updatePass(
ctx.getSource(), ctx.getSource(),
getString(ctx, "uuid"), getString(ctx, "uuid"),
null,
getString(ctx, "password") getString(ctx, "password")
)) ))
) )
) )
) )
.then(literal("byUsername")
.then(argument("username", word())
.then(argument("password", word())
.executes( ctx -> updatePass(
ctx.getSource(),
null,
getString(ctx, "username"),
getString(ctx, "password")
))
)
)
)
)
.then(literal("remove") .then(literal("remove")
.then(literal("byUuid")
.then(argument("uuid", word()) .then(argument("uuid", word())
.executes( ctx -> removeAccount( .executes( ctx -> removeAccount(
ctx.getSource(), ctx.getSource(),
getString(ctx, "uuid") getString(ctx, "uuid"),
null
)) ))
) )
) )
.then(literal("byUsername")
.then(argument("username", word())
.executes( ctx -> removeAccount(
ctx.getSource(),
null,
getString(ctx, "username")
))
)
)
)
); );
} }
// Method called for checking the password // Method called for checking the password
private static int updatePass(ServerCommandSource source, String uuid, String pass) { private static int updatePass(ServerCommandSource source, String uuid, String username, String pass) {
// Getting the player who send the command // Getting the player who send the command
Entity sender = source.getEntity(); Entity sender = source.getEntity();
if(uuid == null)
return -1;
// Create instance // Create instance
Argon2 argon2 = Argon2Factory.create(); Argon2 argon2 = Argon2Factory.create();
char[] password = pass.toCharArray(); char[] password = pass.toCharArray();
try { try {
// Hashed password from DB // Hashed password from DB
String hashed = SimpleAuth.db.getPassword(uuid); String hash = argon2.hash(10, 65536, 1, pass.toCharArray());
// Writing into DB // Writing into DB
SimpleAuth.db.update(uuid, hashed); SimpleAuth.db.update(uuid, username, hash);
if(sender != null) if(sender != null)
sender.sendMessage(userdataUpdated); sender.sendMessage(userdataUpdated);
else else
@ -74,13 +102,15 @@ public class AuthCommand {
// Wipe confidential data // Wipe confidential data
argon2.wipeArray(password); argon2.wipeArray(password);
} }
// TODO -> Kick player whose name was changed?
return 1; // Success return 1; // Success
} }
private static int removeAccount(ServerCommandSource source, String uuid) { private static int removeAccount(ServerCommandSource source, String uuid, String username) {
// Getting the player who send the command
Entity sender = source.getEntity(); Entity sender = source.getEntity();
SimpleAuth.db.delete(uuid); SimpleAuth.db.delete(uuid, username);
// TODO -> Kick player that was unregistered?
if(sender != null) if(sender != null)
sender.sendMessage(userdataDeleted); sender.sendMessage(userdataDeleted);
else else

View File

@ -62,7 +62,7 @@ public class ChangepwCommand {
if (argon2.verify(hashedOld, password)) { if (argon2.verify(hashedOld, password)) {
String hash = argon2.hash(10, 65536, 1, newPass.toCharArray()); String hash = argon2.hash(10, 65536, 1, newPass.toCharArray());
// Writing into DB // Writing into DB
SimpleAuth.db.update(player.getUuidAsString(), hash); SimpleAuth.db.update(player.getUuidAsString(), null, hash);
player.sendMessage(passwordUpdated); player.sendMessage(passwordUpdated);
} }
else else

View File

@ -4,6 +4,7 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import de.mkammerer.argon2.Argon2; import de.mkammerer.argon2.Argon2;
import de.mkammerer.argon2.Argon2Factory; import de.mkammerer.argon2.Argon2Factory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;

View File

@ -48,19 +48,22 @@ public class SimpleAuthDatabase {
// When player registers, we insert the data into DB // When player registers, we insert the data into DB
public boolean registerUser(String uuid, String username, String password) { public boolean registerUser(String uuid, String username, String password) {
String sql = "INSERT INTO users(uuid, username, password) VALUES(?,?,?)"; String sql = "INSERT INTO users(uuid, username, password) VALUES(?,?,?)";
String sqlCheck = "SELECT UUID, Password " String sqlCheck = "SELECT UUID "
+ "FROM users WHERE UUID = ?"; + "FROM users WHERE UUID = ?";
try ( try (
Connection conn = this.connect(); Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql); PreparedStatement pstmt = conn.prepareStatement(sql);
PreparedStatement pstmtCheck = conn.prepareStatement(sql)) { PreparedStatement pstmtCheck = conn.prepareStatement(sqlCheck)) {
pstmtCheck.setString(1,uuid); pstmtCheck.setString(1, uuid);
ResultSet rs = pstmtCheck.executeQuery(); ResultSet rs = pstmtCheck.executeQuery();
// Getting the password // Getting the password
String dbUuid = rs.getString("UUID"); //String dbUuid = null;
if(dbUuid != null) { try {
rs.getString("UUID");
return false;
} catch(SQLException ignored) {
pstmt.setString(1, uuid); pstmt.setString(1, uuid);
pstmt.setString(2, username); pstmt.setString(2, username);
pstmt.setString(3, password); pstmt.setString(3, password);
@ -69,20 +72,21 @@ public class SimpleAuthDatabase {
return true; return true;
} }
} catch (SQLException e) { } catch (SQLException e) {
LOGGER.error(e.getMessage()); LOGGER.error("Register error: " + e.getMessage());
}
return false; return false;
} }
}
// Deletes row containing the username provided // Deletes row containing the username provided
public void delete(String uuid) { public void delete(String uuid, String username) {
String sql = "DELETE FROM users WHERE uuid = ?"; String sql = "DELETE FROM users WHERE uuid = ? OR username = ?";
try (Connection conn = this.connect(); try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) { PreparedStatement pstmt = conn.prepareStatement(sql)) {
// set the corresponding param // set the corresponding param
pstmt.setString(1, uuid); pstmt.setString(1, uuid);
pstmt.setString(2, username);
// execute the delete statement // execute the delete statement
pstmt.executeUpdate(); pstmt.executeUpdate();
@ -92,9 +96,9 @@ public class SimpleAuthDatabase {
} }
// Updates the password of the user // Updates the password of the user
public void update(String uuid, String pass) { public void update(String uuid, String username, String pass) {
String sql = "UPDATE users SET password = ? " String sql = "UPDATE users SET password = ? "
+ "WHERE uuid = ?"; + "WHERE uuid = ? OR username = ?";
try (Connection conn = this.connect(); try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) { PreparedStatement pstmt = conn.prepareStatement(sql)) {
@ -102,6 +106,7 @@ public class SimpleAuthDatabase {
// set the corresponding param // set the corresponding param
pstmt.setString(1, pass); pstmt.setString(1, pass);
pstmt.setString(2, uuid); pstmt.setString(2, uuid);
pstmt.setString(3, username);
// update // update
pstmt.executeUpdate(); pstmt.executeUpdate();

View File

@ -1,9 +1,7 @@
package org.samo_lego.simpleauth.event; package org.samo_lego.simpleauth.event;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.SimpleAuth;
@ -36,8 +34,8 @@ public class AuthEventHandler {
return false; return false;
} }
// Interacting with block // Using a block (right-click function)
public static ActionResult onInteractBlock(ServerPlayerEntity player) { public static ActionResult onUseBlock(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(player)) { if(!SimpleAuth.authenticatedUsers.contains(player)) {
player.sendMessage(notAuthenticated); player.sendMessage(notAuthenticated);
return ActionResult.FAIL; return ActionResult.FAIL;
@ -46,16 +44,34 @@ public class AuthEventHandler {
} }
// Punching a block // Punching a block
public static ActionResult onAttackBlock(PlayerEntity playerEntity) { public static ActionResult onAttackBlock(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(playerEntity)) { if(!SimpleAuth.authenticatedUsers.contains(player)) {
playerEntity.sendMessage(notAuthenticated); player.sendMessage(notAuthenticated);
return ActionResult.FAIL; return ActionResult.FAIL;
} }
return ActionResult.PASS; return ActionResult.PASS;
} }
// Interacting with item // Using an item
public static ActionResult onInteractItem(ServerPlayerEntity player) { public static ActionResult onUseItem(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(player)) {
player.sendMessage(notAuthenticated);
return ActionResult.FAIL;
}
return ActionResult.PASS;
}
// Attacking an entity
public static ActionResult onAttackEntity(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(player)) {
player.sendMessage(notAuthenticated);
return ActionResult.FAIL;
}
return ActionResult.PASS;
}
// Interacting with entity
public static ActionResult onUseEntity(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(player)) { if(!SimpleAuth.authenticatedUsers.contains(player)) {
player.sendMessage(notAuthenticated); player.sendMessage(notAuthenticated);
return ActionResult.FAIL; return ActionResult.FAIL;
@ -64,11 +80,11 @@ public class AuthEventHandler {
return ActionResult.PASS; return ActionResult.PASS;
} }
// Dropping an item // Dropping an item
public static boolean onDropItem(ServerPlayerEntity player) { public static ActionResult onDropItem(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(player)) { if(!SimpleAuth.authenticatedUsers.contains(player)) {
player.sendMessage(notAuthenticated); player.sendMessage(notAuthenticated);
return true; return ActionResult.FAIL;
} }
return false; return ActionResult.PASS;
} }
} }

View File

@ -1,21 +0,0 @@
package org.samo_lego.simpleauth.event.block;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface BreakBlockCallback {
Event<BreakBlockCallback> EVENT = EventFactory.createArrayBacked(BreakBlockCallback.class, listeners -> (world, pos, state, player) -> {
for(BreakBlockCallback callback : listeners) {
if(callback.onBlockBroken(world, pos, state, player)) {
return true;
}
}
return false;
});
boolean onBlockBroken(World world, BlockPos pos, BlockState state, PlayerEntity player);
}

View File

@ -1,20 +0,0 @@
package org.samo_lego.simpleauth.event.block;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
public interface InteractBlockCallback {
Event<InteractBlockCallback> EVENT = EventFactory.createArrayBacked(InteractBlockCallback.class,
(listeners) -> (player) -> {
for (InteractBlockCallback event : listeners) {
ActionResult result = event.onInteractBlock(player);
if(result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult onInteractBlock(ServerPlayerEntity player);
}

View File

@ -2,17 +2,20 @@ package org.samo_lego.simpleauth.event.item;
import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
public interface DropItemCallback { public interface DropItemCallback {
Event<DropItemCallback> EVENT = EventFactory.createArrayBacked(DropItemCallback.class, listeners -> (playerEntity) -> { Event<DropItemCallback> EVENT = EventFactory.createArrayBacked(DropItemCallback.class, listeners -> (player) -> {
for(DropItemCallback callback : listeners) { for (DropItemCallback event : listeners) {
if(callback.onDropItem(playerEntity)) { ActionResult result = event.onDropItem(player);
return true;
if (result != ActionResult.PASS) {
return result;
} }
} }
return false; return ActionResult.PASS;
}); });
boolean onDropItem(ServerPlayerEntity playerEntity); ActionResult onDropItem(PlayerEntity player);
} }

View File

@ -1,20 +0,0 @@
package org.samo_lego.simpleauth.event.item;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
public interface InteractItemCallback {
Event<InteractItemCallback> EVENT = EventFactory.createArrayBacked(InteractItemCallback.class,
(listeners) -> (player) -> {
for (InteractItemCallback event : listeners) {
ActionResult result = event.onInteractItem(player);
if(result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult onInteractItem(ServerPlayerEntity player);
}

View File

@ -3,6 +3,7 @@ package org.samo_lego.simpleauth.mixin;
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.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import org.samo_lego.simpleauth.event.item.DropItemCallback; import org.samo_lego.simpleauth.event.item.DropItemCallback;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -12,13 +13,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerEntity.class) @Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity { public abstract class MixinPlayerEntity {
// Thanks to AbusedLib https://github.com/abused/AbusedLib // Thanks to PR https://github.com/FabricMC/fabric/pull/260 and AbusedLib
@Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At("HEAD")) /*@Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At("HEAD"))
private void dropItem(ItemStack stack, boolean boolean_1, boolean boolean_2, CallbackInfoReturnable<ItemStack> info) { private void dropItem(ItemStack stack, boolean boolean_1, boolean boolean_2, CallbackInfoReturnable<ItemStack> info) {
ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; ServerPlayerEntity player = (ServerPlayerEntity) (Object) this;
if(DropItemCallback.EVENT.invoker().onDropItem(player)) { ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player);
player.giveItemStack(stack);
info.setReturnValue(ItemStack.EMPTY); if (result == ActionResult.FAIL) {
} info.cancel();
} }
}*/
} }

View File

@ -1,57 +0,0 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.samo_lego.simpleauth.event.block.BreakBlockCallback;
import org.samo_lego.simpleauth.event.block.InteractBlockCallback;
import org.samo_lego.simpleauth.event.item.InteractItemCallback;
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.CallbackInfoReturnable;
@Mixin(ServerPlayerInteractionManager.class)
public abstract class MixinServerPlayerInteractionManager {
@Shadow public ServerWorld world;
@Shadow public ServerPlayerEntity player;
// We inject the following code to tryBreakBlock method, by TextileLib
@Inject(method = "tryBreakBlock", at = @At("HEAD"), cancellable = true)
private void tryBreakBlock(BlockPos pos, CallbackInfoReturnable<Boolean> info) {
// Triggering the event
if(BreakBlockCallback.EVENT.invoker().onBlockBroken(world, pos, world.getBlockState(pos), player)) {
info.setReturnValue(false);
}
}
// Interacting with blocks
@Inject(method="interactBlock", at = @At("HEAD"), cancellable = true)
private void interactBlock(PlayerEntity playerEntity_1, World world_1, ItemStack itemStack_1, Hand hand_1, BlockHitResult blockHitResult_1, CallbackInfoReturnable<ActionResult> info){
// Callback
ActionResult result = InteractBlockCallback.EVENT.invoker().onInteractBlock((ServerPlayerEntity) playerEntity_1);
if(result == ActionResult.FAIL) {
info.cancel();
}
}
// Interacting with items
@Inject(method="interactItem", at = @At("HEAD"), cancellable = true)
private void interactItem(PlayerEntity playerEntity_1, World world_1, ItemStack itemStack_1, Hand hand_1, CallbackInfoReturnable<ActionResult> info){
// Callback
ActionResult result = InteractItemCallback.EVENT.invoker().onInteractItem((ServerPlayerEntity) playerEntity_1);
if(result == ActionResult.FAIL) {
info.cancel();
}
}
}

View File

@ -5,7 +5,7 @@
"mixins": [ "mixins": [
], ],
"server": [ "server": [
"MixinServerPlayerInteractionManager",
"MixinPlayerManager", "MixinPlayerManager",
"MixinPlayerEntity" "MixinPlayerEntity"
], ],