Merge pull request #1 from samolego/dev

All functionality + update to 1.15pre2
This commit is contained in:
samo_lego 2019-11-26 22:14:10 +01:00 committed by GitHub
commit 235d05b6df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 217 additions and 85 deletions

View File

@ -1,17 +1,15 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.14.4
yarn_mappings=1.14.4+build.12
loader_version=0.6.1+build.164
# Fabric properties
minecraft_version=1.15-pre2
yarn_mappings=1.15-pre2+build.3
loader_version=0.7.1+build.173
#Fabric api
fabric_version=0.4.16+build.268-1.15
# Mod Properties
mod_version = 1.0.0
maven_group = org.samo_lego
archives_base_name = simpleauth
# 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

View File

@ -2,6 +2,7 @@ package org.samo_lego.simpleauth;
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.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
@ -10,6 +11,8 @@ import org.apache.logging.log4j.Logger;
import org.samo_lego.simpleauth.commands.*;
import org.samo_lego.simpleauth.database.SimpleAuthDatabase;
import org.samo_lego.simpleauth.event.AuthEventHandler;
import org.samo_lego.simpleauth.event.entity.player.OnChatCallback;
import org.samo_lego.simpleauth.event.entity.player.OnPlayerMoveCallback;
import org.samo_lego.simpleauth.event.entity.player.PlayerJoinServerCallback;
import org.samo_lego.simpleauth.event.entity.player.PlayerLeaveServerCallback;
import org.samo_lego.simpleauth.event.item.DropItemCallback;
@ -20,18 +23,22 @@ import java.util.HashSet;
public class SimpleAuth implements DedicatedServerModInitializer {
private static final Logger LOGGER = LogManager.getLogger();
public static SimpleAuthDatabase db = new SimpleAuthDatabase();
public static HashSet<PlayerEntity> authenticatedUsers = new HashSet<>();
public static boolean isAuthenticated(ServerPlayerEntity player) { return authenticatedUsers.contains(player); }
@Override
@Override
public void onInitializeServer() {
// Info I guess :D
LOGGER.info("SimpleAuth mod by samo_lego.");
LOGGER.info("[SimpleAuth] SimpleAuth mod by samo_lego.");
// The support on discord was great! I really appreciate your help.
LOGGER.info("This mod wouldn't exist without the awesome Fabric Community. TYSM guys!");
LOGGER.info("[SimpleAuth] This mod wouldn't exist without the awesome Fabric Community. TYSM guys!");
// Connecting to db
db.openConnection();
// Creating data directory (database is stored there)
File file = new File("./mods/SimpleAuth");
if (!file.exists() && !file.mkdir())
LOGGER.error("Error creating directory");
LOGGER.error("[SimpleAuth] Error creating directory!");
// Registering the commands
@ -47,18 +54,22 @@ public class SimpleAuth implements DedicatedServerModInitializer {
PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin);
PlayerLeaveServerCallback.EVENT.register(AuthEventHandler::onPlayerLeave);
DropItemCallback.EVENT.register(AuthEventHandler::onDropItem);
//todo
OnChatCallback.EVENT.register(AuthEventHandler::onPlayerChat);
OnPlayerMoveCallback.EVENT.register(AuthEventHandler::onPlayerMove);
// From Fabric API
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
ServerStopCallback.EVENT.register(minecraftServer -> SimpleAuth.onStopServer());
// Making a table in the database
db.makeTable();
}
public static HashSet<PlayerEntity> authenticatedUsers = new HashSet<>();
public static boolean isAuthenticated(ServerPlayerEntity player) { return authenticatedUsers.contains(player); }
private static void onStopServer() {
LOGGER.info("[SimpleAuth] Shutting down SimpleAuth.");
db.close();
}
}

View File

@ -46,6 +46,10 @@ public class LoginCommand {
return 0;
}
else if (AuthHelper.checkPass(player.getUuidAsString(), pass.toCharArray())) {
SimpleAuth.authenticatedUsers.add(player);
// Player no longer needs to be invisible and invulnerable
player.setInvulnerable(false);
player.setInvisible(false);
player.sendMessage(text);
return 1;
}

View File

@ -50,6 +50,9 @@ public class RegisterCommand {
String hash = AuthHelper.hashPass(pass1.toCharArray());
if (SimpleAuth.db.registerUser(player.getUuidAsString(), source.getName(), hash)) {
SimpleAuth.authenticatedUsers.add(player);
// Player no longer needs to be invisible and invulnerable
player.setInvulnerable(false);
player.setInvisible(false);
player.sendMessage(registerSuccess);
return 1;
}

View File

@ -8,20 +8,21 @@ import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.TranslatableText;
import org.samo_lego.simpleauth.SimpleAuth;
import org.samo_lego.simpleauth.utils.AuthHelper;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.word;
import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;
public class UnregisterCommand { // TODO
public class UnregisterCommand {
private static TranslatableText enterPassword = new TranslatableText("command.simpleauth.password");
private static TranslatableText wrongPassword = new TranslatableText("command.simpleauth.wrongPassword");
private static TranslatableText accountDeleted = new TranslatableText("command.simpleauth.passwordUpdated");
private static TranslatableText accountDeleted = new TranslatableText("command.simpleauth.accountDeleted");
public static void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher) {
// Registering the "/changepw" command
dispatcher.register(literal("changepw")
// Registering the "/unregister" command
dispatcher.register(literal("unregister")
.executes(ctx -> {
ctx.getSource().getPlayer().sendMessage(enterPassword);
return 1;
@ -36,11 +37,16 @@ public class UnregisterCommand { // TODO
);
}
// Method called for checking the password and then changing it
// Method called for checking the password and then removing user's account from db
private static int unregister(ServerCommandSource source, String pass) throws CommandSyntaxException {
// Getting the player who send the command
ServerPlayerEntity player = source.getPlayer();
return 1;
if (AuthHelper.checkPass(player.getUuidAsString(), pass.toCharArray())) {
SimpleAuth.db.delete(player.getUuidAsString(), null);
player.sendMessage(accountDeleted);
return 1;
}
player.sendMessage(wrongPassword);
return 0;
}
}

View File

@ -14,21 +14,32 @@ public class SimpleAuthDatabase {
private static final Logger LOGGER = LogManager.getLogger();
// Connects to the DB
private Connection connect() {
private Connection conn;
public void openConnection() {
// SQLite connection string
String url = "jdbc:sqlite:mods/SimpleAuth/players.db";
Connection conn = null;
try {
conn = DriverManager.getConnection(url);
} catch (SQLException e) {
LOGGER.error(e.getMessage());
}
return conn;
}
// Cllosing connection
public void close() {
if (conn != null) {
try {
conn.close();
LOGGER.info("[SimpleAuth] Database connection closed successfully.");
} catch (SQLException e) {
LOGGER.info("[SimpleAuth] Error: " + e);
}
}
}
// If the mod runs for the first time, we need to create the DB table
public void makeTable() {
try (Connection conn = this.connect()) {
try {
// Creating database table if it doesn't exist yet
String sql = "CREATE TABLE IF NOT EXISTS users (\n" +
" `UserID` INTEGER PRIMARY KEY AUTOINCREMENT,\n" +
@ -50,9 +61,8 @@ public class SimpleAuthDatabase {
String sql = "INSERT INTO users(uuid, username, password) VALUES(?,?,?)";
String sqlCheck = "SELECT UUID "
+ "FROM users WHERE UUID = ?";
try (
Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql);
try (PreparedStatement pstmt = conn.prepareStatement(sql);
PreparedStatement pstmtCheck = conn.prepareStatement(sqlCheck)) {
pstmtCheck.setString(1, uuid);
@ -81,8 +91,7 @@ public class SimpleAuthDatabase {
public void delete(String uuid, String username) {
String sql = "DELETE FROM users WHERE uuid = ? OR username = ?";
try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// set the corresponding param
pstmt.setString(1, uuid);
@ -100,8 +109,7 @@ public class SimpleAuthDatabase {
String sql = "UPDATE users SET password = ? "
+ "WHERE uuid = ? OR username = ?";
try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// set the corresponding param
pstmt.setString(1, pass);
@ -121,10 +129,9 @@ public class SimpleAuthDatabase {
+ "FROM users WHERE UUID = ?";
String pass = null;
try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// Setting statement
pstmt.setString(1,uuid);
pstmt.setString(1, uuid);
ResultSet rs = pstmt.executeQuery();
// Getting the password

View File

@ -1,9 +1,12 @@
package org.samo_lego.simpleauth.event;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.packet.ChatMessageC2SPacket;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
import net.minecraft.util.TypedActionResult;
import org.samo_lego.simpleauth.SimpleAuth;
/**
@ -16,8 +19,12 @@ public class AuthEventHandler {
// Player joining the server
public static void onPlayerJoin(ServerPlayerEntity player) {
// Player not authenticated
if (!SimpleAuth.isAuthenticated(player))
if (!SimpleAuth.isAuthenticated(player)) {
player.sendMessage(notAuthenticated);
// Setting the player to be invisible to mobs and also invulnerable
player.setInvulnerable(true);
player.setInvisible(true);
}
}
// Player leaving the server
@ -25,13 +32,22 @@ public class AuthEventHandler {
SimpleAuth.authenticatedUsers.remove(player);
}
// Breaking block
public static boolean onBlockBroken(PlayerEntity player) {
if (!SimpleAuth.isAuthenticated((ServerPlayerEntity) player)) {
// todo
public static ActionResult onPlayerChat(PlayerEntity player, ChatMessageC2SPacket chatMessageC2SPacket) {
String msg = chatMessageC2SPacket.getChatMessage();
if(!SimpleAuth.authenticatedUsers.contains(player) && !(msg.startsWith("/login") || msg.startsWith("/register"))) {
player.sendMessage(notAuthenticated);
return true;
return ActionResult.FAIL;
}
return false;
return ActionResult.PASS;
}
//todo
public static ActionResult onPlayerMove(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(player)) {
// TP player back?
return ActionResult.FAIL;
}
return ActionResult.PASS;
}
// Using a block (right-click function)
@ -53,13 +69,13 @@ public class AuthEventHandler {
}
// Using an item
public static ActionResult onUseItem(PlayerEntity player) {
public static TypedActionResult<ItemStack> onUseItem(PlayerEntity player) {
if(!SimpleAuth.authenticatedUsers.contains(player)) {
player.sendMessage(notAuthenticated);
return ActionResult.FAIL;
return TypedActionResult.fail(ItemStack.EMPTY);
}
return ActionResult.PASS;
return TypedActionResult.pass(ItemStack.EMPTY);
}
// Attacking an entity
public static ActionResult onAttackEntity(PlayerEntity player) {

View File

@ -0,0 +1,22 @@
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.entity.player.PlayerEntity;
import net.minecraft.server.network.packet.ChatMessageC2SPacket;
import net.minecraft.util.ActionResult;
public interface OnChatCallback {
Event<OnChatCallback> EVENT = EventFactory.createArrayBacked(OnChatCallback.class, listeners -> (player, chatMessageC2SPacket) -> {
for (OnChatCallback event : listeners) {
ActionResult result = event.onPlayerChat(player, chatMessageC2SPacket);
if (result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult onPlayerChat(PlayerEntity player, ChatMessageC2SPacket chatMessageC2SPacket);
}

View File

@ -0,0 +1,22 @@
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.entity.player.PlayerEntity;
import net.minecraft.server.network.packet.ChatMessageC2SPacket;
import net.minecraft.util.ActionResult;
public interface OnPlayerMoveCallback {
Event<OnPlayerMoveCallback> EVENT = EventFactory.createArrayBacked(OnPlayerMoveCallback.class, listeners -> (player) -> {
for (OnPlayerMoveCallback event : listeners) {
ActionResult result = event.onPlayerMove(player);
if (result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult onPlayerMove(PlayerEntity player);
}

View File

@ -5,7 +5,6 @@ import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.server.network.ServerPlayerEntity;
public interface PlayerJoinServerCallback {
Event<PlayerJoinServerCallback> EVENT = EventFactory.createArrayBacked(PlayerJoinServerCallback.class, listeners -> (player) -> {
for (PlayerJoinServerCallback callback : listeners) {
callback.onPlayerJoin(player);

View File

@ -9,7 +9,6 @@ public interface DropItemCallback {
Event<DropItemCallback> EVENT = EventFactory.createArrayBacked(DropItemCallback.class, listeners -> (player) -> {
for (DropItemCallback event : listeners) {
ActionResult result = event.onDropItem(player);
if (result != ActionResult.PASS) {
return result;
}

View File

@ -1,20 +0,0 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
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(Entity.class)
public abstract class MixinEntity {
/*@Inject(method = "canSeePlayer", at = @At("HEAD"), cancellable = true)
private void canSeePlayer(PlayerEntity playerEntity_1, CallbackInfoReturnable<Boolean> info) {
if(!CanSeePlayerCallback.EVENT.invoker().canSeePlayer((ServerPlayerEntity) playerEntity_1))
info.setReturnValue(false);
}*/
}

View File

@ -1,10 +1,13 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.container.PlayerContainer;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
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;
@ -13,14 +16,22 @@ 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
/*@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) {
@Shadow @Final public PlayerContainer playerContainer;
// 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 dropAtFeet, boolean saveThrower, CallbackInfoReturnable<ItemEntity> cir) {
ServerPlayerEntity player = (ServerPlayerEntity) (Object) this;
ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player);
if (result == ActionResult.FAIL) {
info.cancel();
// Canceling the item drop, as well as giving the items back to player (and updating inv with packet)
player.giveItemStack(stack);
player.inventory.updateItems();
playerContainer.sendContentUpdates();
cir.cancel();
}
}*/
}
}

View File

@ -0,0 +1,56 @@
package org.samo_lego.simpleauth.mixin;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.packet.ChatMessageC2SPacket;
import net.minecraft.server.network.packet.PlayerMoveC2SPacket;
import net.minecraft.util.ActionResult;
import org.samo_lego.simpleauth.event.entity.player.OnChatCallback;
import org.samo_lego.simpleauth.event.entity.player.OnPlayerMoveCallback;
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;
@Mixin(ServerPlayNetworkHandler.class)
public class MixinServerPlayNetworkHandler {
@Shadow
public ServerPlayerEntity player;
// TODO
@Inject(
method = "onChatMessage(Lnet/minecraft/server/network/packet/ChatMessageC2SPacket;)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 onChatMessage(ChatMessageC2SPacket chatMessageC2SPacket_1, CallbackInfo ci) {
ActionResult result = OnChatCallback.EVENT.invoker().onPlayerChat(player, chatMessageC2SPacket_1);
if (result == ActionResult.FAIL) {
ci.cancel();
}
}
// TODO
@Inject(
method="onPlayerMove(Lnet/minecraft/server/network/packet/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 = OnPlayerMoveCallback.EVENT.invoker().onPlayerMove(player);
if (result == ActionResult.FAIL) {
ci.cancel();
}
}
}

View File

@ -23,8 +23,6 @@ public class AuthHelper {
} finally {
// Wipe confidential data
argon2.wipeArray(pass);
// Todo del line
System.out.println("Pass data wiped.");
}
return false;
}

View File

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