mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-10 09:46:24 +00:00
Reformat all code
Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
This commit is contained in:
@@ -1,6 +1,21 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.tectonic.loading.TypeRegistry;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.dfsek.terra.api.Logger;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
@@ -26,59 +41,91 @@ import com.dfsek.terra.registry.CheckedRegistryImpl;
|
||||
import com.dfsek.terra.registry.master.AddonRegistry;
|
||||
import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
import com.dfsek.terra.util.logging.DebugLogger;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Skeleton implementation of {@link TerraPlugin}
|
||||
*
|
||||
* <p>
|
||||
* Implementations must invoke {@link #load()} in their constructors.
|
||||
*/
|
||||
public abstract class AbstractTerraPlugin implements TerraPlugin {
|
||||
private final Lazy<DebugLogger> debugLogger = Lazy.lazy(() -> new DebugLogger(logger()));
|
||||
private final EventManager eventManager = new EventManagerImpl(this);
|
||||
|
||||
private final ConfigRegistry configRegistry = new ConfigRegistry();
|
||||
|
||||
private final CheckedRegistry<ConfigPack> checkedConfigRegistry = new CheckedRegistryImpl<>(configRegistry);
|
||||
|
||||
private final Profiler profiler = new ProfilerImpl();
|
||||
|
||||
private final GenericLoaders loaders = new GenericLoaders(this);
|
||||
|
||||
private final PluginConfigImpl config = new PluginConfigImpl();
|
||||
|
||||
private final CommandManager manager = new TerraCommandManager(this);
|
||||
|
||||
private final AddonRegistry addonRegistry = new AddonRegistry(this);
|
||||
|
||||
private final Lazy<Logger> logger = Lazy.lazy(() -> createLogger());
|
||||
|
||||
private static final MutableBoolean LOADED = new MutableBoolean(false);
|
||||
|
||||
|
||||
private final EventManager eventManager = new EventManagerImpl(this);
|
||||
|
||||
private final ConfigRegistry configRegistry = new ConfigRegistry();
|
||||
|
||||
private final CheckedRegistry<ConfigPack> checkedConfigRegistry = new CheckedRegistryImpl<>(configRegistry);
|
||||
|
||||
private final Profiler profiler = new ProfilerImpl();
|
||||
|
||||
private final GenericLoaders loaders = new GenericLoaders(this);
|
||||
|
||||
private final PluginConfigImpl config = new PluginConfigImpl();
|
||||
|
||||
private final CommandManager manager = new TerraCommandManager(this);
|
||||
|
||||
private final AddonRegistry addonRegistry = new AddonRegistry(this);
|
||||
|
||||
private final Lazy<Logger> logger = Lazy.lazy(() -> createLogger());
|
||||
private final Lazy<DebugLogger> debugLogger = Lazy.lazy(() -> new DebugLogger(logger()));
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
loaders.register(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger logger() {
|
||||
return logger.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginConfig getTerraConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return LangUtil.getLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckedRegistry<ConfigPack> getConfigRegistry() {
|
||||
return checkedConfigRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<TerraAddon> getAddons() {
|
||||
return addonRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getDebugLogger() {
|
||||
return debugLogger.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Profiler getProfiler() {
|
||||
return profiler;
|
||||
}
|
||||
|
||||
protected void load() {
|
||||
if(LOADED.get()) {
|
||||
throw new IllegalStateException("Someone tried to initialize Terra, but Terra has already initialized. This is most likely due to a broken platform implementation, or a misbehaving mod.");
|
||||
throw new IllegalStateException(
|
||||
"Someone tried to initialize Terra, but Terra has already initialized. This is most likely due to a broken platform " +
|
||||
"implementation, or a misbehaving mod.");
|
||||
}
|
||||
LOADED.set(true);
|
||||
|
||||
|
||||
logger().info("Initializing Terra...");
|
||||
|
||||
|
||||
getPlatformAddon().ifPresent(addonRegistry::register);
|
||||
|
||||
|
||||
try(InputStream stream = getClass().getResourceAsStream("/config.yml")) {
|
||||
File configFile = new File(getDataFolder(), "config.yml");
|
||||
if(!configFile.exists()) {
|
||||
@@ -87,12 +134,12 @@ public abstract class AbstractTerraPlugin implements TerraPlugin {
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
config.load(this); // load config.yml
|
||||
|
||||
|
||||
LangUtil.load(config.getLanguage(), this); // load language
|
||||
|
||||
|
||||
if(config.dumpDefaultConfig()) {
|
||||
try(InputStream resourcesConfig = getClass().getResourceAsStream("/resources.yml")) {
|
||||
if(resourcesConfig == null) {
|
||||
@@ -125,86 +172,41 @@ public abstract class AbstractTerraPlugin implements TerraPlugin {
|
||||
} else {
|
||||
getDebugLogger().info("Skipping resource dumping.");
|
||||
}
|
||||
|
||||
|
||||
debugLogger.value().setDebug(config.isDebugLogging()); // enable debug logger if applicable
|
||||
|
||||
|
||||
if(config.isDebugProfiler()) { // if debug.profiler is enabled, start profiling
|
||||
profiler.start();
|
||||
}
|
||||
|
||||
|
||||
addonRegistry.register(new InternalAddon(this));
|
||||
|
||||
|
||||
if(!addonRegistry.loadAll(getClass().getClassLoader())) { // load all addons
|
||||
throw new IllegalStateException("Failed to load addons. Please correct addon installations to continue.");
|
||||
}
|
||||
logger().info("Loaded addons.");
|
||||
|
||||
|
||||
try {
|
||||
CommandUtil.registerAll(manager);
|
||||
} catch(MalformedCommandException e) {
|
||||
e.printStackTrace(); // TODO do something here even though this should literally never happen
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
logger().info("Finished initialization.");
|
||||
}
|
||||
|
||||
|
||||
protected abstract Logger createLogger();
|
||||
|
||||
protected Optional<TerraAddon> getPlatformAddon() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
protected abstract Logger createLogger();
|
||||
|
||||
@Override
|
||||
public PluginConfig getTerraConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckedRegistry<ConfigPack> getConfigRegistry() {
|
||||
return checkedConfigRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<TerraAddon> getAddons() {
|
||||
return addonRegistry;
|
||||
}
|
||||
|
||||
|
||||
public ConfigRegistry getRawConfigRegistry() {
|
||||
return configRegistry;
|
||||
}
|
||||
|
||||
|
||||
public CommandManager getManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getDebugLogger() {
|
||||
return debugLogger.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Profiler getProfiler() {
|
||||
return profiler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
loaders.register(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return LangUtil.getLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger logger() {
|
||||
return logger.value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
import com.dfsek.terra.api.addon.annotations.Addon;
|
||||
import com.dfsek.terra.api.addon.annotations.Author;
|
||||
@@ -8,26 +7,27 @@ import com.dfsek.terra.api.addon.annotations.Version;
|
||||
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
|
||||
|
||||
@Addon("terra")
|
||||
@Author("Terra")
|
||||
@Version("1.0.0")
|
||||
public class InternalAddon extends TerraAddon {
|
||||
private final AbstractTerraPlugin main;
|
||||
|
||||
|
||||
public InternalAddon(AbstractTerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
main.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, PlatformInitializationEvent.class)
|
||||
.then(event -> {
|
||||
main.logger().info("Loading config packs...");
|
||||
main.getRawConfigRegistry().loadAll(main);
|
||||
main.logger().info("Loaded packs.");
|
||||
})
|
||||
.global();
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(this, PlatformInitializationEvent.class)
|
||||
.then(event -> {
|
||||
main.logger().info("Loading config packs...");
|
||||
main.getRawConfigRegistry().loadAll(main);
|
||||
main.logger().info("Loaded packs.");
|
||||
})
|
||||
.global();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,18 @@ import com.dfsek.terra.api.command.annotation.Command;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
|
||||
|
||||
@Command(
|
||||
usage = "/terra addons"
|
||||
)
|
||||
public class AddonsCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
sender.sendMessage("Installed Addons:");
|
||||
main.getAddons().forEach(addon -> sender.sendMessage(" - " + addon.getName() + " v" + addon.getVersion() + " by " + addon.getAuthor()));
|
||||
main.getAddons().forEach(
|
||||
addon -> sender.sendMessage(" - " + addon.getName() + " v" + addon.getVersion() + " by " + addon.getAuthor()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.dfsek.terra.api.command.CommandManager;
|
||||
import com.dfsek.terra.api.command.exception.MalformedCommandException;
|
||||
import com.dfsek.terra.commands.profiler.ProfileCommand;
|
||||
|
||||
|
||||
public final class CommandUtil {
|
||||
public static void registerAll(CommandManager manager) throws MalformedCommandException {
|
||||
manager.register("profile", ProfileCommand.class);
|
||||
@@ -12,6 +13,6 @@ public final class CommandUtil {
|
||||
manager.register("version", VersionCommand.class);
|
||||
manager.register("getblock", GetBlockCommand.class);
|
||||
manager.register("packs", PacksCommand.class);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,38 @@
|
||||
package com.dfsek.terra.commands;
|
||||
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
|
||||
|
||||
public final class ExecutionState {
|
||||
private final Set<String> switches = new HashSet<>();
|
||||
private final Map<String, String> args = new HashMap<>();
|
||||
private final CommandSender sender;
|
||||
|
||||
|
||||
protected ExecutionState(CommandSender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
|
||||
protected void addSwitch(String flag) {
|
||||
switches.add(flag);
|
||||
}
|
||||
|
||||
|
||||
protected void addArgument(String arg, String value) {
|
||||
args.put(arg, value);
|
||||
}
|
||||
|
||||
|
||||
public String getArgument(String argument) {
|
||||
return args.get(argument);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasSwitch(String flag) {
|
||||
return switches.contains(flag);
|
||||
}
|
||||
|
||||
|
||||
public CommandSender getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.entity.Player;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
|
||||
|
||||
@WorldCommand
|
||||
@DebugCommand
|
||||
@PlayerCommand
|
||||
@@ -19,7 +20,7 @@ import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
public class GetBlockCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
@@ -9,22 +9,23 @@ import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
|
||||
|
||||
@Command(
|
||||
usage = "/terra packs"
|
||||
)
|
||||
public class PacksCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
CheckedRegistry<ConfigPack> registry = main.getConfigRegistry();
|
||||
|
||||
|
||||
if(registry.entries().size() == 0) {
|
||||
LangUtil.send("command.packs.none", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LangUtil.send("command.packs.main", sender);
|
||||
registry.entries().forEach(entry -> {
|
||||
LangUtil.send("command.packs.pack", sender, entry.getID(), entry.getAuthor(), entry.getVersion());
|
||||
|
||||
@@ -7,13 +7,14 @@ import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
|
||||
|
||||
@Command(
|
||||
usage = "/terra reload"
|
||||
)
|
||||
public class ReloadCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
if(!main.reload()) {
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
package com.dfsek.terra.commands;
|
||||
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.command.CommandManager;
|
||||
import com.dfsek.terra.api.command.CommandTemplate;
|
||||
@@ -24,138 +36,156 @@ import com.dfsek.terra.api.entity.Player;
|
||||
import com.dfsek.terra.api.injection.exception.InjectionException;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
import com.dfsek.terra.inject.InjectorImpl;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TerraCommandManager implements CommandManager {
|
||||
private final Map<String, CommandHolder> commands = new HashMap<>();
|
||||
private final InjectorImpl<TerraPlugin> pluginInjector;
|
||||
private final TerraPlugin main;
|
||||
|
||||
|
||||
public TerraCommandManager(TerraPlugin main) {
|
||||
this.main = main;
|
||||
this.pluginInjector = new InjectorImpl<>(main);
|
||||
pluginInjector.addExplicitTarget(TerraPlugin.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(String commandName, CommandSender sender, List<String> argsIn) throws CommandException {
|
||||
if(!commands.containsKey(commandName)) throw new InvalidArgumentsException("No such command \"" + commandName + "\"");
|
||||
execute(commands.get(commandName), sender, new ArrayList<>(argsIn));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(String name, Class<? extends CommandTemplate> clazz) throws MalformedCommandException {
|
||||
commands.put(name, new CommandHolder(clazz));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(String command, CommandSender sender, List<String> args) throws CommandException {
|
||||
if(args.isEmpty()) return new ArrayList<>(commands.keySet()).stream().sorted(String::compareTo).collect(Collectors.toList());
|
||||
if(!commands.containsKey(command)) return Collections.emptyList();
|
||||
return tabComplete(commands.get(command), sender, new ArrayList<>(args)).stream().filter(
|
||||
s -> s.toLowerCase().startsWith(args.get(args.size() - 1).toLowerCase())).sorted(String::compareTo).collect(
|
||||
Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxArgumentDepth() {
|
||||
int max = 0;
|
||||
for(CommandHolder value : commands.values()) {
|
||||
max = FastMath.max(getMaxArgumentDepth(value), max);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
private void execute(CommandHolder commandHolder, CommandSender sender, List<String> args) throws CommandException {
|
||||
Class<? extends CommandTemplate> commandClass = commandHolder.clazz;
|
||||
|
||||
|
||||
if(commandClass.isAnnotationPresent(DebugCommand.class) && !main.getTerraConfig().isDebugCommands()) {
|
||||
sender.sendMessage("Command must be executed with debug commands enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(commandClass.isAnnotationPresent(PlayerCommand.class) && !(sender instanceof Player)) {
|
||||
sender.sendMessage("Command must be executed by player.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(commandClass.isAnnotationPresent(WorldCommand.class) && (!(sender instanceof Player))) {
|
||||
sender.sendMessage("Command must be executed in a Terra world.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
List<String> ogArgs = new ArrayList<>(args);
|
||||
|
||||
|
||||
ExecutionState state = new ExecutionState(sender);
|
||||
|
||||
|
||||
if(!commandClass.isAnnotationPresent(Command.class)) {
|
||||
invoke(commandClass, state, commandHolder);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Command command = commandClass.getAnnotation(Command.class);
|
||||
|
||||
|
||||
if(command.arguments().length == 0 && command.subcommands().length == 0) {
|
||||
if(args.isEmpty()) {
|
||||
invoke(commandClass, state, commandHolder);
|
||||
return;
|
||||
} else throw new InvalidArgumentsException("Expected 0 arguments, found " + args.size());
|
||||
}
|
||||
|
||||
|
||||
if(!args.isEmpty() && commandHolder.subcommands.containsKey(args.get(0))) {
|
||||
String c = args.get(0);
|
||||
args.remove(0);
|
||||
execute(commandHolder.subcommands.get(c), sender, args);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
boolean req = true;
|
||||
for(Argument argument : command.arguments()) {
|
||||
if(!req && argument.required()) {
|
||||
throw new MalformedCommandException("Required arguments must come first! Arguments: " + Arrays.toString(command.arguments()));
|
||||
throw new MalformedCommandException(
|
||||
"Required arguments must come first! Arguments: " + Arrays.toString(command.arguments()));
|
||||
}
|
||||
req = argument.required();
|
||||
|
||||
|
||||
if(args.isEmpty()) {
|
||||
if(req) throw new InvalidArgumentsException("Invalid arguments: " + ogArgs + ", usage: " + command.usage());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
String arg = args.get(0);
|
||||
|
||||
|
||||
if(arg.startsWith("-")) { // switches have started.
|
||||
if(req) throw new InvalidArgumentsException("Switches must come after arguments.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
state.addArgument(argument.value(), args.remove(0));
|
||||
}
|
||||
|
||||
|
||||
while(!args.isEmpty()) {
|
||||
String aSwitch = args.remove(0);
|
||||
if(!aSwitch.startsWith("-")) throw new SwitchFormatException("Invalid switch \"" + aSwitch + "\"");
|
||||
|
||||
|
||||
String val = aSwitch.substring(1); // remove dash
|
||||
|
||||
|
||||
if(!commandHolder.switches.containsKey(val)) throw new SwitchFormatException("No such switch \"" + aSwitch + "\"");
|
||||
|
||||
|
||||
state.addSwitch(commandHolder.switches.get(val));
|
||||
}
|
||||
|
||||
|
||||
invoke(commandClass, state, commandHolder);
|
||||
}
|
||||
|
||||
|
||||
private void invoke(Class<? extends CommandTemplate> clazz, ExecutionState state, CommandHolder holder) throws CommandException {
|
||||
try {
|
||||
CommandTemplate template = clazz.getConstructor().newInstance();
|
||||
|
||||
|
||||
pluginInjector.inject(template);
|
||||
|
||||
|
||||
for(Field field : ReflectionUtil.getFields(clazz)) {
|
||||
if(field.isAnnotationPresent(ArgumentTarget.class)) {
|
||||
ArgumentTarget argumentTarget = field.getAnnotation(ArgumentTarget.class);
|
||||
if(!holder.argumentMap.containsKey(argumentTarget.value())) {
|
||||
throw new MalformedCommandException("Argument Target specifies nonexistent argument \"" + argumentTarget.value() + "\"");
|
||||
throw new MalformedCommandException(
|
||||
"Argument Target specifies nonexistent argument \"" + argumentTarget.value() + "\"");
|
||||
}
|
||||
|
||||
|
||||
String argument = argumentTarget.value();
|
||||
|
||||
ArgumentParser<?> argumentParser = holder.argumentMap.get(argumentTarget.value()).argumentParser().getConstructor().newInstance();
|
||||
|
||||
|
||||
ArgumentParser<?> argumentParser = holder.argumentMap.get(argumentTarget.value())
|
||||
.argumentParser()
|
||||
.getConstructor()
|
||||
.newInstance();
|
||||
|
||||
pluginInjector.inject(argumentParser);
|
||||
|
||||
|
||||
field.setAccessible(true);
|
||||
String value = state.getArgument(argument);
|
||||
|
||||
|
||||
if(value == null) value = holder.argumentMap.get(argumentTarget.value()).defaultValue();
|
||||
|
||||
|
||||
field.set(template, argumentParser.parse(state.getSender(), value));
|
||||
}
|
||||
if(field.isAnnotationPresent(SwitchTarget.class)) {
|
||||
@@ -163,16 +193,16 @@ public class TerraCommandManager implements CommandManager {
|
||||
if(!holder.switches.containsValue(switchTarget.value())) {
|
||||
throw new MalformedCommandException("Switch Target specifies nonexistent switch \"" + switchTarget.value() + "\"");
|
||||
}
|
||||
|
||||
|
||||
if(!(field.getType() == boolean.class)) {
|
||||
throw new MalformedCommandException("Switch Target must be of type boolean.");
|
||||
}
|
||||
|
||||
|
||||
field.setAccessible(true);
|
||||
field.setBoolean(template, state.hasSwitch(switchTarget.value()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
template.execute(state.getSender());
|
||||
} catch(Throwable e) {
|
||||
@@ -182,45 +212,15 @@ public class TerraCommandManager implements CommandManager {
|
||||
throw new MalformedCommandException("Unable to reflectively instantiate command: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(String name, Class<? extends CommandTemplate> clazz) throws MalformedCommandException {
|
||||
commands.put(name, new CommandHolder(clazz));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(String command, CommandSender sender, List<String> args) throws CommandException {
|
||||
if(args.isEmpty()) return new ArrayList<>(commands.keySet()).stream().sorted(String::compareTo).collect(Collectors.toList());
|
||||
if(!commands.containsKey(command)) return Collections.emptyList();
|
||||
return tabComplete(commands.get(command), sender, new ArrayList<>(args)).stream().filter(s -> s.toLowerCase().startsWith(args.get(args.size() - 1).toLowerCase())).sorted(String::compareTo).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxArgumentDepth() {
|
||||
int max = 0;
|
||||
for(CommandHolder value : commands.values()) {
|
||||
max = FastMath.max(getMaxArgumentDepth(value), max);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
private int getMaxArgumentDepth(CommandHolder holder) {
|
||||
int max = 0;
|
||||
max = FastMath.max(holder.arguments.size() + holder.switchList.size(), max);
|
||||
for(CommandHolder value : holder.subcommands.values()) {
|
||||
max = FastMath.max(max, getMaxArgumentDepth(value) + 1);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
private List<String> tabComplete(CommandHolder holder, CommandSender sender, List<String> args) throws CommandException {
|
||||
if(args.isEmpty()) return Collections.emptyList();
|
||||
List<String> completions = new ArrayList<>();
|
||||
|
||||
|
||||
if(args.size() == 1) {
|
||||
completions.addAll(holder.subcommands.keySet());
|
||||
}
|
||||
|
||||
|
||||
if(holder.subcommands.containsKey(args.get(0))) {
|
||||
List<String> newArgs = new ArrayList<>(args);
|
||||
newArgs.remove(0);
|
||||
@@ -237,7 +237,17 @@ public class TerraCommandManager implements CommandManager {
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
|
||||
|
||||
private int getMaxArgumentDepth(CommandHolder holder) {
|
||||
int max = 0;
|
||||
max = FastMath.max(holder.arguments.size() + holder.switchList.size(), max);
|
||||
for(CommandHolder value : holder.subcommands.values()) {
|
||||
max = FastMath.max(max, getMaxArgumentDepth(value) + 1);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pre-processes command metadata.
|
||||
*/
|
||||
@@ -248,7 +258,7 @@ public class TerraCommandManager implements CommandManager {
|
||||
private final List<Argument> arguments;
|
||||
private final List<Switch> switchList;
|
||||
private final Map<String, Argument> argumentMap = new HashMap<>();
|
||||
|
||||
|
||||
private CommandHolder(Class<? extends CommandTemplate> clazz) throws MalformedCommandException {
|
||||
this.clazz = clazz;
|
||||
if(clazz.isAnnotationPresent(Command.class)) {
|
||||
|
||||
@@ -7,13 +7,14 @@ import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
|
||||
|
||||
@Command(
|
||||
usage = "/terra version"
|
||||
)
|
||||
public class VersionCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
String terraVersion = main.getVersion();
|
||||
|
||||
@@ -9,12 +9,13 @@ import com.dfsek.terra.api.command.annotation.type.WorldCommand;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
|
||||
|
||||
@Command(
|
||||
subcommands = {
|
||||
@Subcommand(value = "query", aliases = {"q"}, clazz = ProfileQueryCommand.class),
|
||||
@Subcommand(value = "start", aliases = {"s"}, clazz = ProfileStartCommand.class),
|
||||
@Subcommand(value = "stop", aliases = {"st"}, clazz = ProfileStopCommand.class),
|
||||
@Subcommand(value = "reset", aliases = {"r"}, clazz = ProfileResetCommand.class)
|
||||
@Subcommand(value = "query", aliases = "q", clazz = ProfileQueryCommand.class),
|
||||
@Subcommand(value = "start", aliases = "s", clazz = ProfileStartCommand.class),
|
||||
@Subcommand(value = "stop", aliases = "st", clazz = ProfileStopCommand.class),
|
||||
@Subcommand(value = "reset", aliases = "r", clazz = ProfileResetCommand.class)
|
||||
},
|
||||
usage = "Commands to enable/disable/query/reset the profiler."
|
||||
)
|
||||
|
||||
@@ -7,12 +7,13 @@ import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
|
||||
|
||||
@Command
|
||||
@DebugCommand
|
||||
public class ProfileQueryCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
StringBuilder data = new StringBuilder("Terra Profiler data dump: \n");
|
||||
|
||||
@@ -7,12 +7,13 @@ import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
|
||||
|
||||
@Command
|
||||
@DebugCommand
|
||||
public class ProfileResetCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
main.getProfiler().reset();
|
||||
|
||||
@@ -7,12 +7,13 @@ import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
|
||||
|
||||
@Command
|
||||
@DebugCommand
|
||||
public class ProfileStartCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
main.getProfiler().start();
|
||||
|
||||
@@ -7,12 +7,13 @@ import com.dfsek.terra.api.command.annotation.type.DebugCommand;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
|
||||
|
||||
@Command
|
||||
@DebugCommand
|
||||
public class ProfileStopCommand implements CommandTemplate {
|
||||
@Inject
|
||||
private TerraPlugin main;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
main.getProfiler().stop();
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.dfsek.terra.config;
|
||||
|
||||
import com.dfsek.tectonic.loading.TypeRegistry;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
@@ -14,25 +17,25 @@ import com.dfsek.terra.config.loaders.MaterialSetLoader;
|
||||
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
|
||||
import com.dfsek.terra.config.loaders.RangeLoader;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class GenericLoaders implements LoaderRegistrar {
|
||||
private final TerraPlugin main;
|
||||
|
||||
|
||||
public GenericLoaders(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
registry.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader())
|
||||
.registerLoader(Range.class, new RangeLoader())
|
||||
.registerLoader(MaterialSet.class, new MaterialSetLoader())
|
||||
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader());
|
||||
|
||||
|
||||
if(main != null) {
|
||||
registry.registerLoader(TerraAddon.class, main.getAddons())
|
||||
.registerLoader(BlockType.class, (t, object, cf) -> main.getWorldHandle().createBlockData((String) object).getBlockType())
|
||||
.registerLoader(BlockType.class,
|
||||
(t, object, cf) -> main.getWorldHandle().createBlockData((String) object).getBlockType())
|
||||
.registerLoader(BlockState.class, (t, object, cf) -> main.getWorldHandle().createBlockData((String) object));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,81 +6,75 @@ import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.yaml.YamlConfiguration;
|
||||
import com.dfsek.terra.api.Logger;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.Logger;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class PluginConfigImpl implements ConfigTemplate, com.dfsek.terra.api.config.PluginConfig {
|
||||
@Value("debug.commands")
|
||||
@Default
|
||||
private boolean debugCommands = false;
|
||||
|
||||
|
||||
@Value("debug.log")
|
||||
@Default
|
||||
private boolean debugLog = false;
|
||||
|
||||
|
||||
@Value("debug.profiler")
|
||||
@Default
|
||||
private boolean debugProfiler = false;
|
||||
|
||||
|
||||
@Value("debug.script")
|
||||
@Default
|
||||
private boolean debugScript = false;
|
||||
|
||||
|
||||
@Value("language")
|
||||
@Default
|
||||
private String language = "en_us";
|
||||
|
||||
|
||||
@Value("data-save")
|
||||
@Default
|
||||
private Duration dataSave = Duration.parse("PT6M");
|
||||
|
||||
|
||||
@Value("biome-search-resolution")
|
||||
@Default
|
||||
private int biomeSearch = 4;
|
||||
|
||||
|
||||
@Value("cache.carver")
|
||||
@Default
|
||||
private int carverCache = 256;
|
||||
|
||||
|
||||
@Value("cache.structure")
|
||||
@Default
|
||||
private int structureCache = 32;
|
||||
|
||||
|
||||
@Value("cache.sampler")
|
||||
@Default
|
||||
private int samplerCache = 64;
|
||||
|
||||
|
||||
@Value("cache.biome")
|
||||
@Default
|
||||
private int biomeCache = 512;
|
||||
|
||||
|
||||
@Value("cache.biome-provider")
|
||||
@Default
|
||||
private int providerCache = 32;
|
||||
|
||||
|
||||
@Value("dump-default")
|
||||
@Default
|
||||
private boolean dumpDefaultData = true;
|
||||
|
||||
|
||||
@Value("script.max-recursion")
|
||||
@Default
|
||||
private int maxRecursion = 1000;
|
||||
|
||||
|
||||
@Override
|
||||
public void load(TerraPlugin main) {
|
||||
Logger logger = main.logger();
|
||||
@@ -92,80 +86,80 @@ public class PluginConfigImpl implements ConfigTemplate, com.dfsek.terra.api.con
|
||||
logger.severe("Failed to load config");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
if(isDebugCommands()) logger.info("Debug commands enabled.");
|
||||
if(isDebugLogging()) logger.info("Debug logging enabled.");
|
||||
if(isDebugProfiler()) logger.info("Debug profiler enabled.");
|
||||
if(isDebugScript()) logger.info("Script debug blocks enabled.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugCommands() {
|
||||
return debugCommands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugLogging() {
|
||||
return debugLog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugProfiler() {
|
||||
return debugProfiler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugScript() {
|
||||
return debugScript;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDataSaveInterval() {
|
||||
return dataSave.toMillis() / 20L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiomeSearchResolution() {
|
||||
return biomeSearch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCarverCacheSize() {
|
||||
return carverCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStructureCache() {
|
||||
return structureCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSamplerCache() {
|
||||
return samplerCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRecursion() {
|
||||
return maxRecursion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiomeCache() {
|
||||
return biomeCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProviderCache() {
|
||||
return providerCache;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean dumpDefaultConfig() {
|
||||
return dumpDefaultData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugCommands() {
|
||||
return debugCommands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugLogging() {
|
||||
return debugLog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugProfiler() {
|
||||
return debugProfiler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugScript() {
|
||||
return debugScript;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDataSaveInterval() {
|
||||
return dataSave.toMillis() / 20L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiomeSearchResolution() {
|
||||
return biomeSearch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCarverCacheSize() {
|
||||
return carverCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStructureCache() {
|
||||
return structureCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSamplerCache() {
|
||||
return samplerCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRecursion() {
|
||||
return maxRecursion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiomeCache() {
|
||||
return biomeCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProviderCache() {
|
||||
return providerCache;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,64 +11,65 @@ import com.dfsek.terra.api.world.World;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.generator.ChunkGenerator;
|
||||
|
||||
|
||||
public class DummyWorld implements World {
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
throw new UnsupportedOperationException("Cannot get handle of DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return 2403L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(int x, int z) {
|
||||
throw new UnsupportedOperationException("Cannot get chunk in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockData(int x, int y, int z) {
|
||||
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockData(int x, int y, int z, BlockState data, boolean physics) {
|
||||
throw new UnsupportedOperationException("Cannot set block in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockState(int x, int y, int z) {
|
||||
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(Vector3 location, EntityType entityType) {
|
||||
throw new UnsupportedOperationException("Cannot spawn entity in DummyWorld");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlockData(int x, int y, int z, BlockState data, boolean physics) {
|
||||
throw new UnsupportedOperationException("Cannot set block in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return 2403L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHeight() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAt(int x, int z) {
|
||||
throw new UnsupportedOperationException("Cannot get chunk in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockData(int x, int y, int z) {
|
||||
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockState(int x, int y, int z) {
|
||||
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getGenerator() {
|
||||
throw new UnsupportedOperationException("Cannot get generator of DummyWorld");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProvider() {
|
||||
throw new UnsupportedOperationException("Cannot get biome provider of DummyWorld");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WorldConfig getConfig() {
|
||||
throw new UnsupportedOperationException("Cannot get config of DummyWorld");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
throw new UnsupportedOperationException("Cannot get handle of DummyWorld");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,21 +9,22 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
/**
|
||||
* Load all {@code *.yml} files from a {@link java.nio.file.Path}.
|
||||
*/
|
||||
public class FolderLoader extends LoaderImpl {
|
||||
private final Path path;
|
||||
|
||||
|
||||
public FolderLoader(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public InputStream get(String singleFile) throws IOException {
|
||||
return new FileInputStream(new File(path.toFile(), singleFile));
|
||||
}
|
||||
|
||||
|
||||
protected void load(String directory, String extension) {
|
||||
File newPath = new File(path.toFile(), directory);
|
||||
newPath.mkdirs();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.dfsek.terra.config.fileloaders;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -12,21 +11,24 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
|
||||
|
||||
public abstract class LoaderImpl implements Loader {
|
||||
protected final Map<String, InputStream> streams = new HashMap<>();
|
||||
|
||||
|
||||
@Override
|
||||
public Loader thenNames(Consumer<List<String>> consumer) throws ConfigException {
|
||||
consumer.accept(new ArrayList<>(streams.keySet()));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Loader thenEntries(Consumer<Set<Map.Entry<String, InputStream>>> consumer) throws ConfigException {
|
||||
consumer.accept(streams.entrySet());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a subdirectory.
|
||||
*
|
||||
@@ -39,9 +41,7 @@ public abstract class LoaderImpl implements Loader {
|
||||
load(directory, extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract void load(String directory, String extension);
|
||||
|
||||
|
||||
/**
|
||||
* Close all InputStreams opened.
|
||||
*/
|
||||
@@ -57,4 +57,6 @@ public abstract class LoaderImpl implements Loader {
|
||||
streams.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract void load(String directory, String extension);
|
||||
}
|
||||
|
||||
@@ -6,13 +6,14 @@ import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
|
||||
public class ZIPLoader extends LoaderImpl {
|
||||
private final ZipFile file;
|
||||
|
||||
|
||||
public ZIPLoader(ZipFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public InputStream get(String singleFile) throws IOException {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
@@ -22,7 +23,7 @@ public class ZIPLoader extends LoaderImpl {
|
||||
}
|
||||
throw new IllegalArgumentException("No such file: " + singleFile);
|
||||
}
|
||||
|
||||
|
||||
protected void load(String directory, String extension) {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package com.dfsek.terra.config.lang;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.dfsek.terra.api.Logger;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.lang.Language;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class LangUtil {
|
||||
private static Language language;
|
||||
|
||||
|
||||
public static void load(String langID, TerraPlugin main) {
|
||||
Logger logger = main.logger();
|
||||
File file = new File(main.getDataFolder(), "lang");
|
||||
@@ -25,11 +26,11 @@ public final class LangUtil {
|
||||
logger.severe("Double-check your configuration before reporting this to Terra!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Language getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
|
||||
public static void send(String messageID, CommandSender sender, String... args) {
|
||||
language.getMessage(messageID).send(sender, args);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ package com.dfsek.terra.config.lang;
|
||||
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.yaml.YamlConfiguration;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.lang.Message;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -13,20 +11,34 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.lang.Message;
|
||||
|
||||
|
||||
public class LanguageImpl implements com.dfsek.terra.api.lang.Language {
|
||||
private final Configuration configuration;
|
||||
|
||||
|
||||
public LanguageImpl(File file) throws IOException {
|
||||
configuration = new YamlConfiguration(new FileInputStream(file), file.getName());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void log(String messageID, Level level, Logger logger, String... args) {
|
||||
getMessage(messageID).log(logger, level, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String messageID, CommandSender sender, String... args) {
|
||||
getMessage(messageID).send(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Message getMessage(String id) {
|
||||
Message temp = null;
|
||||
if(configuration.contains(id)) {
|
||||
Object m = configuration.get(id);
|
||||
|
||||
|
||||
if(m instanceof List) {
|
||||
temp = new MultiLineMessage((List<String>) m);
|
||||
} else if(m instanceof String) {
|
||||
@@ -36,14 +48,4 @@ public class LanguageImpl implements com.dfsek.terra.api.lang.Language {
|
||||
if(temp == null || temp.isEmpty()) return new SingleLineMessage("message:" + id + ":translation_undefined");
|
||||
return temp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String messageID, Level level, Logger logger, String... args) {
|
||||
getMessage(messageID).log(logger, level, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String messageID, CommandSender sender, String... args) {
|
||||
getMessage(messageID).send(sender, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
package com.dfsek.terra.config.lang;
|
||||
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.lang.Message;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.lang.Message;
|
||||
|
||||
|
||||
public class MultiLineMessage implements Message {
|
||||
private final List<String> message;
|
||||
|
||||
|
||||
public MultiLineMessage(List<String> message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void log(Logger logger, Level level, String... args) {
|
||||
for(String line : message) {
|
||||
logger.log(level, String.format(line, Arrays.asList(args).toArray()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void send(CommandSender sender, String... args) {
|
||||
for(String line : message) {
|
||||
sender.sendMessage(String.format(line, Arrays.asList(args).toArray()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return message == null || message.isEmpty();
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
package com.dfsek.terra.config.lang;
|
||||
|
||||
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.lang.Message;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.api.lang.Message;
|
||||
|
||||
|
||||
public class SingleLineMessage implements Message {
|
||||
private final String message;
|
||||
|
||||
|
||||
public SingleLineMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
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, String... args) {
|
||||
sender.sendMessage(String.format(message, Arrays.asList(args).toArray()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return message == null || message.equals("");
|
||||
|
||||
@@ -6,20 +6,21 @@ import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
|
||||
|
||||
public class GenericTemplateSupplierLoader<T> implements TypeLoader<T> {
|
||||
private final Registry<Supplier<ObjectTemplate<T>>> registry;
|
||||
|
||||
|
||||
public GenericTemplateSupplierLoader(Registry<Supplier<ObjectTemplate<T>>> registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
|
||||
|
||||
@@ -6,11 +6,10 @@ import com.dfsek.tectonic.loading.TypeLoader;
|
||||
|
||||
import java.lang.reflect.AnnotatedParameterizedType;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class LinkedHashMapLoader implements TypeLoader<LinkedHashMap<Object, Object>> {
|
||||
@Override
|
||||
@@ -25,7 +24,7 @@ public class LinkedHashMapLoader implements TypeLoader<LinkedHashMap<Object, Obj
|
||||
map.put(loader.loadType(key, entry.getKey()), loader.loadType(value, entry.getValue()));
|
||||
}
|
||||
} else throw new LoadException("Unable to load config");
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ package com.dfsek.terra.config.loaders;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class MaterialSetLoader implements TypeLoader<MaterialSet> {
|
||||
@@ -16,7 +17,7 @@ public class MaterialSetLoader implements TypeLoader<MaterialSet> {
|
||||
public MaterialSet load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
List<String> stringData = (List<String>) o;
|
||||
MaterialSet set = new MaterialSet();
|
||||
|
||||
|
||||
for(String string : stringData) {
|
||||
try {
|
||||
set.add(configLoader.loadType(BlockType.class, string));
|
||||
@@ -24,7 +25,7 @@ public class MaterialSetLoader implements TypeLoader<MaterialSet> {
|
||||
throw new LoadException("Invalid data identifier \"" + string + "\"", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,21 @@ package com.dfsek.terra.config.loaders;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
import java.lang.reflect.AnnotatedParameterizedType;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
|
||||
@Override
|
||||
public ProbabilityCollection<Object> load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
ProbabilityCollection<Object> collection = new ProbabilityCollection<>();
|
||||
|
||||
|
||||
if(type instanceof AnnotatedParameterizedType) {
|
||||
AnnotatedParameterizedType pType = (AnnotatedParameterizedType) type;
|
||||
AnnotatedType generic = pType.getAnnotatedActualTypeArguments()[0];
|
||||
@@ -41,9 +41,9 @@ public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollec
|
||||
throw new LoadException("Malformed Probability Collection: " + o);
|
||||
}
|
||||
} else throw new LoadException("Unable to load config! Could not retrieve parameterized type: " + type);
|
||||
|
||||
|
||||
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ package com.dfsek.terra.config.loaders;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.util.ConstantRange;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class RangeLoader implements TypeLoader<Range> {
|
||||
@@ -19,7 +20,7 @@ public class RangeLoader implements TypeLoader<Range> {
|
||||
return new ConstantRange(map.get("min"), map.get("max"));
|
||||
} else {
|
||||
int h = configLoader.loadType(Integer.class, o);
|
||||
return new ConstantRange(h, h+1);
|
||||
return new ConstantRange(h, h + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,22 @@ package com.dfsek.terra.config.loaders.config;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
|
||||
|
||||
public class BufferedImageLoader implements TypeLoader<BufferedImage> {
|
||||
private final Loader files;
|
||||
|
||||
|
||||
public BufferedImageLoader(Loader files) {
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BufferedImage load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
|
||||
try {
|
||||
|
||||
@@ -2,12 +2,13 @@ package com.dfsek.terra.config.loaders.config;
|
||||
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.structure.StructureSpawn;
|
||||
import com.dfsek.terra.math.GridSpawn;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class GridSpawnLoader implements TypeLoader<StructureSpawn> {
|
||||
|
||||
@@ -3,17 +3,19 @@ package com.dfsek.terra.config.pack;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
|
||||
|
||||
public class ConfigPackAddonsTemplate implements ConfigTemplate {
|
||||
@Value("addons")
|
||||
@Default
|
||||
private Set<TerraAddon> addons = new HashSet<>();
|
||||
|
||||
|
||||
private final Set<TerraAddon> addons = new HashSet<>();
|
||||
|
||||
|
||||
public Set<TerraAddon> getAddons() {
|
||||
return addons;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,27 @@ import com.dfsek.tectonic.loading.TypeLoader;
|
||||
import com.dfsek.tectonic.loading.TypeRegistry;
|
||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||
import com.dfsek.tectonic.yaml.YamlConfiguration;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
import com.dfsek.terra.api.config.ConfigFactory;
|
||||
@@ -52,83 +73,63 @@ import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||
import com.dfsek.terra.registry.RegistryFactoryImpl;
|
||||
import com.dfsek.terra.registry.config.ConfigTypeRegistry;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a Terra configuration pack.
|
||||
*/
|
||||
public class ConfigPackImpl implements ConfigPack {
|
||||
private final ConfigPackTemplate template = new ConfigPackTemplate();
|
||||
|
||||
|
||||
private final RegistryFactory registryFactory = new RegistryFactoryImpl();
|
||||
|
||||
|
||||
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
|
||||
private final ConfigLoader selfLoader = new ConfigLoader();
|
||||
private final Scope varScope = new Scope();
|
||||
private final TerraPlugin main;
|
||||
private final Loader loader;
|
||||
|
||||
|
||||
private final Configuration configuration;
|
||||
|
||||
|
||||
private final Set<TerraAddon> addons;
|
||||
|
||||
|
||||
private final BiomeProvider seededBiomeProvider;
|
||||
|
||||
|
||||
private final Map<Type, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> registryMap = new HashMap<>();
|
||||
|
||||
|
||||
private final ConfigTypeRegistry configTypeRegistry;
|
||||
|
||||
|
||||
|
||||
|
||||
private final TreeMap<Integer, List<ImmutablePair<String, ConfigType<?, ?>>>> configTypes = new TreeMap<>();
|
||||
|
||||
|
||||
public ConfigPackImpl(File folder, TerraPlugin main) throws ConfigException {
|
||||
try {
|
||||
this.loader = new FolderLoader(folder.toPath());
|
||||
this.main = main;
|
||||
this.configTypeRegistry = createRegistry();
|
||||
long l = System.nanoTime();
|
||||
|
||||
|
||||
register(abstractConfigLoader);
|
||||
main.register(abstractConfigLoader);
|
||||
|
||||
|
||||
register(selfLoader);
|
||||
main.register(selfLoader);
|
||||
|
||||
|
||||
File pack = new File(folder, "pack.yml");
|
||||
|
||||
|
||||
try {
|
||||
this.configuration = new YamlConfiguration(new FileInputStream(pack), "pack.yml");
|
||||
|
||||
|
||||
ConfigPackAddonsTemplate addonsTemplate = new ConfigPackAddonsTemplate();
|
||||
selfLoader.load(addonsTemplate, configuration);
|
||||
this.addons = addonsTemplate.getAddons();
|
||||
|
||||
|
||||
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this, template -> selfLoader.load(template, configuration)));
|
||||
|
||||
|
||||
selfLoader.load(template, configuration);
|
||||
|
||||
|
||||
main.logger().info("Loading config pack \"" + template.getID() + "\"");
|
||||
load(l, main);
|
||||
|
||||
|
||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||
selfLoader.load(packPostTemplate, configuration);
|
||||
seededBiomeProvider = packPostTemplate.getProviderBuilder();
|
||||
@@ -142,20 +143,20 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
}
|
||||
toWorldConfig(new DummyWorld()); // Build now to catch any errors immediately.
|
||||
}
|
||||
|
||||
|
||||
public ConfigPackImpl(ZipFile file, TerraPlugin main) throws ConfigException {
|
||||
try {
|
||||
this.loader = new ZIPLoader(file);
|
||||
this.main = main;
|
||||
this.configTypeRegistry = createRegistry();
|
||||
long l = System.nanoTime();
|
||||
|
||||
|
||||
register(selfLoader);
|
||||
main.register(selfLoader);
|
||||
|
||||
|
||||
register(abstractConfigLoader);
|
||||
main.register(abstractConfigLoader);
|
||||
|
||||
|
||||
try {
|
||||
ZipEntry pack = null;
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
@@ -163,25 +164,25 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(entry.getName().equals("pack.yml")) pack = entry;
|
||||
}
|
||||
|
||||
|
||||
if(pack == null) throw new LoadException("No pack.yml file found in " + file.getName());
|
||||
|
||||
|
||||
this.configuration = new YamlConfiguration(file.getInputStream(pack), "pack.yml");
|
||||
|
||||
|
||||
ConfigPackAddonsTemplate addonsTemplate = new ConfigPackAddonsTemplate();
|
||||
selfLoader.load(addonsTemplate, configuration);
|
||||
this.addons = addonsTemplate.getAddons();
|
||||
|
||||
|
||||
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this, template -> selfLoader.load(template, configuration)));
|
||||
|
||||
|
||||
|
||||
|
||||
selfLoader.load(template, configuration);
|
||||
main.logger().info("Loading config pack \"" + template.getID() + "\"");
|
||||
|
||||
|
||||
load(l, main);
|
||||
|
||||
|
||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||
|
||||
|
||||
selfLoader.load(packPostTemplate, configuration);
|
||||
seededBiomeProvider = packPostTemplate.getProviderBuilder();
|
||||
checkDeadEntries(main);
|
||||
@@ -192,127 +193,24 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
main.logger().severe("Failed to load config pack from ZIP archive \"" + file.getName() + "\"");
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
toWorldConfig(new DummyWorld()); // Build now to catch any errors immediately.
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ConfigTypeRegistry createRegistry() {
|
||||
return new ConfigTypeRegistry(main, (id, configType) -> {
|
||||
OpenRegistry<?> openRegistry = configType.registrySupplier(this).get();
|
||||
if(registryMap.containsKey(configType.getTypeKey().getType())) { // Someone already registered something; we need to copy things to the new registry.
|
||||
registryMap.get(configType.getTypeKey().getType()).getLeft().forEach(((OpenRegistry<Object>) openRegistry)::register);
|
||||
}
|
||||
selfLoader.registerLoader(configType.getTypeKey().getType(), openRegistry);
|
||||
abstractConfigLoader.registerLoader(configType.getTypeKey().getType(), openRegistry);
|
||||
registryMap.put(configType.getTypeKey().getType(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry)));
|
||||
});
|
||||
}
|
||||
|
||||
private void checkDeadEntries(TerraPlugin main) {
|
||||
registryMap.forEach((clazz, pair) -> ((OpenRegistryImpl<?>) pair.getLeft()).getDeadEntries().forEach((id, value) -> main.getDebugLogger().warning("Dead entry in '" + ReflectionUtil.typeToString(clazz) + "' registry: '" + id + "'")));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> ConfigPackImpl applyLoader(Type type, TypeLoader<T> loader) {
|
||||
abstractConfigLoader.registerLoader(type, loader);
|
||||
selfLoader.registerLoader(type, loader);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> ConfigPackImpl applyLoader(Type type, Supplier<ObjectTemplate<T>> loader) {
|
||||
abstractConfigLoader.registerLoader(type, loader);
|
||||
selfLoader.registerLoader(type, loader);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Map<Type, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> getRegistryMap() {
|
||||
return registryMap;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private void load(long start, TerraPlugin main) throws ConfigException {
|
||||
configTypes.values().forEach(list -> list.forEach(pair -> configTypeRegistry.register(pair.getLeft(), pair.getRight())));
|
||||
|
||||
for(Map.Entry<String, Double> var : template.getVariables().entrySet()) {
|
||||
varScope.create(var.getKey(), var.getValue());
|
||||
}
|
||||
|
||||
Map<String, Configuration> configurations = new HashMap<>();
|
||||
|
||||
main.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader, configurations::put)); // Create all the configs.
|
||||
|
||||
MetaStringPreprocessor stringPreprocessor = new MetaStringPreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, stringPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, stringPreprocessor);
|
||||
|
||||
MetaListLikePreprocessor listPreprocessor = new MetaListLikePreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, listPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, listPreprocessor);
|
||||
|
||||
MetaMapPreprocessor mapPreprocessor = new MetaMapPreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, mapPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, mapPreprocessor);
|
||||
|
||||
MetaValuePreprocessor valuePreprocessor = new MetaValuePreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
|
||||
MetaNumberPreprocessor numberPreprocessor = new MetaNumberPreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, numberPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, numberPreprocessor);
|
||||
|
||||
Map<ConfigType<? extends ConfigTemplate, ?>, List<Configuration>> configs = new HashMap<>();
|
||||
|
||||
for(Configuration configuration : configurations.values()) { // Sort the configs
|
||||
if(configuration.contains("type")) { // Only sort configs with type key
|
||||
ProtoConfig config = new ProtoConfig();
|
||||
selfLoader.load(config, configuration);
|
||||
configs.computeIfAbsent(config.getType(), configType -> new ArrayList<>()).add(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
for(ConfigType<?, ?> configType : configTypeRegistry.entries()) { // Load the configs
|
||||
CheckedRegistry registry = getCheckedRegistry(configType.getTypeKey());
|
||||
main.getEventManager().callEvent(new ConfigTypePreLoadEvent(configType, registry, this));
|
||||
for(AbstractConfiguration config : abstractConfigLoader.loadConfigs(configs.getOrDefault(configType, Collections.emptyList()))) {
|
||||
try {
|
||||
Object loaded = ((ConfigFactory) configType.getFactory()).build(selfLoader.load(configType.getTemplate(this, main), config), main);
|
||||
registry.register(config.getID(), loaded);
|
||||
main.getEventManager().callEvent(new ConfigurationLoadEvent(this, config, template -> selfLoader.load(template, config), configType, loaded));
|
||||
} catch(DuplicateEntryException e) {
|
||||
throw new LoadException("Duplicate registry entry: ", e);
|
||||
}
|
||||
}
|
||||
main.getEventManager().callEvent(new ConfigTypePostLoadEvent(configType, registry, this));
|
||||
}
|
||||
|
||||
main.getEventManager().callEvent(new ConfigPackPostLoadEvent(this, template -> selfLoader.load(template, configuration)));
|
||||
main.logger().info("Loaded config pack \"" + template.getID() + "\" v" + template.getVersion() + " by " + template.getAuthor() + " in " + (System.nanoTime() - start) / 1000000D + "ms.");
|
||||
}
|
||||
|
||||
public ConfigPackTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> CheckedRegistry<T> getRegistry(Type type) {
|
||||
return (CheckedRegistry<T>) registryMap.getOrDefault(type, ImmutablePair.ofNull()).getRight();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> CheckedRegistry<T> getCheckedRegistry(Type type) throws IllegalStateException {
|
||||
return (CheckedRegistry<T>) registryMap.getOrDefault(type, ImmutablePair.ofNull()).getRight();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> OpenRegistry<T> getOpenRegistry(Class<T> clazz) {
|
||||
return (OpenRegistry<T>) registryMap.getOrDefault(clazz, ImmutablePair.ofNull()).getLeft();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
registry
|
||||
@@ -320,57 +218,12 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
.registerLoader(BufferedImage.class, new BufferedImageLoader(loader));
|
||||
registryMap.forEach((clazz, reg) -> registry.registerLoader(clazz, reg.getLeft()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProviderBuilder() {
|
||||
return seededBiomeProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> CheckedRegistry<T> getOrCreateRegistry(Type type) {
|
||||
return (CheckedRegistry<T>) registryMap.computeIfAbsent(type, c -> {
|
||||
OpenRegistry<T> registry = new OpenRegistryImpl<>();
|
||||
selfLoader.registerLoader(c, registry);
|
||||
abstractConfigLoader.registerLoader(c, registry);
|
||||
main.getDebugLogger().info("Registered loader for registry of class " + ReflectionUtil.typeToString(c));
|
||||
|
||||
if(type instanceof ParameterizedType) {
|
||||
ParameterizedType param = (ParameterizedType) type;
|
||||
Type base = param.getRawType();
|
||||
if(base instanceof Class // should always be true but we'll check anyways
|
||||
&& Supplier.class.isAssignableFrom((Class<?>) base)) { // If it's a supplier
|
||||
Type supplied = param.getActualTypeArguments()[0]; // Grab the supplied type
|
||||
if(supplied instanceof ParameterizedType) {
|
||||
ParameterizedType suppliedParam = (ParameterizedType) supplied;
|
||||
Type suppliedBase = suppliedParam.getRawType();
|
||||
if(suppliedBase instanceof Class // should always be true but we'll check anyways
|
||||
&& ObjectTemplate.class.isAssignableFrom((Class<?>) suppliedBase)) {
|
||||
Type templateType = suppliedParam.getActualTypeArguments()[0];
|
||||
GenericTemplateSupplierLoader<?> loader = new GenericTemplateSupplierLoader<>((Registry<Supplier<ObjectTemplate<Supplier<ObjectTemplate<?>>>>>) registry);
|
||||
selfLoader.registerLoader(templateType, loader);
|
||||
abstractConfigLoader.registerLoader(templateType, loader);
|
||||
main.getDebugLogger().info("Registered template loader for registry of class " + ReflectionUtil.typeToString(templateType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ImmutablePair.of(registry, new CheckedRegistryImpl<>(registry));
|
||||
}).getRight();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public WorldConfigImpl toWorldConfig(World world) {
|
||||
return new WorldConfigImpl(world, this, main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GenerationStageProvider> getStages() {
|
||||
return template.getStages();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void registerConfigType(ConfigType<?, ?> type, String id, int priority) {
|
||||
Set<String> contained = new HashSet<>();
|
||||
@@ -380,74 +233,236 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
}));
|
||||
configTypes.computeIfAbsent(priority, p -> new ArrayList<>()).add(ImmutablePair.of(id, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader getLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<TerraAddon> addons() {
|
||||
return addons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return template.getID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return template.getAuthor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return template.getVersion();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean vanillaMobs() {
|
||||
return template.vanillaMobs();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean vanillaStructures() {
|
||||
return template.vanillaStructures();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean vanillaCaves() {
|
||||
return template.vanillaCaves();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean disableStructures() {
|
||||
return template.disableStructures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getLocatable() {
|
||||
return template.getLocatable();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean doBetaCarvers() {
|
||||
return template.doBetaCarvers();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean vanillaFlora() {
|
||||
return template.vanillaDecorations();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getBiomeProviderBuilder() {
|
||||
return seededBiomeProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> CheckedRegistry<T> getOrCreateRegistry(Type type) {
|
||||
return (CheckedRegistry<T>) registryMap.computeIfAbsent(type, c -> {
|
||||
OpenRegistry<T> registry = new OpenRegistryImpl<>();
|
||||
selfLoader.registerLoader(c, registry);
|
||||
abstractConfigLoader.registerLoader(c, registry);
|
||||
main.getDebugLogger().info("Registered loader for registry of class " + ReflectionUtil.typeToString(c));
|
||||
|
||||
if(type instanceof ParameterizedType) {
|
||||
ParameterizedType param = (ParameterizedType) type;
|
||||
Type base = param.getRawType();
|
||||
if(base instanceof Class // should always be true but we'll check anyways
|
||||
&& Supplier.class.isAssignableFrom((Class<?>) base)) { // If it's a supplier
|
||||
Type supplied = param.getActualTypeArguments()[0]; // Grab the supplied type
|
||||
if(supplied instanceof ParameterizedType) {
|
||||
ParameterizedType suppliedParam = (ParameterizedType) supplied;
|
||||
Type suppliedBase = suppliedParam.getRawType();
|
||||
if(suppliedBase instanceof Class // should always be true but we'll check anyways
|
||||
&& ObjectTemplate.class.isAssignableFrom((Class<?>) suppliedBase)) {
|
||||
Type templateType = suppliedParam.getActualTypeArguments()[0];
|
||||
GenericTemplateSupplierLoader<?> loader = new GenericTemplateSupplierLoader<>(
|
||||
(Registry<Supplier<ObjectTemplate<Supplier<ObjectTemplate<?>>>>>) registry);
|
||||
selfLoader.registerLoader(templateType, loader);
|
||||
abstractConfigLoader.registerLoader(templateType, loader);
|
||||
main.getDebugLogger().info(
|
||||
"Registered template loader for registry of class " + ReflectionUtil.typeToString(templateType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ImmutablePair.of(registry, new CheckedRegistryImpl<>(registry));
|
||||
}).getRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GenerationStageProvider> getStages() {
|
||||
return template.getStages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader getLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return template.getAuthor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return template.getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getLocatable() {
|
||||
return template.getLocatable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryFactory getRegistryFactory() {
|
||||
return registryFactory;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChunkGeneratorProvider getGeneratorProvider() {
|
||||
return template.getGeneratorProvider();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ConfigTypeRegistry createRegistry() {
|
||||
return new ConfigTypeRegistry(main, (id, configType) -> {
|
||||
OpenRegistry<?> openRegistry = configType.registrySupplier(this).get();
|
||||
if(registryMap.containsKey(configType.getTypeKey()
|
||||
.getType())) { // Someone already registered something; we need to copy things to the
|
||||
// new registry.
|
||||
registryMap.get(configType.getTypeKey().getType()).getLeft().forEach(((OpenRegistry<Object>) openRegistry)::register);
|
||||
}
|
||||
selfLoader.registerLoader(configType.getTypeKey().getType(), openRegistry);
|
||||
abstractConfigLoader.registerLoader(configType.getTypeKey().getType(), openRegistry);
|
||||
registryMap.put(configType.getTypeKey().getType(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry)));
|
||||
});
|
||||
}
|
||||
|
||||
private void checkDeadEntries(TerraPlugin main) {
|
||||
registryMap.forEach((clazz, pair) -> ((OpenRegistryImpl<?>) pair.getLeft()).getDeadEntries()
|
||||
.forEach((id, value) -> main.getDebugLogger()
|
||||
.warning("Dead entry in '" +
|
||||
ReflectionUtil.typeToString(
|
||||
clazz) +
|
||||
"' registry: '" +
|
||||
id + "'")));
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private void load(long start, TerraPlugin main) throws ConfigException {
|
||||
configTypes.values().forEach(list -> list.forEach(pair -> configTypeRegistry.register(pair.getLeft(), pair.getRight())));
|
||||
|
||||
for(Map.Entry<String, Double> var : template.getVariables().entrySet()) {
|
||||
varScope.create(var.getKey(), var.getValue());
|
||||
}
|
||||
|
||||
Map<String, Configuration> configurations = new HashMap<>();
|
||||
|
||||
main.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader, configurations::put)); // Create all the configs.
|
||||
|
||||
MetaStringPreprocessor stringPreprocessor = new MetaStringPreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, stringPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, stringPreprocessor);
|
||||
|
||||
MetaListLikePreprocessor listPreprocessor = new MetaListLikePreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, listPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, listPreprocessor);
|
||||
|
||||
MetaMapPreprocessor mapPreprocessor = new MetaMapPreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, mapPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, mapPreprocessor);
|
||||
|
||||
MetaValuePreprocessor valuePreprocessor = new MetaValuePreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, valuePreprocessor);
|
||||
|
||||
MetaNumberPreprocessor numberPreprocessor = new MetaNumberPreprocessor(configurations);
|
||||
selfLoader.registerPreprocessor(Meta.class, numberPreprocessor);
|
||||
abstractConfigLoader.registerPreprocessor(Meta.class, numberPreprocessor);
|
||||
|
||||
Map<ConfigType<? extends ConfigTemplate, ?>, List<Configuration>> configs = new HashMap<>();
|
||||
|
||||
for(Configuration configuration : configurations.values()) { // Sort the configs
|
||||
if(configuration.contains("type")) { // Only sort configs with type key
|
||||
ProtoConfig config = new ProtoConfig();
|
||||
selfLoader.load(config, configuration);
|
||||
configs.computeIfAbsent(config.getType(), configType -> new ArrayList<>()).add(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
for(ConfigType<?, ?> configType : configTypeRegistry.entries()) { // Load the configs
|
||||
CheckedRegistry registry = getCheckedRegistry(configType.getTypeKey());
|
||||
main.getEventManager().callEvent(new ConfigTypePreLoadEvent(configType, registry, this));
|
||||
for(AbstractConfiguration config : abstractConfigLoader.loadConfigs(
|
||||
configs.getOrDefault(configType, Collections.emptyList()))) {
|
||||
try {
|
||||
Object loaded = ((ConfigFactory) configType.getFactory()).build(
|
||||
selfLoader.load(configType.getTemplate(this, main), config), main);
|
||||
registry.register(config.getID(), loaded);
|
||||
main.getEventManager().callEvent(
|
||||
new ConfigurationLoadEvent(this, config, template -> selfLoader.load(template, config), configType, loaded));
|
||||
} catch(DuplicateEntryException e) {
|
||||
throw new LoadException("Duplicate registry entry: ", e);
|
||||
}
|
||||
}
|
||||
main.getEventManager().callEvent(new ConfigTypePostLoadEvent(configType, registry, this));
|
||||
}
|
||||
|
||||
main.getEventManager().callEvent(new ConfigPackPostLoadEvent(this, template -> selfLoader.load(template, configuration)));
|
||||
main.logger().info(
|
||||
"Loaded config pack \"" + template.getID() + "\" v" + template.getVersion() + " by " + template.getAuthor() + " in " +
|
||||
(System.nanoTime() - start) / 1000000D + "ms.");
|
||||
}
|
||||
|
||||
protected Map<Type, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> getRegistryMap() {
|
||||
return registryMap;
|
||||
}
|
||||
|
||||
public ConfigPackTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> CheckedRegistry<T> getRegistry(Type type) {
|
||||
return (CheckedRegistry<T>) registryMap.getOrDefault(type, ImmutablePair.ofNull()).getRight();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> CheckedRegistry<T> getCheckedRegistry(Type type) throws IllegalStateException {
|
||||
return (CheckedRegistry<T>) registryMap.getOrDefault(type, ImmutablePair.ofNull()).getRight();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> OpenRegistry<T> getOpenRegistry(Class<T> clazz) {
|
||||
return (OpenRegistry<T>) registryMap.getOrDefault(clazz, ImmutablePair.ofNull()).getLeft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return template.getID();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@ package com.dfsek.terra.config.pack;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class ConfigPackPostTemplate implements ConfigTemplate {
|
||||
@Value("biomes")
|
||||
private @Meta BiomeProvider providerBuilder;
|
||||
|
||||
|
||||
public BiomeProvider getProviderBuilder() {
|
||||
return providerBuilder;
|
||||
}
|
||||
|
||||
@@ -3,163 +3,164 @@ package com.dfsek.terra.config.pack;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider;
|
||||
import com.dfsek.terra.api.world.generator.GenerationStageProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
||||
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
|
||||
public class ConfigPackTemplate implements ConfigTemplate {
|
||||
@Value("id")
|
||||
private String id;
|
||||
|
||||
|
||||
@Value("variables")
|
||||
@Default
|
||||
private @Meta Map<String, @Meta Double> variables = new HashMap<>();
|
||||
|
||||
|
||||
@Value("beta.carving")
|
||||
@Default
|
||||
private @Meta boolean betaCarvers = false;
|
||||
|
||||
|
||||
@Value("structures.locatable")
|
||||
@Default
|
||||
private @Meta Map<@Meta String, @Meta String> locatable = new HashMap<>();
|
||||
|
||||
|
||||
@Value("blend.terrain.elevation")
|
||||
@Default
|
||||
private @Meta int elevationBlend = 4;
|
||||
|
||||
|
||||
@Value("vanilla.mobs")
|
||||
@Default
|
||||
private @Meta boolean vanillaMobs = true;
|
||||
|
||||
|
||||
@Value("vanilla.caves")
|
||||
@Default
|
||||
private @Meta boolean vanillaCaves = false;
|
||||
|
||||
|
||||
@Value("vanilla.decorations")
|
||||
@Default
|
||||
private @Meta boolean vanillaDecorations = false;
|
||||
|
||||
|
||||
@Value("vanilla.structures")
|
||||
@Default
|
||||
private @Meta boolean vanillaStructures = false;
|
||||
|
||||
|
||||
@Value("author")
|
||||
@Default
|
||||
private String author = "Anon Y. Mous";
|
||||
|
||||
|
||||
@Value("disable.sapling")
|
||||
@Default
|
||||
private @Meta boolean disableSaplings = false;
|
||||
|
||||
|
||||
@Value("stages")
|
||||
private @Meta List<@Meta GenerationStageProvider> stages;
|
||||
|
||||
|
||||
@Value("version")
|
||||
@Default
|
||||
private String version = "0.1.0";
|
||||
|
||||
|
||||
@Value("disable.carvers")
|
||||
@Default
|
||||
private @Meta boolean disableCarvers = false;
|
||||
|
||||
|
||||
@Value("disable.structures")
|
||||
@Default
|
||||
private @Meta boolean disableStructures = false;
|
||||
|
||||
|
||||
@Value("disable.ores")
|
||||
@Default
|
||||
private @Meta boolean disableOres = false;
|
||||
|
||||
|
||||
@Value("disable.trees")
|
||||
@Default
|
||||
private @Meta boolean disableTrees = false;
|
||||
|
||||
|
||||
@Value("disable.flora")
|
||||
@Default
|
||||
private @Meta boolean disableFlora = false;
|
||||
|
||||
|
||||
@Value("generator")
|
||||
private @Meta ChunkGeneratorProvider generatorProvider;
|
||||
|
||||
public ChunkGeneratorProvider getGeneratorProvider() {
|
||||
return generatorProvider;
|
||||
}
|
||||
|
||||
public List<GenerationStageProvider> getStages() {
|
||||
return stages;
|
||||
}
|
||||
|
||||
|
||||
public boolean disableCarvers() {
|
||||
return disableCarvers;
|
||||
}
|
||||
|
||||
|
||||
public boolean disableFlora() {
|
||||
return disableFlora;
|
||||
}
|
||||
|
||||
|
||||
public boolean disableOres() {
|
||||
return disableOres;
|
||||
}
|
||||
|
||||
|
||||
public boolean disableStructures() {
|
||||
return disableStructures;
|
||||
}
|
||||
|
||||
|
||||
public boolean disableTrees() {
|
||||
return disableTrees;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean isDisableSaplings() {
|
||||
return disableSaplings;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
|
||||
public boolean vanillaMobs() {
|
||||
return vanillaMobs;
|
||||
}
|
||||
|
||||
|
||||
public boolean vanillaCaves() {
|
||||
return vanillaCaves;
|
||||
}
|
||||
|
||||
|
||||
public boolean vanillaDecorations() {
|
||||
return vanillaDecorations;
|
||||
}
|
||||
|
||||
|
||||
public boolean vanillaStructures() {
|
||||
return vanillaStructures;
|
||||
}
|
||||
|
||||
public Map<String, Double> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public int getElevationBlend() {
|
||||
return elevationBlend;
|
||||
}
|
||||
|
||||
public Map<String, String> getLocatable() {
|
||||
return locatable;
|
||||
}
|
||||
|
||||
|
||||
public boolean doBetaCarvers() {
|
||||
return betaCarvers;
|
||||
}
|
||||
|
||||
public ChunkGeneratorProvider getGeneratorProvider() {
|
||||
return generatorProvider;
|
||||
}
|
||||
|
||||
public List<GenerationStageProvider> getStages() {
|
||||
return stages;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean isDisableSaplings() {
|
||||
return disableSaplings;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public Map<String, Double> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public int getElevationBlend() {
|
||||
return elevationBlend;
|
||||
}
|
||||
|
||||
public Map<String, String> getLocatable() {
|
||||
return locatable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.dfsek.terra.config.pack;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.WorldConfig;
|
||||
@@ -10,111 +14,108 @@ import com.dfsek.terra.api.world.generator.SamplerCache;
|
||||
import com.dfsek.terra.registry.LockedRegistryImpl;
|
||||
import com.dfsek.terra.world.SamplerCacheImpl;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class WorldConfigImpl implements WorldConfig {
|
||||
private final SamplerCache samplerCache;
|
||||
|
||||
|
||||
private final BiomeProvider provider;
|
||||
|
||||
|
||||
private final World world;
|
||||
private final ConfigPackImpl pack;
|
||||
|
||||
|
||||
private final Map<Type, Registry<?>> registryMap = new HashMap<>();
|
||||
|
||||
|
||||
public WorldConfigImpl(World world, ConfigPackImpl pack, TerraPlugin main) {
|
||||
this.world = world;
|
||||
this.pack = pack;
|
||||
this.samplerCache = new SamplerCacheImpl(main, world);
|
||||
|
||||
|
||||
pack.getRegistryMap().forEach((clazz, pair) -> registryMap.put(clazz, new LockedRegistryImpl<>(pair.getLeft())));
|
||||
|
||||
|
||||
this.provider = pack.getBiomeProviderBuilder();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int elevationBlend() {
|
||||
return pack.getTemplate().getElevationBlend();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableTrees() {
|
||||
return pack.getTemplate().disableTrees();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableCarving() {
|
||||
return pack.getTemplate().disableCarvers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableOres() {
|
||||
return pack.getTemplate().disableOres();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableFlora() {
|
||||
return pack.getTemplate().disableFlora();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableStructures() {
|
||||
return pack.getTemplate().disableStructures();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Registry<T> getRegistry(Class<T> clazz) {
|
||||
return (LockedRegistryImpl<T>) registryMap.get(clazz);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SamplerCache getSamplerCache() {
|
||||
return samplerCache;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int elevationBlend() {
|
||||
return pack.getTemplate().getElevationBlend();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableTrees() {
|
||||
return pack.getTemplate().disableTrees();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableCarving() {
|
||||
return pack.getTemplate().disableCarvers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableOres() {
|
||||
return pack.getTemplate().disableOres();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableFlora() {
|
||||
return pack.getTemplate().disableFlora();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableStructures() {
|
||||
return pack.getTemplate().disableStructures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return pack.getID();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return pack.getAuthor();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return pack.getVersion();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, String> getLocatable() {
|
||||
return pack.getLocatable();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDisableSaplings() {
|
||||
return getTemplate().isDisableSaplings();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return pack.getID();
|
||||
}
|
||||
|
||||
public ConfigPackTemplate getTemplate() {
|
||||
return pack.getTemplate();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
@@ -14,11 +13,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
|
||||
public class MetaListLikePreprocessor extends MetaPreprocessor<Meta> {
|
||||
public MetaListLikePreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
@@ -26,38 +28,40 @@ public class MetaListLikePreprocessor extends MetaPreprocessor<Meta> {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) t.getType();
|
||||
if(parameterizedType.getRawType() instanceof Class) { // Should always be true but we check anyways
|
||||
Class<?> baseClass = (Class<?>) parameterizedType.getRawType();
|
||||
|
||||
if((List.class.isAssignableFrom(baseClass) || Set.class.isAssignableFrom(baseClass)) && c instanceof List) { // List or set metaconfig
|
||||
|
||||
if((List.class.isAssignableFrom(baseClass) || Set.class.isAssignableFrom(baseClass)) &&
|
||||
c instanceof List) { // List or set metaconfig
|
||||
List<Object> list = (List<Object>) c;
|
||||
|
||||
|
||||
int offset = 0;
|
||||
List<Object> newList = new ArrayList<>((List<Object>) c);
|
||||
|
||||
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
Object o = list.get(i);
|
||||
if(!(o instanceof String)) continue;
|
||||
String s = ((String) o).trim();
|
||||
if(!s.startsWith("<< ")) continue;
|
||||
String meta = s.substring(3);
|
||||
|
||||
|
||||
Object metaValue = getMetaValue(meta);
|
||||
|
||||
|
||||
if(!(metaValue instanceof List)) {
|
||||
throw new LoadException("MetaList/Set injection candidate must be list, is type " + metaValue.getClass().getCanonicalName());
|
||||
throw new LoadException(
|
||||
"MetaList/Set injection candidate must be list, is type " + metaValue.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
|
||||
List<Object> metaList = (List<Object>) metaValue;
|
||||
|
||||
|
||||
newList.remove(i + offset); // Remove placeholder
|
||||
newList.addAll(i + offset, metaList); // Add metalist values where placeholder was
|
||||
offset += metaList.size() - 1; // add metalist size to offset, subtract one to account for placeholder.
|
||||
}
|
||||
|
||||
|
||||
return (Result<T>) Result.overwrite(newList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Result.noOp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,23 +4,26 @@ import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
|
||||
public class MetaMapPreprocessor extends MetaPreprocessor<Meta> {
|
||||
private static final TypeKey<List<String>> STRING_LIST = new TypeKey<>() {
|
||||
};
|
||||
|
||||
public MetaMapPreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
private static final TypeKey<List<String>> STRING_LIST = new TypeKey<>() {};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
@@ -28,32 +31,33 @@ public class MetaMapPreprocessor extends MetaPreprocessor<Meta> {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) t.getType();
|
||||
if(parameterizedType.getRawType() instanceof Class) { // Should always be true but we check anyways
|
||||
Class<?> baseClass = (Class<?>) parameterizedType.getRawType();
|
||||
|
||||
|
||||
if(Map.class.isAssignableFrom(baseClass) && c instanceof Map) { // Map metaconfig
|
||||
Map<Object, Object> map = (Map<Object, Object>) c;
|
||||
|
||||
|
||||
Map<Object, Object> newMap = new HashMap<>(map);
|
||||
|
||||
|
||||
if(map.containsKey("<<")) {
|
||||
newMap.putAll(map);
|
||||
newMap.remove("<<"); // Remove placeholder
|
||||
|
||||
|
||||
List<String> keys = (List<String>) loader.loadType(STRING_LIST.getAnnotatedType(), map.get("<<"));
|
||||
keys.forEach(key -> {
|
||||
Object meta = getMetaValue(key);
|
||||
if(!(meta instanceof Map)) {
|
||||
throw new LoadException("MetaMap injection candidate must be list, is type " + meta.getClass().getCanonicalName());
|
||||
throw new LoadException(
|
||||
"MetaMap injection candidate must be list, is type " + meta.getClass().getCanonicalName());
|
||||
}
|
||||
newMap.putAll((Map<?, ?>) meta);
|
||||
});
|
||||
return (Result<T>) Result.overwrite(newMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Result.noOp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,22 +6,32 @@ import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.tectonic.util.ReflectionUtil;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public static final TypeKey<String> META_STRING_KEY = new TypeKey<@Meta String>() {};
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
|
||||
public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public static final TypeKey<String> META_STRING_KEY = new TypeKey<@Meta String>() {
|
||||
};
|
||||
|
||||
public MetaNumberPreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
|
||||
private static boolean isNumber(Class<?> clazz) {
|
||||
return Number.class.isAssignableFrom(clazz)
|
||||
|| byte.class.equals(clazz)
|
||||
|| int.class.equals(clazz)
|
||||
|| long.class.equals(clazz)
|
||||
|| float.class.equals(clazz)
|
||||
|| double.class.equals(clazz);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
@@ -35,13 +45,4 @@ public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
|
||||
}
|
||||
return Result.noOp();
|
||||
}
|
||||
|
||||
private static boolean isNumber(Class<?> clazz) {
|
||||
return Number.class.isAssignableFrom(clazz)
|
||||
|| byte.class.equals(clazz)
|
||||
|| int.class.equals(clazz)
|
||||
|| long.class.equals(clazz)
|
||||
|| float.class.equals(clazz)
|
||||
|| double.class.equals(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,26 +7,27 @@ import com.dfsek.tectonic.preprocessor.ValuePreprocessor;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public abstract class MetaPreprocessor<A extends Annotation> implements ValuePreprocessor<A> {
|
||||
private final Map<String, Configuration> configs;
|
||||
|
||||
|
||||
public MetaPreprocessor(Map<String, Configuration> configs) {
|
||||
this.configs = configs;
|
||||
}
|
||||
|
||||
|
||||
protected Object getMetaValue(String meta) {
|
||||
int sep = meta.indexOf(':');
|
||||
String file = meta.substring(0, sep);
|
||||
String key = meta.substring(sep + 1);
|
||||
|
||||
|
||||
if(!configs.containsKey(file)) throw new LoadException("Cannot fetch metavalue: No such config: " + file);
|
||||
|
||||
|
||||
Configuration config = configs.get(file);
|
||||
|
||||
|
||||
if(!config.contains(key)) {
|
||||
throw new LoadException("Cannot fetch metavalue: No such key " + key + " in configuration " + config.getName());
|
||||
}
|
||||
|
||||
|
||||
return config.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,19 +4,20 @@ import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import org.apache.commons.text.StringSubstitutor;
|
||||
import org.apache.commons.text.lookup.StringLookup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
|
||||
public class MetaStringPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public MetaStringPreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) {
|
||||
@@ -25,7 +26,8 @@ public class MetaStringPreprocessor extends MetaPreprocessor<Meta> {
|
||||
StringSubstitutor substitutor = new StringSubstitutor(key -> {
|
||||
Object meta = getMetaValue(key);
|
||||
if(!(meta instanceof String) && !(meta instanceof Number) && !(meta instanceof Character) && !(meta instanceof Boolean)) {
|
||||
throw new LoadException("MetaString template injection candidate must be string or primitive, is type " + meta.getClass().getCanonicalName());
|
||||
throw new LoadException("MetaString template injection candidate must be string or primitive, is type " +
|
||||
meta.getClass().getCanonicalName());
|
||||
}
|
||||
return meta.toString();
|
||||
});
|
||||
@@ -33,6 +35,6 @@ public class MetaStringPreprocessor extends MetaPreprocessor<Meta> {
|
||||
}
|
||||
return Result.noOp();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,18 +3,20 @@ package com.dfsek.terra.config.preprocessor;
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.preprocessor.Result;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaValuePreprocessor extends MetaPreprocessor<Meta> {
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
|
||||
public class MetaValuePreprocessor extends MetaPreprocessor<Meta> {
|
||||
|
||||
public MetaValuePreprocessor(Map<String, Configuration> configs) {
|
||||
super(configs);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NotNull <T> Result<T> process(AnnotatedType t, T c, ConfigLoader configLoader, Meta annotation) {
|
||||
|
||||
@@ -2,20 +2,22 @@ package com.dfsek.terra.config.prototype;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigType;
|
||||
|
||||
|
||||
public class ProtoConfig implements ConfigTemplate {
|
||||
@Value("id")
|
||||
private String id;
|
||||
|
||||
|
||||
@Value("type")
|
||||
private ConfigType<?, ?> type;
|
||||
|
||||
|
||||
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public ConfigType<?, ?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
package com.dfsek.terra.event;
|
||||
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
import com.dfsek.terra.api.event.events.FailThroughEvent;
|
||||
import com.dfsek.terra.api.event.functional.EventContext;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
@@ -12,73 +7,78 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
import com.dfsek.terra.api.event.events.FailThroughEvent;
|
||||
import com.dfsek.terra.api.event.functional.EventContext;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
|
||||
|
||||
public class EventContextImpl<T extends Event> implements EventContext<T>, Comparable<EventContextImpl<?>> {
|
||||
private final List<Consumer<T>> actions = new ArrayList<>();
|
||||
private final TerraAddon addon;
|
||||
private final Type eventType;
|
||||
private final FunctionalEventHandlerImpl parent;
|
||||
private int priority;
|
||||
private boolean failThrough = false;
|
||||
private boolean global = false;
|
||||
|
||||
private final TerraAddon addon;
|
||||
|
||||
private final Type eventType;
|
||||
|
||||
private final FunctionalEventHandlerImpl parent;
|
||||
|
||||
|
||||
public EventContextImpl(TerraAddon addon, Type eventType, FunctionalEventHandlerImpl parent) {
|
||||
this.addon = addon;
|
||||
this.eventType = eventType;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
public void handle(T event) {
|
||||
actions.forEach(action -> action.accept(event));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventContext<T> then(Consumer<T> action) {
|
||||
actions.add(action);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventContext<T> priority(int priority) {
|
||||
this.priority = priority;
|
||||
parent.recomputePriorities(eventType);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventContext<T> failThrough() {
|
||||
if(!FailThroughEvent.class.isAssignableFrom(ReflectionUtil.getRawType(eventType))) {
|
||||
throw new IllegalStateException("Cannot fail-through on event which does not implement FailThroughEvent: " + ReflectionUtil.typeToString(eventType));
|
||||
throw new IllegalStateException(
|
||||
"Cannot fail-through on event which does not implement FailThroughEvent: " + ReflectionUtil.typeToString(eventType));
|
||||
}
|
||||
this.failThrough = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventContext<T> global() {
|
||||
this.global = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull EventContextImpl<?> o) {
|
||||
return this.priority - o.priority;
|
||||
}
|
||||
|
||||
|
||||
public boolean isGlobal() {
|
||||
return global;
|
||||
}
|
||||
|
||||
|
||||
public int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
|
||||
public TerraAddon getAddon() {
|
||||
return addon;
|
||||
}
|
||||
|
||||
|
||||
public boolean isFailThrough() {
|
||||
return failThrough;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
package com.dfsek.terra.event;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.event.EventHandler;
|
||||
import com.dfsek.terra.api.event.EventManager;
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EventManagerImpl implements EventManager {
|
||||
private final Map<Class<?>, EventHandler> handlers = new HashMap<>();
|
||||
private final TerraPlugin main;
|
||||
|
||||
|
||||
public EventManagerImpl(TerraPlugin main) {
|
||||
this.main = main;
|
||||
registerHandler(FunctionalEventHandler.class, new FunctionalEventHandlerImpl(main)); // default handler
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void callEvent(Event event) {
|
||||
handlers.values().forEach(handler -> handler.handle(event));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends EventHandler> void registerHandler(Class<T> clazz, T handler) {
|
||||
handlers.put(clazz, handler);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends EventHandler> T getHandler(Class<T> clazz) {
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.dfsek.terra.event;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
import com.dfsek.terra.api.event.events.FailThroughEvent;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.api.event.functional.EventContext;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -19,15 +10,25 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.addon.TerraAddon;
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
import com.dfsek.terra.api.event.events.FailThroughEvent;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.api.event.functional.EventContext;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
|
||||
public class FunctionalEventHandlerImpl implements FunctionalEventHandler {
|
||||
private final Map<Type, List<EventContextImpl<?>>> contextMap = new HashMap<>();
|
||||
|
||||
|
||||
private final TerraPlugin main;
|
||||
|
||||
|
||||
public FunctionalEventHandlerImpl(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void handle(Event event) {
|
||||
@@ -46,25 +47,26 @@ public class FunctionalEventHandlerImpl implements FunctionalEventHandler {
|
||||
e.printStackTrace(new PrintWriter(writer));
|
||||
main.logger().warning("Exception occurred during event handling:");
|
||||
main.logger().warning(writer.toString());
|
||||
main.logger().warning("Report this to the maintainers of " + context.getAddon().getName() + ", " + context.getAddon().getAuthor());
|
||||
main.logger().warning(
|
||||
"Report this to the maintainers of " + context.getAddon().getName() + ", " + context.getAddon().getAuthor());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Event> EventContext<T> register(TerraAddon addon, Class<T> clazz) {
|
||||
EventContextImpl<T> eventContext = new EventContextImpl<>(addon, clazz, this);
|
||||
contextMap.computeIfAbsent(clazz, c -> new ArrayList<>()).add(eventContext);
|
||||
return eventContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends Event> EventContext<T> register(TerraAddon addon, TypeKey<T> clazz) {
|
||||
EventContextImpl<T> eventContext = new EventContextImpl<>(addon, clazz.getType(), this);
|
||||
contextMap.computeIfAbsent(clazz.getType(), c -> new ArrayList<>()).add(eventContext);
|
||||
return eventContext;
|
||||
}
|
||||
|
||||
|
||||
public void recomputePriorities(Type target) {
|
||||
contextMap.get(target).sort(Comparator.naturalOrder());
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package com.dfsek.terra.inject;
|
||||
|
||||
import com.dfsek.terra.api.injection.Injector;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
import com.dfsek.terra.api.injection.exception.InjectionException;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.injection.Injector;
|
||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||
import com.dfsek.terra.api.injection.exception.InjectionException;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
|
||||
|
||||
public class InjectorImpl<T> implements Injector<T> {
|
||||
private final T value;
|
||||
private final Set<Class<? extends T>> targets = new HashSet<>();
|
||||
|
||||
|
||||
/**
|
||||
* Instantiate an Injector with a value to inject
|
||||
*
|
||||
@@ -23,14 +23,14 @@ public class InjectorImpl<T> implements Injector<T> {
|
||||
public InjectorImpl(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void addExplicitTarget(Class<? extends T> target) {
|
||||
targets.add(target);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void inject(Object object) throws InjectionException {
|
||||
for(Field field : ReflectionUtil.getFields(object.getClass())) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.dfsek.terra.math;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.util.PopulationUtil;
|
||||
import com.dfsek.terra.api.vector.Vector3;
|
||||
import com.dfsek.terra.util.FastRandom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Class to procedurally determine the spawn point of an object based on a grid with padding between cells.
|
||||
@@ -15,13 +16,13 @@ public class GridSpawn implements com.dfsek.terra.api.structure.StructureSpawn {
|
||||
private final int separation;
|
||||
private final int width;
|
||||
private final int salt;
|
||||
|
||||
|
||||
public GridSpawn(int width, int separation, int salt) {
|
||||
this.separation = separation;
|
||||
this.width = width;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vector3 getNearestSpawn(int x, int z, long seed) {
|
||||
int structureChunkX = x / (width + 2 * separation);
|
||||
@@ -39,13 +40,14 @@ public class GridSpawn implements com.dfsek.terra.api.structure.StructureSpawn {
|
||||
}
|
||||
return shortest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the X/Z coordinates of the spawn point in the nearest Chunk (not Minecraft chunk)
|
||||
*
|
||||
* @param structureChunkX Chunk X coordinate
|
||||
* @param structureChunkZ Chunk Z coordinate
|
||||
* @param seed Seed for RNG
|
||||
*
|
||||
* @return Vector representing spawnpoint
|
||||
*/
|
||||
public Vector3 getChunkSpawn(int structureChunkX, int structureChunkZ, long seed) {
|
||||
@@ -56,11 +58,11 @@ public class GridSpawn implements com.dfsek.terra.api.structure.StructureSpawn {
|
||||
int sz = structureChunkZ * (width + 2 * separation) + offsetZ;
|
||||
return new Vector3(sx, 0, sz);
|
||||
}
|
||||
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
public int getSeparation() {
|
||||
return separation;
|
||||
}
|
||||
|
||||
@@ -3,22 +3,22 @@ package com.dfsek.terra.profiler;
|
||||
public class Frame {
|
||||
private final String id;
|
||||
private final long start;
|
||||
|
||||
|
||||
public Frame(String id) {
|
||||
this.id = id;
|
||||
this.start = System.nanoTime();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getStart() {
|
||||
return start;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package com.dfsek.terra.profiler;
|
||||
|
||||
import com.dfsek.terra.api.profiler.Profiler;
|
||||
import com.dfsek.terra.api.profiler.Timings;
|
||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||
import com.dfsek.terra.profiler.exception.MalformedStackException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.dfsek.terra.api.profiler.Profiler;
|
||||
import com.dfsek.terra.api.profiler.Timings;
|
||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||
import com.dfsek.terra.profiler.exception.MalformedStackException;
|
||||
|
||||
|
||||
public class ProfilerImpl implements Profiler {
|
||||
private static final ThreadLocal<Stack<Frame>> THREAD_STACK = ThreadLocal.withInitial(Stack::new);
|
||||
private static final ThreadLocal<Map<String, List<Long>>> TIMINGS = ThreadLocal.withInitial(HashMap::new);
|
||||
@@ -19,12 +20,12 @@ public class ProfilerImpl implements Profiler {
|
||||
private static boolean instantiated = false;
|
||||
private final List<Map<String, List<Long>>> accessibleThreadMaps = new ArrayList<>();
|
||||
private volatile boolean running = false;
|
||||
|
||||
|
||||
public ProfilerImpl() {
|
||||
if(instantiated) throw new IllegalStateException("Only one instance of Profiler may exist!");
|
||||
instantiated = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void push(String frame) {
|
||||
STACK_SIZE.get().increment();
|
||||
@@ -33,7 +34,7 @@ public class ProfilerImpl implements Profiler {
|
||||
stack.push(new Frame(stack.isEmpty() ? frame : stack.peek().getId() + "." + frame));
|
||||
} else SAFE.set(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void pop(String frame) {
|
||||
MutableInteger size = STACK_SIZE.get();
|
||||
@@ -41,36 +42,41 @@ public class ProfilerImpl implements Profiler {
|
||||
if(running && SAFE.get()) {
|
||||
long time = System.nanoTime();
|
||||
Stack<Frame> stack = THREAD_STACK.get();
|
||||
|
||||
|
||||
Map<String, List<Long>> timingsMap = TIMINGS.get();
|
||||
|
||||
|
||||
if(timingsMap.size() == 0) {
|
||||
synchronized(accessibleThreadMaps) {
|
||||
accessibleThreadMaps.add(timingsMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Frame top = stack.pop();
|
||||
if((stack.size() != 0 && !top.getId().endsWith("." + frame)) || (stack.size() == 0 && !top.getId().equals(frame)))
|
||||
if(stack.size() != 0 ? !top.getId().endsWith("." + frame) : !top.getId().equals(frame))
|
||||
throw new MalformedStackException("Expected " + frame + ", found " + top);
|
||||
|
||||
|
||||
List<Long> timings = timingsMap.computeIfAbsent(top.getId(), id -> new ArrayList<>());
|
||||
|
||||
|
||||
timings.add(time - top.getStart());
|
||||
}
|
||||
if(size.get() == 0) SAFE.set(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
running = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
accessibleThreadMaps.forEach(Map::clear);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Timings> getTimings() {
|
||||
Map<String, Timings> map = new HashMap<>();
|
||||
@@ -84,9 +90,4 @@ public class ProfilerImpl implements Profiler {
|
||||
}));
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
accessibleThreadMaps.forEach(Map::clear);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ package com.dfsek.terra.profiler.exception;
|
||||
|
||||
public class MalformedStackException extends ProfilerException {
|
||||
private static final long serialVersionUID = -3009539681021691054L;
|
||||
|
||||
|
||||
public MalformedStackException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
public MalformedStackException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
|
||||
public MalformedStackException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ package com.dfsek.terra.profiler.exception;
|
||||
|
||||
public class ProfilerException extends RuntimeException {
|
||||
private static final long serialVersionUID = 8206737998791649002L;
|
||||
|
||||
|
||||
public ProfilerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
public ProfilerException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
|
||||
public ProfilerException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@@ -2,17 +2,18 @@ package com.dfsek.terra.registry;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a registry that ensures checked additions.
|
||||
*
|
||||
@@ -20,52 +21,52 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class CheckedRegistryImpl<T> implements CheckedRegistry<T> {
|
||||
private final OpenRegistry<T> registry;
|
||||
|
||||
|
||||
public CheckedRegistryImpl(OpenRegistry<T> registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(String identifier, T value) throws DuplicateEntryException {
|
||||
registry.registerChecked(identifier, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void registerUnchecked(String identifier, T value) {
|
||||
registry.register(identifier, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T get(String identifier) {
|
||||
return registry.get(identifier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean contains(String identifier) {
|
||||
return registry.contains(identifier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<T> consumer) {
|
||||
registry.forEach(consumer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<String, T> consumer) {
|
||||
registry.forEach(consumer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<T> entries() {
|
||||
return registry.entries();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> keys() {
|
||||
return registry.keys();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
|
||||
return registry.load(t, c, loader);
|
||||
|
||||
@@ -2,15 +2,16 @@ package com.dfsek.terra.registry;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a registry that forbids all write access.
|
||||
*
|
||||
@@ -18,41 +19,41 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class LockedRegistryImpl<T> implements Registry<T> {
|
||||
private final Registry<T> registry;
|
||||
|
||||
|
||||
public LockedRegistryImpl(Registry<T> registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T get(String identifier) {
|
||||
return registry.get(identifier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean contains(String identifier) {
|
||||
return registry.contains(identifier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<T> consumer) {
|
||||
registry.forEach(consumer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<String, T> consumer) {
|
||||
registry.forEach(consumer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<T> entries() {
|
||||
return registry.entries();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> keys() {
|
||||
return registry.keys();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T load(AnnotatedType t, Object c, ConfigLoader loader) throws LoadException {
|
||||
return registry.load(t, c, loader);
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.dfsek.terra.registry;
|
||||
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Collection;
|
||||
@@ -15,6 +13,10 @@ import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||
|
||||
|
||||
/**
|
||||
* Registry implementation with read/write access. For internal use only.
|
||||
*
|
||||
@@ -23,76 +25,83 @@ import java.util.stream.Collectors;
|
||||
public class OpenRegistryImpl<T> implements OpenRegistry<T> {
|
||||
private static final Entry<?> NULL = new Entry<>(null);
|
||||
private final Map<String, Entry<T>> objects;
|
||||
|
||||
|
||||
public OpenRegistryImpl() {
|
||||
objects = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
protected OpenRegistryImpl(Map<String, Entry<T>> init) {
|
||||
this.objects = init;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
T obj = get((String) o);
|
||||
StringBuilder keys = new StringBuilder("[");
|
||||
|
||||
|
||||
objects.keySet().forEach(key -> keys.append(key + ", "));
|
||||
|
||||
|
||||
if(obj == null)
|
||||
throw new LoadException("No such " + type.getType().getTypeName() + " matching \"" + o + "\" was found in this registry. Registry contains items: " + keys.substring(0, keys.length()-2) + "]");
|
||||
throw new LoadException("No such " + type.getType().getTypeName() + " matching \"" + o +
|
||||
"\" was found in this registry. Registry contains items: " + keys.substring(0, keys.length() - 2) +
|
||||
"]");
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean register(String identifier, T value) {
|
||||
return register(identifier, new Entry<>(value));
|
||||
}
|
||||
|
||||
public boolean register(String identifier, Entry<T> value) {
|
||||
boolean exists = objects.containsKey(identifier);
|
||||
objects.put(identifier, value);
|
||||
return exists;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void registerChecked(String identifier, T value) throws DuplicateEntryException {
|
||||
if(objects.containsKey(identifier))
|
||||
throw new DuplicateEntryException("Value with identifier \"" + identifier + "\" is already defined in registry.");
|
||||
register(identifier, value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean contains(String identifier) {
|
||||
return objects.containsKey(identifier);
|
||||
public void clear() {
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
|
||||
public boolean register(String identifier, Entry<T> value) {
|
||||
boolean exists = objects.containsKey(identifier);
|
||||
objects.put(identifier, value);
|
||||
return exists;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T get(String identifier) {
|
||||
return objects.getOrDefault(identifier, (Entry<T>) NULL).getValue();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean contains(String identifier) {
|
||||
return objects.containsKey(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<T> consumer) {
|
||||
objects.forEach((id, obj) -> consumer.accept(obj.getRaw()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<String, T> consumer) {
|
||||
objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<T> entries() {
|
||||
return objects.values().stream().map(Entry::getRaw).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> keys() {
|
||||
return objects.keySet();
|
||||
}
|
||||
|
||||
|
||||
public Map<String, T> getDeadEntries() {
|
||||
Map<String, T> dead = new HashMap<>();
|
||||
objects.forEach((id, entry) -> {
|
||||
@@ -100,32 +109,27 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
|
||||
});
|
||||
return dead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected static final class Entry<T> {
|
||||
private final T value;
|
||||
private final AtomicInteger access = new AtomicInteger(0);
|
||||
|
||||
|
||||
public Entry(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public boolean dead() {
|
||||
return access.get() == 0;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
access.incrementAndGet();
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
private T getRaw() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean dead() {
|
||||
return access.get() == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,26 @@ package com.dfsek.terra.registry;
|
||||
import com.dfsek.tectonic.exception.LoadException;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.loading.TypeLoader;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.registry.meta.RegistryFactory;
|
||||
import com.dfsek.terra.api.util.generic.Lazy;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class RegistryFactoryImpl implements RegistryFactory {
|
||||
@Override
|
||||
public <T> OpenRegistry<T> create() {
|
||||
return new OpenRegistryImpl<>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> OpenRegistry<T> create(Function<OpenRegistry<T>, TypeLoader<T>> loader) {
|
||||
return new OpenRegistryImpl<>() {
|
||||
private final Lazy<TypeLoader<T>> loaderCache = Lazy.lazy(() -> loader.apply(this));
|
||||
|
||||
|
||||
@Override
|
||||
public T load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
return loaderCache.value().load(type, o, configLoader);
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
package com.dfsek.terra.registry.config;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.config.ConfigType;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class ConfigTypeRegistry extends OpenRegistryImpl<ConfigType<?, ?>> {
|
||||
private final BiConsumer<String, ConfigType<?, ?>> callback;
|
||||
|
||||
|
||||
private final TerraPlugin main;
|
||||
|
||||
|
||||
public ConfigTypeRegistry(TerraPlugin main, BiConsumer<String, ConfigType<?, ?>> callback) {
|
||||
super(new LinkedHashMap<>()); // Ordered
|
||||
this.callback = callback;
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean register(String identifier, Entry<ConfigType<?, ?>> value) {
|
||||
callback.accept(identifier, value.getValue());
|
||||
main.getDebugLogger().info("Registered config registry with ID " + identifier + " to type " + ReflectionUtil.typeToString(value.getValue().getTypeKey().getType()));
|
||||
main.getDebugLogger().info("Registered config registry with ID " + identifier + " to type " +
|
||||
ReflectionUtil.typeToString(value.getValue().getTypeKey().getType()));
|
||||
return super.register(identifier, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package com.dfsek.terra.registry.master;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.dfsek.terra.addon.AddonClassLoader;
|
||||
import com.dfsek.terra.addon.AddonPool;
|
||||
import com.dfsek.terra.addon.PreLoadAddon;
|
||||
@@ -11,25 +18,19 @@ import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||
import com.dfsek.terra.inject.InjectorImpl;
|
||||
import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
||||
private final TerraPlugin main;
|
||||
|
||||
|
||||
public AddonRegistry(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
|
||||
public AddonRegistry(TerraAddon addon, TerraPlugin main) {
|
||||
this.main = main;
|
||||
register(addon);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean register(String identifier, TerraAddon addon) {
|
||||
if(contains(identifier)) throw new IllegalArgumentException("Addon " + identifier + " is already registered.");
|
||||
@@ -37,29 +38,30 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
||||
main.logger().info("Loaded addon " + addon.getName() + " v" + addon.getVersion() + ", by " + addon.getAuthor());
|
||||
return super.register(identifier, addon);
|
||||
}
|
||||
|
||||
public boolean register(TerraAddon addon) {
|
||||
return register(addon.getName(), addon);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public boolean register(TerraAddon addon) {
|
||||
return register(addon.getName(), addon);
|
||||
}
|
||||
|
||||
public boolean loadAll() {
|
||||
return loadAll(TerraPlugin.class.getClassLoader());
|
||||
}
|
||||
|
||||
public boolean loadAll(ClassLoader parent) {
|
||||
InjectorImpl<TerraPlugin> pluginInjector = new InjectorImpl<>(main);
|
||||
pluginInjector.addExplicitTarget(TerraPlugin.class);
|
||||
|
||||
|
||||
boolean valid = true;
|
||||
File addonsFolder = new File(main.getDataFolder(), "addons");
|
||||
addonsFolder.mkdirs();
|
||||
|
||||
|
||||
AddonPool pool = new AddonPool();
|
||||
|
||||
|
||||
try {
|
||||
for(File jar : addonsFolder.listFiles(file -> file.getName().endsWith(".jar"))) {
|
||||
main.logger().info("Loading Addon(s) from: " + jar.getName());
|
||||
@@ -67,23 +69,23 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
||||
pool.add(new PreLoadAddon(addonClass, jar));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pool.buildAll();
|
||||
|
||||
|
||||
for(PreLoadAddon addon : pool.getAddons()) {
|
||||
Class<? extends TerraAddon> addonClass = addon.getAddonClass();
|
||||
Constructor<? extends TerraAddon> constructor;
|
||||
|
||||
|
||||
String logPrefix = "Terra:" + addon.getId();
|
||||
Logger addonLogger = Logger.getLogger(logPrefix);
|
||||
|
||||
|
||||
if(!LogManager.getLogManager().addLogger(addonLogger)) {
|
||||
addonLogger = LogManager.getLogManager().getLogger(logPrefix);
|
||||
}
|
||||
|
||||
|
||||
InjectorImpl<Logger> loggerInjector = new InjectorImpl<>(addonLogger);
|
||||
loggerInjector.addExplicitTarget(Logger.class);
|
||||
|
||||
|
||||
try {
|
||||
constructor = addonClass.getConstructor();
|
||||
} catch(NoSuchMethodException e) {
|
||||
@@ -110,7 +112,7 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
||||
e.printStackTrace();
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package com.dfsek.terra.registry.master;
|
||||
|
||||
import com.dfsek.tectonic.exception.ConfigException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.config.pack.ConfigPackImpl;
|
||||
import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* Class to hold config packs
|
||||
@@ -18,7 +20,7 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
|
||||
ConfigPack pack = new ConfigPackImpl(folder, main);
|
||||
register(pack.getID(), pack);
|
||||
}
|
||||
|
||||
|
||||
public boolean loadAll(TerraPlugin main) {
|
||||
boolean valid = true;
|
||||
File packsFolder = new File(main.getDataFolder(), "packs");
|
||||
@@ -42,7 +44,7 @@ public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
public void load(ZipFile file, TerraPlugin main) throws ConfigException {
|
||||
ConfigPackImpl pack = new ConfigPackImpl(file, main);
|
||||
register(pack.getTemplate().getID(), pack);
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
package com.dfsek.terra.transform;
|
||||
|
||||
import com.dfsek.terra.api.transform.Transform;
|
||||
import com.dfsek.terra.api.transform.exception.TransformException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.transform.Transform;
|
||||
import com.dfsek.terra.api.transform.exception.TransformException;
|
||||
|
||||
|
||||
public class MapTransform<F, T> implements Transform<F, T> {
|
||||
private final Map<F, T> map;
|
||||
|
||||
|
||||
public MapTransform(Map<F, T> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
|
||||
public MapTransform() {
|
||||
this.map = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
public MapTransform<F, T> add(F from, T to) {
|
||||
map.put(from, to);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public MapTransform<F, T> remove(F from) {
|
||||
map.remove(from);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T transform(F input) throws TransformException {
|
||||
if(!map.containsKey(input)) throw new TransformException("No key matching " + input.toString() + " found in map.");
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package com.dfsek.terra.transform;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.transform.Transform;
|
||||
import com.dfsek.terra.api.transform.Transformer;
|
||||
import com.dfsek.terra.api.transform.Validator;
|
||||
import com.dfsek.terra.api.transform.exception.AttemptsFailedException;
|
||||
import com.dfsek.terra.api.transform.exception.TransformException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class to translate types from one style/platform to another.
|
||||
@@ -20,11 +21,11 @@ import java.util.Map;
|
||||
*/
|
||||
public class TransformerImpl<F, T> implements Transformer<F, T> {
|
||||
private final LinkedHashMap<Transform<F, T>, List<Validator<T>>> transformers;
|
||||
|
||||
|
||||
private TransformerImpl(LinkedHashMap<Transform<F, T>, List<Validator<T>>> transformer) {
|
||||
this.transformers = transformer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T translate(F from) {
|
||||
List<Throwable> exceptions = new ArrayList<>();
|
||||
@@ -43,7 +44,7 @@ public class TransformerImpl<F, T> implements Transformer<F, T> {
|
||||
}
|
||||
throw new AttemptsFailedException("Could not transform input; all attempts failed: " + from.toString() + "\n", exceptions);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder pattern for building Transformers
|
||||
*
|
||||
@@ -52,14 +53,14 @@ public class TransformerImpl<F, T> implements Transformer<F, T> {
|
||||
*/
|
||||
public static final class Builder<F, T> {
|
||||
private final LinkedHashMap<Transform<F, T>, List<Validator<T>>> transforms = new LinkedHashMap<>();
|
||||
|
||||
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("varargs")
|
||||
public final Builder<F, T> addTransform(Transform<F, T> transform, Validator<T>... validators) {
|
||||
transforms.put(transform, Arrays.asList(validators));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public TransformerImpl<F, T> build() {
|
||||
return new TransformerImpl<>(transforms);
|
||||
}
|
||||
|
||||
@@ -6,61 +6,62 @@ import org.apache.commons.rng.core.source64.XoRoShiRo128PlusPlus;
|
||||
import java.util.Random;
|
||||
import java.util.SplittableRandom;
|
||||
|
||||
public class FastRandom extends Random {
|
||||
|
||||
public class FastRandom extends Random {
|
||||
|
||||
private static final long serialVersionUID = 4571946470190183260L;
|
||||
private XoRoShiRo128PlusPlus random;
|
||||
|
||||
|
||||
public FastRandom() {
|
||||
super();
|
||||
SplittableRandom randomseed = new SplittableRandom();
|
||||
this.random = new XoRoShiRo128PlusPlus(randomseed.nextLong(), randomseed.nextLong());
|
||||
}
|
||||
|
||||
|
||||
public FastRandom(long seed) {
|
||||
super(seed);
|
||||
SplittableRandom randomseed = new SplittableRandom(seed);
|
||||
this.random = new XoRoShiRo128PlusPlus(randomseed.nextLong(), randomseed.nextLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextBoolean() {
|
||||
return random.nextBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt() {
|
||||
return random.nextInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float nextFloat() {
|
||||
return (float) random.nextDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextDouble() {
|
||||
return random.nextDouble();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void setSeed(long seed) {
|
||||
SplittableRandom randomseed = new SplittableRandom(seed);
|
||||
this.random = new XoRoShiRo128PlusPlus(randomseed.nextLong(), randomseed.nextLong());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void nextBytes(byte[] bytes) {
|
||||
random.nextBytes(bytes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int nextInt() {
|
||||
return random.nextInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt(int bound) {
|
||||
return random.nextInt(bound);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long nextLong() {
|
||||
return random.nextLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextBoolean() {
|
||||
return random.nextBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float nextFloat() {
|
||||
return (float) random.nextDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextDouble() {
|
||||
return random.nextDouble();
|
||||
}
|
||||
}
|
||||
@@ -2,35 +2,36 @@ package com.dfsek.terra.util.logging;
|
||||
|
||||
import com.dfsek.terra.api.Logger;
|
||||
|
||||
|
||||
public class DebugLogger implements Logger {
|
||||
private final Logger logger;
|
||||
private boolean debug = false;
|
||||
|
||||
|
||||
public DebugLogger(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
|
||||
public void info(String message) {
|
||||
if(debug) logger.info(message);
|
||||
}
|
||||
|
||||
|
||||
public void warning(String message) {
|
||||
if(debug) logger.warning(message);
|
||||
}
|
||||
|
||||
|
||||
public void severe(String message) {
|
||||
if(debug) logger.severe(message);
|
||||
}
|
||||
|
||||
|
||||
public void stack(Throwable e) {
|
||||
if(debug) e.printStackTrace();
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,23 +2,24 @@ package com.dfsek.terra.util.logging;
|
||||
|
||||
import com.dfsek.terra.api.Logger;
|
||||
|
||||
|
||||
public class JavaLogger implements Logger {
|
||||
private final java.util.logging.Logger logger;
|
||||
|
||||
|
||||
public JavaLogger(java.util.logging.Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void info(String message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void warning(String message) {
|
||||
logger.warning(message);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void severe(String message) {
|
||||
logger.severe(message);
|
||||
|
||||
@@ -1,46 +1,49 @@
|
||||
package com.dfsek.terra.world;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.util.MathUtil;
|
||||
import com.dfsek.terra.api.world.World;
|
||||
import com.dfsek.terra.api.world.generator.Sampler;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import net.jafama.FastMath;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.util.MathUtil;
|
||||
import com.dfsek.terra.api.world.World;
|
||||
import com.dfsek.terra.api.world.generator.Sampler;
|
||||
|
||||
|
||||
public class SamplerCacheImpl implements com.dfsek.terra.api.world.generator.SamplerCache {
|
||||
private final LoadingCache<Long, Sampler> cache;
|
||||
|
||||
|
||||
public SamplerCacheImpl(TerraPlugin main, World world) {
|
||||
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getSamplerCache())
|
||||
.build(new CacheLoader<>() {
|
||||
@Override
|
||||
public Sampler load(@NotNull Long key) {
|
||||
int cx = (int) (key >> 32);
|
||||
int cz = (int) key.longValue();
|
||||
return world.getGenerator().createSampler(cx, cz, world.getBiomeProvider(), world, world.getConfig().elevationBlend());
|
||||
}
|
||||
});
|
||||
.build(new CacheLoader<>() {
|
||||
@Override
|
||||
public Sampler load(@NotNull Long key) {
|
||||
int cx = (int) (key >> 32);
|
||||
int cz = (int) key.longValue();
|
||||
return world.getGenerator().createSampler(cx, cz, world.getBiomeProvider(), world,
|
||||
world.getConfig().elevationBlend());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Sampler get(int x, int z) {
|
||||
int cx = FastMath.floorDiv(x, 16);
|
||||
int cz = FastMath.floorDiv(z, 16);
|
||||
return getChunk(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sampler getChunk(int cx, int cz) {
|
||||
long key = MathUtil.squash(cx, cz);
|
||||
return cache.getUnchecked(key);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cache.invalidateAll();
|
||||
cache.cleanUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sampler getChunk(int cx, int cz) {
|
||||
long key = MathUtil.squash(cx, cz);
|
||||
return cache.getUnchecked(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,124 +3,130 @@ import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
import com.dfsek.tectonic.config.Configuration;
|
||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||
import com.dfsek.tectonic.yaml.YamlConfiguration;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaMapPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaStringPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaMapPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaStringPreprocessor;
|
||||
import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor;
|
||||
|
||||
|
||||
public class MetaTest {
|
||||
@Test
|
||||
public void testMetaList() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
|
||||
loader.load(new MetaListConfig(), meta).list.forEach(System.out::println);
|
||||
}
|
||||
|
||||
private static final class MetaListConfig implements ConfigTemplate {
|
||||
@Value("list")
|
||||
private @Meta List<@Meta String> list;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMetaMap() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
|
||||
loader.load(new MetaMapConfig(), meta).map.forEach((k, v) -> System.out.println(k + ": " + v));
|
||||
}
|
||||
|
||||
private static final class MetaMapConfig implements ConfigTemplate {
|
||||
@Value("map")
|
||||
private @Meta Map<@Meta String, @Meta String> map;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMetaString() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
|
||||
System.out.println(loader.load(new MetaStringConfig(), meta).string);
|
||||
}
|
||||
|
||||
private static final class MetaStringConfig implements ConfigTemplate {
|
||||
@Value("string")
|
||||
private @Meta String string;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMetaNumber() {
|
||||
Configuration meta = new YamlConfiguration(MetaTest.class.getResourceAsStream("/meta.yml"), "meta.yml");
|
||||
Configuration metaTarget = new YamlConfiguration(MetaTest.class.getResourceAsStream("/metaTarget.yml"), "metaTarget.yml");
|
||||
|
||||
|
||||
Map<String, Configuration> configurationMap = new HashMap<>();
|
||||
|
||||
|
||||
configurationMap.put(meta.getName(), meta);
|
||||
configurationMap.put(metaTarget.getName(), metaTarget);
|
||||
|
||||
|
||||
ConfigLoader loader = new ConfigLoader();
|
||||
loader.registerPreprocessor(Meta.class, new MetaStringPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaListLikePreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaMapPreprocessor(configurationMap));
|
||||
loader.registerPreprocessor(Meta.class, new MetaNumberPreprocessor(configurationMap));
|
||||
|
||||
|
||||
loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap));
|
||||
|
||||
|
||||
System.out.println("int: " + loader.load(new MetaNumberConfig(), meta).integer);
|
||||
System.out.println("double: " + loader.load(new MetaNumberConfig(), meta).aDouble);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static final class MetaListConfig implements ConfigTemplate {
|
||||
@Value("list")
|
||||
private @Meta List<@Meta String> list;
|
||||
}
|
||||
|
||||
|
||||
private static final class MetaMapConfig implements ConfigTemplate {
|
||||
@Value("map")
|
||||
private @Meta Map<@Meta String, @Meta String> map;
|
||||
}
|
||||
|
||||
|
||||
private static final class MetaStringConfig implements ConfigTemplate {
|
||||
@Value("string")
|
||||
private @Meta String string;
|
||||
}
|
||||
|
||||
|
||||
private static final class MetaNumberConfig implements ConfigTemplate {
|
||||
@Value("int")
|
||||
private @Meta int integer;
|
||||
|
||||
|
||||
@Value("double")
|
||||
private @Meta double aDouble;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package command;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.dfsek.terra.api.command.CommandManager;
|
||||
import com.dfsek.terra.api.command.CommandTemplate;
|
||||
import com.dfsek.terra.api.command.annotation.Argument;
|
||||
@@ -15,18 +19,16 @@ import com.dfsek.terra.api.command.exception.InvalidArgumentsException;
|
||||
import com.dfsek.terra.api.command.exception.MalformedCommandException;
|
||||
import com.dfsek.terra.api.entity.CommandSender;
|
||||
import com.dfsek.terra.commands.TerraCommandManager;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class CommandTest {
|
||||
@Test
|
||||
public void subcommand() throws CommandException {
|
||||
CommandManager manager = new TerraCommandManager(null);
|
||||
manager.register("test", DemoParentCommand.class);
|
||||
|
||||
|
||||
manager.execute("test", null, Arrays.asList("subcommand1", "first", "2"));
|
||||
manager.execute("test", null, Arrays.asList("subcommand2", "first", "2"));
|
||||
manager.execute("test", null, Arrays.asList("s1", "first", "2", "3.4"));
|
||||
@@ -34,80 +36,80 @@ public class CommandTest {
|
||||
manager.execute("test", null, Arrays.asList("sub1", "first", "2", "3.4"));
|
||||
manager.execute("test", null, Arrays.asList("sub2", "first", "2"));
|
||||
manager.execute("test", null, Arrays.asList("first", "2")); // Parent command args
|
||||
|
||||
|
||||
System.out.println("ARGS: " + manager.getMaxArgumentDepth());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void args() throws CommandException {
|
||||
CommandManager manager = new TerraCommandManager(null);
|
||||
manager.register("test", DemoCommand.class);
|
||||
|
||||
|
||||
manager.execute("test", null, Arrays.asList("first", "2"));
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "3.4"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void argsBeforeFlags() throws CommandException {
|
||||
CommandManager manager = new TerraCommandManager(null);
|
||||
manager.register("test", DemoCommand.class);
|
||||
|
||||
|
||||
try {
|
||||
manager.execute("test", null, Arrays.asList("first", "-flag", "2"));
|
||||
fail();
|
||||
} catch(InvalidArgumentsException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void requiredArgsFirst() throws CommandException {
|
||||
CommandManager manager = new TerraCommandManager(null);
|
||||
manager.register("test", DemoInvalidCommand.class);
|
||||
|
||||
|
||||
try {
|
||||
manager.execute("test", null, Arrays.asList("first", "2"));
|
||||
fail();
|
||||
} catch(MalformedCommandException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void switches() throws CommandException {
|
||||
CommandManager manager = new TerraCommandManager(null);
|
||||
manager.register("test", DemoSwitchCommand.class);
|
||||
|
||||
|
||||
manager.execute("test", null, Arrays.asList("first", "2"));
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "3.4"));
|
||||
|
||||
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "-a"));
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "3.4", "-b"));
|
||||
|
||||
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "-aSwitch"));
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "3.4", "-bSwitch"));
|
||||
|
||||
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "-aSwitch", "-b"));
|
||||
manager.execute("test", null, Arrays.asList("first", "2", "3.4", "-bSwitch", "-a"));
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
arguments = {
|
||||
@Argument(value = "arg0"),
|
||||
@Argument("arg0"),
|
||||
@Argument(value = "arg1", argumentParser = IntegerArgumentParser.class),
|
||||
@Argument(value = "arg2", required = false, argumentParser = DoubleArgumentParser.class, defaultValue = "0")
|
||||
}
|
||||
)
|
||||
public static final class DemoCommand implements CommandTemplate {
|
||||
|
||||
|
||||
@ArgumentTarget("arg0")
|
||||
private String arg0;
|
||||
|
||||
|
||||
@ArgumentTarget("arg1")
|
||||
private Integer arg1;
|
||||
|
||||
|
||||
@ArgumentTarget("arg2")
|
||||
private Double arg2;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
System.out.println(arg0);
|
||||
@@ -115,91 +117,94 @@ public class CommandTest {
|
||||
System.out.println(arg2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Command(
|
||||
arguments = {
|
||||
@Argument(value = "arg0"),
|
||||
@Argument(value = "arg1"),
|
||||
@Argument("arg0"),
|
||||
@Argument("arg1"),
|
||||
@Argument(value = "arg2", required = false)
|
||||
},
|
||||
switches = {
|
||||
@Switch(value = "a", aliases = {"aSwitch"}),
|
||||
@Switch(value = "b", aliases = {"bSwitch"})
|
||||
@Switch(value = "a", aliases = "aSwitch"),
|
||||
@Switch(value = "b", aliases = "bSwitch")
|
||||
}
|
||||
)
|
||||
public static final class DemoSwitchCommand implements CommandTemplate {
|
||||
@ArgumentTarget("arg0")
|
||||
private String arg0;
|
||||
|
||||
|
||||
@ArgumentTarget("arg1")
|
||||
private String arg1;
|
||||
|
||||
|
||||
@ArgumentTarget("arg2")
|
||||
private String arg2;
|
||||
|
||||
|
||||
@SwitchTarget("a")
|
||||
private boolean a;
|
||||
|
||||
|
||||
@SwitchTarget("b")
|
||||
private boolean b;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
System.out.println(arg0);
|
||||
System.out.println(arg1);
|
||||
System.out.println(arg2);
|
||||
|
||||
|
||||
System.out.println("A: " + a);
|
||||
System.out.println("B: " + b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Command(
|
||||
arguments = {
|
||||
@Argument(value = "arg0"),
|
||||
@Argument("arg0"),
|
||||
@Argument(value = "arg2", required = false), // optional arguments must be last. this command is invalid.
|
||||
@Argument(value = "arg1")
|
||||
@Argument("arg1")
|
||||
}
|
||||
)
|
||||
public static final class DemoInvalidCommand implements CommandTemplate {
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
throw new Error("this should never be reached");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Command(
|
||||
arguments = {
|
||||
@Argument(value = "arg0"),
|
||||
@Argument(value = "arg1"),
|
||||
@Argument("arg0"),
|
||||
@Argument("arg1"),
|
||||
@Argument(value = "arg2", required = false),
|
||||
},
|
||||
subcommands = {
|
||||
@Subcommand(
|
||||
value = "subcommand1",
|
||||
aliases = {"s1", "sub1"},
|
||||
aliases = { "s1", "sub1" },
|
||||
clazz = DemoChildCommand.class
|
||||
),
|
||||
@Subcommand(
|
||||
value = "subcommand2",
|
||||
aliases = {"s2", "sub2"},
|
||||
aliases = { "s2", "sub2" },
|
||||
clazz = DemoChildCommand.class // Duplicate command intentional.
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
public static final class DemoParentCommand implements CommandTemplate {
|
||||
@ArgumentTarget("arg0")
|
||||
private String arg0;
|
||||
|
||||
|
||||
@ArgumentTarget("arg1")
|
||||
private String arg1;
|
||||
|
||||
|
||||
@ArgumentTarget("arg2")
|
||||
private String arg2;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
System.out.println(arg0);
|
||||
@@ -207,25 +212,26 @@ public class CommandTest {
|
||||
System.out.println(arg2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Command(
|
||||
arguments = {
|
||||
@Argument(value = "arg0"),
|
||||
@Argument(value = "arg1"),
|
||||
@Argument("arg0"),
|
||||
@Argument("arg1"),
|
||||
@Argument(value = "arg2", required = false),
|
||||
}
|
||||
)
|
||||
public static final class DemoChildCommand implements CommandTemplate {
|
||||
@ArgumentTarget("arg0")
|
||||
private String arg0;
|
||||
|
||||
|
||||
@ArgumentTarget("arg1")
|
||||
private String arg1;
|
||||
|
||||
|
||||
@ArgumentTarget("arg2")
|
||||
private String arg2;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
System.out.println(arg0);
|
||||
|
||||
@@ -3,21 +3,23 @@ package noise;
|
||||
import com.dfsek.tectonic.annotations.Default;
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
public class ColorConfigTemplate implements ConfigTemplate {
|
||||
@Value("colors")
|
||||
private @Meta ProbabilityCollection<@Meta Integer> colors;
|
||||
|
||||
public class ColorConfigTemplate implements ConfigTemplate {
|
||||
@Value("enable")
|
||||
@Default
|
||||
private @Meta boolean enable = false;
|
||||
|
||||
private @Meta
|
||||
final boolean enable = false;
|
||||
@Value("colors")
|
||||
private @Meta ProbabilityCollection<@Meta Integer> colors;
|
||||
|
||||
public boolean enable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
|
||||
public ProbabilityCollection<Integer> getColors() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package noise;
|
||||
|
||||
import com.dfsek.tectonic.annotations.Value;
|
||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
@@ -9,7 +10,7 @@ import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
public class NoiseConfigTemplate implements ConfigTemplate {
|
||||
@Value(".")
|
||||
private NoiseSampler builder;
|
||||
|
||||
|
||||
public NoiseSampler getBuilder() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -3,20 +3,21 @@ package profiler;
|
||||
import com.dfsek.terra.api.profiler.Profiler;
|
||||
import com.dfsek.terra.profiler.ProfilerImpl;
|
||||
|
||||
|
||||
public class ProfilerTest {
|
||||
private static final Profiler PROFILER = new ProfilerImpl();
|
||||
|
||||
|
||||
//@Test
|
||||
public static void main(String... a) throws InterruptedException {
|
||||
//PROFILER.start();
|
||||
for(int i = 0; i < 1000; i++) {
|
||||
doThing();
|
||||
}
|
||||
|
||||
|
||||
for(int i = 0; i < 100; i++) {
|
||||
doThirdOtherThing();
|
||||
}
|
||||
|
||||
|
||||
for(int i = 0; i < 100; i++) {
|
||||
doOtherThing();
|
||||
}
|
||||
@@ -28,12 +29,12 @@ public class ProfilerTest {
|
||||
PROFILER.pop("thing");
|
||||
PROFILER.push("thing4");
|
||||
PROFILER.pop("thing4");
|
||||
|
||||
|
||||
PROFILER.getTimings().forEach((id, timings) -> {
|
||||
System.out.println(id + ": " + timings.toString());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static void doThing() throws InterruptedException {
|
||||
PROFILER.push("thing");
|
||||
Thread.sleep(1);
|
||||
@@ -41,7 +42,7 @@ public class ProfilerTest {
|
||||
thing4();
|
||||
PROFILER.pop("thing");
|
||||
}
|
||||
|
||||
|
||||
private static void doOtherThing() throws InterruptedException {
|
||||
PROFILER.push("thing2");
|
||||
Thread.sleep(2);
|
||||
@@ -49,13 +50,13 @@ public class ProfilerTest {
|
||||
thing4();
|
||||
PROFILER.pop("thing2");
|
||||
}
|
||||
|
||||
|
||||
private static void doThirdOtherThing() throws InterruptedException {
|
||||
PROFILER.push("thing3");
|
||||
Thread.sleep(2);
|
||||
PROFILER.pop("thing3");
|
||||
}
|
||||
|
||||
|
||||
private static void thing4() throws InterruptedException {
|
||||
PROFILER.push("thing4");
|
||||
Thread.sleep(2);
|
||||
|
||||
Reference in New Issue
Block a user