Translation support

This commit is contained in:
dfsek 2020-10-07 02:46:44 -07:00
parent c107f98550
commit 68863241da
41 changed files with 272 additions and 109 deletions

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.async;
import com.dfsek.terra.Terra;
import com.dfsek.terra.biome.TerraBiomeGrid;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -51,13 +52,13 @@ public class AsyncBiomeFinder implements Runnable {
toggle = !toggle;
}
if(checkBiome(x, z).equals(target) && p.isOnline()) {
p.sendMessage("Located biome at (" + x + ", " + z + ").");
LangUtil.send("command.biome.biome-found", p, String.valueOf(x), String.valueOf(z));
if(tp) {
int finalX = x;
int finalZ = z;
Bukkit.getScheduler().runTask(Terra.getInstance(), () -> p.teleport(new Location(p.getWorld(), finalX, p.getLocation().getY(), finalZ)));
}
} else if(p.isOnline()) p.sendMessage("Unable to locate biome.");
} else if(p.isOnline()) LangUtil.send("command.biome.unable-to-locate", p);
}
private Biome checkBiome(int x, int z) {

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.biome;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.base.ConfigUtil;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.procgen.math.Vector2;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -12,6 +13,7 @@ import org.polydev.gaea.generation.GenerationPhase;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
public class TerraBiomeGrid extends BiomeGrid {
private static int failNum = 0;
@ -48,7 +50,7 @@ public class TerraBiomeGrid extends BiomeGrid {
b = (UserDefinedBiome) zone.getGrid(xp, zp).getBiome(xp, zp, phase);
} catch(NullPointerException e) {
if(ConfigUtil.debug) e.printStackTrace();
if(failNum % 256 == 0) Bukkit.getLogger().severe("[Terra] A severe configuration error has prevented Terra from properly generating terrain at coordinates: " + x + ", " + z + ". Please check your configuration for errors. Any config errors will have been reported above.");
if(failNum % 256 == 0) LangUtil.log("error.severe-config", Level.SEVERE, String.valueOf(x), String.valueOf(z));
failNum++;
return null;
}

View File

@ -5,6 +5,7 @@ import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.base.WorldConfig;
import com.dfsek.terra.config.genconfig.OreConfig;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
@ -23,17 +24,16 @@ public class OreCommand extends WorldCommand {
if(args.length > 0) {
OreConfig ore = TerraWorld.getWorld(w).getConfig().getOre(args[0]);
if(ore == null) {
sender.sendMessage("Unable to find Ore");
LangUtil.send("command.ore.invalid-ore", sender, args[0]);
return true;
}
if(bl == null) {
sender.sendMessage("Block out of range");
LangUtil.send("command.ore.out-of-range", sender);
return true;
}
ore.doVein(bl.getLocation(), new Random());
} else {
sender.sendMessage("---------------Terra/ore---------------");
sender.sendMessage("Generates a vein of ore at the block you are looking at.");
LangUtil.send("command.ore.main-menu", sender);
}
return true;
}

View File

@ -3,6 +3,7 @@ package com.dfsek.terra.command;
import com.dfsek.terra.Terra;
import com.dfsek.terra.command.type.Command;
import com.dfsek.terra.config.base.ConfigUtil;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@ -23,7 +24,7 @@ public class ReloadCommand extends Command {
@Override
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
ConfigUtil.loadConfig(Terra.getInstance());
sender.sendMessage("Reloaded Terra config.");
LangUtil.send("command.reload", sender);
return true;
}

View File

@ -1,6 +1,8 @@
package com.dfsek.terra.command;
import com.dfsek.terra.command.type.Command;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.generation.TerraChunkGenerator;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
@ -10,16 +12,16 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class SaveDataCommand extends Command {
public class SaveDataCommand extends WorldCommand {
@Override
public String getName() {
return "save-data";
}
@Override
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
public boolean execute(@NotNull Player sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
TerraChunkGenerator.saveAll();
sender.sendMessage("Saved population data.");
LangUtil.send("debug.data-save", sender, w.getName());
return true;
}

View File

@ -6,6 +6,7 @@ import com.dfsek.terra.command.image.ImageCommand;
import com.dfsek.terra.command.profile.ProfileCommand;
import com.dfsek.terra.command.structure.StructureCommand;
import com.dfsek.terra.command.type.Command;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@ -35,13 +36,7 @@ public class TerraCommand extends Command {
@Override
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
sender.sendMessage("--------------------Terra--------------------");
sender.sendMessage("reload - Reload configuration data");
sender.sendMessage("biome - Get current biome");
sender.sendMessage("ore - Generate an ore vein at the location you are facing (For debugging)");
sender.sendMessage("save-data - Save population data");
sender.sendMessage("structure - Load and export structures");
sender.sendMessage("profile - Profiler options");
LangUtil.send("command.main-menu", sender);
return true;
}

View File

@ -4,6 +4,7 @@ import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.biome.TerraBiomeGrid;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -20,7 +21,7 @@ public class BiomeCommand extends WorldCommand {
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
TerraBiomeGrid grid = TerraWorld.getWorld(sender.getWorld()).getGrid();
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome(sender.getLocation(), GenerationPhase.POPULATE);
sender.sendMessage("You are in " + TerraWorld.getWorld(w).getConfig().getBiome(biome).getID());
LangUtil.send("command.biome.in", sender, TerraWorld.getWorld(w).getConfig().getBiome(biome).getID());
return true;
}

View File

@ -5,6 +5,7 @@ import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.async.AsyncBiomeFinder;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.generation.TerraChunkGenerator;
import org.bukkit.Bukkit;
import org.bukkit.World;
@ -30,14 +31,14 @@ public class BiomeLocateCommand extends WorldCommand {
try {
maxRadius = Integer.parseInt(args[1]);
} catch(NumberFormatException e) {
sender.sendMessage("Invalid radius: " + args[1]);
LangUtil.send("command.biome.invalid-radius", sender, args[1]);
return true;
}
UserDefinedBiome b;
try {
b = TerraWorld.getWorld(world).getConfig().getBiome(id).getBiome();
} catch(IllegalArgumentException | NullPointerException e) {
sender.sendMessage("Invalid biome ID: " + id);
LangUtil.send("command.biome.invalid", sender, id);
return true;
}
Bukkit.getScheduler().runTaskAsynchronously(Terra.getInstance(), new AsyncBiomeFinder(TerraWorld.getWorld(world).getGrid(), b, sender, 0, maxRadius, tp));

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.geometry;
import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.procgen.voxel.DeformedSphere;
import com.dfsek.terra.procgen.voxel.Sphere;
import org.bukkit.Material;
@ -21,14 +22,14 @@ public class DeformedSphereCommand extends PlayerCommand {
try {
radius = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
sender.sendMessage("Invalid radius: " + args[0]);
LangUtil.send("command.geometry.deform.invalid-radius", sender, args[0]);
return true;
}
double deform;
try {
deform = Double.parseDouble(args[1]);
} catch(NumberFormatException e) {
sender.sendMessage("Invalid deform: " + args[1]);
LangUtil.send("command.geometry.deform.invalid-deform", sender, args[1]);
return true;
}
@ -36,7 +37,7 @@ public class DeformedSphereCommand extends PlayerCommand {
try {
freq = Float.parseFloat(args[2]);
} catch(NumberFormatException e) {
sender.sendMessage("Invalid frequency: " + args[2]);
LangUtil.send("command.geometry.deform.invalid-frequency", sender, args[2]);
return true;
}
FastNoise n = new FastNoise((int) sender.getWorld().getSeed());

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.geometry;
import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -13,11 +14,7 @@ import java.util.List;
public class GeometryCommand extends PlayerCommand {
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
sender.sendMessage("---------------Terra/geometry----------------");
sender.sendMessage("Various voxel geometry debugging commands");
sender.sendMessage("sphere - Generate a sphere");
sender.sendMessage("deformsphere - Generate a deformed sphere");
sender.sendMessage("tube - Generate a tube");
LangUtil.send("command.geometry.main-menu", sender);
return true;
}

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.geometry;
import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.procgen.voxel.Sphere;
import org.bukkit.Material;
import org.bukkit.command.Command;
@ -19,7 +20,7 @@ public class SphereCommand extends PlayerCommand {
try {
radius = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
sender.sendMessage("Invalid radius: " + args[0]);
LangUtil.send("command.geometry.sphere.invalid-radius", sender, args[0]);
return true;
}
Sphere sphere = new Sphere(sender.getLocation().toVector(), radius);

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.command.geometry;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.util.structure.WorldEditUtil;
import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.procgen.voxel.Tube;
@ -23,7 +24,7 @@ public class TubeCommand extends PlayerCommand {
try {
radius = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
sender.sendMessage("Invalid radius: " + args[0]);
LangUtil.send("command.geometry.tube.invalid-radius", sender, args[0]);
return true;
}
Tube tube = new Tube(l[0].toVector(), l[1].toVector(), radius);

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.command.image;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.command.image.gui.GUICommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -15,9 +16,7 @@ import java.util.List;
public class ImageCommand extends WorldCommand {
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
sender.sendMessage("---------------Terra/image---------------");
sender.sendMessage("render - Render an image with a given width and height, that can later be imported as a world.");
sender.sendMessage("gui - Open debug GUI (Must be enabled in config)");
LangUtil.send("command.image.main-menu", sender);
return true;
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.command.image;
import com.dfsek.terra.Terra;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.image.WorldImageGenerator;
import org.bukkit.World;
import org.bukkit.command.Command;
@ -23,11 +24,11 @@ public class RenderCommand extends WorldCommand {
file.mkdirs();
file.createNewFile();
g.save(file);
sender.sendMessage("Saved image to " + file.getPath());
LangUtil.send("command.image.render.save", sender, file.getAbsolutePath());
return true;
} catch(Exception e) {
e.printStackTrace();
sender.sendMessage("An error occurred while generating the image!");
LangUtil.send("command.image.render.error", sender);
return true;
}
}

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.image.gui;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -14,9 +15,7 @@ import java.util.List;
public class GUICommand extends WorldCommand {
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
sender.sendMessage("-------------Terra/image/gui-------------");
sender.sendMessage("raw - Open GUI with raw Biome data");
sender.sendMessage("step - Re-render data to show borders more clearly");
LangUtil.send("command.image.gui.main-menu", sender);
return true;
}

View File

@ -4,6 +4,7 @@ import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.base.ConfigUtil;
import com.dfsek.terra.config.base.WorldConfig;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.image.ImageLoader;
import org.bukkit.World;
import org.bukkit.command.Command;
@ -18,7 +19,7 @@ public class RawGUICommand extends WorldCommand {
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
if(! ConfigUtil.debug) {
sender.sendMessage("Debug mode must be enabled to use the debug GUI! The debug GUI is NOT PRODUCTION SAFE!");
LangUtil.send("command.image.gui.debug", sender);
return true;
}
ImageLoader loader = TerraWorld.getWorld(world).getWorldConfig().imageLoader;

View File

@ -4,6 +4,7 @@ import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.base.ConfigUtil;
import com.dfsek.terra.config.base.WorldConfig;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.image.ImageLoader;
import org.bukkit.World;
import org.bukkit.command.Command;
@ -18,7 +19,7 @@ public class StepGUICommand extends WorldCommand {
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
if(! ConfigUtil.debug) {
sender.sendMessage("Debug mode must be enabled to use the debug GUI! The debug GUI is NOT PRODUCTION SAFE!");
LangUtil.send("command.image.gui.debug", sender);
return true;
}
ImageLoader loader = TerraWorld.getWorld(world).getWorldConfig().imageLoader;

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.profile;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -14,11 +15,7 @@ import java.util.List;
public class ProfileCommand extends WorldCommand {
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
sender.sendMessage("---------------Terra/profile---------------");
sender.sendMessage("start - Starts the profiler");
sender.sendMessage("stop - Stops the profiler");
sender.sendMessage("query - Fetches profiler data");
sender.sendMessage("reset - Resets profiler data");
LangUtil.send("command.profile.main-menu", sender);
return true;
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.command.profile;
import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -17,7 +18,7 @@ public class ResetCommand extends WorldCommand {
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
WorldProfiler profile = TerraProfiler.fromWorld(world);
profile.reset();
sender.sendMessage("Profiler has been reset.");
LangUtil.send("command.profile.reset", sender);
return true;
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.command.profile;
import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -17,7 +18,7 @@ public class StartCommand extends WorldCommand {
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
WorldProfiler profile = TerraProfiler.fromWorld(world);
profile.setProfiling(true);
sender.sendMessage("Profiler has started.");
LangUtil.send("command.profile.start", sender);
return true;
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.command.profile;
import com.dfsek.terra.TerraProfiler;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -17,7 +18,7 @@ public class StopCommand extends WorldCommand {
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
WorldProfiler profile = TerraProfiler.fromWorld(world);
profile.setProfiling(false);
sender.sendMessage("Profiler has stopped.");
LangUtil.send("command.profile.stop", sender);
return true;
}

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.structure;
import com.dfsek.terra.Terra;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.util.structure.WorldEditUtil;
import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.structure.GaeaStructure;
@ -35,7 +36,7 @@ public class ExportCommand extends PlayerCommand {
file.getParentFile().mkdirs();
file.createNewFile();
structure.save(file);
sender.sendMessage("Saved structure with ID " + structure.getId() + ", UUID: " + structure.getUuid().toString() + " to " + file.getPath());
LangUtil.send("command.structure.export", sender, file.getAbsolutePath());
} catch(IOException e) {
e.printStackTrace();
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.command.structure;
import com.dfsek.terra.Terra;
import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.structure.GaeaStructure;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -23,7 +24,7 @@ public class LoadCommand extends PlayerCommand {
else struc.paste(sender.getLocation(), sender.getLocation().getChunk(), r);
} catch(IOException e) {
e.printStackTrace();
sender.sendMessage("Structure not found.");
LangUtil.send("command.structure.invalid", sender, args[0]);
}
return true;
}

View File

@ -6,6 +6,7 @@ import com.dfsek.terra.async.AsyncStructureFinder;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.command.type.WorldCommand;
import com.dfsek.terra.config.genconfig.StructureConfig;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.generation.TerraChunkGenerator;
import com.dfsek.terra.procgen.GridSpawn;
import org.bukkit.Bukkit;
@ -35,14 +36,14 @@ public class LocateCommand extends WorldCommand {
try {
maxRadius = Integer.parseInt(args[1]);
} catch(NumberFormatException e) {
sender.sendMessage("Invalid radius: " + args[1]);
LangUtil.send("command.structure.invalid-radius", sender, args[1]);
return true;
}
StructureConfig s;
try {
s = Objects.requireNonNull(TerraWorld.getWorld(world).getConfig().getStructure(id));
} catch(IllegalArgumentException | NullPointerException e) {
sender.sendMessage("Invalid biome ID: " + id);
LangUtil.send("command.structure.invalid", sender, id);
return true;
}
Bukkit.getScheduler().runTaskAsynchronously(Terra.getInstance(), new AsyncStructureFinder(TerraWorld.getWorld(world).getGrid(), s, sender, 0, maxRadius, tp));

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.structure;
import com.dfsek.terra.command.type.PlayerCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -13,9 +14,7 @@ import java.util.List;
public class StructureCommand extends PlayerCommand {
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
sender.sendMessage("---------------Terra/structure---------------");
sender.sendMessage("export - Export your current WorldEdit selection as a Terra structure.");
sender.sendMessage("load - Load a Terra structure");
LangUtil.send("command.structure.main-menu", sender);
return true;
}

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.command.type;
import com.dfsek.terra.Debug;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
@ -67,7 +68,7 @@ public abstract class Command implements CommandExecutor, TabCompleter {
if(c.getName().equals(args[0])) return c.onCommand(sender, command, label, Arrays.stream(args, 1, args.length).toArray(String[]::new));
}
if(args.length != arguments()) {
sender.sendMessage("Invalid command. (Expected " + arguments() + " arguments, found " + args.length + ").");
LangUtil.send("command.invalid", sender, String.valueOf(arguments()), String.valueOf(args.length));
return true;
}
return execute(sender, command, label, args);

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.command.type;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@ -23,7 +24,7 @@ public abstract class PlayerCommand extends Command {
@Override
public final boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!(sender instanceof Player)) {
sender.sendMessage("Command is for players only.");
LangUtil.send("command.players-only", sender);
return true;
}
Player p = (Player) sender;

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.command.type;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.generation.TerraChunkGenerator;
import org.bukkit.World;
import org.bukkit.command.Command;
@ -27,7 +28,7 @@ public abstract class WorldCommand extends PlayerCommand {
if(sender.getWorld().getGenerator() instanceof TerraChunkGenerator) {
return execute(sender, command, label, args, sender.getWorld());
} else {
sender.sendMessage("This world is not a Terra world!");
LangUtil.send("command.world", sender);
}
return true;
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.config;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.base.ConfigUtil;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.polydev.gaea.commons.io.FilenameUtils;
@ -16,10 +17,11 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.stream.Stream;
public class ConfigLoader {
public static <T extends TerraConfig> Map<String, T> load(JavaPlugin main, Path file, ConfigPack config, Class<T> clazz) {
public static <T extends TerraConfig> Map<String, T> load(Path file, ConfigPack config, Class<T> clazz) {
long l = System.nanoTime();
Map<String, T> configs = new HashMap<>();
file.toFile().mkdirs();
@ -30,22 +32,19 @@ public class ConfigLoader {
try {
Constructor<T> c = clazz.getConstructor(File.class, ConfigPack.class);
T o = c.newInstance(path.toFile(), config);
if(ids.contains(o.getID())) Bukkit.getLogger().severe("Duplicate ID found in file: " + path.toString());
if(ids.contains(o.getID())) LangUtil.log("config.error.duplicate", Level.SEVERE, path.toString());
ids.add(o.getID());
configs.put(o.getID(), o);
main.getLogger().info("Loaded " + o.toString() + " from file " + path.toString());
LangUtil.log("config.loaded", Level.INFO, o.toString(), path.toString());
} catch(IllegalAccessException | InstantiationException | NoSuchMethodException e) {
main.getLogger().severe("An error occurred while loading configurations.");
e.printStackTrace();
main.getLogger().severe("Please report this to Terra.");
LangUtil.log("config.error.generic", Level.SEVERE, path.toString());
} catch(IllegalArgumentException | InvocationTargetException e) {
if(ConfigUtil.debug) e.printStackTrace();
main.getLogger().severe("Configuration error for Terra object. File: " + path.toString());
main.getLogger().severe(((e instanceof InvocationTargetException) ? "INVOCATION: " + e.getCause().getMessage() : e.getMessage()));
main.getLogger().severe("Correct this before proceeding!");
LangUtil.log("config.error.file", Level.SEVERE, path.toString(), ((e instanceof InvocationTargetException) ? "INVOCATION: " + e.getCause().getMessage() : e.getMessage()));
}
});
main.getLogger().info("\nLoaded " + configs.size() + " " + clazz.getSimpleName() + "(s) in " + (System.nanoTime() - l) / 1000000D + "ms.\n");
LangUtil.log("config.loaded-all", Level.INFO, String.valueOf(configs.size()), clazz.getSimpleName(), String.valueOf((System.nanoTime() - l) / 1000000D));
} catch(IOException e) {
e.printStackTrace();
}

View File

@ -1,8 +1,6 @@
package com.dfsek.terra.config.base;
import com.dfsek.terra.Debug;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.UserDefinedGrid;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.ConfigLoader;
import com.dfsek.terra.config.exception.ConfigException;
@ -14,6 +12,7 @@ import com.dfsek.terra.config.genconfig.FloraConfig;
import com.dfsek.terra.config.genconfig.OreConfig;
import com.dfsek.terra.config.genconfig.PaletteConfig;
import com.dfsek.terra.config.genconfig.StructureConfig;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
@ -26,7 +25,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.stream.Collectors;
/**
@ -61,30 +60,29 @@ public class ConfigPack extends YamlConfiguration {
public boolean biomeBlend;
public float blendFreq;
public ConfigPack(JavaPlugin main, File file) throws IOException, InvalidConfigurationException {
public ConfigPack(File file) throws IOException, InvalidConfigurationException {
long l = System.nanoTime();
load(new File(file, "config.yml"));
dataFolder = file;
Logger logger = main.getLogger();
if(!contains("id")) throw new ConfigException("No ID specified!", "null");
this.id = getString("id");
ores = ConfigLoader.load(main, new File(file, "ores").toPath(), this, OreConfig.class);
ores = ConfigLoader.load(new File(file, "ores").toPath(), this, OreConfig.class);
palettes = ConfigLoader.load(main, new File(file, "palettes").toPath(), this, PaletteConfig.class);
palettes = ConfigLoader.load(new File(file, "palettes").toPath(), this, PaletteConfig.class);
carvers = ConfigLoader.load(main, new File(file, "carving").toPath(), this, CarverConfig.class);
carvers = ConfigLoader.load(new File(file, "carving").toPath(), this, CarverConfig.class);
flora = ConfigLoader.load(main, new File(file, "flora").toPath(), this, FloraConfig.class);
flora = ConfigLoader.load(new File(file, "flora").toPath(), this, FloraConfig.class);
structures = ConfigLoader.load(main, new File(file, "structures").toPath(), this, StructureConfig.class);
structures = ConfigLoader.load(new File(file, "structures").toPath(), this, StructureConfig.class);
abstractBiomes = ConfigLoader.load(main, new File(file, "abstract" + File.separator + "biomes").toPath(), this, AbstractBiomeConfig.class);
abstractBiomes = ConfigLoader.load(new File(file, "abstract" + File.separator + "biomes").toPath(), this, AbstractBiomeConfig.class);
biomes = ConfigLoader.load(main, new File(file, "biomes").toPath(), this, BiomeConfig.class);
biomes = ConfigLoader.load(new File(file, "biomes").toPath(), this, BiomeConfig.class);
grids = ConfigLoader.load(main, new File(file, "grids").toPath(), this, BiomeGridConfig.class);
grids = ConfigLoader.load(new File(file, "grids").toPath(), this, BiomeGridConfig.class);
zoneFreq = 1f/getInt("frequencies.zone", 1536);
freq1 = 1f/getInt("frequencies.grid-x", 256);
@ -104,7 +102,7 @@ public class ConfigPack extends YamlConfiguration {
biomeList = getStringList("grids");
configs.put(id, this);
logger.info("\n\nLoaded config \"" + getID() + "\" in " + (System.nanoTime() - l)/1000000D + "ms\n\n\n");
LangUtil.log("config-pack.load", Level.INFO, getID(), String.valueOf((System.nanoTime() - l)/1000000D));
}
public Map<String, AbstractBiomeConfig> getAbstractBiomes() {
@ -134,7 +132,7 @@ public class ConfigPack extends YamlConfiguration {
for(Path folder : subfolder) {
ConfigPack config;
try {
config = new ConfigPack(main, folder.toFile());
config = new ConfigPack(folder.toFile());
configs.put(config.getID(), config);
} catch(IOException | InvalidConfigurationException e) {
e.printStackTrace();

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.config.base;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.config.exception.ConfigException;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
@ -22,6 +23,7 @@ public final class ConfigUtil {
public static void loadConfig(JavaPlugin main) {
main.saveDefaultConfig();
FileConfiguration config = main.getConfig();
LangUtil.load(config.getString("language", "en_us"), main);
debug = config.getBoolean("debug", false);
dataSave = Duration.parse(Objects.requireNonNull(config.getString("data-save", "PT6M"))).toMillis()/20L;

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.config.base;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.image.ImageLoader;
import org.bukkit.Bukkit;
import org.bukkit.World;
@ -12,6 +13,7 @@ import org.polydev.gaea.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.logging.Level;
public class WorldConfig {
@ -30,13 +32,13 @@ public class WorldConfig {
public WorldConfig(World w, JavaPlugin main) {
long start = System.nanoTime();
main.getLogger().info("Loading world configuration values for " + w + "...");
LangUtil.log("world-config.load", Level.INFO, w.getName());
FileConfiguration config = new YamlConfiguration();
try { // Load/create world config file
File configFile = new File(main.getDataFolder() + File.separator + "worlds", w.getName() + ".yml");
if(! configFile.exists()) {
configFile.getParentFile().mkdirs();
main.getLogger().info("Configuration for world \"" + w + "\" not found. Copying default config.");
LangUtil.log("world-config.not-found", Level.SEVERE, w.getName());
FileUtils.copyInputStreamToFile(Objects.requireNonNull(main.getResource("world.yml")), configFile);
}
config.load(configFile);
@ -60,7 +62,7 @@ public class WorldConfig {
if(fromImage) {
try {
imageLoader = new ImageLoader(new File(Objects.requireNonNull(config.getString("image.image-location"))), ImageLoader.Align.valueOf(config.getString("image.align", "center").toUpperCase()));
Bukkit.getLogger().info("[Terra] Loading world from image.");
LangUtil.log("world-config.using-image", Level.INFO, w.getName());
} catch(IOException | NullPointerException e) {
e.printStackTrace();
fromImage = false;
@ -73,10 +75,9 @@ public class WorldConfig {
} catch(IOException | InvalidConfigurationException e) {
e.printStackTrace();
main.getLogger().severe("Unable to load configuration for world " + w + ".");
LangUtil.log("world-config.error", Level.SEVERE, w.getName());
}
main.getLogger().info("World load complete. Time elapsed: " + ((double) (System.nanoTime() - start)) / 1000000 + "ms");
LangUtil.log("world-config.done", Level.INFO, w.getName(), String.valueOf(((double) (System.nanoTime() - start)) / 1000000));
}
public ConfigPack getConfig() {

View File

@ -30,12 +30,12 @@ public class PaletteConfig extends TerraConfig {
Palette<BlockData> pal;
if(getBoolean("simplex", false)) {
useNoise = true;
FastNoise pNoise = new FastNoise(getInt("seed", 3));
FastNoise pNoise = new FastNoise(getInt("seed", 2403));
pNoise.setNoiseType(FastNoise.NoiseType.SimplexFractal);
pNoise.setFractalOctaves(4);
pNoise.setFrequency((float) getDouble("frequency", 0.02));
pal = new SimplexPalette<>(pNoise);
} else pal = new RandomPalette<>(new Random(getInt("seed", 3)));
} else pal = new RandomPalette<>(new Random(getInt("seed", 2403)));
palette = getPalette(getMapList("blocks"), pal);
}

View File

@ -1,11 +1,20 @@
package com.dfsek.terra.config.lang;
import com.dfsek.terra.Debug;
import com.dfsek.terra.Terra;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
public final class LangUtil {
@ -13,6 +22,14 @@ public final class LangUtil {
private static Logger logger;
public static void load(String langID, JavaPlugin main) {
logger = main.getLogger();
File file = new File(main.getDataFolder(), "lang");
try(JarFile jar = new JarFile(new File(Terra.class.getProtectionDomain().getCodeSource().getLocation().toURI()))) {
copyResourcesToDirectory(jar, file.toString());
} catch(IOException | URISyntaxException e) {
Debug.error("Failed to dump language files!");
e.printStackTrace();
Debug.error("Report this to Terra!");
}
try {
language = new Language(new File(Terra.getInstance().getDataFolder(), "lang" + File.separator + langID + ".yml"));
} catch(InvalidConfigurationException | IOException e) {
@ -21,4 +38,35 @@ public final class LangUtil {
logger.severe("Double-check your configuration before reporting this to Terra!");
}
}
private static void copyResourcesToDirectory(JarFile fromJar, String destDir) throws IOException {
for(Enumeration<JarEntry> entries = fromJar.entries(); entries.hasMoreElements(); ) {
JarEntry entry = entries.nextElement();
if(entry.getName().startsWith("lang" + "/") && ! entry.isDirectory()) {
File dest = new File(destDir + File.separator + entry.getName().substring("lang".length() + 1));
Debug.info("Output: " + dest.toString());
if(dest.exists()) continue;
File parent = dest.getParentFile();
if(parent != null) {
parent.mkdirs();
}
Debug.info("Output does not already exist. Creating... ");
try(FileOutputStream out = new FileOutputStream(dest); InputStream in = fromJar.getInputStream(entry)) {
byte[] buffer = new byte[8 * 1024];
int s;
while((s = in.read(buffer)) > 0) {
out.write(buffer, 0, s);
}
} catch(IOException e) {
throw new IOException("Could not copy asset from jar file", e);
}
}
}
}
public static void log(String messageID, Level level, String... args) {
language.getMessage(messageID).log(logger, level, args);
}
public static void send(String messageID, CommandSender sender, String... args) {
language.getMessage(messageID).send(sender, args);
}
}

View File

@ -7,23 +7,26 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Language extends YamlConfiguration {
private final Map<String, Message> messages;
public Language(File file) throws IOException, InvalidConfigurationException {
load(file);
messages = new HashMap<>();
messages.put("enable", new MultiLineMessage(getStringList("enable")));
messages.put("disable", new MultiLineMessage(getStringList("disable")));
}
@Override
public void load(@NotNull File file) throws IOException, InvalidConfigurationException {
super.load(file);
}
public Message getMessage(String id) {
Message temp = messages.get(id);
if(temp == null || temp.isEmpty()) return new SingleLineMessage(id + ":translation_undefined");
Object m = get(id);
Message temp;
if(m instanceof List) {
temp = new MultiLineMessage(getStringList(id));
} else if(m instanceof String) {
temp = new SingleLineMessage(getString(id));
} else return new SingleLineMessage("message:" + id + ":translation_undefined");
if(temp.isEmpty()) return new SingleLineMessage("message:" + id + ":translation_undefined");
return temp;
}
}

View File

@ -6,7 +6,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
public interface Message {
void log(Logger logger, Level level);
void send(CommandSender sender);
void log(Logger logger, Level level, String... args);
void send(CommandSender sender, String... args);
boolean isEmpty();
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.config.lang;
import org.bukkit.command.CommandSender;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -12,16 +13,16 @@ public class MultiLineMessage implements Message {
this.message = message;
}
@Override
public void log(Logger logger, Level level) {
public void log(Logger logger, Level level, String... args) {
for(String line: message) {
logger.log(level, line);
logger.log(level, String.format(line, Arrays.asList(args).toArray()));
}
}
@Override
public void send(CommandSender sender) {
public void send(CommandSender sender, String... args) {
for(String line: message) {
sender.sendMessage(line);
sender.sendMessage(String.format(line, Arrays.asList(args).toArray()));
}
}

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.config.lang;
import org.bukkit.command.CommandSender;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -11,13 +12,13 @@ public class SingleLineMessage implements Message {
this.message = message;
}
@Override
public void log(Logger logger, Level level) {
logger.log(level, message);
public void log(Logger logger, Level level, String... args) {
logger.log(level, String.format(message, Arrays.asList(args).toArray()));
}
@Override
public void send(CommandSender sender) {
sender.sendMessage(message);
public void send(CommandSender sender, String... args) {
sender.sendMessage(String.format(message, Arrays.asList(args).toArray()));
}
@Override

View File

@ -7,6 +7,7 @@ import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
import com.dfsek.terra.config.genconfig.biome.BiomeSlabConfig;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.population.CavePopulator;
import com.dfsek.terra.population.FloraPopulator;
import com.dfsek.terra.population.OrePopulator;
@ -42,6 +43,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
public class TerraChunkGenerator extends GaeaChunkGenerator {
private final PopulationManager popMan = new PopulationManager(Terra.getInstance());
@ -142,7 +144,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
popMan.loadBlocks(w);
} catch(IOException e) {
if(e instanceof FileNotFoundException) {
Bukkit.getLogger().warning("[Terra] No population chunks were loaded. If this is your first time starting your server with Terra, or if you are creating a new world, this is normal.");
LangUtil.log("warning.no-population", Level.WARNING);
} else e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();

View File

@ -1,4 +1,5 @@
debug: false
data-save: PT6M
language: "en_us"
master-disable:
caves: false

View File

@ -6,4 +6,102 @@ disable:
- "Thank you for using Terra!"
command:
player-only: "This command is for players only!"
terra-world: "This command must be executed in a Terra world!"
terra-world: "This command must be executed in a Terra world!"
invalid: "Invalid command. (Expected %1$s arguments, found %2$s)."
players-only: "Command is for players only."
world: "This command must be executed in a Terra world!"
reload: "Reloaded Terra config."
main-menu:
- "--------------------Terra--------------------"
- "reload - Reload configuration data"
- "biome - Get current biome"
- "ore - Generate an ore vein at the location you are facing (For debugging)"
- "save-data - Save population data"
- "structure - Load and export structures"
- "profile - Profiler options"
- "image - Image/GUI options"
biome:
biome-found: "Located biome at (%1$s, %2$s)"
unable-to-locate: "Unable to locate biome."
invalid-radius: "Invalid radius: \"%s\""
invalid: "Invalid Biome ID: \"%s\""
in: "You are in \"%s\""
ore:
main-menu:
- "---------------Terra/ore---------------"
- "Generates a vein of ore at the block you are looking at."
out-of-range: "Block out of range"
invalid-ore: "Unable to find Ore \"%s\""
geometry:
main-menu:
- "---------------Terra/geometry----------------"
- "Various voxel geometry debugging commands"
- "sphere - Generate a sphere"
- "deformsphere - Generate a deformed sphere"
- "tube - Generate a tube"
deform:
invalid-radius: "Invalid radius: \"%s\""
invalid-deform: "Invalid deform: \"%s\""
invalid-frequency: "Invalid frequency: \"%s\""
sphere:
invalid-radius: "Invalid radius: \"%s\""
tube:
invalid-radius: "Invalid radius: \"%s\""
image:
main-menu:
- "---------------Terra/image---------------"
- "render - Render an image with a given width and height, that can later be imported as a world."
- "gui - Open debug GUI (Must be enabled in config)"
gui:
main-menu:
- "-------------Terra/image/gui-------------"
- "raw - Open GUI with raw Biome data"
- "step - Re-render data to show borders more clearly"
debug: "Debug mode must be enabled to use the debug GUI! The debug GUI is NOT PRODUCTION SAFE!"
render:
save: "Saved image as \"%s\""
error: "An error occurred while generating the image!"
profile:
main-menu:
- "---------------Terra/profile---------------"
- "start - Starts the profiler"
- "stop - Stops the profiler"
- "query - Fetches profiler data"
- "reset - Resets profiler data"
reset: "Profiler has been reset."
start: "Profiler has started."
stop: "Profiler has stopped."
structure:
main-menu:
- "---------------Terra/structure---------------"
- "export - Export your current WorldEdit selection as a Terra structure."
- "load - Load a Terra structure"
invalid-radius: "Invalid radius: \"%s\""
invalid: "Invalid Structure ID: \"%s\""
export: "Saved structure to \"%s\""
world-config:
loading: "Loading world configuration values for world %s..."
not-found: "Configuration for world \"%s\" not found. Copying default config."
using-image: "Loading world from image."
error: "Unable to load configuration for world %s"
done: "World load complete. Time elapsed: %sms"
config-pack:
loaded: "Loaded config %1$s in %2$sms."
config:
loaded: "Loaded %1$s from file %2$s"
loaded-all: "Loaded %1$s %2$s(s) in %3$sms."
error:
duplicate: "Duplicate ID found in file: %s"
file:
- "Configuration error for Terra object. File: %1$s"
- "%2$s"
- "Correct this before proceeding!"
generic:
- "An error occurred while loading configurations."
- "Please report this to Terra."
warning:
no-population: "No population chunks were loaded. If this is your first time starting your server with Terra, or if you are creating a new world, this is normal."
error:
severe-config: "A severe configuration error has prevented Terra from properly generating terrain at coordinates: %1$s, %2$s. Please check your configuration for errors. Any config errors will have been reported above."
debug:
data-save: "Saved population data for world \"%s\""