parent
a9015b521e
commit
b98f627875
12
build.gradle
12
build.gradle
|
@ -21,7 +21,19 @@ dependencies {
|
|||
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modCompile "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
// jBCrypt library for password hashing
|
||||
implementation "org.mindrot:jbcrypt:0.4"
|
||||
implementation 'org.jetbrains:annotations:15.0'
|
||||
|
||||
// TextileLib by NerdHubMC for events
|
||||
/*repositories {
|
||||
maven {
|
||||
name = "NerdHub Maven"
|
||||
url = "https://maven.abusedmaster.xyz"
|
||||
}
|
||||
}
|
||||
modCompile "com.github.NerdHubMC:TextileLib:${textilelib_version}"*/
|
||||
|
||||
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
||||
// You may need to force-disable transitiveness on them.
|
||||
|
|
|
@ -15,4 +15,5 @@ org.gradle.jvmargs=-Xmx1G
|
|||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.3.2+build.218-1.14
|
||||
# textilelib
|
||||
textilelib_version=1.0.0-SNAPSHOT
|
||||
|
|
|
@ -2,10 +2,18 @@ package org.samo_lego.simpleauth;
|
|||
|
||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||
import net.fabricmc.fabric.api.registry.CommandRegistry;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.samo_lego.simpleauth.commands.LoginCommand;
|
||||
import org.samo_lego.simpleauth.commands.RegisterCommand;
|
||||
import org.samo_lego.simpleauth.event.AuthEventHandler;
|
||||
import org.samo_lego.simpleauth.event.entity.player.BreakBlockCallback;
|
||||
import org.samo_lego.simpleauth.event.entity.player.InteractBlockCallback;
|
||||
import org.samo_lego.simpleauth.event.entity.player.InteractItemCallback;
|
||||
import org.samo_lego.simpleauth.event.entity.player.PlayerJoinWorldCallback;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class SimpleAuth implements DedicatedServerModInitializer {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
@ -14,11 +22,22 @@ public class SimpleAuth implements DedicatedServerModInitializer {
|
|||
public void onInitializeServer() {
|
||||
// Info I guess :D
|
||||
LOGGER.info("SimpleAuth mod by samo_lego.");
|
||||
LOGGER.info("This mod wouldn't exist without the awesome Fabric Community. TYSM guys!");
|
||||
|
||||
// Registering the commands
|
||||
CommandRegistry.INSTANCE.register(false, dispatcher -> {
|
||||
RegisterCommand.register(dispatcher);
|
||||
LoginCommand.register(dispatcher);
|
||||
});
|
||||
|
||||
// Registering the events
|
||||
InteractBlockCallback.EVENT.register(AuthEventHandler::onInteractBlock);
|
||||
InteractItemCallback.EVENT.register(AuthEventHandler::onInteractItem);
|
||||
PlayerJoinWorldCallback.EVENT.register((world, player) -> AuthEventHandler.onPlayerJoin(player));
|
||||
BreakBlockCallback.EVENT.register((world, pos, state, player) -> AuthEventHandler.onBlockBroken(player));
|
||||
}
|
||||
public static HashSet<ServerPlayerEntity> authenticatedUsers = new HashSet<>();
|
||||
|
||||
public static boolean isAuthenticated(ServerPlayerEntity player) { return authenticatedUsers.contains(player); }
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package org.samo_lego.simpleauth.commands;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import org.mindrot.jbcrypt.BCrypt;
|
||||
import org.samo_lego.simpleauth.SimpleAuth;
|
||||
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.word;
|
||||
|
@ -24,13 +27,18 @@ public class LoginCommand {
|
|||
}));
|
||||
}
|
||||
// Method called for checking the password
|
||||
private static int login(ServerCommandSource source, String pass) {
|
||||
private static int login(ServerCommandSource source, String pass) throws CommandSyntaxException {
|
||||
String savedHashed = "judf"; // Hashed password provided upon registration
|
||||
|
||||
// Getting the player who send the command
|
||||
ServerPlayerEntity player = source.getPlayer();
|
||||
|
||||
// Comparing hashed password with one from the file
|
||||
if(BCrypt.checkpw(pass, savedHashed)){ //From database
|
||||
if(true/*BCrypt.checkpw(pass, savedHashed)*/){ //From database
|
||||
Text text = new LiteralText(source.getName() + ", you have entered login command");
|
||||
source.getMinecraftServer().getPlayerManager().broadcastChatMessage(text, false);
|
||||
SimpleAuth.authenticatedUsers.add(player);
|
||||
System.out.println(SimpleAuth.authenticatedUsers);
|
||||
}
|
||||
return 1; // Success
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package org.samo_lego.simpleauth.event;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import org.samo_lego.simpleauth.SimpleAuth;
|
||||
|
||||
public class AuthEventHandler {
|
||||
public static void onPlayerJoin(ServerPlayerEntity player) {
|
||||
// Player not authenticated
|
||||
if (!SimpleAuth.isAuthenticated(player))
|
||||
System.out.println("Not authenticated!");
|
||||
}
|
||||
|
||||
// Breaking block
|
||||
public static boolean onBlockBroken(PlayerEntity player) {
|
||||
// Player not authenticated
|
||||
if (!SimpleAuth.isAuthenticated((ServerPlayerEntity) player))
|
||||
{
|
||||
System.out.println("Not authenticated!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Interacting with block
|
||||
public static ActionResult onInteractBlock(ServerPlayerEntity player) {
|
||||
if(!SimpleAuth.authenticatedUsers.contains(player))
|
||||
return ActionResult.FAIL;
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
// Interacting with item
|
||||
public static ActionResult onInteractItem(ServerPlayerEntity player) {
|
||||
System.out.println("Called");
|
||||
if(!SimpleAuth.authenticatedUsers.contains(player))
|
||||
return ActionResult.FAIL;
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
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.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BlockDropsCallback {
|
||||
|
||||
Event<BlockDropsCallback> EVENT = EventFactory.createArrayBacked(BlockDropsCallback.class, listeners -> (world, pos, state, drops, harvester, tool) -> {
|
||||
for(BlockDropsCallback callback : listeners) {
|
||||
if(callback.onDrop(world, pos, state, drops, harvester, tool)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* fired when a block is about to drop it's items
|
||||
*
|
||||
* @return {@code true} to cancel all drops
|
||||
*/
|
||||
boolean onDrop(World world, BlockPos pos, BlockState state, List<ItemStack> drops, @Nullable PlayerEntity harvester, ItemStack tool);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.samo_lego.simpleauth.event.entity;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public interface EntitySpawnCallback {
|
||||
|
||||
Event<EntitySpawnCallback> EVENT = EventFactory.createArrayBacked(EntitySpawnCallback.class, listeners -> entity -> {
|
||||
for(EntitySpawnCallback callback : listeners) {
|
||||
if(callback.spawnEntity(entity)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* fired when an entity is spawned
|
||||
*
|
||||
* @return {@code true} to stop the entity from spawning
|
||||
*/
|
||||
boolean spawnEntity(Entity entity);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.samo_lego.simpleauth.event.entity.player;
|
||||
|
||||
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;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
/**
|
||||
* fired when a block is broken by a player
|
||||
*
|
||||
* @return {@code true} to cancel the event
|
||||
*/
|
||||
boolean onBlockBroken(World world, BlockPos pos, BlockState state, @Nullable PlayerEntity player);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.samo_lego.simpleauth.event.entity.player;
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.samo_lego.simpleauth.event.entity.player;
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.samo_lego.simpleauth.event.entity.player;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
public interface PlayerJoinWorldCallback {
|
||||
|
||||
Event<PlayerJoinWorldCallback> EVENT = EventFactory.createArrayBacked(PlayerJoinWorldCallback.class, listeners -> (world, player) -> {
|
||||
for (PlayerJoinWorldCallback callback : listeners) {
|
||||
callback.onPlayerJoin(world, player);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Fired when a player joins a world
|
||||
*/
|
||||
void onPlayerJoin(ServerWorld world, ServerPlayerEntity player);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.samo_lego.simpleauth.mixin;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.samo_lego.simpleauth.event.block.BlockDropsCallback;
|
||||
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;
|
||||
|
||||
|
||||
//FIXME this needs a better implementation to catch all of a block's drops, not just those from getDroppedStacks
|
||||
@Mixin(Block.class)
|
||||
public abstract class MixinBlockOld {
|
||||
|
||||
@Inject(method = "afterBreak", at = @At("HEAD"), cancellable = true)
|
||||
private void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack, CallbackInfo ci) {
|
||||
if(!world.isClient && BlockDropsCallback.EVENT.invoker().onDrop(world, pos, state, Block.getDroppedStacks(state, (ServerWorld) world, pos, blockEntity), player, stack)) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package org.samo_lego.simpleauth.mixin;
|
||||
|
||||
import net.minecraft.client.network.packet.BlockUpdateS2CPacket;
|
||||
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.SimpleAuth;
|
||||
import org.samo_lego.simpleauth.event.entity.player.BreakBlockCallback;
|
||||
import org.samo_lego.simpleauth.event.entity.player.InteractBlockCallback;
|
||||
import org.samo_lego.simpleauth.event.entity.player.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)) {
|
||||
/*// Update client as they will believe they have broken the block.
|
||||
if(this.player != null) {
|
||||
this.player.networkHandler.sendPacket(new BlockUpdateS2CPacket(world, pos));
|
||||
}*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.samo_lego.simpleauth.mixin;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import org.samo_lego.simpleauth.event.entity.EntitySpawnCallback;
|
||||
import org.samo_lego.simpleauth.event.entity.player.PlayerJoinWorldCallback;
|
||||
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;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ServerWorld.class)
|
||||
public abstract class MixinServerWorld {
|
||||
|
||||
@Inject(method = "addPlayer", at = @At("RETURN"))
|
||||
private void method_18771(ServerPlayerEntity serverPlayerEntity, CallbackInfo ci) {
|
||||
PlayerJoinWorldCallback.EVENT.invoker().onPlayerJoin(serverPlayerEntity.getServerWorld(), serverPlayerEntity);
|
||||
}
|
||||
|
||||
@Inject(method = "spawnEntity", at = @At("HEAD"), cancellable = true)
|
||||
private void spawnEntity(Entity entity, CallbackInfoReturnable<Boolean> cir) {
|
||||
int chunkX = MathHelper.floor(entity.x / 16.0D);
|
||||
int chunkZ = MathHelper.floor(entity.z / 16.0D);
|
||||
if(entity.teleporting || entity instanceof PlayerEntity || ((World) (Object) this).isChunkLoaded(chunkX, chunkZ)) {
|
||||
if(EntitySpawnCallback.EVENT.invoker().spawnEntity(entity)) {
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package org.samo_lego.simpleauth.mixin;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
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(MinecraftServer.class)
|
||||
public class SimpleAuthMixin {
|
||||
@Inject(at = @At("HEAD"), method = "start()V")
|
||||
private void init(CallbackInfo info) {
|
||||
System.out.println("This line is printed by an example mod mixin!");
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@
|
|||
"mixins": [
|
||||
],
|
||||
"server": [
|
||||
"SimpleAuthMixin"
|
||||
"MixinServerPlayerInteractionManager",
|
||||
"MixinServerWorld"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
Loading…
Reference in New Issue