Add persistent spawns. Persistent spawns now saved to disk.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package nl.getagripgal.persistentspawn;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.coordinates.Coordinates;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
/**
|
||||
* The command handlers for the mod.
|
||||
*/
|
||||
public class CommandHandlers {
|
||||
/**
|
||||
* The command handler for the `setpersistentspawn` command.
|
||||
*
|
||||
* @param context The command context.
|
||||
* @return The exit code.
|
||||
*/
|
||||
public static int setPersistentSpawn(CommandContext<CommandSourceStack> context) {
|
||||
Coordinates positionArgument = context.getArgument("position", Coordinates.class);
|
||||
Identifier dimensionArgument = context.getArgument("dimension", Identifier.class);
|
||||
|
||||
PersistentSpawnManager.CurrentSpawn = positionArgument.getPosition(context.getSource());
|
||||
PersistentSpawnManager.Dimension = ResourceKey.create(Registries.DIMENSION, dimensionArgument);
|
||||
|
||||
PersistentSpawnManager.syncToDisk();
|
||||
|
||||
Vec3 position = PersistentSpawnManager.CurrentSpawn;
|
||||
context.getSource()
|
||||
.sendSuccess(
|
||||
() -> Component.literal("Set spawn at %s in %s".formatted(position.toString(),
|
||||
dimensionArgument.toString())),
|
||||
false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The command handler for the `setpersistentspawnenabled` command.
|
||||
*
|
||||
* @param context The command context.
|
||||
* @return The exit code.
|
||||
*/
|
||||
public static int enablePersistentSpawn(CommandContext<CommandSourceStack> context) {
|
||||
boolean enable = context.getArgument("enable", Boolean.class);
|
||||
|
||||
PersistentSpawnManager.Enabled = enable;
|
||||
PersistentSpawnManager.syncToDisk();
|
||||
|
||||
if (!enable) {
|
||||
context.getSource()
|
||||
.sendSuccess(
|
||||
() -> Component.literal("Disabled persistent spawn."), false);
|
||||
return 1;
|
||||
}
|
||||
context.getSource()
|
||||
.sendSuccess(
|
||||
() -> Component.literal("Enabled persistent spawn."), false);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package nl.getagripgal.persistentspawn;
|
||||
|
||||
import java.util.Set;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
/**
|
||||
* The event handlers for the mod.
|
||||
*/
|
||||
public class EventHandlers {
|
||||
/**
|
||||
* The handler for the player join event.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
public static void onPlayerJoin(ServerPlayer player) {
|
||||
if (!PersistentSpawnManager.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerLevel level = (ServerLevel) player.level().getServer().getLevel(PersistentSpawnManager.Dimension);
|
||||
player.teleportTo(level, PersistentSpawnManager.CurrentSpawn.x, PersistentSpawnManager.CurrentSpawn.y,
|
||||
PersistentSpawnManager.CurrentSpawn.z, Set.of(), 0.0f, 0.0f, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package nl.getagripgal.persistentspawn;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.commands.arguments.DimensionArgument;
|
||||
import net.minecraft.commands.arguments.coordinates.Vec3Argument;
|
||||
import net.minecraft.server.permissions.Permissions;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
|
||||
/**
|
||||
* A very simple mod that implements the functionality of spawning a player at
|
||||
* the same location on every join.
|
||||
*/
|
||||
public class PersistentSpawn implements ModInitializer {
|
||||
public static final String MOD_ID = "spawnpointonjoin";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
registerCommands();
|
||||
registerEvents();
|
||||
PersistentSpawnManager.loadFromDisk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands.
|
||||
*/
|
||||
private void registerCommands() {
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher
|
||||
.register(Commands.literal("setpersistentspawn")
|
||||
.requires(source -> source.permissions().hasPermission(Permissions.COMMANDS_MODERATOR))
|
||||
.then(Commands.argument("position", Vec3Argument.vec3())
|
||||
.then(Commands.argument("dimension", DimensionArgument.dimension())
|
||||
.executes(CommandHandlers::setPersistentSpawn)))));
|
||||
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher
|
||||
.register(Commands.literal("setpersistentspawnenabled")
|
||||
.requires(source -> source.permissions().hasPermission(Permissions.COMMANDS_MODERATOR))
|
||||
.then(Commands.argument("enable", BoolArgumentType.bool())
|
||||
.executes(CommandHandlers::enablePersistentSpawn))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the events.
|
||||
*/
|
||||
private void registerEvents() {
|
||||
ServerPlayerEvents.JOIN.register(EventHandlers::onPlayerJoin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package nl.getagripgal.persistentspawn;
|
||||
|
||||
/**
|
||||
* The spawn config as stored on disk.
|
||||
*/
|
||||
public class PersistentSpawnConfig {
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
public String dimension;
|
||||
public boolean enabled;
|
||||
|
||||
public static PersistentSpawnConfig defaultConfig() {
|
||||
PersistentSpawnConfig config = new PersistentSpawnConfig();
|
||||
config.x = 0;
|
||||
config.y = 100;
|
||||
config.z = 0;
|
||||
config.dimension = "minecraft:overworld";
|
||||
config.enabled = false;
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package nl.getagripgal.persistentspawn;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.moandjiezana.toml.Toml;
|
||||
import com.moandjiezana.toml.TomlWriter;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
/**
|
||||
* Manages the persistent spawn point.
|
||||
*/
|
||||
public class PersistentSpawnManager {
|
||||
/**
|
||||
* The config file path.
|
||||
*/
|
||||
public static final String CONFIG_FILE = "config/spawnpointonjoin.toml";
|
||||
|
||||
/**
|
||||
* The currently registered spawn position.
|
||||
*/
|
||||
public static Vec3 CurrentSpawn = Vec3.ZERO;
|
||||
|
||||
/**
|
||||
* The dimension of the spawn location.
|
||||
*/
|
||||
public static ResourceKey<Level> Dimension = null;
|
||||
|
||||
/**
|
||||
* Whether the persistent spawn is enabled.
|
||||
*/
|
||||
public static boolean Enabled = false;
|
||||
|
||||
/**
|
||||
* Load the spawn config from disk.
|
||||
*/
|
||||
public static void loadFromDisk() {
|
||||
try {
|
||||
Toml toml = new Toml().read(new File(CONFIG_FILE));
|
||||
PersistentSpawnConfig config = toml.to(PersistentSpawnConfig.class);
|
||||
|
||||
CurrentSpawn = new Vec3(config.x, config.y, config.z);
|
||||
Dimension = ResourceKey.create(Registries.DIMENSION, Identifier.parse(config.dimension));
|
||||
Enabled = config.enabled;
|
||||
} catch (Exception e) {
|
||||
PersistentSpawn.LOGGER.error(
|
||||
"Failed to load persistent spawn config from disk, using defaults. This means persistent spawn will be disabled.",
|
||||
e);
|
||||
PersistentSpawnConfig defaultConfig = PersistentSpawnConfig.defaultConfig();
|
||||
CurrentSpawn = new Vec3(defaultConfig.x, defaultConfig.y, defaultConfig.z);
|
||||
Dimension = ResourceKey.create(Registries.DIMENSION, Identifier.parse(defaultConfig.dimension));
|
||||
Enabled = defaultConfig.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the current spawn config to spawn.
|
||||
*/
|
||||
public static void syncToDisk() {
|
||||
try {
|
||||
PersistentSpawnConfig config = new PersistentSpawnConfig();
|
||||
config.x = (int) CurrentSpawn.x;
|
||||
config.y = (int) CurrentSpawn.y;
|
||||
config.z = (int) CurrentSpawn.z;
|
||||
config.dimension = Dimension.identifier().toString();
|
||||
config.enabled = Enabled;
|
||||
|
||||
TomlWriter writer = new TomlWriter();
|
||||
writer.write(config, new File(CONFIG_FILE));
|
||||
} catch (Exception e) {
|
||||
PersistentSpawn.LOGGER.error("Failed to save persistent spawn config to disk.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 200 B |
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "spawnpointonjoin",
|
||||
"version": "1.0.0",
|
||||
"name": "SpawnpointOnJoin",
|
||||
"description": "A very simple mod that implements the functionality of spawning a player at the same location on every join.",
|
||||
"authors": [
|
||||
"GetAGripGal"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://fabricmc.net/",
|
||||
"sources": "https://github.com/FabricMC/fabric-example-mod"
|
||||
},
|
||||
"license": "CC0-1.0",
|
||||
"icon": "assets/spawnpointonjoin/icon.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"nl.getagripgal.persistentspawn.PersistentSpawn"
|
||||
],
|
||||
"client": []
|
||||
},
|
||||
"mixins": [],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.18.4",
|
||||
"minecraft": "~1.21.11",
|
||||
"java": ">=21",
|
||||
"fabric-api": "*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "nl.getagripgal.persistentspawn.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"overwrites": {
|
||||
"requireAnnotations": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user