···44The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
55and this project kind of adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6677-### WIP [1.4.0]
88-#### Changed
99-- The loading logic of the storage file
1010-1111-#### Added
1212-- **a config file!**
1313- - The config file starts at **version 0**!
1414-- versioning to the storage file for better handling of migrations.
1515- - We start at **version 1**, all previous version are version 0.
1616-1717-187### [1.3.4]
198- Updated Italian translations (Thanks to [Jump-333](https://github.com/Jump-333)!)
209- Turned DeathLocation into a Hashmap
+14-17
README.md
···4455Here is the [Changelog](https://github.com/MrSn0wy/TeleportCommands/blob/main/CHANGELOG.md)
6677-## Currently available commands:
77+### Currently available commands:
8899- `/worldspawn [<Disable Safety>]` - Teleports you to the world spawn (in the overworld), if given true it will not do safety checks
1010- `/back [<Disable Safety>]` - Teleports you to the location where you last died, if given true it will not do safety checks
···32323333<br>
34343535-## TODO:
3636-### Planned commands:
3535+### TODO:
3636+#### Planned commands:
3737- [ ] `/wild` - Teleports you to a random location in the Overworld
3838- [x] `/worldspawn` - Teleports you to the worldspawn
3939-- [ ] `/spawn <dimension>` - Teleports you to your spawn point in a dimension, defaults to your current dimension
3939+- [ ] `/spawn <dimension>` - Teleports you to your spawnpoint in a dimension, defaults to your current dimension
4040- [ ] `/previous` - Go to the last teleported location
41414242-### Improvements:
4242+#### Improvements:
4343- [ ] Look into changing the mod into the more safe and sane kotlin (I love java)
4444- [ ] Add game tests
4545- [ ] Find the easiest way to backport the mod to older version (help)
···5656- [x] Add Quilt support and NeoForge
575758585959-## Want to help?
5959+### Want to help?
60601. You can create a translation file so other people can use the mod in their native language: [translations.md](./common/src/main/resources/assets/teleport_commands/lang/translations.md)
616162626363-## How to build
6464-### Getting the correct environment
6565-#### Nixos
6363+### How to build
6464+#### Getting the correct environment
6665If you are on nixos you can simply go into the folder of where you cloned the repo, and run `nix develop .`. This will give you the environment I use (apart from the IDE) :3.
67666868-#### Generic linux
6967On any other linux distro, just install the jetbrains jdk, or try openjdk21.
70687171-#### Windows
7272-On windows probably go to the openjdk website and install the 21 version? Idk goodluck.
6969+On windows probably go to the openjdk website and install the 21 version? idk goodluck.
73707474-### Building
7575-Then on linux just run `./gradlew build`. To make it into a single mod jar just run `./gradlew mergeJars`.
7171+#### Building
7272+Then on linux just do `./gradlew build` and to make it in a single mod jar `./gradlew mergeJars`.
76737774Or on windows, just do `.\gradlew.bat build` and `.\gradlew.bat mergeJars`.
7875Note that this isn't tested for windows, but I think that is how it works.
79768080-### Getting the jars
7777+#### Getting the jars
8178Then you can find your jars in `fabric/build/libs/` (for fabric), `neoforge/build/libs/` (for neoforge) or `merged/build/libs/` (if you made the merged jar file).
82798380If you have any issues just make an issue or contact me on Discord `@mrsnowy_`
84818585-## Random notes lol
8686-Text Colors:
8282+### Notes
8383+Colors:
8784- Green = When something succeeds and an action will happen
8885- Aqua = When something needs attention
8986- White = When something is done
···11package dev.mrsnowy.teleport_commands.storage;
2233-import com.google.gson.*;
33+import com.google.gson.Gson;
44+import com.google.gson.GsonBuilder;
45import dev.mrsnowy.teleport_commands.Constants;
56import dev.mrsnowy.teleport_commands.TeleportCommands;
67import dev.mrsnowy.teleport_commands.common.NamedLocation;
78import dev.mrsnowy.teleport_commands.common.Player;
8999-import java.io.FileReader;
1010+import java.io.File;
1011import java.nio.file.Files;
1112import java.nio.file.Path;
1213import java.nio.file.StandardOpenOption;
···2122 public static Path STORAGE_FOLDER;
2223 public static Path STORAGE_FILE;
2324 public static StorageClass STORAGE;
2424- private static final Gson GSON = new GsonBuilder().create();
2525- private static final int defaultVersion = new StorageClass().getVersion();
26252727- /// Initializes the StorageManager class and loads the storage from the filesystem.
2826 public static void StorageInit() {
2927 STORAGE_FOLDER = TeleportCommands.SAVE_DIR.resolve("TeleportCommands/");
3028 STORAGE_FILE = STORAGE_FOLDER.resolve("storage.json");
31293230 try {
3333- StorageLoader();
3434-3535- } catch (Exception e) {
3636- // crashing is probably better here, otherwise the whole mod will be broken
3737- Constants.LOGGER.error("Error while initializing the storage file! Exiting! => ", e);
3838- throw new RuntimeException("Error while initializing the storage file! Exiting! => ", e);
3939- }
4040- }
4141-4242- /// Loads the storage from the filesystem
4343- public static void StorageLoader() throws Exception {
4444-4545- if (!STORAGE_FILE.toFile().exists() || STORAGE_FILE.toFile().length() == 0) {
4646- Constants.LOGGER.warn("Storage file was not found or was empty! Initializing storage");
4747-4848- Files.createDirectories(STORAGE_FOLDER);
4949- STORAGE = new StorageClass();
5050- StorageSaver();
5151- Constants.LOGGER.info("Storage created successfully!");
5252- }
5353-5454- StorageMigrator();
5555-5656- FileReader reader = new FileReader(STORAGE_FILE.toFile());
5757- STORAGE = GSON.fromJson(reader, StorageClass.class);
5858- if (STORAGE == null) {
5959- Constants.LOGGER.warn("Storage file was empty! Initializing storage");
6060- STORAGE = new StorageClass();
6161- StorageSaver();
6262- }
6363-6464- STORAGE.cleanup();
6565-6666- StorageSaver(); // Save it so any missing values get added to the file.
6767- Constants.LOGGER.info("Storage loaded successfully!");
6868- }
6969-7070- /// This function checks what version the storage file is and migrates it to the current version of the mod.
7171- public static void StorageMigrator() throws Exception {
7272- FileReader reader = new FileReader(STORAGE_FILE.toFile());
7373- JsonObject jsonObject = GSON.fromJson(reader, JsonObject.class);
7474-7575- int version = jsonObject.has("version") ? jsonObject.get("version").getAsInt() : 0;
7676-7777- if (version < defaultVersion) {
7878- Constants.LOGGER.warn("Storage file is v{}, migrating to v{}!", version, defaultVersion);
7979-8080- // In v1.1.0 "Player_UUID" got renamed to "UUID". Since the storage file didn't have a version yet, it is set to version 0.
8181- if (version == 0) {
8282-8383- if (jsonObject.has("Players") && jsonObject.get("Players").isJsonArray()) {
8484-8585- JsonArray players = jsonObject.get("Players").getAsJsonArray();
8686-8787- for (JsonElement playerElement : players) {
8888- JsonObject player = playerElement.getAsJsonObject();
8989-9090- String UUID = player.has("Player_UUID")
9191- ? player.get("Player_UUID").getAsString() : (player.has("UUID")
9292- ? player.get("UUID").getAsString() : null);
9393-9494- if (UUID == null || UUID.isBlank()) {
9595- // remove it then, it's an invalid entry 0.0
9696- players.remove(player); // may return true or false for success, but idc
9797-9898- } else {
9999- player.remove("Player_UUID");
100100- player.addProperty("UUID", UUID);
101101- }
102102- }
103103- }
3131+ // check if the folder exists and create it
3232+ if (!Files.exists(STORAGE_FOLDER)) {
3333+ Files.createDirectories(STORAGE_FOLDER);
3434+ }
10435105105- jsonObject.addProperty("version", 1);
3636+ // check if the file exists and create it
3737+ if (!Files.exists(STORAGE_FILE)) {
3838+ Files.createFile(STORAGE_FILE);
10639 }
10740108108- // Save the storage :3
109109- byte[] json = GSON.toJson(jsonObject, JsonArray.class).getBytes();
110110- Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
111111-112112- Constants.LOGGER.info("Storage file migrated to v{} successfully!", defaultVersion);
113113- } else if (version > defaultVersion) {
114114- String message = String.format("Teleport Commands: The storage file's version is newer than the supported version, found v%s, expected <= v%s.\n" +
115115- "If you intentionally backported then you can attempt to downgrade the storage file located at this location: \"%s\".\n",
116116- version, defaultVersion, STORAGE_FILE.toAbsolutePath());
4141+ // create the basic storage if it is empty
4242+ if (new File(String.valueOf(STORAGE_FILE)).length() == 0) {
4343+ StorageManager.STORAGE = new StorageClass();
4444+ StorageSaver(); // todo! verify that it creates em correctly
4545+ }
11746118118- throw new IllegalStateException(message);
4747+ } catch (Exception e) {
4848+ Constants.LOGGER.error("Error while creating the storage file! Exiting! => ", e);
4949+ // crashing is probably better here, otherwise the whole mod will be broken
5050+ System.exit(1);
11951 }
12052 }
12153122122- /// Saves the storage to the filesystem
12354 public static void StorageSaver() throws Exception {
12455 // todo! maybe throttle saves?
125125- byte[] json = GSON.toJson( StorageManager.STORAGE ).getBytes();
5656+ Gson gson = new GsonBuilder().create();
5757+ byte[] json = gson.toJson( StorageManager.STORAGE ).getBytes();
12658127127- Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
5959+ Files.write(STORAGE_FILE, json, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
12860 }
129611306213163 public static class StorageClass {
132132- private final int version = 1;
13364 private final ArrayList<NamedLocation> Warps = new ArrayList<>();
13465 private final ArrayList<Player> Players = new ArrayList<>();
13566136136- /// Cleans up any values in the storage class
137137- public void cleanup() throws Exception {
138138- for (Player player : Players) {
139139- // Remove players with invalid UUID's
140140- if (player.getUUID().isBlank()) {
141141- Players.remove(player);
142142- }
143143-144144- List<NamedLocation> homes = player.getHomes();
145145-146146- // Delete any homes with an invalid world_id (if enabled in config)
147147- if (ConfigManager.CONFIG.home.isDeleteInvalid()) {
148148- homes.removeIf(home -> home.getWorld().isEmpty());
149149- }
150150-151151- // Remove players with no homes
152152- if (homes.isEmpty()) {
153153- Players.remove(player);
154154- }
155155- }
156156-157157- // Delete any warps with an invalid world_id (if enabled in config)
158158- if (ConfigManager.CONFIG.warp.isDeleteInvalid()) {
159159- Warps.removeIf(warp -> warp.getWorld().isEmpty());
160160- }
161161-162162- StorageSaver();
163163- }
164164-165165- public int getVersion() {
166166- return version;
167167- }
6767+ // -----
1686816969 // returns all warps
17070 public List<NamedLocation> getWarps() {
···11+package dev.mrsnowy.teleport_commands.storage;
22+33+public class configManager {
44+// Currently nothing to see here... yet
55+66+ // --- Ideas! ---
77+ // Make config options for disabling certain commands
88+ // Make config options for renaming certain commands
99+ // Make config option for changing required permission level for certain commands
1010+ // Make config for setting max homes
1111+ // Make config that adds a delay between teleports and when fighting. (in teleport function?)
1212+ // Make config that automatically deletes namedLocations (warps/homes) with invalid world id's
1313+ // Make config for setting the world_id for /worldspawn ?
1414+}
-1
flake.nix
···2222 default = pkgs.mkShell {
2323 packages = with pkgs; [
2424 jetbrains.jdk-no-jcef # Jetbrains jdk
2525- just # for the justfile
2625 flite # Make mc not complain
27262827 # Took these from https://github.com/NixOS/nixpkgs/blob/nixos-25.05/pkgs/by-name/pr/prismlauncher/package.nix#L123