diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1bf6b86..55b66ff 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -12,7 +12,7 @@ jobs:
matrix:
# Use these Java versions
java: [
- 21, # Currently min for minecraft
+ 17, # Currently min for minecraft
]
runs-on: ubuntu-22.04
steps:
@@ -24,14 +24,16 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
- distribution: 'temurin'
+ distribution: temurin
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: build
run: ./gradlew build
- name: capture build artifacts
- if: ${{ matrix.java == '21' }} # Only upload artifacts built from latest java
+ if: ${{ matrix.java == '17' }} # Only upload artifacts built from latest java
uses: actions/upload-artifact@v4
with:
name: Artifacts
- path: build/libs/
\ No newline at end of file
+ path: |
+ */build/libs
+ if-no-files-found: error
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index c476faf..c6728e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,39 +1,22 @@
# gradle
-
.gradle/
build/
out/
classes/
-# eclipse
-
-*.launch
-
# idea
-
-.idea/
-*.iml
+out
*.ipr
*.iws
+*.iml
+.idea/*
+!.idea/scopes
-# vscode
-
-.settings/
-.vscode/
-bin/
-.classpath
-.project
-
-# macos
-
-*.DS_Store
-
-# fabric
-
-run/
+# other
+run
+runs
# java
-
hs_err_*.log
replay_*.log
*.hprof
diff --git a/README.md b/README.md
index 3c8adac..5068d23 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Teleport Commands
-A Minecraft fabric server-side mod that adds various teleportation related commands, like /home /tpa and /back
+A Minecraft Fabric and NeoForge server-side mod that adds various teleportation related commands, like /home /tpa and /back
### This mod is still in beta, if there are any problems then let me know!
diff --git a/build.gradle b/build.gradle
index 189b207..a667404 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,86 +1,4 @@
-plugins {
- id 'fabric-loom' version '1.6-SNAPSHOT'
- id 'maven-publish'
-}
-
-version = project.mod_version
-group = project.maven_group
-
-base {
- archivesName = project.archives_base_name
-}
-
-repositories {
- // Add repositories to retrieve artifacts from in here.
- // You should only use this when depending on other mods because
- // Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
- // See https://docs.gradle.org/current/userguide/declaring_repositories.html
- // for more information about repositories.
-}
-
-loom {
- splitEnvironmentSourceSets()
-
- mods {
- "teleport_commands" {
- sourceSet sourceSets.main
- }
- }
-
-}
-
-dependencies {
- // To change the versions see the gradle.properties file
- minecraft "com.mojang:minecraft:${project.minecraft_version}"
- mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
- modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
-
- // Fabric API. This is technically optional, but you probably want it anyway.
- modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
-
-}
-
-processResources {
- inputs.property "version", project.version
-
- filesMatching("fabric.mod.json") {
- expand "version": project.version
- }
-}
-
-tasks.withType(JavaCompile).configureEach {
- it.options.release = 17
-}
-
-java {
- // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
- // if it is present.
- // If you remove this line, sources will not be generated.
- withSourcesJar()
-
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
-}
-
-jar {
- from("LICENSE") {
- rename { "${it}_${project.base.archivesName.get()}"}
- }
-}
-
-// configure the maven publication
-publishing {
- publications {
- create("mavenJava", MavenPublication) {
- from components.java
- }
- }
-
- // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
- repositories {
- // Add repositories to publish to here.
- // Notice: This block does NOT have the same function as the block in the top level.
- // The repositories here will be used for publishing your artifact, not for
- // retrieving dependencies.
- }
+plugins {
+ // Required for NeoGradle
+ id "org.jetbrains.gradle.plugin.idea-ext" version "1.1.7"
}
\ No newline at end of file
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
new file mode 100644
index 0000000..9a20d71
--- /dev/null
+++ b/buildSrc/build.gradle
@@ -0,0 +1,3 @@
+plugins {
+ id 'groovy-gradle-plugin'
+}
diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle
new file mode 100644
index 0000000..c19cd09
--- /dev/null
+++ b/buildSrc/src/main/groovy/multiloader-common.gradle
@@ -0,0 +1,111 @@
+plugins {
+ id 'java-library'
+ id 'maven-publish'
+}
+
+base {
+ archivesName = "${mod_id}-${project.name}-${minecraft_version}"
+}
+
+java {
+ toolchain.languageVersion = JavaLanguageVersion.of(java_version)
+ withSourcesJar()
+ withJavadocJar()
+}
+
+repositories {
+ mavenCentral()
+ // https://docs.gradle.org/current/userguide/declaring_repositories.html#declaring_content_exclusively_found_in_one_repository
+ exclusiveContent {
+ forRepository {
+ maven {
+ name = 'Sponge'
+ url = 'https://repo.spongepowered.org/repository/maven-public'
+ }
+ }
+ filter { includeGroupAndSubgroups("org.spongepowered") }
+ }
+ maven {
+ name = 'BlameJared'
+ url = 'https://maven.blamejared.com'
+ }
+}
+
+dependencies {
+ implementation 'org.jetbrains:annotations:24.1.0'
+}
+
+// Declare capabilities on the outgoing configurations.
+// Read more about capabilities here: https://docs.gradle.org/current/userguide/component_capabilities.html#sec:declaring-additional-capabilities-for-a-local-component
+['apiElements', 'runtimeElements', 'sourcesElements', 'javadocElements'].each { variant ->
+ configurations."$variant".outgoing {
+ capability("$group:$mod_id-${project.name}-${minecraft_version}:$version")
+ capability("$group:$mod_id:$version")
+ }
+ publishing.publications.configureEach {
+ suppressPomMetadataWarningsFor(variant)
+ }
+}
+
+sourcesJar {
+ from(rootProject.file("LICENSE")) {
+ rename { "${it}_${mod_name}" }
+ }
+}
+
+jar {
+ from(rootProject.file("LICENSE")) {
+ rename { "${it}_${mod_name}" }
+ }
+
+ manifest {
+ attributes([
+ 'Specification-Title' : mod_name,
+ 'Specification-Vendor' : mod_author,
+ 'Specification-Version' : project.jar.archiveVersion,
+ 'Implementation-Title' : project.name,
+ 'Implementation-Version': project.jar.archiveVersion,
+ 'Implementation-Vendor' : mod_author,
+ 'Built-On-Minecraft' : minecraft_version
+ ])
+ }
+}
+
+processResources {
+ def expandProps = [
+ "version": version,
+ "group": project.group, //Else we target the task's group.
+ "minecraft_version": minecraft_version,
+ "minecraft_version_range": minecraft_version_range,
+ "fabric_version": fabric_version,
+ "fabric_loader_version": fabric_loader_version,
+ "mod_name": mod_name,
+ "mod_author": mod_author,
+ "mod_id": mod_id,
+ "license": license,
+ "description": project.description,
+ "neoforge_version": neoforge_version,
+ "neoforge_loader_version_range": neoforge_loader_version_range,
+ "credits": credits,
+ "java_version": java_version
+ ]
+
+ filesMatching(['pack.mcmeta', 'fabric.mod.json', 'META-INF/mods.toml', 'META-INF/neoforge.mods.toml', '*.mixins.json']) {
+ expand expandProps
+ }
+ inputs.properties(expandProps)
+}
+
+publishing {
+ publications {
+ register('mavenJava', MavenPublication) {
+ artifactId base.archivesName.get()
+ from components.java
+ }
+ }
+ repositories {
+ maven {
+ url System.getenv("local_maven_url")
+ }
+ }
+}
diff --git a/buildSrc/src/main/groovy/multiloader-loader.gradle b/buildSrc/src/main/groovy/multiloader-loader.gradle
new file mode 100644
index 0000000..f51ea40
--- /dev/null
+++ b/buildSrc/src/main/groovy/multiloader-loader.gradle
@@ -0,0 +1,44 @@
+plugins {
+ id 'multiloader-common'
+}
+
+configurations {
+ commonJava{
+ canBeResolved = true
+ }
+ commonResources{
+ canBeResolved = true
+ }
+}
+
+dependencies {
+ compileOnly(project(':common')) {
+ capabilities {
+ requireCapability "$group:$mod_id"
+ }
+ }
+ commonJava project(path: ':common', configuration: 'commonJava')
+ commonResources project(path: ':common', configuration: 'commonResources')
+}
+
+tasks.named('compileJava', JavaCompile) {
+ dependsOn(configurations.commonJava)
+ source(configurations.commonJava)
+}
+
+processResources {
+ dependsOn(configurations.commonResources)
+ from(configurations.commonResources)
+}
+
+tasks.named('javadoc', Javadoc).configure {
+ dependsOn(configurations.commonJava)
+ source(configurations.commonJava)
+}
+
+tasks.named("sourcesJar", Jar) {
+ dependsOn(configurations.commonJava)
+ from(configurations.commonJava)
+ dependsOn(configurations.commonResources)
+ from(configurations.commonResources)
+}
diff --git a/common/build.gradle b/common/build.gradle
new file mode 100644
index 0000000..246b541
--- /dev/null
+++ b/common/build.gradle
@@ -0,0 +1,33 @@
+plugins {
+ id 'multiloader-common'
+ id 'org.spongepowered.gradle.vanilla' version '0.2.1-SNAPSHOT'
+}
+
+minecraft {
+ version(minecraft_version)
+ def aw = file("src/main/resources/${mod_id}.accesswidener")
+ if(aw.exists()){
+ accessWideners(aw)
+ }
+}
+
+dependencies {
+ compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5'
+}
+
+configurations {
+ commonJava {
+ canBeResolved = false
+ canBeConsumed = true
+ }
+ commonResources {
+ canBeResolved = false
+ canBeConsumed = true
+ }
+}
+
+artifacts {
+ commonJava sourceSets.main.java.sourceDirectories.singleFile
+ commonResources sourceSets.main.resources.sourceDirectories.singleFile
+}
+
diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java b/common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java
new file mode 100644
index 0000000..e6a5ee7
--- /dev/null
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java
@@ -0,0 +1,57 @@
+package dev.mrsnowy.teleport_commands;
+
+import dev.mrsnowy.teleport_commands.storage.StorageManager;
+import dev.mrsnowy.teleport_commands.commands.*;
+import net.minecraft.commands.Commands;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.level.storage.LevelResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Objects;
+
+import static dev.mrsnowy.teleport_commands.utils.tools.DeathLocationUpdater;
+
+public class TeleportCommands {
+
+ public static final String MOD_ID = "teleport_commands";
+ public static final String MOD_NAME = "Teleport Commands";
+ public static final Logger LOGGER = LoggerFactory.getLogger(MOD_NAME);
+ public static String MOD_LOADER;
+ public static Path SAVE_DIR;
+ public static Path CONFIG_DIR;
+ public static MinecraftServer Server;
+
+ public static void initializeMod(MinecraftServer server, String ModLoader) {
+ // initialize da variables
+
+ MOD_LOADER = ModLoader;
+
+ SAVE_DIR = Path.of(String.valueOf(server.getWorldPath(LevelResource.ROOT)));
+
+ // Construct the game directory path
+ CONFIG_DIR = Paths.get(System.getProperty("user.dir")).resolve("config");
+
+ Server = server;
+
+ // initialize commands, also allows me to easily disable any when there is a config
+ Commands commandManager = server.getCommands();
+ back.register(commandManager);
+ home.register(commandManager);
+ tpa.register(commandManager);
+
+ StorageManager.StorageInit();
+ }
+
+ public static void onPlayerDeath(ServerPlayer player) {
+ try {
+ // update /back command position
+ DeathLocationUpdater(player.position(), player.serverLevel(), player.getStringUUID());
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java
new file mode 100644
index 0000000..b208c51
--- /dev/null
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/back.java
@@ -0,0 +1,60 @@
+package dev.mrsnowy.teleport_commands.commands;
+
+import dev.mrsnowy.teleport_commands.TeleportCommands;
+import dev.mrsnowy.teleport_commands.storage.StorageManager;
+import java.util.Objects;
+import net.minecraft.ChatFormatting;
+import net.minecraft.commands.Commands;
+import net.minecraft.network.chat.Component;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.phys.Vec3;
+
+import static dev.mrsnowy.teleport_commands.storage.StorageManager.GetPlayerStorage;
+import static dev.mrsnowy.teleport_commands.utils.tools.Teleporter;
+
+public class back {
+
+ public static void register(Commands commandManager) {
+
+ commandManager.getDispatcher().register(Commands.literal("back").executes(context -> {
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ player.displayClientMessage(Component.literal("Teleporting"), true);
+ ToDeathLocation(player);
+ } catch (Exception e) {
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ player.displayClientMessage(Component.literal("Error Teleporting!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ return 1;
+ }
+ return 0;
+ }));
+ }
+
+
+
+ private static void ToDeathLocation(ServerPlayer player) throws Exception {
+ StorageManager.StorageClass.Player playerStorage = GetPlayerStorage(player.getStringUUID()).playerStorage;
+
+ Vec3 pos = new Vec3(playerStorage.deathLocation.x, playerStorage.deathLocation.y, playerStorage.deathLocation.z);
+
+ boolean found = false;
+ for (ServerLevel currentWorld : Objects.requireNonNull(player.getServer()).getAllLevels()) {
+ if (Objects.equals(currentWorld.dimension().location().toString(), playerStorage.deathLocation.world)) {
+ Teleporter(player, currentWorld, pos);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ player.displayClientMessage(Component.literal("No Location Found!"), true);
+ }
+ }
+}
diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java
new file mode 100644
index 0000000..47c6219
--- /dev/null
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/home.java
@@ -0,0 +1,404 @@
+package dev.mrsnowy.teleport_commands.commands;
+
+import com.mojang.brigadier.arguments.StringArgumentType;
+import dev.mrsnowy.teleport_commands.TeleportCommands;
+import dev.mrsnowy.teleport_commands.storage.StorageManager;
+import dev.mrsnowy.teleport_commands.suggestions.HomesuggestionProvider;
+import java.util.Objects;
+import net.minecraft.ChatFormatting;
+import net.minecraft.commands.Commands;
+import net.minecraft.network.chat.ClickEvent;
+import net.minecraft.network.chat.Component;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.phys.Vec3;
+
+import static net.minecraft.commands.Commands.argument;
+import static dev.mrsnowy.teleport_commands.storage.StorageManager.GetPlayerStorage;
+import static dev.mrsnowy.teleport_commands.storage.StorageManager.StorageSaver;
+import static dev.mrsnowy.teleport_commands.utils.tools.Teleporter;
+
+public class home {
+ public static void register(Commands commandManager) {
+
+ commandManager.getDispatcher().register(Commands.literal("sethome")
+ .then(argument("name", StringArgumentType.string())
+ .executes(context -> {
+ final String name = StringArgumentType.getString(context, "name");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ player.displayClientMessage(Component.literal("Home Set"), true);
+ SetHome(player, name);
+
+ } catch (Exception e) {
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ player.displayClientMessage(Component.literal("Error Setting Home!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ return 1;
+ }
+ return 0;
+ })));
+
+
+ commandManager.getDispatcher().register(Commands.literal("home")
+ .executes(context -> {
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ player.displayClientMessage(Component.literal("Going Home"), true);
+ GoHome(player, "");
+
+ } catch (Exception e) {
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ player.displayClientMessage(Component.literal("Error Going Home!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ return 1;
+ }
+ return 0;
+ })
+ .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
+ .executes(context -> {
+ final String name = StringArgumentType.getString(context, "name");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ player.displayClientMessage(Component.literal("Going Home"), true);
+ GoHome(player, name);
+
+ } catch (Exception e) {
+ player.displayClientMessage(Component.literal("Error Going Home!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ return 1;
+ }
+ return 0;
+ })));
+
+ commandManager.getDispatcher().register(Commands.literal("delhome")
+ .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
+ .executes(context -> {
+ final String name = StringArgumentType.getString(context, "name");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ player.displayClientMessage(Component.literal("Home Deleted"), true);
+ DeleteHome(player, name);
+
+ } catch (Exception e) {
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ player.displayClientMessage(Component.literal("Error Deleting Home!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ return 1;
+ }
+ return 0;
+ })));
+
+ commandManager.getDispatcher().register(Commands.literal("renamehome")
+ .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
+ .then(argument("newName", StringArgumentType.string())
+ .executes(context -> {
+ final String name = StringArgumentType.getString(context, "name");
+ final String newName = StringArgumentType.getString(context, "newName");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ player.displayClientMessage(Component.literal("Home Renamed"), true);
+ RenameHome(player, name, newName);
+ } catch (Exception e) {
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ player.displayClientMessage(Component.literal("Error Renaming Home!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ return 1;
+ }
+ return 0;
+ }))));
+
+
+ commandManager.getDispatcher().register(Commands.literal("homes")
+ .executes(context -> {
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ PrintHomes(player);
+ } catch (Exception e) {
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ player.displayClientMessage(Component.literal("Error Getting Homes!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ return 1;
+ }
+ return 0;
+ }));
+
+ commandManager.getDispatcher().register(Commands.literal("defaulthome")
+ .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
+ .executes(context -> {
+ final String name = StringArgumentType.getString(context, "name");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ try {
+ SetDefaultHome(player, name);
+ } catch (Exception e) {
+ TeleportCommands.LOGGER.error(String.valueOf(e));
+ player.displayClientMessage(Component.literal("Error Changing Default Home!").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), true);
+ return 1;
+ }
+ return 0;
+ })));
+ }
+
+
+
+ private static void SetHome(ServerPlayer player, String homeName) throws Exception {
+ homeName = homeName.toLowerCase();
+ Vec3 pos = player.position();
+ ServerLevel world = player.serverLevel();
+
+ StorageManager.PlayerStorageResult storages = GetPlayerStorage(player.getStringUUID());
+ StorageManager.StorageClass storage = storages.storage;
+ StorageManager.StorageClass.Player playerStorage = storages.playerStorage;
+
+ boolean homeNotFound = true;
+
+ // check for duplicates
+ for (StorageManager.StorageClass.Player.Home currentHome : playerStorage.Homes) {
+ if (Objects.equals(currentHome.name, homeName)) {
+ homeNotFound = false;
+ break;
+ }
+ }
+
+ if (homeNotFound) {
+ // Create a new Home
+ StorageManager.StorageClass.Player.Home homeLocation = new StorageManager.StorageClass.Player.Home();
+
+ homeLocation.name = homeName;
+ homeLocation.x = Double.parseDouble(String.format("%.1f", pos.x()));
+ homeLocation.y = Double.parseDouble(String.format("%.1f", pos.y()));
+ homeLocation.z = Double.parseDouble(String.format("%.1f", pos.z()));
+ homeLocation.world = world.dimension().location().toString();
+
+ playerStorage.Homes.add(homeLocation);
+
+ if (playerStorage.Homes.size() == 1) {
+ playerStorage.DefaultHome = homeName;
+ }
+
+ StorageSaver(storage);
+ } else {
+ player.displayClientMessage(Component.literal("Home Already Exists!"), true);
+ }
+ }
+
+ private static void GoHome(ServerPlayer player, String homeName) throws Exception {
+ homeName = homeName.toLowerCase();
+ StorageManager.StorageClass.Player playerStorage = GetPlayerStorage(player.getStringUUID()).playerStorage;
+
+ // check if there is a default exists
+ if (homeName.isEmpty()) {
+ if (playerStorage.DefaultHome.isEmpty()) {
+ player.displayClientMessage(Component.literal("You Have No Homes!"), true);
+ return;
+ } else {
+ homeName = playerStorage.DefaultHome;
+ }
+ }
+
+ boolean foundHome = false;
+ boolean foundWorld = false;
+
+ // find correct home
+ for (StorageManager.StorageClass.Player.Home currentHome : playerStorage.Homes) {
+ if (Objects.equals(currentHome.name, homeName)){
+ foundHome = true;
+
+ // find correct world
+ for (ServerLevel currentWorld : Objects.requireNonNull(player.getServer()).getAllLevels()) {
+ if (Objects.equals(currentWorld.dimension().location().toString(), currentHome.world)) {
+ Teleporter(player, currentWorld, new Vec3(currentHome.x, currentHome.y, currentHome.z));
+ foundWorld = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!foundHome) {
+ player.displayClientMessage(Component.literal("Home Not Found!"), true);
+ } else if (!foundWorld) {
+ player.displayClientMessage(Component.literal("World Not Found!"), true);
+ }
+ }
+
+ private static void DeleteHome(ServerPlayer player, String homeName) throws Exception {
+ homeName = homeName.toLowerCase();
+ StorageManager.PlayerStorageResult storages = GetPlayerStorage(player.getStringUUID());
+ StorageManager.StorageClass storage = storages.storage;
+ StorageManager.StorageClass.Player playerStorage = storages.playerStorage;
+
+ StorageManager.StorageClass.Player.Home homeToDelete = null;
+
+ // get correct home
+ for (StorageManager.StorageClass.Player.Home currentHome : playerStorage.Homes) {
+ if (Objects.equals(currentHome.name, homeName)){
+ homeToDelete = currentHome;
+ break;
+ }
+ }
+
+ if (Objects.nonNull(homeToDelete)) {
+ playerStorage.Homes.remove(homeToDelete);
+ StorageSaver(storage);
+ } else {
+ player.displayClientMessage(Component.literal("Home Not Found!"), true);
+ }
+ }
+
+ private static void RenameHome(ServerPlayer player, String homeName, String newHomeName) throws Exception {
+ homeName = homeName.toLowerCase();
+ newHomeName = newHomeName.toLowerCase();
+
+ StorageManager.PlayerStorageResult storages = GetPlayerStorage(player.getStringUUID());
+ StorageManager.StorageClass storage = storages.storage;
+ StorageManager.StorageClass.Player playerStorage = storages.playerStorage;
+
+ StorageManager.StorageClass.Player.Home homeToRename = null;
+ boolean newNameNotFound = true;
+
+ // check for duplicates
+ for (StorageManager.StorageClass.Player.Home currentHome : playerStorage.Homes) {
+ if (Objects.equals(currentHome.name, newHomeName)) {
+ newNameNotFound = false;
+ break;
+ }
+ }
+
+ if (newNameNotFound) {
+ // get correct home
+ for (StorageManager.StorageClass.Player.Home currentHome : playerStorage.Homes) {
+ if (Objects.equals(currentHome.name, homeName)){
+ homeToRename = currentHome;
+ break;
+ }
+ }
+
+ if (Objects.nonNull(homeToRename)) {
+ if (Objects.equals(playerStorage.DefaultHome, homeToRename.name)) {
+ playerStorage.DefaultHome = newHomeName;
+ }
+
+ homeToRename.name = newHomeName;
+ StorageSaver(storage);
+ } else {
+ player.displayClientMessage(Component.literal("Home Not Found!"), true);
+ }
+ } else {
+ player.displayClientMessage(Component.literal("Home Already Exists!"), true);
+ }
+
+ }
+
+ private static void PrintHomes(ServerPlayer player) throws Exception {
+ StorageManager.StorageClass.Player playerStorage = GetPlayerStorage(player.getStringUUID()).playerStorage;
+ boolean anyHomes = false;
+
+ for (StorageManager.StorageClass.Player.Home currenthome : playerStorage.Homes) {
+ if (!anyHomes) {
+ player.displayClientMessage(Component.literal("Homes: \n").withStyle(ChatFormatting.YELLOW, ChatFormatting.BOLD), false);
+ anyHomes = true;
+ }
+
+ String name = String.format(" - %s", currenthome.name);
+ String nameDefault = " (Default)";
+
+
+ String coords = String.format(" [X%.1f Y%.1f Z%.1f]", currenthome.x, currenthome.y, currenthome.z);
+ String dimension = String.format(" [%s]", currenthome.world);
+
+ if (Objects.equals(currenthome.name, playerStorage.DefaultHome)) {
+ player.displayClientMessage(Component.literal(name).withStyle(ChatFormatting.AQUA)
+ .append(Component.literal(nameDefault).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD)),
+ false
+ );
+ } else {
+ player.displayClientMessage(Component.literal(name).withStyle(ChatFormatting.AQUA), false);
+ }
+
+
+ player.displayClientMessage(Component.literal(" |").withStyle(ChatFormatting.AQUA)
+ .append(Component.literal(coords).withStyle(ChatFormatting.LIGHT_PURPLE).withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, String.format("X%.2f Y%.2f Z%.2f", currenthome.x, currenthome.y, currenthome.z)))))
+ .append(Component.literal(dimension).withStyle(ChatFormatting.DARK_PURPLE).withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, currenthome.world)))),
+ false
+ );
+
+ player.displayClientMessage(Component.literal(" |").withStyle(ChatFormatting.AQUA)
+ .append(Component.literal(" [Tp]").withStyle(ChatFormatting.GREEN).withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/home %s", currenthome.name)))))
+ .append(Component.literal(" [Rename]").withStyle(ChatFormatting.BLUE).withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.format("/renamehome %s ", currenthome.name)))))
+ .append(Component.literal(" [Delete]\n").withStyle(ChatFormatting.RED).withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.format("/delhome %s", currenthome.name))))),
+ false
+ );
+ }
+
+ if (!anyHomes) {
+ player.displayClientMessage(Component.literal("No homes set"), true);
+ }
+ }
+
+ private static void SetDefaultHome(ServerPlayer player, String homeName) throws Exception {
+ homeName = homeName.toLowerCase();
+ StorageManager.PlayerStorageResult storages = GetPlayerStorage(player.getStringUUID());
+ StorageManager.StorageClass storage = storages.storage;
+ StorageManager.StorageClass.Player playerStorage = storages.playerStorage;
+
+ boolean homeExists = false;
+
+ // check if home exists
+ for (StorageManager.StorageClass.Player.Home currentHome : playerStorage.Homes) {
+ if (Objects.equals(currentHome.name, homeName)){
+ homeExists = true;
+ break;
+ }
+ }
+
+ if (homeExists) {
+ if (Objects.equals(playerStorage.DefaultHome, homeName)) {
+ player.displayClientMessage(Component.literal("Home is already set as default!"), true);
+
+ } else {
+ playerStorage.DefaultHome = homeName;
+ StorageSaver(storage);
+ }
+ } else {
+ player.displayClientMessage(Component.literal("Home not found!"), true);
+ }
+ }
+}
diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java
new file mode 100644
index 0000000..2ffedb8
--- /dev/null
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/commands/tpa.java
@@ -0,0 +1,200 @@
+package dev.mrsnowy.teleport_commands.commands;
+
+import dev.mrsnowy.teleport_commands.TeleportCommands;
+import java.util.*;
+import net.minecraft.ChatFormatting;
+import net.minecraft.commands.Commands;
+import net.minecraft.commands.arguments.EntityArgument;
+import net.minecraft.network.chat.ClickEvent;
+import net.minecraft.network.chat.Component;
+import net.minecraft.server.level.ServerPlayer;
+
+import static dev.mrsnowy.teleport_commands.utils.tools.Teleporter;
+
+public class tpa {
+
+ private static final ArrayList tpaList = new ArrayList<>();
+
+ private static class tpaArrayClass {
+ private String InitPlayer;
+ private String RecPlayer;
+ private boolean here;
+ }
+
+ public static void register(Commands commandManager) {
+
+ commandManager.getDispatcher().register(Commands.literal("tpa")
+ .then(Commands.argument("player", EntityArgument.player())
+ .executes(context -> {
+ final ServerPlayer TargetPlayer = EntityArgument.getPlayer(context, "player");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ tpaCommandHandler(player, TargetPlayer, false);
+ return 0;
+ })));
+
+ commandManager.getDispatcher().register(Commands.literal("tpahere")
+ .then(Commands.argument("player", EntityArgument.player())
+ .executes(context -> {
+ final ServerPlayer TargetPlayer = EntityArgument.getPlayer(context, "player");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ tpaCommandHandler(player, TargetPlayer, true);
+ return 0;
+ })));
+
+ commandManager.getDispatcher().register(Commands.literal("tpaaccept")
+ .then(Commands.argument("player", EntityArgument.player())
+ .executes(context -> {
+ final ServerPlayer TargetPlayer = EntityArgument.getPlayer(context, "player");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ tpaAccept(player, TargetPlayer);
+ return 0;
+ })));
+
+ commandManager.getDispatcher().register(Commands.literal("tpadeny")
+ .then(Commands.argument("player", EntityArgument.player())
+ .executes(context -> {
+ final ServerPlayer TargetPlayer = EntityArgument.getPlayer(context, "player");
+ ServerPlayer player = context.getSource().getPlayer();
+
+ if (player == null) {
+ TeleportCommands.LOGGER.error("Error while executing the command, No player found!");
+ return 1;
+ }
+
+ tpaDeny(player, TargetPlayer);
+ return 0;
+ })));
+ }
+
+
+
+ private static void tpaCommandHandler(ServerPlayer FromPlayer, ServerPlayer ToPlayer, boolean here) {
+
+ if (FromPlayer == ToPlayer) {
+ FromPlayer.displayClientMessage(Component.literal("Well, that was easy").withStyle(ChatFormatting.AQUA),true);
+
+ } else {
+ String ToMessage;
+ String FromMessage;
+
+ // Store da request
+ tpaArrayClass tpaRequest = new tpaArrayClass();
+ tpaRequest.InitPlayer = FromPlayer.getStringUUID();
+ tpaRequest.RecPlayer = ToPlayer.getStringUUID();
+ tpaRequest.here = here;
+ tpaList.add(tpaRequest);
+
+ if (here) {
+ ToMessage = "TpaHere Request Received From ";
+ FromMessage = "TpaHere Request Send to ";
+
+ } else {
+ ToMessage = "Tpa Request Received From ";
+ FromMessage = "Tpa Request Send to ";
+ }
+
+ String ToPlayerString = Objects.requireNonNull(ToPlayer.getName().tryCollapseToString());
+ String FromPlayerString = Objects.requireNonNull(FromPlayer.getName().tryCollapseToString());
+
+ FromPlayer.displayClientMessage(Component.literal(FromMessage).withStyle(ChatFormatting.AQUA)
+ .append(Component.literal(ToPlayerString).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD))
+// .append(Text.literal("\n[Cancel]").formatted(Formatting.BLUE, Formatting.BOLD))
+ ,true
+ );
+
+ ToPlayer.displayClientMessage(Component.literal(ToMessage).withStyle(ChatFormatting.AQUA)
+ .append(Component.literal(FromPlayerString).withStyle(ChatFormatting.AQUA, ChatFormatting.BOLD))
+ .append(Component.literal("\n[Accept]").withStyle(ChatFormatting.GREEN, ChatFormatting.BOLD).withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/tpaaccept %s", FromPlayerString)))))
+ .append(Component.literal(" [Deny]").withStyle(ChatFormatting.RED, ChatFormatting.BOLD).withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/tpadeny %s", FromPlayerString))))),
+ false
+ );
+
+ Timer timer = new Timer();
+ timer.schedule(
+ new TimerTask() {
+ @Override
+ public void run() {
+ boolean successful = tpaList.remove(tpaRequest);
+ if (successful) {
+ if (here) {
+ FromPlayer.displayClientMessage(Component.literal("TpaHere Request Expired").withStyle(ChatFormatting.AQUA),true);
+ } else {
+ FromPlayer.displayClientMessage(Component.literal("Tpa Request Expired").withStyle(ChatFormatting.AQUA),true);
+ }
+ }
+ }
+ }, 30 * 1000
+ );
+ }
+ }
+
+ private static void tpaAccept(ServerPlayer FromPlayer, ServerPlayer ToPlayer) {
+ if (FromPlayer == ToPlayer) {
+ FromPlayer.displayClientMessage(Component.literal("Uhm.. no?").withStyle(ChatFormatting.AQUA),true);
+ } else {
+ Optional tpaStorage = tpaList.stream()
+ .filter(tpa -> Objects.equals(ToPlayer.getStringUUID(), tpa.InitPlayer))
+ .filter(tpa -> Objects.equals(FromPlayer.getStringUUID(), tpa.RecPlayer))
+ .findFirst();
+
+ if (tpaStorage.isPresent()) {
+ if (tpaStorage.get().here) {
+ FromPlayer.displayClientMessage(Component.literal("Teleporting"),true);
+ ToPlayer.displayClientMessage(Component.literal("Request Accepted"),true);
+
+ Teleporter(FromPlayer, ToPlayer.serverLevel(), ToPlayer.position());
+ } else {
+ ToPlayer.displayClientMessage(Component.literal("Teleporting"),true);
+ FromPlayer.displayClientMessage(Component.literal("Request Accepted"),true);
+
+ Teleporter(ToPlayer, FromPlayer.serverLevel(), FromPlayer.position());
+ }
+
+ tpaList.remove(tpaStorage.get());
+ } else {
+ FromPlayer.displayClientMessage(Component.literal("No Requests found!").withStyle(ChatFormatting.AQUA),true);
+ }
+ }
+ }
+
+ private static void tpaDeny(ServerPlayer FromPlayer, ServerPlayer ToPlayer) {
+ if (FromPlayer == ToPlayer) {
+ FromPlayer.displayClientMessage(Component.literal("Uhm.. no?").withStyle(ChatFormatting.AQUA),true);
+ } else {
+ Optional tpaStorage = tpaList.stream()
+ .filter(tpa -> Objects.equals(ToPlayer.getStringUUID(), tpa.InitPlayer))
+ .filter(tpa -> Objects.equals(FromPlayer.getStringUUID(), tpa.RecPlayer))
+ .findFirst();
+
+ if (tpaStorage.isPresent()) {
+ tpaList.remove(tpaStorage.get());
+
+ if (tpaStorage.get().here) {
+ ToPlayer.displayClientMessage(Component.literal("Request Denied").withStyle(ChatFormatting.AQUA),true);
+ } else {
+ FromPlayer.displayClientMessage(Component.literal("Request Denied").withStyle(ChatFormatting.AQUA),true);
+ }
+ } else {
+ FromPlayer.displayClientMessage(Component.literal("No Requests found!").withStyle(ChatFormatting.AQUA),true);
+ }
+ }
+ }
+}
diff --git a/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java b/common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java
similarity index 99%
rename from src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java
rename to common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java
index 984aee9..a8d6b20 100644
--- a/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/storage/StorageManager.java
@@ -14,7 +14,6 @@ import java.util.Objects;
import java.util.Optional;
public class StorageManager {
-
public static Path STORAGE_FOLDER;
public static Path STORAGE_FILE;
diff --git a/src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java b/common/src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java
similarity index 50%
rename from src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java
rename to common/src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java
index d6b1e81..1271693 100644
--- a/src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/storage/configManager.java
@@ -1,8 +1,6 @@
package dev.mrsnowy.teleport_commands.storage;
-//import java.nio.file.Path;
-//import net.fabricmc.loader.api.FabricLoader;
-
public class configManager {
+// Currently nothing to see here... yet
}
diff --git a/src/main/java/dev/mrsnowy/teleport_commands/suggestions/HomesuggestionProvider.java b/common/src/main/java/dev/mrsnowy/teleport_commands/suggestions/HomesuggestionProvider.java
similarity index 66%
rename from src/main/java/dev/mrsnowy/teleport_commands/suggestions/HomesuggestionProvider.java
rename to common/src/main/java/dev/mrsnowy/teleport_commands/suggestions/HomesuggestionProvider.java
index 90358ad..40555c8 100644
--- a/src/main/java/dev/mrsnowy/teleport_commands/suggestions/HomesuggestionProvider.java
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/suggestions/HomesuggestionProvider.java
@@ -6,23 +6,19 @@ import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import dev.mrsnowy.teleport_commands.TeleportCommands;
import dev.mrsnowy.teleport_commands.storage.StorageManager;
-import net.minecraft.server.command.ServerCommandSource;
-import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.server.world.ServerWorld;
-import net.minecraft.util.math.Vec3d;
-
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.server.level.ServerPlayer;
import static dev.mrsnowy.teleport_commands.storage.StorageManager.GetPlayerStorage;
-public class HomesuggestionProvider implements SuggestionProvider {
+public class HomesuggestionProvider implements SuggestionProvider {
@Override
- public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) {
+ public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) {
try {
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
- StorageManager.StorageClass.Player playerStorage = null;
- playerStorage = GetPlayerStorage(player.getUuidAsString()).playerStorage;
+ ServerPlayer player = Objects.requireNonNull(context.getSource().getPlayer());
+ StorageManager.StorageClass.Player playerStorage = GetPlayerStorage(player.getStringUUID()).playerStorage;
for (StorageManager.StorageClass.Player.Home currenthome : playerStorage.Homes) {
builder.suggest(currenthome.name);
diff --git a/common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java b/common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java
new file mode 100644
index 0000000..c481f03
--- /dev/null
+++ b/common/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java
@@ -0,0 +1,62 @@
+package dev.mrsnowy.teleport_commands.utils;
+
+import dev.mrsnowy.teleport_commands.storage.StorageManager;
+import java.util.*;
+import net.minecraft.core.particles.ParticleTypes;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.sounds.SoundEvent;
+import net.minecraft.sounds.SoundSource;
+import net.minecraft.world.phys.Vec3;
+
+import static dev.mrsnowy.teleport_commands.storage.StorageManager.GetPlayerStorage;
+import static dev.mrsnowy.teleport_commands.storage.StorageManager.StorageSaver;
+import static net.minecraft.sounds.SoundEvents.ENDERMAN_TELEPORT;
+
+public class tools {
+
+ public static void Teleporter(ServerPlayer player, ServerLevel world, Vec3 coords) {
+ world.sendParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() + 1, player.getZ(), 20, 0.0D, 0.0D, 0.0D, 0.01);
+ world.sendParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 1.0D, 0.0D, 0.03);
+ world.playSound(null, player.blockPosition(), SoundEvent.createVariableRangeEvent(ENDERMAN_TELEPORT.getLocation()), SoundSource.PLAYERS, 0.4f, 1.0f);
+
+ var flying = player.getAbilities().flying;
+
+ player.teleportTo(world, coords.x, coords.y, coords.z, player.getYRot(), player.getXRot());
+
+ // Restore flying when teleporting dimensions
+ if (flying) {
+ player.getAbilities().flying = true;
+ player.onUpdateAbilities();
+ }
+
+ world.playSound(null, player.blockPosition(), SoundEvent.createVariableRangeEvent(ENDERMAN_TELEPORT.getLocation()), SoundSource.PLAYERS, 0.4f, 1.0f);
+ Timer timer = new Timer();
+
+ timer.schedule(
+ new TimerTask() {
+ @Override
+ public void run() {
+ world.sendParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() , player.getZ(), 20, 0.0D, 1.0D, 0.0D, 0.01);
+ world.sendParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 0.0D, 0.0D, 0.03);
+ }
+ }, 100 // hopefully good, 2 ticks
+ );
+ }
+
+
+
+ public static void DeathLocationUpdater(Vec3 pos, ServerLevel world, String UUID) throws Exception {
+ StorageManager.PlayerStorageResult storages = GetPlayerStorage(UUID);
+
+ StorageManager.StorageClass storage = storages.storage;
+ StorageManager.StorageClass.Player playerStorage = storages.playerStorage;
+
+ playerStorage.deathLocation.x = Double.parseDouble(String.format("%.1f", pos.x()));
+ playerStorage.deathLocation.y = Double.parseDouble(String.format("%.1f", pos.y()));
+ playerStorage.deathLocation.z = Double.parseDouble(String.format("%.1f", pos.z()));
+ playerStorage.deathLocation.world = world.dimension().location().toString();
+
+ StorageSaver(storage);
+ }
+}
diff --git a/common/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta
new file mode 100644
index 0000000..52854ec
--- /dev/null
+++ b/common/src/main/resources/pack.mcmeta
@@ -0,0 +1,6 @@
+{
+ "pack": {
+ "description": "${mod_name}",
+ "pack_format": 8
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/teleport_commands/icon.png b/common/src/main/resources/teleport_commands.png
similarity index 100%
rename from src/main/resources/assets/teleport_commands/icon.png
rename to common/src/main/resources/teleport_commands.png
diff --git a/fabric/build.gradle b/fabric/build.gradle
new file mode 100644
index 0000000..6acbfc5
--- /dev/null
+++ b/fabric/build.gradle
@@ -0,0 +1,34 @@
+plugins {
+ id 'multiloader-loader'
+ id 'fabric-loom' version '1.6-SNAPSHOT'
+}
+dependencies {
+ minecraft "com.mojang:minecraft:${minecraft_version}"
+ mappings loom.officialMojangMappings()
+ modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}"
+ modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
+}
+
+loom {
+ def aw = project(":common").file("src/main/resources/${mod_id}.accesswidener")
+ if (aw.exists()) {
+ accessWidenerPath.set(aw)
+ }
+ mixin {
+ defaultRefmapName.set("${mod_id}.refmap.json")
+ }
+ runs {
+ client {
+ client()
+ setConfigName("Fabric Client")
+ ideConfigGenerated(true)
+ runDir("runs/client")
+ }
+ server {
+ server()
+ setConfigName("Fabric Server")
+ ideConfigGenerated(true)
+ runDir("runs/server")
+ }
+ }
+}
\ No newline at end of file
diff --git a/fabric/src/main/java/dev/mrsnowy/teleport_commands/fabricInit.java b/fabric/src/main/java/dev/mrsnowy/teleport_commands/fabricInit.java
new file mode 100644
index 0000000..f584f28
--- /dev/null
+++ b/fabric/src/main/java/dev/mrsnowy/teleport_commands/fabricInit.java
@@ -0,0 +1,35 @@
+package dev.mrsnowy.teleport_commands;
+
+import net.fabricmc.api.ModInitializer;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
+import net.minecraft.server.level.ServerPlayer;
+
+import java.util.Objects;
+
+public class fabricInit implements ModInitializer {
+
+ @Override
+ public void onInitialize() {
+ // This code runs as soon as Minecraft is in a mod-load-ready state.
+ // However, some things (like resources) may still be uninitialized.
+ // Proceed with mild caution.
+
+ TeleportCommands.LOGGER.info("Teleport Commands loaded! Hello Fabric!");
+
+ // initialize the mod
+ ServerLifecycleEvents.SERVER_STARTED.register((server) -> {
+ TeleportCommands.initializeMod(server, "Fabric");
+ });
+
+
+ // check if it is a player and check if the player died
+ ServerEntityEvents.ENTITY_UNLOAD.register((entity, world) -> {
+ if (entity instanceof ServerPlayer player) {
+ if (player.getRemovalReason() != null && (Objects.equals(player.getRemovalReason().toString(), "KILLED") || Objects.equals(player.getRemovalReason().toString(), "DISCARDED"))) {
+ TeleportCommands.onPlayerDeath(player);
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json
new file mode 100644
index 0000000..9a1b48b
--- /dev/null
+++ b/fabric/src/main/resources/fabric.mod.json
@@ -0,0 +1,41 @@
+{
+ "schemaVersion": 1,
+ "id": "${mod_id}",
+ "version": "${version}",
+ "name": "${mod_name}",
+ "description": "${description}",
+ "authors": [
+ "${mod_author}"
+ ],
+ "contact": {
+ "homepage": "https://mrsnowy.dev/",
+ "sources": "https://github.com/MrSn0wy/TeleportCommands",
+ "issues": "https://github.com/MrSn0wy/TeleportCommands/issues"
+ },
+ "license": "${license}",
+ "icon": "${mod_id}.png",
+ "environment": "*",
+ "entrypoints": {
+ "main": [
+ "dev.mrsnowy.teleport_commands.fabricInit"
+ ]
+ },
+ "custom": {
+ "modmenu": {
+ "links": {
+ "modmenu.modrinth": "https://modrinth.com/mod/teleport-commands",
+ "modmenu.kofi": "https://ko-fi.com/mr_snowy"
+ }
+ }
+ },
+ "depends": {
+ "fabricloader": ">=${fabric_loader_version}",
+ "fabric-api": "*",
+ "minecraft": "${minecraft_version}",
+ "java": ">=${java_version}"
+ },
+ "suggests": {
+ "another-mod": "*"
+ }
+}
+
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 9f586ee..a5f9d92 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,17 +1,29 @@
-# Done to increase the memory available to gradle.
-org.gradle.jvmargs=-Xmx2G
-org.gradle.parallel=true
+# Important Notes:
+# Every field you add must be added to the root build.gradle expandProps map.
-# Fabric Properties
-# check these on https://fabricmc.net/develop
+# Project
+version=1.0.5
+group=dev.mrsnowy.teleport_commands
+java_version=17
+
+# Common
minecraft_version=1.20.4
-yarn_mappings=1.20.4+build.3
-loader_version=0.15.9
+mod_name=Teleport Commands
+mod_author=Mr. Snowy
+mod_id=teleport_commands
+license=MIT
+credits=Mr. Snowy
+description=A server-side mod that adds various teleportation related commands.
+minecraft_version_range=[1.20.4, 1.21)
+
+# Fabric
+fabric_version=0.97.0+1.20.4
+fabric_loader_version=0.15.10
-# Mod Properties
-mod_version=1.0.2
-maven_group=dev.mrsnowy.teleport_commands
-archives_base_name=teleport_commands
+# NeoForge
+neoforge_version=20.4.234
+neoforge_loader_version_range=[2,)
-# Dependencies
-fabric_version=0.97.0+1.20.4
\ No newline at end of file
+# Gradle
+org.gradle.jvmargs=-Xmx3G
+org.gradle.daemon=false
\ No newline at end of file
diff --git a/neoforge/build.gradle b/neoforge/build.gradle
new file mode 100644
index 0000000..01d6588
--- /dev/null
+++ b/neoforge/build.gradle
@@ -0,0 +1,38 @@
+plugins {
+ id 'multiloader-loader'
+ id 'net.neoforged.gradle.userdev' version '7.0.107'
+}
+
+// Automatically enable neoforge AccessTransformers if the file exists
+// This location is hardcoded in FML and can not be changed.
+// https://github.com/neoforged/FancyModLoader/blob/a952595eaaddd571fbc53f43847680b00894e0c1/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java#L118
+def at = file('src/main/resources/META-INF/accesstransformer.cfg')
+if (at.exists()) {
+ minecraft.accessTransformers.file at
+}
+runs {
+ configureEach {
+ modSource project.sourceSets.main
+ }
+ client {
+ systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
+ }
+ server {
+ systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
+ programArgument '--nogui'
+ }
+
+ gameTestServer {
+ systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
+ }
+
+ data {
+ programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
+ }
+}
+
+sourceSets.main.resources { srcDir 'src/generated/resources' }
+
+dependencies {
+ implementation "net.neoforged:neoforge:${neoforge_version}"
+}
\ No newline at end of file
diff --git a/neoforge/src/main/java/dev/mrsnowy/teleport_commands/neoforgeInit.java b/neoforge/src/main/java/dev/mrsnowy/teleport_commands/neoforgeInit.java
new file mode 100644
index 0000000..5a95b2b
--- /dev/null
+++ b/neoforge/src/main/java/dev/mrsnowy/teleport_commands/neoforgeInit.java
@@ -0,0 +1,40 @@
+package dev.mrsnowy.teleport_commands;
+
+import net.neoforged.bus.api.EventPriority;
+import net.neoforged.bus.api.IEventBus;
+import net.neoforged.bus.api.SubscribeEvent;
+import net.neoforged.fml.common.Mod;
+import net.neoforged.neoforge.event.entity.living.LivingDeathEvent;
+import net.neoforged.neoforge.event.server.ServerStartingEvent;
+import net.minecraft.server.level.ServerPlayer;
+
+@Mod(TeleportCommands.MOD_ID)
+public class neoforgeInit {
+
+ public neoforgeInit(IEventBus eventBus) {
+ // This method is invoked by the NeoForge mod loader when it is ready
+ // to load your mod. You can access NeoForge and Common code in this
+ // project.
+
+ TeleportCommands.LOGGER.info("Teleport Commands loaded! Hello NeoForge!");
+ }
+
+ @Mod.EventBusSubscriber(modid = TeleportCommands.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
+ private static class NeoForgeEventSubscriber {
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ private static void onServerStarting(ServerStartingEvent event) {
+ // initialize the mod
+ TeleportCommands.initializeMod(event.getServer(), "NeoForge");
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ private static void onEntityUnload(LivingDeathEvent event) {
+ // check if it is a player
+ if (event.getEntity() instanceof ServerPlayer player) {
+ TeleportCommands.onPlayerDeath(player);
+ }
+ }
+ }
+}
+
diff --git a/neoforge/src/main/resources/META-INF/mods.toml b/neoforge/src/main/resources/META-INF/mods.toml
new file mode 100644
index 0000000..64284bb
--- /dev/null
+++ b/neoforge/src/main/resources/META-INF/mods.toml
@@ -0,0 +1,32 @@
+modLoader = "javafml" #mandatory
+loaderVersion = "${neoforge_loader_version_range}" #mandatory
+license = "${license}" # Review your options at https://choosealicense.com/.
+issueTrackerURL="https://github.com/MrSn0wy/TeleportCommands/issues" #optional
+[[mods]] #mandatory
+modId = "${mod_id}" #mandatory
+version = "${version}" #mandatory
+displayName = "${mod_name}" #mandatory
+#updateJSONURL="https://change.me.example.invalid/updates.json" #optional (see https://docs.neoforged.net/docs/misc/updatechecker/)
+displayURL="https://github.com/MrSn0wy/TeleportCommands" #optional (displayed in the mod UI)
+logoFile="${mod_id}.png" #optional
+credits="${credits}" #optional
+authors = "${mod_author}" #optional
+description = '''${description}''' #mandatory (Supports multiline text)
+[[dependencies.${mod_id}]] #optional
+modId = "neoforge" #mandatory
+type="required" #mandatory (Can be one of "required", "optional", "incompatible" or "discouraged")
+versionRange = "${neoforge_loader_version_range}" #mandatory
+ordering = "NONE" # The order that this dependency should load in relation to your mod, required to be either 'BEFORE' or 'AFTER' if the dependency is not mandatory
+side = "BOTH" # Side this dependency is applied on - 'BOTH', 'CLIENT' or 'SERVER'
+[[dependencies.${mod_id}]]
+modId = "minecraft"
+type="required" #mandatory (Can be one of "required", "optional", "incompatible" or "discouraged")
+versionRange = "${minecraft_version_range}"
+ordering = "NONE"
+side = "BOTH"
+
+# Features are specific properties of the game environment, that you may want to declare you require. This example declares
+# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
+# stop your mod loading on the server for example.
+#[features.${mod_id}]
+#openGLVersion="[3.2,)"
\ No newline at end of file
diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml
new file mode 100644
index 0000000..68c011c
--- /dev/null
+++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml
@@ -0,0 +1,32 @@
+modLoader = "javafml" #mandatory
+loaderVersion = "${neoforge_loader_version_range}" #mandatory
+license = "${license}" # Review your options at https://choosealicense.com/.
+#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
+[[mods]] #mandatory
+modId = "${mod_id}" #mandatory
+version = "${version}" #mandatory
+displayName = "${mod_name}" #mandatory
+#updateJSONURL="https://change.me.example.invalid/updates.json" #optional (see https://docs.neoforged.net/docs/misc/updatechecker/)
+#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional (displayed in the mod UI)
+logoFile="${mod_id}.png" #optional
+credits="${credits}" #optional
+authors = "${mod_author}" #optional
+description = '''${description}''' #mandatory (Supports multiline text)
+[[dependencies.${mod_id}]] #optional
+modId = "neoforge" #mandatory
+type="required" #mandatory (Can be one of "required", "optional", "incompatible" or "discouraged")
+versionRange = "${neoforge_loader_version_range}" #mandatory
+ordering = "NONE" # The order that this dependency should load in relation to your mod, required to be either 'BEFORE' or 'AFTER' if the dependency is not mandatory
+side = "BOTH" # Side this dependency is applied on - 'BOTH', 'CLIENT' or 'SERVER'
+[[dependencies.${mod_id}]]
+modId = "minecraft"
+type="required" #mandatory (Can be one of "required", "optional", "incompatible" or "discouraged")
+versionRange = "${minecraft_version_range}"
+ordering = "NONE"
+side = "BOTH"
+
+# Features are specific properties of the game environment, that you may want to declare you require. This example declares
+# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
+# stop your mod loading on the server for example.
+#[features.${mod_id}]
+#openGLVersion="[3.2,)"
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 75c4d72..0a54af6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,10 +1,52 @@
-pluginManagement {
- repositories {
- maven {
- name = 'Fabric'
- url = 'https://maven.fabricmc.net/'
- }
- mavenCentral()
- gradlePluginPortal()
- }
-}
\ No newline at end of file
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ mavenCentral()
+ exclusiveContent {
+ forRepository {
+ maven {
+ name = 'Fabric'
+ url = uri("https://maven.fabricmc.net")
+ }
+ }
+ filter {
+ includeGroup("net.fabricmc")
+ includeGroup("fabric-loom")
+ }
+ }
+ exclusiveContent {
+ forRepository {
+ maven {
+ name = 'NeoForge'
+ url = uri("https://maven.neoforged.net/releases")
+ }
+ }
+ filter {
+ includeGroupAndSubgroups("net.neoforged")
+ includeGroup("codechicken")
+ }
+ }
+ exclusiveContent {
+ forRepository {
+ maven {
+ name = 'Sponge Snapshots'
+ url = uri("https://repo.spongepowered.org/repository/maven-public")
+ }
+ }
+ filter {
+ includeGroupAndSubgroups("org.spongepowered")
+ includeGroup("net.minecraftforge")
+ }
+ }
+ }
+}
+
+plugins {
+ id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
+}
+
+// This should match the folder name of the project, or else IDEA may complain (see https://youtrack.jetbrains.com/issue/IDEA-317606)
+rootProject.name = 'MultiLoader-Template'
+include("common")
+include("fabric")
+include("neoforge")
diff --git a/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java b/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java
deleted file mode 100644
index 4f55378..0000000
--- a/src/main/java/dev/mrsnowy/teleport_commands/TeleportCommands.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package dev.mrsnowy.teleport_commands;
-
-import dev.mrsnowy.teleport_commands.storage.StorageManager;
-import dev.mrsnowy.teleport_commands.utils.commands;
-import net.fabricmc.api.ModInitializer;
-
-import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
-import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
-import net.fabricmc.loader.api.FabricLoader;
-import net.minecraft.entity.Entity;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.server.world.ServerWorld;
-import net.minecraft.util.WorldSavePath;
-import net.minecraft.world.World;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.nio.file.Path;
-import java.util.Objects;
-
-import static dev.mrsnowy.teleport_commands.utils.tools.DeathLocationUpdater;
-
-public class TeleportCommands implements ModInitializer {
- // This logger is used to write text to the console and the log file.
- // It is considered best practice to use your mod id as the logger's name.
- // That way, it's clear which mod wrote info, warnings, and errors.
- public static final String MOD_ID = "teleport_commands";
- public static final Logger LOGGER = LoggerFactory.getLogger("teleport_commands");
-
- public static Path SAVE_DIR;
- public static Path CONFIG_DIR;
- public static StorageManager Storage;
- public static MinecraftServer Server;
-
- @Override
- public void onInitialize() {
- // This code runs as soon as Minecraft is in a mod-load-ready state.
- // However, some things (like resources) may still be uninitialized.
- // Proceed with mild caution.
- ServerWorldEvents.LOAD.register(this::onWorldLoad);
-
- ServerEntityEvents.ENTITY_UNLOAD.register(this::onPlayerUnload);
-
- // todo: /back /tpa /tpahere /home /homes /sethome /delhome /renamehome /defaulthome /spawn /worldspawn
- commands.registerCommands();
- }
-
-
-
- private void onPlayerUnload(Entity entity, ServerWorld world) {
- if (entity instanceof ServerPlayerEntity player) {
-// LOGGER.info(String.valueOf(entity.getRemovalReason()));
- if (player.getRemovalReason() != null && (Objects.equals(player.getRemovalReason().toString(), "KILLED") || Objects.equals(player.getRemovalReason().toString(), "DISCARDED"))) {
- try {
- // /back command position
- LOGGER.info(player.getPos().toString());
- DeathLocationUpdater(player.getPos(), player.getServerWorld(), player.getUuidAsString());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
-
- private void onWorldLoad(MinecraftServer minecraftServer, ServerWorld serverWorld) {
- // make it run only once
- if (serverWorld.getRegistryKey() == World.OVERWORLD) {
- // initialize da variables
- SAVE_DIR = Path.of(String.valueOf(minecraftServer.getSavePath(WorldSavePath.ROOT)));
- CONFIG_DIR = FabricLoader.getInstance().getConfigDir();
-
- Server = minecraftServer;
- StorageManager.StorageInit();
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/dev/mrsnowy/teleport_commands/utils/commands.java b/src/main/java/dev/mrsnowy/teleport_commands/utils/commands.java
deleted file mode 100644
index 4bd8358..0000000
--- a/src/main/java/dev/mrsnowy/teleport_commands/utils/commands.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package dev.mrsnowy.teleport_commands.utils;
-
-import com.mojang.brigadier.arguments.StringArgumentType;
-import dev.mrsnowy.teleport_commands.TeleportCommands;
-import dev.mrsnowy.teleport_commands.suggestions.HomesuggestionProvider;
-import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
-import net.minecraft.command.argument.EntityArgumentType;
-import net.minecraft.server.command.CommandManager;
-import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.text.Text;
-import net.minecraft.util.Formatting;
-
-import javax.swing.text.html.parser.Entity;
-import java.util.Objects;
-
-import static net.minecraft.server.command.CommandManager.argument;
-import static net.minecraft.server.command.CommandManager.literal;
-
-public class commands {
- public static void registerCommands() {
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("back")
- .executes(context -> {
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
- try {
- player.sendMessage(Text.literal("Teleporting"), true);
- tools.ToDeathLocation(player);
- } catch (Exception e) {
- TeleportCommands.LOGGER.error(String.valueOf(e));
- player.sendMessage(Text.literal("Error Teleporting!").formatted(Formatting.RED, Formatting.BOLD), true);
- return 1;
- }
- return 0;
- })));
-
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("sethome")
- .then(argument("name", StringArgumentType.string())
- .executes(context -> {
- final String name = StringArgumentType.getString(context, "name");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- try {
- player.sendMessage(Text.literal("Home Set"), true);
- tools.SetHome(player, name);
-
- } catch (Exception e) {
- TeleportCommands.LOGGER.error(String.valueOf(e));
- player.sendMessage(Text.literal("Error Setting Home!").formatted(Formatting.RED, Formatting.BOLD), true);
- return 1;
- }
- return 0;
- }))));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("home")
- .executes(context -> {
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- try {
- player.sendMessage(Text.literal("Going Home"), true);
- tools.GoHome(player, "");
-
- } catch (Exception e) {
- TeleportCommands.LOGGER.error(String.valueOf(e));
- player.sendMessage(Text.literal("Error Going Home!").formatted(Formatting.RED, Formatting.BOLD), true);
- return 1;
- }
- return 0;
- })
- .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
- .executes(context -> {
- final String name = StringArgumentType.getString(context, "name");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- try {
- player.sendMessage(Text.literal("Going Home"), true);
- tools.GoHome(player, name);
-
- } catch (Exception e) {
- player.sendMessage(Text.literal("Error Going Home!").formatted(Formatting.RED, Formatting.BOLD), true);
- TeleportCommands.LOGGER.error(String.valueOf(e));
- return 1;
- }
- return 0;
- }))));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("delhome")
- .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
- .executes(context -> {
- final String name = StringArgumentType.getString(context, "name");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- try {
- player.sendMessage(Text.literal("Home Deleted"), true);
- tools.DeleteHome(player, name);
-
- } catch (Exception e) {
- TeleportCommands.LOGGER.error(String.valueOf(e));
- player.sendMessage(Text.literal("Error Deleting Home!").formatted(Formatting.RED, Formatting.BOLD), true);
- return 1;
- }
- return 0;
- }))));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("renamehome")
- .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
- .then(argument("newName", StringArgumentType.string())
- .executes(context -> {
- final String name = StringArgumentType.getString(context, "name");
- final String newName = StringArgumentType.getString(context, "newName");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- try {
- player.sendMessage(Text.literal("Home Renamed"), true);
- tools.RenameHome(player, name, newName);
- } catch (Exception e) {
- TeleportCommands.LOGGER.error(String.valueOf(e));
- player.sendMessage(Text.literal("Error Renaming Home!").formatted(Formatting.RED, Formatting.BOLD), true);
- return 1;
- }
- return 0;
- })))));
-
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("homes")
- .executes(context -> {
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
- try {
- tools.PrintHomes(player);
- } catch (Exception e) {
- TeleportCommands.LOGGER.error(String.valueOf(e));
- player.sendMessage(Text.literal("Error Getting Homes!").formatted(Formatting.RED, Formatting.BOLD), true);
- return 1;
- }
- return 0;
- })));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("defaulthome")
- .then(argument("name", StringArgumentType.string()).suggests(new HomesuggestionProvider())
- .executes(context -> {
- final String name = StringArgumentType.getString(context, "name");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
- try {
- tools.SetDefaultHome(player, name);
- } catch (Exception e) {
- TeleportCommands.LOGGER.error(String.valueOf(e));
- player.sendMessage(Text.literal("Error Changing Default Home!").formatted(Formatting.RED, Formatting.BOLD), true);
- return 1;
- }
- return 0;
- }))));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("tpa")
- .then(CommandManager.argument("player", EntityArgumentType.player())
- .executes(context -> {
- final ServerPlayerEntity TargetPlayer = EntityArgumentType.getPlayer(context, "player");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- tools.tpaCommandHandler(player, TargetPlayer, false);
- return 0;
- }))));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("tpahere")
- .then(CommandManager.argument("player", EntityArgumentType.player())
- .executes(context -> {
- final ServerPlayerEntity TargetPlayer = EntityArgumentType.getPlayer(context, "player");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- tools.tpaCommandHandler(player, TargetPlayer, true);
- return 0;
- }))));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("tpaaccept")
- .then(CommandManager.argument("player", EntityArgumentType.player())
- .executes(context -> {
- final ServerPlayerEntity TargetPlayer = EntityArgumentType.getPlayer(context, "player");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- tools.tpaAccept(player, TargetPlayer);
- return 0;
- }))));
-
- CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("tpadeny")
- .then(CommandManager.argument("player", EntityArgumentType.player())
- .executes(context -> {
- final ServerPlayerEntity TargetPlayer = EntityArgumentType.getPlayer(context, "player");
- ServerPlayerEntity player = Objects.requireNonNull(context.getSource().getPlayer());
-
- tools.tpaDeny(player, TargetPlayer);
- return 0;
- }))));
- }
-}
diff --git a/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java b/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java
deleted file mode 100644
index f9a1dbe..0000000
--- a/src/main/java/dev/mrsnowy/teleport_commands/utils/tools.java
+++ /dev/null
@@ -1,421 +0,0 @@
-package dev.mrsnowy.teleport_commands.utils;
-
-import net.fabricmc.fabric.api.dimension.v1.FabricDimensions;
-import net.minecraft.particle.ParticleTypes;
-import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.server.world.ServerWorld;
-import net.minecraft.sound.SoundCategory;
-import net.minecraft.sound.SoundEvent;
-import net.minecraft.text.ClickEvent;
-import net.minecraft.text.Text;
-import net.minecraft.util.Formatting;
-import net.minecraft.util.math.Vec3d;
-import net.minecraft.world.TeleportTarget;
-
-import java.util.*;
-
-import static dev.mrsnowy.teleport_commands.storage.StorageManager.*;
-import static net.minecraft.sound.SoundEvents.ENTITY_ENDERMAN_TELEPORT;
-
-public class tools {
- private static ArrayList tpaList = new ArrayList<>();
-
- private static class tpaArrayClass {
- private String InitPlayer;
- private String RecPlayer;
- private boolean here;
- }
-
- private static void Teleporter(ServerPlayerEntity player, ServerWorld world, Vec3d coords) {
- world.spawnParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() + 1, player.getZ(), 20, 0.0D, 0.0D, 0.0D, 0.01);
- world.spawnParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 1.0D, 0.0D, 0.03);
- world.playSound(null, player.getBlockPos(), SoundEvent.of(ENTITY_ENDERMAN_TELEPORT.getId()), SoundCategory.PLAYERS, 0.4f, 1.0f);
-
- FabricDimensions.teleport(player, world, new TeleportTarget(coords, Vec3d.ZERO, player.getYaw(), player.getPitch()));
-
- world.playSound(null, player.getBlockPos(), SoundEvent.of(ENTITY_ENDERMAN_TELEPORT.getId()), SoundCategory.PLAYERS, 0.4f, 1.0f);
- Timer timer = new Timer();
-
- timer.schedule(
- new TimerTask() {
- @Override
- public void run() {
- world.spawnParticles(ParticleTypes.SNOWFLAKE, player.getX(), player.getY() , player.getZ(), 20, 0.0D, 1.0D, 0.0D, 0.01);
- world.spawnParticles(ParticleTypes.WHITE_SMOKE, player.getX(), player.getY(), player.getZ(), 15, 0.0D, 0.0D, 0.0D, 0.03);
- }
- }, 100 // hopefully good, 2 ticks
- );
- }
-
-
- public static void SetHome(ServerPlayerEntity player, String homeName) throws Exception {
- homeName = homeName.toLowerCase();
- Vec3d pos = player.getPos();
- ServerWorld world = player.getServerWorld();
-
- PlayerStorageResult storages = GetPlayerStorage(player.getUuidAsString());
- StorageClass storage = storages.storage;
- StorageClass.Player playerStorage = storages.playerStorage;
-
- boolean homeNotFound = true;
-
- // check for duplicates
- for (StorageClass.Player.Home currentHome : playerStorage.Homes) {
- if (Objects.equals(currentHome.name, homeName)) {
- homeNotFound = false;
- break;
- }
- }
-
- if (homeNotFound) {
- // Create a new Home
- StorageClass.Player.Home homeLocation = new StorageClass.Player.Home();
-
- homeLocation.name = homeName;
- homeLocation.x = Double.parseDouble(String.format("%.1f", pos.getX()));
- homeLocation.y = Double.parseDouble(String.format("%.1f", pos.getY()));;
- homeLocation.z = Double.parseDouble(String.format("%.1f", pos.getZ()));;
- homeLocation.world = world.getRegistryKey().getValue().toString();
-
- playerStorage.Homes.add(homeLocation);
-
- if (playerStorage.Homes.size() == 1) {
- playerStorage.DefaultHome = homeName;
- }
-
- StorageSaver(storage);
- } else {
- player.sendMessage(Text.literal("Home Already Exists!"), true);
- }
- }
-
- public static void GoHome(ServerPlayerEntity player, String homeName) throws Exception {
- homeName = homeName.toLowerCase();
- StorageClass.Player playerStorage = GetPlayerStorage(player.getUuidAsString()).playerStorage;
-
- // check if there is a default exists
- if (homeName.isEmpty()) {
- if (playerStorage.DefaultHome.isEmpty()) {
- player.sendMessage(Text.literal("You Have No Homes!"), true);
- return;
- } else {
- homeName = playerStorage.DefaultHome;
- }
- }
-
- boolean foundHome = false;
- boolean foundWorld = false;
-
- // find correct home
- for (StorageClass.Player.Home currentHome : playerStorage.Homes) {
- if (Objects.equals(currentHome.name, homeName)){
- foundHome = true;
-
- // find correct world
- for (ServerWorld currentWorld : Objects.requireNonNull(player.getServer()).getWorlds()) {
- if (Objects.equals(currentWorld.getRegistryKey().getValue().toString(), currentHome.world)) {
- Teleporter(player, currentWorld, new Vec3d(currentHome.x, currentHome.y, currentHome.z));
- foundWorld = true;
- break;
- }
- }
- }
- }
-
- if (!foundHome) {
- player.sendMessage(Text.literal("Home Not Found!"), true);
- } else if (!foundWorld) {
- player.sendMessage(Text.literal("World Not Found!"), true);
- }
- }
-
- public static void DeleteHome(ServerPlayerEntity player, String homeName) throws Exception {
- homeName = homeName.toLowerCase();
- PlayerStorageResult storages = GetPlayerStorage(player.getUuidAsString());
- StorageClass storage = storages.storage;
- StorageClass.Player playerStorage = storages.playerStorage;
-
- StorageClass.Player.Home homeToDelete = null;
-
- // get correct home
- for (StorageClass.Player.Home currentHome : playerStorage.Homes) {
- if (Objects.equals(currentHome.name, homeName)){
- homeToDelete = currentHome;
- break;
- }
- }
-
- if (Objects.nonNull(homeToDelete)) {
- playerStorage.Homes.remove(homeToDelete);
- StorageSaver(storage);
- } else {
- player.sendMessage(Text.literal("Home Not Found!"), true);
- }
- }
-
- public static void RenameHome(ServerPlayerEntity player, String homeName, String newHomeName) throws Exception {
- homeName = homeName.toLowerCase();
- newHomeName = newHomeName.toLowerCase();
-
- PlayerStorageResult storages = GetPlayerStorage(player.getUuidAsString());
- StorageClass storage = storages.storage;
- StorageClass.Player playerStorage = storages.playerStorage;
-
- StorageClass.Player.Home homeToRename = null;
- boolean newNameNotFound = true;
-
- // check for duplicates
- for (StorageClass.Player.Home currentHome : playerStorage.Homes) {
- if (Objects.equals(currentHome.name, newHomeName)) {
- newNameNotFound = false;
- break;
- }
- }
-
- if (newNameNotFound) {
- // get correct home
- for (StorageClass.Player.Home currentHome : playerStorage.Homes) {
- if (Objects.equals(currentHome.name, homeName)){
- homeToRename = currentHome;
- break;
- }
- }
-
- if (Objects.nonNull(homeToRename)) {
- if (Objects.equals(playerStorage.DefaultHome, homeToRename.name)) {
- playerStorage.DefaultHome = newHomeName;
- }
-
- homeToRename.name = newHomeName;
- StorageSaver(storage);
- } else {
- player.sendMessage(Text.literal("Home Not Found!"), true);
- }
- } else {
- player.sendMessage(Text.literal("Home Already Exists!"), true);
- }
-
- }
-
- public static void PrintHomes(ServerPlayerEntity player) throws Exception {
- StorageClass.Player playerStorage = GetPlayerStorage(player.getUuidAsString()).playerStorage;
- boolean anyHomes = false;
-
- for (StorageClass.Player.Home currenthome : playerStorage.Homes) {
- if (!anyHomes) {
- player.sendMessage(Text.literal("Homes: \n").formatted(Formatting.YELLOW, Formatting.BOLD), false);
- anyHomes = true;
- }
-
- String name = String.format(" - %s", currenthome.name);
- String nameDefault = " (Default)";
-
-
- String coords = String.format(" [X%.1f Y%.1f Z%.1f]", currenthome.x, currenthome.y, currenthome.z);
- String dimension = String.format(" [%s]", currenthome.world);
-
- if (Objects.equals(currenthome.name, playerStorage.DefaultHome)) {
- player.sendMessage(Text.literal(name).formatted(Formatting.AQUA)
- .append(Text.literal(nameDefault).formatted(Formatting.AQUA, Formatting.BOLD)),
- false
- );
- } else {
- player.sendMessage(Text.literal(name).formatted(Formatting.AQUA), false);
- }
-
-
- player.sendMessage(Text.literal(" |").formatted(Formatting.AQUA)
- .append(Text.literal(coords).formatted(Formatting.LIGHT_PURPLE).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, String.format("X%.2f Y%.2f Z%.2f", currenthome.x, currenthome.y, currenthome.z)))))
- .append(Text.literal(dimension).formatted(Formatting.DARK_PURPLE).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, currenthome.world)))),
- false
- );
-
- player.sendMessage(Text.literal(" |").formatted(Formatting.AQUA)
- .append(Text.literal(" [Tp]").formatted(Formatting.GREEN).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/home %s", currenthome.name)))))
- .append(Text.literal(" [Rename]").formatted(Formatting.BLUE).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.format("/renamehome %s ", currenthome.name)))))
- .append(Text.literal(" [Delete]\n").formatted(Formatting.RED).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.format("/delhome %s", currenthome.name))))),
- false
- );
- }
-
- if (!anyHomes) {
- player.sendMessage(Text.literal("No homes set"), true);
- }
- }
-
- public static void SetDefaultHome(ServerPlayerEntity player, String homeName) throws Exception {
- homeName = homeName.toLowerCase();
- PlayerStorageResult storages = GetPlayerStorage(player.getUuidAsString());
- StorageClass storage = storages.storage;
- StorageClass.Player playerStorage = storages.playerStorage;
-
- boolean homeExists = false;
-
- // check if home exists
- for (StorageClass.Player.Home currentHome : playerStorage.Homes) {
- if (Objects.equals(currentHome.name, homeName)){
- homeExists = true;
- break;
- }
- }
-
- if (homeExists) {
- if (Objects.equals(playerStorage.DefaultHome, homeName)) {
- player.sendMessage(Text.literal("Home is already set as default!"), true);
-
- } else {
- playerStorage.DefaultHome = homeName;
- StorageSaver(storage);
- }
- } else {
- player.sendMessage(Text.literal("Home not found!"), true);
- }
- }
-
-
- public static void ToDeathLocation(ServerPlayerEntity player) throws Exception {
- StorageClass.Player playerStorage = GetPlayerStorage(player.getUuidAsString()).playerStorage;
-
- Vec3d pos = new Vec3d(playerStorage.deathLocation.x, playerStorage.deathLocation.y, playerStorage.deathLocation.z);
-
- boolean found = false;
- for (ServerWorld currentWorld : Objects.requireNonNull(player.getServer()).getWorlds()) {
- if (Objects.equals(currentWorld.getRegistryKey().getValue().toString(), playerStorage.deathLocation.world)) {
- Teleporter(player, currentWorld, pos);
- found = true;
- break;
- }
- }
-
- if (!found) {
- player.sendMessage(Text.literal("No Location Found!"), true);
- }
- }
-
- public static void tpaCommandHandler(ServerPlayerEntity FromPlayer, ServerPlayerEntity ToPlayer, boolean here) {
-
- if (FromPlayer == ToPlayer) {
- FromPlayer.sendMessage(Text.literal("Well, that was easy").formatted(Formatting.AQUA),true);
-
- } else {
- String ToMessage;
- String FromMessage;
-
- // Store da request
- tpaArrayClass tpaRequest = new tpaArrayClass();
- tpaRequest.InitPlayer = FromPlayer.getUuidAsString();
- tpaRequest.RecPlayer = ToPlayer.getUuidAsString();
- tpaRequest.here = here;
- tpaList.add(tpaRequest);
-
- if (here) {
- ToMessage = "TpaHere Request Received From ";
- FromMessage = "TpaHere Request Send to ";
-
- } else {
- ToMessage = "Tpa Request Received From ";
- FromMessage = "Tpa Request Send to ";
- }
-
- String ToPlayerString = Objects.requireNonNull(ToPlayer.getName().getLiteralString());
- String FromPlayerString = Objects.requireNonNull(FromPlayer.getName().getLiteralString());
-
- FromPlayer.sendMessage(Text.literal(FromMessage).formatted(Formatting.AQUA)
- .append(Text.literal(ToPlayerString).formatted(Formatting.AQUA, Formatting.BOLD))
-// .append(Text.literal("\n[Cancel]").formatted(Formatting.BLUE, Formatting.BOLD))
- ,true
- );
-
- ToPlayer.sendMessage(Text.literal(ToMessage).formatted(Formatting.AQUA)
- .append(Text.literal(FromPlayerString).formatted(Formatting.AQUA, Formatting.BOLD))
- .append(Text.literal("\n[Accept]").formatted(Formatting.GREEN, Formatting.BOLD).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/tpaaccept %s", FromPlayerString)))))
- .append(Text.literal(" [Deny]").formatted(Formatting.RED, Formatting.BOLD).styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/tpadeny %s", FromPlayerString))))),
- false
- );
-
- Timer timer = new Timer();
- timer.schedule(
- new TimerTask() {
- @Override
- public void run() {
- boolean successful = tpaList.remove(tpaRequest);
- if (successful) {
- if (here) {
- FromPlayer.sendMessage(Text.literal("TpaHere Request Expired").formatted(Formatting.AQUA),true);
- } else {
- FromPlayer.sendMessage(Text.literal("Tpa Request Expired").formatted(Formatting.AQUA),true);
- }
- }
- }
- }, 30 * 1000
- );
- }
- }
-
- public static void tpaAccept(ServerPlayerEntity FromPlayer, ServerPlayerEntity ToPlayer) {
- if (FromPlayer == ToPlayer) {
- FromPlayer.sendMessage(Text.literal("No").formatted(Formatting.AQUA),true);
- } else {
- Optional tpaStorage = tpaList.stream()
- .filter(tpa -> Objects.equals(ToPlayer.getUuidAsString(), tpa.InitPlayer))
- .filter(tpa -> Objects.equals(FromPlayer.getUuidAsString(), tpa.RecPlayer))
- .findFirst();
-
- if (tpaStorage.isPresent()) {
- if (tpaStorage.get().here) {
- FromPlayer.sendMessage(Text.literal("Teleporting"),true);
- ToPlayer.sendMessage(Text.literal("Request Accepted"),true);
-
- Teleporter(FromPlayer, ToPlayer.getServerWorld(), ToPlayer.getPos());
- } else {
- ToPlayer.sendMessage(Text.literal("Teleporting"),true);
- FromPlayer.sendMessage(Text.literal("Request Accepted"),true);
-
- Teleporter(ToPlayer, FromPlayer.getServerWorld(), FromPlayer.getPos());
- }
-
- tpaList.remove(tpaStorage.get());
- } else {
- FromPlayer.sendMessage(Text.literal("No Requests found!").formatted(Formatting.AQUA),true);
- }
- }
- }
-
- public static void tpaDeny(ServerPlayerEntity FromPlayer, ServerPlayerEntity ToPlayer) {
- if (FromPlayer == ToPlayer) {
- FromPlayer.sendMessage(Text.literal("No").formatted(Formatting.AQUA),true);
- } else {
- Optional tpaStorage = tpaList.stream()
- .filter(tpa -> Objects.equals(ToPlayer.getUuidAsString(), tpa.InitPlayer))
- .filter(tpa -> Objects.equals(FromPlayer.getUuidAsString(), tpa.RecPlayer))
- .findFirst();
-
- if (tpaStorage.isPresent()) {
- tpaList.remove(tpaStorage.get());
-
- if (tpaStorage.get().here) {
- ToPlayer.sendMessage(Text.literal("Request Denied").formatted(Formatting.AQUA),true);
- } else {
- FromPlayer.sendMessage(Text.literal("Request Denied").formatted(Formatting.AQUA),true);
- }
- } else {
- FromPlayer.sendMessage(Text.literal("No Requests found!").formatted(Formatting.AQUA),true);
- }
- }
- }
-
-
- public static void DeathLocationUpdater(Vec3d pos, ServerWorld world, String UUID) throws Exception {
- PlayerStorageResult storages = GetPlayerStorage(UUID);
-
- StorageClass storage = storages.storage;
- StorageClass.Player playerStorage = storages.playerStorage;
-
- playerStorage.deathLocation.x = Double.parseDouble(String.format("%.1f", pos.getX()));;
- playerStorage.deathLocation.y = Double.parseDouble(String.format("%.1f", pos.getY()));;
- playerStorage.deathLocation.z = Double.parseDouble(String.format("%.1f", pos.getZ()));;
- playerStorage.deathLocation.world = world.getRegistryKey().getValue().toString();
-
- StorageSaver(storage);
- }
-}
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
deleted file mode 100644
index d7af2c2..0000000
--- a/src/main/resources/fabric.mod.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "schemaVersion": 1,
- "id": "teleport_commands",
- "version": "${version}",
- "name": "Teleport Commands",
- "description": "A fabric server-side mod that adds various teleportation related commands",
- "authors": [
- "Mr. Snowy"
- ],
- "contact": {
- "homepage": "https://mrsnowy.dev/",
- "sources": "https://github.com/MrSn0wy/TeleportCommands",
- "issues": "https://github.com/MrSn0wy/TeleportCommands/issues"
- },
- "license": "MIT",
- "icon": "assets/teleport_commands/icon.png",
- "environment": "*",
- "entrypoints": {
- "main": [
- "dev.mrsnowy.teleport_commands.TeleportCommands"
- ]
- },
- "custom": {
- "modmenu": {
- "links": {
- "modmenu.modrinth": "https://modrinth.com/mod/teleport-commands",
- "modmenu.kofi": "https://ko-fi.com/mr_snowy"
- }
- }
- },
- "depends": {
- "fabricloader": ">=0.15.9",
- "minecraft": "~1.20.4",
- "java": ">=17",
- "fabric-api": ">=0.97.0"
- }
-}
\ No newline at end of file