Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fa59a78
fix(tpll): 🐛 don't call api on a single world / server setup
Zoriot Jul 30, 2025
b91e05f
refactor(tpll): ♻️ improve error handling + reformat code
Zoriot Aug 20, 2025
1ff5eb2
fix(tpll): 🐛 correct coordinate order in projection and improve heigh…
Zoriot Oct 20, 2025
8f0cb13
fix(tpll): apply correct offset, use improved parsing, use terra gen …
Zoriot Nov 2, 2025
81553fe
fix(tpll): 🐛 enhance argument parsing for teleport command and improv…
Zoriot Nov 30, 2025
9b5d7cf
fix(tpll): 🐛 remove unnecessary player validation message in teleport…
Zoriot Nov 30, 2025
c2258d6
fix(tpll): 🐛 add confirmation message for successful teleport command…
Zoriot Nov 30, 2025
8bae2fc
fix(tpll): 🐛 reorder command argument structure to improve execution …
Zoriot Dec 1, 2025
18638cc
fix(tpll): 🐛 refactor argument parsing in teleport command for improv…
Zoriot Dec 8, 2025
a850c64
fix(tpll): 🐛 add detailed documentation for /tpll command and refacto…
Zoriot Dec 8, 2025
89362a6
fix(tpll): 🐛 improve command usage messages and refactor coordinate p…
Zoriot Dec 9, 2025
48fe0c0
refactor(tpll): ♻️ Simplify the logic quite a lot
Zoriot Dec 23, 2025
7da4b06
feat(tpll): ✨ add connected mode configuration for SonarQube integration
Zoriot Dec 24, 2025
2a6493f
refactor: ♻️ Change config calls to getConfig and add Property class
Zoriot Dec 25, 2025
6a999d9
fix(tpll): 🐛 Fix getting proxy configured server
Zoriot Dec 25, 2025
2b9d0da
fix(tpll): implement asynchronous height fetching logic
Zoriot Dec 28, 2025
a99c050
fix(tpll): fix build #sorry
Zoriot Dec 28, 2025
22013f2
fix(tpll): improve player join handling and linked worlds configuration
Zoriot Dec 30, 2025
71d9fb3
fix(tpll): update teleportation logic to handle height fetching and l…
Zoriot Dec 30, 2025
3452d0f
fix(tpll): refactor linked worlds handling to dynamically fetch from …
Zoriot Dec 30, 2025
2b8cfde
fix(tpll): enhance configuration handling and improve linked worlds l…
Zoriot Dec 30, 2025
00344c6
fix(tpll): add permission based tpll for other worlds
Zoriot Dec 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .sonarlint/connectedMode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"sonarQubeUri": "https://sonarqube.app.k8s.bteger.dev",
"projectKey": "BTE-Germany_TerraPlusMinus_776220d7-94a3-47ab-a1af-0f299952ab48"
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>de.btegermany</groupId>
<artifactId>terraplusminus</artifactId>
<version>1.5.1</version>
<version>1.6.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Terraplusminus</name>
Expand Down
103 changes: 66 additions & 37 deletions src/main/java/de/btegermany/terraplusminus/Terraplusminus.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@
import de.btegermany.terraplusminus.commands.OffsetCommand;
import de.btegermany.terraplusminus.commands.TpllCommand;
import de.btegermany.terraplusminus.commands.WhereCommand;
import de.btegermany.terraplusminus.events.PlayerCommandPreprocessEvent;
import de.btegermany.terraplusminus.events.PlayerJoinEvent;
import de.btegermany.terraplusminus.events.PlayerMoveEvent;
import de.btegermany.terraplusminus.events.PluginMessageEvent;
import de.btegermany.terraplusminus.gen.RealWorldGenerator;
import de.btegermany.terraplusminus.utils.ConfigurationHelper;
import de.btegermany.terraplusminus.utils.PluginConfigManipulator;
import de.btegermany.terraplusminus.utils.LinkedWorld;
import de.btegermany.terraplusminus.utils.PlayerHashMapManagement;
import de.btegermany.terraplusminus.utils.FolderMigrator;
import de.btegermany.terraplusminus.utils.*;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.plugin.configuration.PluginMeta;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
import lombok.Getter;
import lombok.Setter;
import net.buildtheearth.terraminusminus.TerraConfig;
import net.buildtheearth.terraminusminus.TerraConstants;
import net.buildtheearth.terraminusminus.util.http.Disk;
Expand All @@ -33,6 +32,7 @@
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.io.*;
Expand All @@ -44,9 +44,22 @@
import static net.daporkchop.lib.common.util.PValidation.checkState;

public final class Terraplusminus extends JavaPlugin implements Listener {
/**
* @deprecated Static Fields should not be used, because else config reloads won't work properly.
* We'll rework the whole config system in a future update to make it more robust. Maybe switching to configurate.
*/
@Deprecated(since = "1.6.0", forRemoval = true)
public static FileConfiguration config;
/**
* @deprecated We'll switch to basic dependency injection from now on. Static Fields should not be used.
*/
@Deprecated(since = "1.6.0", forRemoval = true)
public static Terraplusminus instance;

@Getter
@Setter
private String registeredServerName = null;

@Override
public void onEnable() {
new Metrics(this, 28392); // https://bstats.org/plugin/bukkit/Terraplusminus/28392
Expand All @@ -68,20 +81,34 @@ public void onEnable() {
// Register plugin messaging channel
PlayerHashMapManagement playerHashMapManagement = new PlayerHashMapManagement();
this.getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:terraplusminus");
this.getServer().getMessenger().registerIncomingPluginChannel(this, "bungeecord:terraplusminus", new PluginMessageEvent(playerHashMapManagement));
PluginMessageEvent pluginMessageListener = new PluginMessageEvent(playerHashMapManagement, this);
this.getServer().getMessenger().registerIncomingPluginChannel(this, "bungeecord:terraplusminus", pluginMessageListener);

// Linked Server current server initialization
if (getConfig().getBoolean(Properties.LINKED_WORLDS_ENABLED) && getConfig().getString(Properties.LINKED_WORLDS_METHOD, "").equalsIgnoreCase("SERVER")) {
this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
this.getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", pluginMessageListener);
getComponentLogger().debug("Linked server initialization successful");
}
// --------------------------

// Registering events
Bukkit.getPluginManager().registerEvents(this, this);
if (Terraplusminus.config.getBoolean("height_in_actionbar")) {
if (getConfig().getBoolean("height_in_actionbar") ||
(getConfig().getBoolean(Properties.LINKED_WORLDS_ENABLED) && getConfig().getString(Properties.LINKED_WORLDS_METHOD, "").equalsIgnoreCase("MULTIVERSE"))) {
Bukkit.getPluginManager().registerEvents(new PlayerMoveEvent(this), this);
}
if (Terraplusminus.config.getBoolean("linked_worlds.enabled")) {
Bukkit.getPluginManager().registerEvents(new PlayerJoinEvent(playerHashMapManagement), this);
if (getConfig().getBoolean(Properties.LINKED_WORLDS_ENABLED)) {
Bukkit.getPluginManager().registerEvents(new PlayerJoinEvent(playerHashMapManagement, this), this);
}

String passthroughTpll = getConfig().getString(Properties.PASSTHROUGH_TPLL);
if (passthroughTpll != null && !passthroughTpll.isEmpty()) {
Bukkit.getPluginManager().registerEvents(new PlayerCommandPreprocessEvent(passthroughTpll), this);
}
// --------------------------

TerraConfig.reducedConsoleMessages = Terraplusminus.config.getBoolean("reduced_console_messages"); // Disables console log of fetching data
TerraConfig.reducedConsoleMessages = getConfig().getBoolean("reduced_console_messages"); // Disables console log of fetching data

registerCommands();

Expand All @@ -102,9 +129,9 @@ public void onDisable() {
}

@EventHandler
public void onWorldInit(WorldInitEvent event) {
public void onWorldInit(@NotNull WorldInitEvent event) {
World world = event.getWorld();
boolean shouldInstallHeightDatapack = Terraplusminus.config.getBoolean("height_datapack");
boolean shouldInstallHeightDatapack = getConfig().getBoolean(Properties.HEIGHT_DATAPACK);
boolean isDefaultWorld = Bukkit.getWorlds().getFirst().getUID().equals(world.getUID());
if (shouldInstallHeightDatapack && isDefaultWorld) {
// Datapacks should be installed in the default world and will apply to all of them.
Expand All @@ -114,24 +141,26 @@ public void onWorldInit(WorldInitEvent event) {
}


@Contract("_, _ -> new")
@Override
public ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, String id) {
public @NotNull ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, String id) {
// Multiverse different y-offset support
int yOffset = 0;
if (Terraplusminus.config.getBoolean("linked_worlds.enabled") && Terraplusminus.config.getString("linked_worlds.method").equalsIgnoreCase("MULTIVERSE")) {
if (getConfig().getBoolean(Properties.LINKED_WORLDS_ENABLED)
&& getConfig().getString(Properties.LINKED_WORLDS_METHOD, "").equalsIgnoreCase(Properties.NonConfigurable.METHOD_MV)) {
for (LinkedWorld world : ConfigurationHelper.getWorlds()) {
if (world.getWorldName().equalsIgnoreCase(worldName)) {
yOffset = world.getOffset();
}
}
} else {
yOffset = Terraplusminus.config.getInt("y_offset");
yOffset = getConfig().getInt(Properties.Y_OFFSET);
}
return new RealWorldGenerator(yOffset);
return new RealWorldGenerator(yOffset, this);
}


public void enforceDatapackInstallation(String datapackResourcePath, World world) {
public void enforceDatapackInstallation(String datapackResourcePath, @NotNull World world) {
String datapackName = Path.of(datapackResourcePath).getFileName().toString();
File droppedFile = world
.getWorldFolder().toPath()
Expand Down Expand Up @@ -159,24 +188,26 @@ public void enforceDatapackInstallation(String datapackResourcePath, World world
Bukkit.getServer().shutdown();
}

/**
* @deprecated We'll rework the whole config system in a future update to make it more robust. Maybe switching to configurate.
* The current system has some flaws like only can update one config version at a time and is generally hard to maintain.
*/
@Deprecated(since = "1.6.0", forRemoval = true)
private void updateConfig() {
PluginConfigManipulator manipulator = new PluginConfigManipulator(this);

double configVersion = Terraplusminus.config.getDouble("config_version");
double configVersion = getConfig().getDouble("config_version");

if (configVersion == 0.0) { // That's the default value if the field was not set at all in the YAML
this.getComponentLogger().error("Old config detected. Please delete and restart/reload.");
}
if (configVersion == 1.0) {
String passthroughTpll = Terraplusminus.config.getString("passthrough_tpll");
if (passthroughTpll == null) {
passthroughTpll = "";
}
int y = (int) Terraplusminus.config.getDouble("terrain_offset");
Terraplusminus.config.set("terrain_offset.x", 0);
Terraplusminus.config.set("terrain_offset.y", y);
Terraplusminus.config.set("terrain_offset.z", 0);
Terraplusminus.config.set("config_version", 1.1);
String passthroughTpll = getConfig().getString(Properties.PASSTHROUGH_TPLL, "");
int y = (int) getConfig().getDouble("terrain_offset");
getConfig().set("terrain_offset.x", 0);
getConfig().set("terrain_offset.y", y);
getConfig().set("terrain_offset.z", 0);
getConfig().set("config_version", 1.1);
this.saveConfig();
manipulator.addLineAbove(
"terrain_offset",
Expand All @@ -198,7 +229,7 @@ private void updateConfig() {

}
if (configVersion == 1.1) {
Terraplusminus.config.set("config_version", 1.2);
getConfig().set("config_version", 1.2);
this.saveConfig();
manipulator.addLineAbove(
"# If disabled, tree generation is turned off.",
Expand All @@ -215,7 +246,7 @@ private void updateConfig() {
);
}
if (configVersion == 1.2) {
Terraplusminus.config.set("config_version", 1.3);
getConfig().set("config_version", 1.3);
this.saveConfig();
manipulator.deleteLine("# Linked servers -------------------------------------");
manipulator.deleteLine("# If the height limit on this server is not enough, other servers can be linked to generate higher or lower sections");
Expand All @@ -241,7 +272,7 @@ private void updateConfig() {
);
}
if (configVersion == 1.3) {
Terraplusminus.config.set("config_version", 1.4);
getConfig().set("config_version", 1.4);
this.saveConfig();
manipulator.addLineBelow(
"prefix:",
Expand All @@ -265,9 +296,9 @@ private void updateConfig() {
""");
}
if (configVersion == 1.4) {
Terraplusminus.config.set("config_version", 1.5);
getConfig().set("config_version", 1.5);
this.saveConfig();
boolean differentBiomes = Terraplusminus.config.getBoolean("different_biomes");
boolean differentBiomes = getConfig().getBoolean("different_biomes");
manipulator.deleteLine("# The biomes will be generated with https://en.wikipedia.org/wiki/K%C3%B6ppen_climate_classification.");
manipulator.deleteLine("# If turned off, everything will be plains biome.");
manipulator.deleteLine("different_biomes:");
Expand All @@ -290,7 +321,7 @@ private void registerCommands() {
LifecycleEventManager<Plugin> manager = this.getLifecycleManager();
manager.registerEventHandler(LifecycleEvents.COMMANDS, event -> {
final Commands commands = event.registrar();
commands.register("tpll", "Teleports you to longitude and latitude", List.of("tpc"), new TpllCommand());
commands.register(TpllCommand.create(), "tpll", List.of("tpc"));
commands.register("where", "Gives you the longitude and latitude of your minecraft coordinates", new WhereCommand());
commands.register("offset", "Displays the x,y and z offset of your world", new OffsetCommand());
});
Expand All @@ -306,14 +337,12 @@ private void setupTerraMinusMinus() {
Http.userAgent(userAgent);
}

// The old way is deprecated and the new one is experimental, let's go with the new one
private String getVersion() {
private @NotNull String getVersion() {
PluginMeta meta = this.getPluginMeta();
return meta.getVersion();
}

// This method has to rely on the unstable paper API as we use paper-plugin.yml, which itself is experimental
private String createHttpUserAgent() {
private @NotNull String createHttpUserAgent() {
PluginMeta metadata = this.getPluginMeta();
return format(Locale.ENGLISH, "%s/%s (%s/%s; +%s)",
metadata.getName(),
Expand Down
Loading