Compare commits

...

12 Commits

Author SHA1 Message Date
dfsek
414d5dae3b implement RegistryArgument 2021-09-06 15:52:42 -07:00
dfsek
d8377915d7 remove DoubleArgumentParser 2021-09-06 14:38:54 -07:00
dfsek
a0b4841bf9 make cloud "api" dependency 2021-09-06 14:38:46 -07:00
dfsek
814d3fe7c2 remove command exceptions 2021-09-06 14:35:03 -07:00
dfsek
f71fbeda84 remove CommandManager 2021-09-06 14:34:12 -07:00
dfsek
3bd78b9658 remove BukkitCommandAdapter 2021-09-06 14:34:01 -07:00
dfsek
b398febee3 remove CommandUtil 2021-09-06 14:33:41 -07:00
dfsek
5e0775850a remove TerraCommandManager 2021-09-06 14:33:22 -07:00
dfsek
c9f19937c9 fabric cloud impl 2021-09-06 14:31:40 -07:00
dfsek
bdb486188e bukkit commandregistrationevent 2021-09-06 13:50:43 -07:00
dfsek
320a7595f6 create CommandRegistrationEvent 2021-09-06 13:40:46 -07:00
dfsek
0706a4d0b7 depend on Cloud API 2021-09-06 13:34:53 -07:00
33 changed files with 231 additions and 875 deletions

View File

@@ -4,5 +4,7 @@ dependencies {
"shadedApi"("com.dfsek.tectonic:common:2.1.2")
"shadedApi"("net.jafama:jafama:2.3.2")
"api"("cloud.commandframework", "cloud-core", "1.5.0")
}

View File

@@ -0,0 +1,117 @@
package com.dfsek.terra.api.cloud;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.arguments.standard.EnumArgument;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import com.dfsek.terra.api.registry.Registry;
import io.leangen.geantyref.TypeToken;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.function.BiFunction;
/**
* An argument which recieves values from a registry.
*
* @param <T>
*/
public class RegistryArgument<C, T> extends CommandArgument<C, T> {
public RegistryArgument(Registry<T> registry,
Class<T> registryClass,
boolean required,
@NonNull String name,
@NonNull String defaultValue,
@Nullable BiFunction<CommandContext<C>, String, List<String>> suggestionsProvider,
@NonNull ArgumentDescription defaultDescription) {
super(required, name, new RegistryParser<>(registry), defaultValue, registryClass, suggestionsProvider, defaultDescription);
}
public static <C1, T1> Builder<C1, T1> newBuilder(Registry<T1> registry, Class<T1> clazz, String name) {
return new Builder<>(clazz, name, registry);
}
public static <C1, T1> RegistryArgument<C1, T1> of(Registry<T1> registry, Class<T1> registryClass, String name) {
return RegistryArgument.<C1, T1>newBuilder(registry, registryClass, name).build();
}
public static final class Builder<C, R> extends CommandArgument.Builder<C, R> {
private final Registry<R> registry;
private final Class<R> registryType;
private Builder(@NonNull Class<R> valueType, @NonNull String name, Registry<R> registry) {
super(valueType, name);
this.registry = registry;
this.registryType = valueType;
}
@Override
public @NonNull RegistryArgument<@NonNull C, @NonNull R> build() {
return new RegistryArgument<>(registry, registryType,
this.isRequired(),
this.getName(),
this.getDefaultValue(),
this.getSuggestionsProvider(),
this.getDefaultDescription()
);
}
}
public static final class RegistryParser<C, E> implements ArgumentParser<C, E> {
private final Registry<E> registry;
public RegistryParser(Registry<E> registry) {
this.registry = registry;
}
@Override
public @NonNull ArgumentParseResult<E> parse(
final @NonNull CommandContext<C> commandContext,
final @NonNull Queue<@NonNull String> inputQueue
) {
final String input = inputQueue.peek();
if(input == null) {
return ArgumentParseResult.failure(new NoInputProvidedException(
EnumArgument.EnumParser.class,
commandContext
));
}
if(registry.contains(input)) return ArgumentParseResult.success(registry.get(input));
return ArgumentParseResult.failure(new IllegalArgumentException(input));
}
@Override
public @NonNull List<@NonNull String> suggestions(
@NotNull CommandContext<C> commandContext,
final @NonNull String input) {
return new ArrayList<>(registry.keys());
}
@Override
public boolean isContextFree() {
return true;
}
}
}

View File

@@ -1,18 +0,0 @@
package com.dfsek.terra.api.command;
import java.util.List;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.entity.CommandSender;
public interface CommandManager {
void execute(String command, CommandSender sender, List<String> args) throws CommandException;
void register(String name, Class<? extends CommandTemplate> clazz) throws MalformedCommandException;
List<String> tabComplete(String command, CommandSender sender, List<String> args) throws CommandException;
int getMaxArgumentDepth();
}

View File

@@ -1,11 +0,0 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.entity.CommandSender;
public class DoubleArgumentParser implements ArgumentParser<Double> {
@Override
public Double parse(CommandSender sender, String arg) {
return arg == null ? null : Double.parseDouble(arg);
}
}

View File

@@ -1,13 +0,0 @@
package com.dfsek.terra.api.command.exception;
public abstract class CommandException extends Exception {
private static final long serialVersionUID = -2955328495045879822L;
public CommandException(String message) {
super(message);
}
public CommandException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,13 +0,0 @@
package com.dfsek.terra.api.command.exception;
public class ExecutionException extends CommandException {
private static final long serialVersionUID = -6345523475880607959L;
public ExecutionException(String message) {
super(message);
}
public ExecutionException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,13 +0,0 @@
package com.dfsek.terra.api.command.exception;
public class InvalidArgumentsException extends CommandException {
private static final long serialVersionUID = 7563619667472569824L;
public InvalidArgumentsException(String message) {
super(message);
}
public InvalidArgumentsException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,16 +0,0 @@
package com.dfsek.terra.api.command.exception;
/**
* Thrown when command is incorrectly defined.
*/
public class MalformedCommandException extends CommandException {
private static final long serialVersionUID = -5417760860407895496L;
public MalformedCommandException(String message) {
super(message);
}
public MalformedCommandException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,13 +0,0 @@
package com.dfsek.terra.api.command.exception;
public class SwitchFormatException extends CommandException {
private static final long serialVersionUID = -965858989317844628L;
public SwitchFormatException(String message) {
super(message);
}
public SwitchFormatException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,22 @@
package com.dfsek.terra.api.event.events.platform;
import cloud.commandframework.CommandManager;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.event.events.Event;
/**
* Called when commands should be registered. Listen to this event to register your own commands.
*/
public class CommandRegistrationEvent implements Event {
private final CommandManager<CommandSender> manager;
public CommandRegistrationEvent(CommandManager<CommandSender> manager) {
this.manager = manager;
}
public CommandManager<CommandSender> getManager() {
return manager;
}
}

View File

@@ -19,8 +19,6 @@ import java.util.Optional;
import com.dfsek.terra.api.Logger;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addon.TerraAddon;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.config.PluginConfig;
import com.dfsek.terra.api.event.EventManager;
@@ -30,8 +28,6 @@ import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.util.generic.Lazy;
import com.dfsek.terra.api.util.mutable.MutableBoolean;
import com.dfsek.terra.commands.CommandUtil;
import com.dfsek.terra.commands.TerraCommandManager;
import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.PluginConfigImpl;
import com.dfsek.terra.config.lang.LangUtil;
@@ -62,8 +58,6 @@ public abstract class AbstractTerraPlugin implements TerraPlugin {
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());
@@ -186,12 +180,6 @@ public abstract class AbstractTerraPlugin implements TerraPlugin {
}
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.");
}
@@ -205,8 +193,4 @@ public abstract class AbstractTerraPlugin implements TerraPlugin {
public ConfigRegistry getRawConfigRegistry() {
return configRegistry;
}
public CommandManager getManager() {
return manager;
}
}

View File

@@ -1,18 +0,0 @@
package com.dfsek.terra.commands;
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);
manager.register("reload", ReloadCommand.class);
manager.register("addons", AddonsCommand.class);
manager.register("version", VersionCommand.class);
manager.register("getblock", GetBlockCommand.class);
manager.register("packs", PacksCommand.class);
}
}

View File

@@ -1,294 +0,0 @@
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;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.ExecutionException;
import com.dfsek.terra.api.command.exception.InvalidArgumentsException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.command.exception.SwitchFormatException;
import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.entity.CommandSender;
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;
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()));
}
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() + "\"");
}
String argument = argumentTarget.value();
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)) {
SwitchTarget switchTarget = field.getAnnotation(SwitchTarget.class);
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) {
throw new ExecutionException("Failed to execute command: " + e.getMessage(), e);
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate command: ", e);
}
}
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);
completions.addAll(tabComplete(holder.subcommands.get(args.get(0)), sender, newArgs));
}
try {
if(args.size() <= holder.arguments.size()) {
TabCompleter completer = holder.arguments.get(args.size() - 1).tabCompleter().getConstructor().newInstance();
pluginInjector.inject(completer);
completions.addAll(completer.complete(sender));
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate tab-completer: ", e);
}
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.
*/
private static final class CommandHolder {
private final Class<? extends CommandTemplate> clazz;
private final Map<String, CommandHolder> subcommands = new HashMap<>();
private final Map<String, String> switches = new HashMap<>();
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)) {
Command command = clazz.getAnnotation(Command.class);
for(Subcommand subcommand : command.subcommands()) {
if(subcommands.containsKey(subcommand.value()))
throw new MalformedCommandException("Duplicate subcommand: " + subcommand);
CommandHolder holder = new CommandHolder(subcommand.clazz());
subcommands.put(subcommand.value(), holder);
for(String alias : subcommand.aliases()) {
subcommands.put(alias, holder);
}
}
for(Switch aSwitch : command.switches()) {
if(switches.containsKey(aSwitch.value())) throw new MalformedCommandException("Duplicate switch: " + aSwitch);
switches.put(aSwitch.value(), aSwitch.value());
for(String alias : aSwitch.aliases()) {
switches.put(alias, aSwitch.value());
}
}
for(Argument argument : command.arguments()) {
if(argumentMap.containsKey(argument.value())) throw new MalformedCommandException("Duplicate argument: " + argument);
argumentMap.put(argument.value(), argument);
}
arguments = Arrays.asList(command.arguments());
switchList = Arrays.asList(command.switches());
} else {
arguments = Collections.emptyList();
switchList = Collections.emptyList();
}
}
}
}

View File

@@ -1,242 +0,0 @@
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;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.arg.DoubleArgumentParser;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.command.exception.CommandException;
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 static org.junit.jupiter.api.Assertions.*;
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"));
manager.execute("test", null, Arrays.asList("s2", "first", "2"));
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("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);
System.out.println(arg1);
System.out.println(arg2);
}
}
@Command(
arguments = {
@Argument("arg0"),
@Argument("arg1"),
@Argument(value = "arg2", required = false)
},
switches = {
@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("arg0"),
@Argument(value = "arg2", required = false), // optional arguments must be last. this command is invalid.
@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("arg0"),
@Argument("arg1"),
@Argument(value = "arg2", required = false),
},
subcommands = {
@Subcommand(
value = "subcommand1",
aliases = { "s1", "sub1" },
clazz = DemoChildCommand.class
),
@Subcommand(
value = "subcommand2",
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);
System.out.println(arg1);
System.out.println(arg2);
}
}
@Command(
arguments = {
@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);
System.out.println(arg1);
System.out.println(arg2);
}
}
}

View File

@@ -25,6 +25,8 @@ dependencies {
"compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
"shadedApi"("com.google.guava:guava:30.0-jre")
"shadedApi"("cloud.commandframework", "cloud-bukkit", "1.5.0")
}
val jvmFlags = listOf(

View File

@@ -1,9 +1,15 @@
package com.dfsek.terra.bukkit;
import cloud.commandframework.bukkit.BukkitCommandManager;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import io.papermc.lib.PaperLib;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
@@ -11,22 +17,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
import com.dfsek.terra.bukkit.command.BukkitCommandAdapter;
import com.dfsek.terra.bukkit.command.FixChunkCommand;
import com.dfsek.terra.bukkit.command.SaveDataCommand;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.bukkit.listeners.CommonListener;
import com.dfsek.terra.bukkit.listeners.PaperListener;
import com.dfsek.terra.bukkit.listeners.SpigotListener;
import com.dfsek.terra.bukkit.util.PaperUtil;
import com.dfsek.terra.commands.CommandUtil;
import com.dfsek.terra.commands.TerraCommandManager;
public class TerraBukkitPlugin extends JavaPlugin {
@@ -43,9 +41,25 @@ public class TerraBukkitPlugin extends JavaPlugin {
}
private final TerraPluginImpl terraPlugin = new TerraPluginImpl(this);
private final cloud.commandframework.CommandManager<CommandSender> commandManager;
private final Map<String, com.dfsek.terra.api.world.generator.ChunkGenerator> generatorMap = new HashMap<>();
private final Map<String, ConfigPack> worlds = new HashMap<>();
public TerraBukkitPlugin() {
try {
commandManager = new BukkitCommandManager<>(
this,
CommandExecutionCoordinator.simpleCoordinator(),
BukkitAdapter::adapt,
BukkitAdapter::adapt
);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void onDisable() {
BukkitChunkGeneratorWrapper.saveAll();
@@ -62,27 +76,7 @@ public class TerraBukkitPlugin extends JavaPlugin {
new Metrics(this, 9017); // Set up bStats.
PluginCommand c = Objects.requireNonNull(getCommand("terra"));
CommandManager manager = new TerraCommandManager(terraPlugin);
try {
CommandUtil.registerAll(manager);
manager.register("save-data", SaveDataCommand.class);
manager.register("fix-chunk", FixChunkCommand.class);
} catch(MalformedCommandException e) { // This should never happen.
terraPlugin.logger().severe("Errors occurred while registering commands.");
e.printStackTrace();
terraPlugin.logger().severe("Please report this to Terra.");
Bukkit.getPluginManager().disablePlugin(this);
return;
}
BukkitCommandAdapter command = new BukkitCommandAdapter(manager);
c.setExecutor(command);
c.setTabCompleter(command);
terraPlugin.getEventManager().callEvent(new CommandRegistrationEvent(commandManager)); // Register commands
long save = terraPlugin.getTerraConfig().getDataSaveInterval();

View File

@@ -1,58 +0,0 @@
package com.dfsek.terra.bukkit.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
public class BukkitCommandAdapter implements CommandExecutor, TabCompleter {
private final CommandManager manager;
public BukkitCommandAdapter(CommandManager manager) {
this.manager = manager;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
List<String> argList = new ArrayList<>(Arrays.asList(args));
if(argList.isEmpty()) {
sender.sendMessage("Command requires arguments.");
return true;
}
try {
manager.execute(argList.remove(0), BukkitAdapter.adapt(sender), argList);
} catch(CommandException e) {
sender.sendMessage(e.getMessage());
}
return true;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
@NotNull String[] args) {
List<String> argList = new ArrayList<>(Arrays.asList(args));
try {
return manager.tabComplete(argList.remove(0), BukkitAdapter.adapt(sender), argList).stream()
.filter(s -> s.toLowerCase(Locale.ROOT).startsWith(args[args.length - 1].toLowerCase(Locale.ROOT))).sorted(
String::compareTo).collect(Collectors.toList());
} catch(CommandException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
}

View File

@@ -9,6 +9,8 @@ plugins {
id("com.modrinth.minotaur").version("1.1.0")
}
val fabricApi = "0.31.0+1.16"
addonDir(project.rootProject.file("./run/config/Terra/addons"), tasks.named("runClient").get())
addonDir(project.rootProject.file("./run/config/Terra/addons"), tasks.named("runServer").get())
@@ -32,6 +34,8 @@ dependencies {
exclude(group = "org.apache.logging.log4j", module = "log4j-api")
exclude(group = "org.apache.logging.log4j", module = "log4j-core")
}
"modImplementation"("cloud.commandframework", "cloud-fabric", "1.5.0")
}
tasks.named<ShadowJar>("shadowJar") {

View File

@@ -1,6 +1,14 @@
package com.dfsek.terra.fabric;
package com.dfsek.terra.fabric.entry;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.fabric.FabricServerCommandManager;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.fabric.TerraPluginImpl;
import net.fabricmc.api.ModInitializer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.Registry;
@@ -16,7 +24,7 @@ import com.dfsek.terra.fabric.generation.PopulatorFeature;
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
public class FabricEntryPoint implements ModInitializer {
public class CommonEntryPoint implements ModInitializer {
public static final PopulatorFeature POPULATOR_FEATURE = new PopulatorFeature(DefaultFeatureConfig.CODEC);
public static final ConfiguredFeature<?, ?> POPULATOR_CONFIGURED_FEATURE = POPULATOR_FEATURE.configure(FeatureConfig.DEFAULT).decorate(
Decorator.NOPE.configure(NopeDecoratorConfig.INSTANCE));
@@ -36,5 +44,12 @@ public class FabricEntryPoint implements ModInitializer {
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC);
Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), TerraBiomeSource.CODEC);
FabricServerCommandManager<CommandSender> commandManager = new FabricServerCommandManager<>(
CommandExecutionCoordinator.simpleCoordinator(),
fabricClientCommandSource -> (CommandSender) fabricClientCommandSource,
commandSender -> (ServerCommandSource) commandSender);
TERRA_PLUGIN.getEventManager().callEvent(new CommandRegistrationEvent(commandManager));
}
}

View File

@@ -35,7 +35,7 @@ import com.dfsek.terra.api.world.generator.ChunkData;
import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.api.world.generator.Chunkified;
import com.dfsek.terra.api.world.generator.GeneratorWrapper;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.block.FabricBlockState;
import com.dfsek.terra.fabric.mixin.StructureAccessorAccessor;
import com.dfsek.terra.util.FastRandom;
@@ -46,7 +46,7 @@ public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.C
config -> config.group(
Codec.STRING.fieldOf("pack")
.forGetter(ConfigPack::getID)
).apply(config, config.stable(FabricEntryPoint.getTerraPlugin().getConfigRegistry()::get)));
).apply(config, config.stable(CommonEntryPoint.getTerraPlugin().getConfigRegistry()::get)));
public static final Codec<FabricChunkGeneratorWrapper> CODEC = RecordCodecBuilder.create(
instance -> instance.group(

View File

@@ -14,7 +14,7 @@ import java.util.stream.Collectors;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.util.FabricUtil;
@@ -23,7 +23,7 @@ public class TerraBiomeSource extends BiomeSource {
Codec.STRING.fieldOf("pack").forGetter(ConfigPack::getID)
)
.apply(config, config.stable(
FabricEntryPoint.getTerraPlugin()
CommonEntryPoint.getTerraPlugin()
.getConfigRegistry()::get))));
public static final Codec<TerraBiomeSource> CODEC = RecordCodecBuilder.create(instance -> instance.group(
RegistryLookupCodec.of(Registry.BIOME_KEY).forGetter(source -> source.biomeRegistry),

View File

@@ -11,7 +11,7 @@ import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.event.BiomeRegistrationEvent;
@@ -28,7 +28,7 @@ public class TerraGeneratorType extends GeneratorType {
public GeneratorOptions createDefaultOptions(DynamicRegistryManager.Impl registryManager, long seed, boolean generateStructures,
boolean bonusChest) {
GeneratorOptions options = super.createDefaultOptions(registryManager, seed, generateStructures, bonusChest);
FabricEntryPoint.getTerraPlugin().getEventManager().callEvent(new BiomeRegistrationEvent(registryManager)); // register biomes
CommonEntryPoint.getTerraPlugin().getEventManager().callEvent(new BiomeRegistrationEvent(registryManager)); // register biomes
return options;
}

View File

@@ -1,92 +0,0 @@
package com.dfsek.terra.fabric.mixin;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.fabric.FabricEntryPoint;
import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;
@Mixin(CommandManager.class)
public abstract class CommandManagerMixin {
@Shadow
@Final
private CommandDispatcher<ServerCommandSource> dispatcher;
@Inject(method = "<init>",
at = @At(value = "INVOKE",
target = "Lcom/mojang/brigadier/CommandDispatcher;findAmbiguities(Lcom/mojang/brigadier/AmbiguityConsumer;)V",
remap = false))
private void injectTerraCommands(CommandManager.RegistrationEnvironment environment, CallbackInfo ci) {
com.dfsek.terra.api.command.CommandManager manager = FabricEntryPoint.getTerraPlugin().getManager();
int max = manager.getMaxArgumentDepth();
RequiredArgumentBuilder<ServerCommandSource, String> arg = argument("arg" + (max - 1), StringArgumentType.word());
for(int i = 0; i < max; i++) {
RequiredArgumentBuilder<ServerCommandSource, String> next = argument("arg" + (max - i - 1), StringArgumentType.word());
arg = next.then(assemble(arg, manager));
}
dispatcher.register(literal("terra").executes(context -> 1).then(assemble(arg, manager)));
dispatcher.register(literal("te").executes(context -> 1).then(assemble(arg, manager)));
}
private RequiredArgumentBuilder<ServerCommandSource, String> assemble(RequiredArgumentBuilder<ServerCommandSource, String> in,
com.dfsek.terra.api.command.CommandManager manager) {
return in.suggests((context, builder) -> {
List<String> args = parseCommand(context.getInput());
CommandSender sender = (CommandSender) context.getSource();
try {
sender = (Entity) context.getSource().getEntityOrThrow();
} catch(CommandSyntaxException ignore) {
}
try {
manager.tabComplete(args.remove(0), sender, args).forEach(builder::suggest);
} catch(CommandException e) {
sender.sendMessage(e.getMessage());
}
return builder.buildFuture();
}).executes(context -> {
List<String> args = parseCommand(context.getInput());
CommandSender sender = (CommandSender) context.getSource();
try {
sender = (Entity) context.getSource().getEntityOrThrow();
} catch(CommandSyntaxException ignore) {
}
try {
manager.execute(args.remove(0), sender, args);
} catch(CommandException e) {
context.getSource().sendError(new LiteralText(e.getMessage()));
}
return 1;
});
}
private List<String> parseCommand(String command) {
if(command.startsWith("/terra ")) command = command.substring("/terra ".length());
else if(command.startsWith("/te ")) command = command.substring("/te ".length());
List<String> c = new ArrayList<>(Arrays.asList(command.split(" ")));
if(command.endsWith(" ")) c.add("");
return c;
}
}

View File

@@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.concurrent.Executor;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
@@ -31,7 +31,7 @@ public abstract class ServerWorldMixin {
boolean debugWorld, long l, List<Spawner> list, boolean bl, CallbackInfo ci) {
if(chunkGenerator instanceof FabricChunkGeneratorWrapper) {
((FabricChunkGeneratorWrapper) chunkGenerator).setWorld((ServerWorld) (Object) this);
FabricEntryPoint.getTerraPlugin().logger().info("Registered world " + this);
CommonEntryPoint.getTerraPlugin().logger().info("Registered world " + this);
}
}
}

View File

@@ -21,7 +21,7 @@ import com.dfsek.terra.api.util.collection.MaterialSet;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Tree;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
@Mixin(ConfiguredFeature.class)
@@ -33,7 +33,7 @@ public abstract class ConfiguredFeatureMixin {
@SuppressWarnings({ "ConstantConditions", "try" })
public boolean terra$plant(Vector3 l, World world, Random r) {
String id = BuiltinRegistries.CONFIGURED_FEATURE.getId((ConfiguredFeature<?, ?>) (Object) this).toString();
try(ProfileFrame ignore = FabricEntryPoint.getTerraPlugin().getProfiler().profile("fabric_tree:" + id.toLowerCase(Locale.ROOT))) {
try(ProfileFrame ignore = CommonEntryPoint.getTerraPlugin().getProfiler().profile("fabric_tree:" + id.toLowerCase(Locale.ROOT))) {
StructureWorldAccess fabricWorldAccess = ((StructureWorldAccess) world);
ChunkGenerator generatorWrapper = ((ServerWorldAccess) world).toServerWorld().getChunkManager().getChunkGenerator();
return generate(fabricWorldAccess, generatorWrapper, r, new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()));
@@ -41,8 +41,8 @@ public abstract class ConfiguredFeatureMixin {
}
public Set<BlockType> terra$getSpawnable() {
return MaterialSet.get(FabricEntryPoint.getTerraPlugin().getWorldHandle().createBlockData("minecraft:grass_block"),
FabricEntryPoint.getTerraPlugin().getWorldHandle().createBlockData("minecraft:podzol"),
FabricEntryPoint.getTerraPlugin().getWorldHandle().createBlockData("minecraft:mycelium"));
return MaterialSet.get(CommonEntryPoint.getTerraPlugin().getWorldHandle().createBlockData("minecraft:grass_block"),
CommonEntryPoint.getTerraPlugin().getWorldHandle().createBlockData("minecraft:podzol"),
CommonEntryPoint.getTerraPlugin().getWorldHandle().createBlockData("minecraft:mycelium"));
}
}

View File

@@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.Shadow;
import com.dfsek.terra.api.block.entity.MobSpawner;
import com.dfsek.terra.api.block.entity.SerialState;
import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.mixin.access.MobSpawnerLogicAccessor;
@@ -98,7 +98,7 @@ public abstract class MobSpawnerBlockEntityMixin extends BlockEntity {
SerialState.parse(state).forEach((k, v) -> {
switch(k) {
case "type":
terra$setSpawnedType(FabricEntryPoint.getTerraPlugin().getWorldHandle().getEntity(v));
terra$setSpawnedType(CommonEntryPoint.getTerraPlugin().getWorldHandle().getEntity(v));
return;
case "delay":
terra$setDelay(Integer.parseInt(v));

View File

@@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.generation.TerraGeneratorType;
import com.dfsek.terra.fabric.mixin.access.GeneratorTypeAccessor;
@@ -24,8 +24,8 @@ public class MinecraftClientMixin {
// sorta arbitrary position, after mod init, before window opens
shift = At.Shift.BEFORE))
public void injectConstructor(RunArgs args, CallbackInfo callbackInfo) {
FabricEntryPoint.getTerraPlugin().getEventManager().callEvent(new PlatformInitializationEvent());
FabricEntryPoint.getTerraPlugin().getConfigRegistry().forEach(pack -> {
CommonEntryPoint.getTerraPlugin().getEventManager().callEvent(new PlatformInitializationEvent());
CommonEntryPoint.getTerraPlugin().getConfigRegistry().forEach(pack -> {
final GeneratorType generatorType = new TerraGeneratorType(pack);
//noinspection ConstantConditions
((GeneratorTypeAccessor) generatorType).setTranslationKey(new LiteralText("Terra:" + pack.getID()));

View File

@@ -18,7 +18,7 @@ import java.util.Properties;
import java.util.Random;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.TerraPluginImpl;
import com.dfsek.terra.fabric.event.BiomeRegistrationEvent;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
@@ -37,7 +37,7 @@ public abstract class GeneratorOptionsMixin {
return;
}
TerraPluginImpl main = FabricEntryPoint.getTerraPlugin();
TerraPluginImpl main = CommonEntryPoint.getTerraPlugin();
String prop = properties.get("level-type").toString().trim();
if(prop.startsWith("Terra")) {

View File

@@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
@Mixin(Main.class)
@@ -17,7 +17,7 @@ public class ServerMainMixin {
target = "Lnet/minecraft/util/registry/DynamicRegistryManager;create()" +
"Lnet/minecraft/util/registry/DynamicRegistryManager$Impl;"))
private static void injectConstructor(String[] args, CallbackInfo ci) {
FabricEntryPoint.getTerraPlugin().getEventManager().callEvent(
CommonEntryPoint.getTerraPlugin().getEventManager().callEvent(
new PlatformInitializationEvent()); // Load during MinecraftServer construction, after other mods have registered blocks and stuff
}
}

View File

@@ -1,9 +1,16 @@
package com.dfsek.terra.fabric.util;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.entity.Entity;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.BlockState;
import net.minecraft.block.enums.BlockHalf;
import net.minecraft.block.enums.WallShape;
import net.minecraft.block.enums.WireConnection;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
@@ -214,4 +221,13 @@ public final class FabricAdapter {
throw new IllegalStateException();
}
}
public static CommandSender adapt(ServerCommandSource source) {
try {
return (Entity) source.getEntityOrThrow();
} catch(CommandSyntaxException e) {
e.printStackTrace();
}
return (CommandSender) source;
}
}

View File

@@ -1,5 +1,7 @@
package com.dfsek.terra.fabric.util;
import com.dfsek.terra.api.entity.CommandSender;
import com.mojang.serialization.Lifecycle;
import net.minecraft.block.entity.LootableContainerBlockEntity;
import net.minecraft.block.entity.MobSpawnerBlockEntity;
@@ -29,7 +31,7 @@ import com.dfsek.terra.api.block.entity.MobSpawner;
import com.dfsek.terra.api.block.entity.Sign;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.fabric.FabricEntryPoint;
import com.dfsek.terra.fabric.entry.CommonEntryPoint;
import com.dfsek.terra.fabric.mixin.access.BiomeEffectsAccessor;
@@ -60,7 +62,7 @@ public final class FabricUtil {
generationSettings.surfaceBuilder(
vanilla.getGenerationSettings().getSurfaceBuilder()); // It needs a surfacebuilder, even though we dont use it.
generationSettings.feature(GenerationStep.Feature.VEGETAL_DECORATION, FabricEntryPoint.POPULATOR_CONFIGURED_FEATURE);
generationSettings.feature(GenerationStep.Feature.VEGETAL_DECORATION, CommonEntryPoint.POPULATOR_CONFIGURED_FEATURE);
if(pack.vanillaCaves()) {
for(GenerationStep.Carver carver : GenerationStep.Carver.values()) {

View File

@@ -17,7 +17,7 @@
"environment": "*",
"entrypoints": {
"main": [
"com.dfsek.terra.fabric.FabricEntryPoint"
"com.dfsek.terra.fabric.entry.CommonEntryPoint"
]
},
"mixins": [

View File

@@ -4,7 +4,6 @@
"package": "com.dfsek.terra.fabric.mixin",
"compatibilityLevel": "JAVA_16",
"mixins": [
"CommandManagerMixin",
"ServerWorldMixin",
"StructureAccessorAccessor",
"access.BiomeEffectsAccessor",