Persist coordinates to file

This commit is contained in:
Surya 2021-05-18 23:44:03 +05:30
parent a8a29aaefe
commit c528cd6790
15 changed files with 375 additions and 73 deletions

View File

@ -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.

View File

@ -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

View File

@ -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<ServerCommandSource> context) {
return StringArgumentType.getString(context, "desc");
}
private static int printCoordinates(CommandContext<ServerCommandSource> 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( "<Coordinates> " +
description + " at " + dimensionTypeString + " [ " + x + " , " + y + " , " + z + " ]");
PlayerManager playerManager = source.getMinecraftServer().getPlayerManager();
playerManager.broadcastChatMessage(text, MessageType.CHAT,source.getPlayer().getUuid());
return 1;
}
}

View File

@ -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<FabricClientCommandSource> context)
throws CommandSyntaxException {
FabricClientCommandSource source = context.getSource();
PlayerRawPosition position = positionCalculator.locate(source.getPlayer());
Text text = new LiteralText("<Coordinates> " + position.getWorldDimension() + " at " + " [ " + position.getX()
+ " , " + position.getY() + " , " + position.getZ() + " ]");
source.getPlayer().sendMessage(text, false);
return 1;
}
}

View File

@ -0,0 +1,8 @@
package me.bionicbeanie.mods.core;
import me.bionicbeanie.mods.model.PlayerPosition;
public interface ICoordinateSaveHandler{
void save(PlayerPosition position);
}

View File

@ -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<PlayerPosition> positions) throws IOException;
public void save(PlayerPosition position) throws IOException;
}

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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<PlayerPosition> positions) {
// TODO Auto-generated method stub
}
@Override
public void save(PlayerPosition position) throws IOException {
List<String> lines = Files.readAllLines(saveFilePath);
PlayerPosition[] players = gson.fromJson(String.join("", lines), PlayerPosition[].class);
List<PlayerPosition> 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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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": [