diff --git a/build.gradle b/build.gradle index 7cd0893..a3a77bb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.5-SNAPSHOT' + id 'fabric-loom' version '0.6-SNAPSHOT' id 'maven-publish' } @@ -10,6 +10,13 @@ archivesBaseName = project.archives_base_name version = project.mod_version group = project.maven_group +repositories { + maven { + name = "CottonMC" + url = "https://server.bbkr.space/artifactory/libs-release" + } +} + dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" @@ -18,6 +25,9 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // Cotton MC libgui + modImplementation include("io.github.cottonmc:LibGui:${project.libgui_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. diff --git a/gradle.properties b/gradle.properties index 30b2f63..b432913 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,9 +3,9 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use - minecraft_version=1.16.4 - yarn_mappings=1.16.4+build.9 - loader_version=0.11.1 + minecraft_version=1.16.5 + yarn_mappings=1.16.5+build.9 + loader_version=0.11.3 # Mod Properties mod_version = 1.0.0 @@ -14,4 +14,7 @@ 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.29.3+1.16 + fabric_version=0.34.2+1.16 + + # https://github.com/CottonMC/LibGui/wiki/Setup + libgui_version=3.4.0+1.16.5 diff --git a/src/main/java/me/bionicbeanie/mods/SaveCoordinates.java b/src/main/java/me/bionicbeanie/mods/SaveCoordinates.java deleted file mode 100644 index 9e934ff..0000000 --- a/src/main/java/me/bionicbeanie/mods/SaveCoordinates.java +++ /dev/null @@ -1,65 +0,0 @@ -package me.bionicbeanie.mods; - -import static net.minecraft.server.command.CommandManager.literal; - -import com.mojang.brigadier.arguments.StringArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; -import net.minecraft.network.MessageType; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.dimension.DimensionType; - -public class SaveCoordinates implements ModInitializer { - - @Override - public void onInitialize() { - CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> { - dispatcher.register(literal("sc").then(CommandManager.argument("desc", StringArgumentType.string()) - .executes(SaveCoordinates::printCoordinates))); - }); - } - - private static String getDimensionTypeString(ServerCommandSource source) { - // Does not work with modded dimensions - - DimensionType dimensionType = source.getEntity().world.getDimension(); - - if (dimensionType.isNatural()) { - return "Overworld"; - } - - if (dimensionType.isUltrawarm()) { - return "Nether"; - } - - return "End"; - } - - private static String getDescription(CommandContext context) { - return StringArgumentType.getString(context, "desc"); - } - - private static int printCoordinates(CommandContext context) throws CommandSyntaxException { - ServerCommandSource source = context.getSource(); - String dimensionTypeString = getDimensionTypeString(source); - String description = getDescription(context); - Vec3d pos = source.getEntity().getPos(); - long x = Math.round(pos.x); - long y = Math.round(pos.y); - long z = Math.round(pos.z); - Text text = new LiteralText( " " + - description + " at " + dimensionTypeString + " [ " + x + " , " + y + " , " + z + " ]"); - PlayerManager playerManager = source.getMinecraftServer().getPlayerManager(); - - playerManager.broadcastChatMessage(text, MessageType.CHAT,source.getPlayer().getUuid()); - return 1; - } -} diff --git a/src/main/java/me/bionicbeanie/mods/SaveCoordinatesClient.java b/src/main/java/me/bionicbeanie/mods/SaveCoordinatesClient.java new file mode 100644 index 0000000..2f48d9e --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/SaveCoordinatesClient.java @@ -0,0 +1,63 @@ +package me.bionicbeanie.mods; + +import org.lwjgl.glfw.GLFW; + +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import me.bionicbeanie.mods.core.ICoordinateSaveHandler; +import me.bionicbeanie.mods.core.IFileStore; +import me.bionicbeanie.mods.core.IPositionCalculator; +import me.bionicbeanie.mods.gui.CoordinatesScreen; +import me.bionicbeanie.mods.gui.PlayerPositionGuiDescription; +import me.bionicbeanie.mods.impl.CoordinateSaveHandler; +import me.bionicbeanie.mods.impl.FileStore; +import me.bionicbeanie.mods.impl.PositionCalculator; +import me.bionicbeanie.mods.model.PlayerRawPosition; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.minecraft.client.options.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; + +public class SaveCoordinatesClient implements ClientModInitializer { + + private static IPositionCalculator positionCalculator = new PositionCalculator(); + + @Override + public void onInitializeClient() { + + ClientCommandManager.DISPATCHER.register(ClientCommandManager.literal("coords").then(ClientCommandManager + .argument("desc", StringArgumentType.string()).executes(SaveCoordinatesClient::printCoordinates))); + + KeyBinding keyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.savecoords.coords", + InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_H, "category.savecoords.generic")); + + ClientTickEvents.END_CLIENT_TICK.register(client -> { + while (keyBinding.wasPressed()) { + PlayerRawPosition rawPosition = positionCalculator.locate(client.player); + IFileStore fileStore = new FileStore(client.runDirectory.getAbsolutePath()); + ICoordinateSaveHandler saveHandler = new CoordinateSaveHandler(fileStore); + client.openScreen(new CoordinatesScreen(new PlayerPositionGuiDescription(rawPosition, saveHandler))); + } + }); + } + + private static int printCoordinates(CommandContext context) + throws CommandSyntaxException { + FabricClientCommandSource source = context.getSource(); + PlayerRawPosition position = positionCalculator.locate(source.getPlayer()); + + Text text = new LiteralText(" " + position.getWorldDimension() + " at " + " [ " + position.getX() + + " , " + position.getY() + " , " + position.getZ() + " ]"); + + source.getPlayer().sendMessage(text, false); + + return 1; + } +} diff --git a/src/main/java/me/bionicbeanie/mods/core/ICoordinateSaveHandler.java b/src/main/java/me/bionicbeanie/mods/core/ICoordinateSaveHandler.java new file mode 100644 index 0000000..5cb84f0 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/core/ICoordinateSaveHandler.java @@ -0,0 +1,8 @@ +package me.bionicbeanie.mods.core; + +import me.bionicbeanie.mods.model.PlayerPosition; + +public interface ICoordinateSaveHandler{ + + void save(PlayerPosition position); +} diff --git a/src/main/java/me/bionicbeanie/mods/core/IFileStore.java b/src/main/java/me/bionicbeanie/mods/core/IFileStore.java new file mode 100644 index 0000000..6d6e017 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/core/IFileStore.java @@ -0,0 +1,13 @@ +package me.bionicbeanie.mods.core; + +import java.io.IOException; +import java.util.List; + +import me.bionicbeanie.mods.model.PlayerPosition; + +public interface IFileStore { + + public void save(List positions) throws IOException; + + public void save(PlayerPosition position) throws IOException; +} diff --git a/src/main/java/me/bionicbeanie/mods/core/IPositionCalculator.java b/src/main/java/me/bionicbeanie/mods/core/IPositionCalculator.java new file mode 100644 index 0000000..a8be730 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/core/IPositionCalculator.java @@ -0,0 +1,9 @@ +package me.bionicbeanie.mods.core; + +import me.bionicbeanie.mods.model.PlayerRawPosition; +import net.minecraft.client.network.ClientPlayerEntity; + +public interface IPositionCalculator { + + public PlayerRawPosition locate(ClientPlayerEntity player); +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/CoordinatesScreen.java b/src/main/java/me/bionicbeanie/mods/gui/CoordinatesScreen.java new file mode 100644 index 0000000..91269f3 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/CoordinatesScreen.java @@ -0,0 +1,15 @@ +package me.bionicbeanie.mods.gui; + +import io.github.cottonmc.cotton.gui.GuiDescription; +import io.github.cottonmc.cotton.gui.client.CottonClientScreen; + +public class CoordinatesScreen extends CottonClientScreen{ + + public CoordinatesScreen(GuiDescription description) { + super(description); + // TODO Auto-generated constructor stub + } + + + +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/PlayerPositionGuiDescription.java b/src/main/java/me/bionicbeanie/mods/gui/PlayerPositionGuiDescription.java new file mode 100644 index 0000000..35e61d5 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/PlayerPositionGuiDescription.java @@ -0,0 +1,76 @@ +package me.bionicbeanie.mods.gui; + +import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription; +import io.github.cottonmc.cotton.gui.widget.WButton; +import io.github.cottonmc.cotton.gui.widget.WGridPanel; +import io.github.cottonmc.cotton.gui.widget.WSprite; +import io.github.cottonmc.cotton.gui.widget.WText; +import io.github.cottonmc.cotton.gui.widget.WTextField; +import io.github.cottonmc.cotton.gui.widget.WWidget; +import me.bionicbeanie.mods.core.ICoordinateSaveHandler; +import me.bionicbeanie.mods.model.PlayerPosition; +import me.bionicbeanie.mods.model.PlayerRawPosition; +import net.minecraft.text.LiteralText; +import net.minecraft.util.Identifier; + +public class PlayerPositionGuiDescription extends LightweightGuiDescription { + + public PlayerPositionGuiDescription(PlayerRawPosition rawPosition, ICoordinateSaveHandler onSave) { + WGridPanel root = new WGridPanel(18); + setRootPanel(root); + + // 18 * 18 is the size of 1 item slot. Inset is 7 px + // Dims should be 18 * 3 + 14 by 18 + 14 + root.setSize(70, 34); + + WWidget xText = CreateWidgetForCoordinate(rawPosition.getX()); + WWidget yText = CreateWidgetForCoordinate(rawPosition.getY()); + WWidget zText = CreateWidgetForCoordinate(rawPosition.getZ()); + + root.add(xText, 0, 1, 5, 2); + root.add(yText, 0, 2, 5, 2); + root.add(zText, 0, 3, 5, 2); + + WWidget icon = CreateWorldIcon(rawPosition.getWorldDimension()); + root.add(icon, 3, 0, 1, 1); + + WTextField name = CreateNameField(); + root.add(name, 2, 2, 5, 5); + + WWidget save = CreateSaveButton(onSave, rawPosition, name); + root.add(save, 3, 4, 2, 2); + + root.validate(this); + } + + private WWidget CreateWidgetForCoordinate(long l) { + return new WText(new LiteralText(String.valueOf(l)), 0x3939ac); + } + + private WWidget CreateWorldIcon(String dimension) { + String dimensionItem = "netherite_ingot"; + + if(dimension.contains("overworld")) { + dimensionItem = "diamond"; + } else if(dimension.contains("end")) { + dimensionItem = "ender_eye"; + } + return new WSprite(new Identifier("minecraft:textures/item/" + dimensionItem + ".png")); + } + + private WTextField CreateNameField() { + return new WTextField(new LiteralText("name")); + } + + private WWidget CreateSaveButton(ICoordinateSaveHandler onSaveHandler, PlayerRawPosition rawPosition, WTextField textField) { + WButton button = new WButton(new LiteralText("save")); + button.setOnClick(new Runnable() { + + @Override + public void run() { + onSaveHandler.save(new PlayerPosition(rawPosition, textField.getText())); + } + }); + return button; + } +} diff --git a/src/main/java/me/bionicbeanie/mods/impl/CoordinateSaveHandler.java b/src/main/java/me/bionicbeanie/mods/impl/CoordinateSaveHandler.java new file mode 100644 index 0000000..969db85 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/impl/CoordinateSaveHandler.java @@ -0,0 +1,26 @@ +package me.bionicbeanie.mods.impl; + +import java.io.IOException; + +import me.bionicbeanie.mods.core.ICoordinateSaveHandler; +import me.bionicbeanie.mods.core.IFileStore; +import me.bionicbeanie.mods.model.PlayerPosition; + +public class CoordinateSaveHandler implements ICoordinateSaveHandler{ + + private IFileStore fileStore; + + public CoordinateSaveHandler(IFileStore fileStore) { + this.fileStore = fileStore; + } + + @Override + public void save(PlayerPosition position) { + try { + this.fileStore.save(position); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/me/bionicbeanie/mods/impl/FileStore.java b/src/main/java/me/bionicbeanie/mods/impl/FileStore.java new file mode 100644 index 0000000..dc22b2c --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/impl/FileStore.java @@ -0,0 +1,64 @@ +package me.bionicbeanie.mods.impl; + +import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.LinkedList; +import java.util.List; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import me.bionicbeanie.mods.core.IFileStore; +import me.bionicbeanie.mods.model.PlayerPosition; + +public class FileStore implements IFileStore { + + private static String DEFAULT_DIR = "saveCoordinates"; + private static String DEFAULT_FILE = "coordiates.json"; + + private Path saveFilePath; + private Gson gson; + + public FileStore(String baseDir) { + this.gson = new GsonBuilder().setPrettyPrinting().create(); + this.saveFilePath = Path.of(baseDir, DEFAULT_DIR, DEFAULT_FILE); + + try { + Files.createDirectories(Path.of(baseDir, DEFAULT_DIR)); + Files.createFile(this.saveFilePath); + }catch(FileAlreadyExistsException e) { + //ignore + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void save(List positions) { + // TODO Auto-generated method stub + + } + + @Override + public void save(PlayerPosition position) throws IOException { + List lines = Files.readAllLines(saveFilePath); + PlayerPosition[] players = gson.fromJson(String.join("", lines), PlayerPosition[].class); + + List playersList = new LinkedList<>(); + + if(players != null) { + for(int i = 0; i < players.length; ++i) { + playersList.add(players[i]); + } + } + + playersList.add(position); + + String serialized = gson.toJson(playersList.toArray()); + Files.writeString(saveFilePath, serialized, StandardOpenOption.WRITE); + } + +} diff --git a/src/main/java/me/bionicbeanie/mods/impl/PositionCalculator.java b/src/main/java/me/bionicbeanie/mods/impl/PositionCalculator.java new file mode 100644 index 0000000..dfdf79c --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/impl/PositionCalculator.java @@ -0,0 +1,19 @@ +package me.bionicbeanie.mods.impl; + +import me.bionicbeanie.mods.core.IPositionCalculator; +import me.bionicbeanie.mods.model.PlayerRawPosition; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.util.math.Vec3d; + +public class PositionCalculator implements IPositionCalculator{ + + public PlayerRawPosition locate(ClientPlayerEntity player) { + Vec3d pos = player.getPos(); + long x = Math.round(pos.x); + long y = Math.round(pos.y); + long z = Math.round(pos.z); + String worldDimension = player.world.getRegistryKey().getValue().toString(); + + return new PlayerRawPosition(x, y, z, worldDimension); + } +} diff --git a/src/main/java/me/bionicbeanie/mods/model/PlayerPosition.java b/src/main/java/me/bionicbeanie/mods/model/PlayerPosition.java new file mode 100644 index 0000000..6203be8 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/model/PlayerPosition.java @@ -0,0 +1,32 @@ +package me.bionicbeanie.mods.model; + +public class PlayerPosition { + + private PlayerRawPosition rawPosition; + private String locationName; + + public PlayerPosition(PlayerRawPosition rawPosition, String locationName) { + this.rawPosition = rawPosition; + this.locationName = locationName; + } + + public long getX() { + return rawPosition.getX(); + } + + public long getY() { + return rawPosition.getY(); + } + + public long getZ() { + return rawPosition.getZ(); + } + + public String getWorldDimension() { + return rawPosition.getWorldDimension(); + } + + public String getLocationName() { + return locationName; + } +} diff --git a/src/main/java/me/bionicbeanie/mods/model/PlayerRawPosition.java b/src/main/java/me/bionicbeanie/mods/model/PlayerRawPosition.java new file mode 100644 index 0000000..ea61f2f --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/model/PlayerRawPosition.java @@ -0,0 +1,29 @@ +package me.bionicbeanie.mods.model; + +public class PlayerRawPosition { + private long x, y, z; + private String worldDimension; + + public PlayerRawPosition(long x, long y, long z, String worldDimension) { + this.x = x; + this.y = y; + this.z = z; + this.worldDimension = worldDimension; + } + + public long getX() { + return x; + } + + public long getY() { + return y; + } + + public long getZ() { + return z; + } + + public String getWorldDimension() { + return worldDimension; + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index eb28af0..18bf688 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -4,7 +4,7 @@ "version": "${version}", "name": "Save Coordinates", - "description": "Fabric mod to easily save the current coordinates and share", + "description": "Fabric mod to store the current coordinates", "authors": [ "cool-mist" ], @@ -18,8 +18,8 @@ "environment": "*", "entrypoints": { - "main": [ - "me.bionicbeanie.mods.SaveCoordinates" + "client": [ + "me.bionicbeanie.mods.SaveCoordinatesClient" ] }, "mixins": [