Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.entity.bot.action.BotAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider;

import java.util.Collection;
import java.util.List;
import java.util.UUID;

/**
Expand Down Expand Up @@ -44,5 +47,13 @@ public interface BotManager {
*/
<T extends BotAction<T>> T newAction(@NotNull Class<T> type);

CustomAction newCustomAction(String actionId);

void registerAction(CustomActionProvider executor);

void unregisterAction(String id);

List<String> getCustomActions();

BotCreator botCreator(@NotNull String realName, @NotNull Location location);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.leavesmc.leaves.entity.bot.action.custom;

import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import io.papermc.paper.command.brigadier.CommandSourceStack;

public interface BrigadierLikeProcessor extends CommandProcessor {

void buildCommand(LiteralArgumentBuilder<CommandSourceStack> root);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.leavesmc.leaves.entity.bot.action.custom;

import org.bukkit.command.CommandSender;

import java.util.List;

public interface BukkitLikeProcessor extends CommandProcessor {

List<String> getSuggestion(CommandSender sender, String[] args);

void loadAction(CommandSender sender, String[] args, CustomAction action);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.leavesmc.leaves.entity.bot.action.custom;

import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public interface CommandProcessor {

@ApiStatus.Internal
CommandProcessor DUMMY_PROCESSOR = new CommandProcessor() {

};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.leavesmc.leaves.entity.bot.action.custom;

import org.leavesmc.leaves.entity.bot.action.BotAction;

public interface CustomAction extends BotAction<CustomAction> {

<T> T getMeta(String key);

<T> void setMeta(String key, T meta);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.leavesmc.leaves.entity.bot.action.custom;

import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.ApiStatus;
import org.leavesmc.leaves.entity.bot.Bot;

public abstract class CustomActionProvider {

private CommandProcessor processor = CommandProcessor.DUMMY_PROCESSOR;

public abstract String id();

public abstract Plugin provider();

public abstract boolean doTick(Bot bot, CustomAction action);

public void withProcessor(CommandProcessor processor) {
this.processor = processor;
}

@ApiStatus.Internal
public CommandProcessor processor() {
return processor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider;

import java.util.Collection;
import java.util.HashMap;
Expand All @@ -16,7 +17,10 @@ public class Actions {
private static final Map<String, AbstractBotAction<?>> actionsByName = new HashMap<>();
private static final Map<Class<?>, AbstractBotAction<?>> actionsByClass = new HashMap<>();

static {

private static final Map<String, CustomActionProvider> customActionsById = new HashMap<>();

static {
register(new ServerAttackAction(), AttackAction.class);
register(new ServerBreakBlockAction(), BreakBlockAction.class);
register(new ServerDropAction(), DropAction.class);
Expand Down Expand Up @@ -60,6 +64,22 @@ public static boolean unregister(@NotNull String name) {
return false;
}

public static void addCustom(CustomActionProvider provider) {
customActionsById.put(provider.id(), provider);
}

public static @Nullable CustomActionProvider getCustom(String id) {
return customActionsById.get(id);
}

public static void removeCustom(String id) {
customActionsById.remove(id);
}

public static Collection<String> getCustomActions() {
return customActionsById.keySet();
}

@NotNull
@Contract(pure = true)
public static Collection<AbstractBotAction<?>> getAll() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.leavesmc.leaves.bot.agent.actions.custom;

import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider;
import org.leavesmc.leaves.entity.bot.actions.CraftCustomAction;

import java.util.HashMap;
import java.util.Map;

public class ServerCustomAction extends AbstractBotAction<ServerCustomAction> {

private final CustomActionProvider customActionProvider;

private final Map<String, Object> metaMap = new HashMap<>();

public ServerCustomAction(CustomActionProvider customActionProvider) {
super(customActionProvider.id(), null); // Don't create here
this.customActionProvider = customActionProvider;
}

@Override
public boolean doTick(@NotNull ServerBot bot) {
return customActionProvider.doTick(bot.getBukkitEntity(), (CustomAction) this.asCraft());
}

@Override
public Object asCraft() {
return new CraftCustomAction(this);
}

@SuppressWarnings("unchecked")
public <T> T getMeta(String key) {
return (T) metaMap.get(key);
}

public <T> void setMeta(String key, T meta) {
metaMap.put(key, meta);
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
package org.leavesmc.leaves.command.bot.subcommands.action;

import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction;
import org.leavesmc.leaves.command.ArgumentNode;
import org.leavesmc.leaves.command.CommandContext;
import org.leavesmc.leaves.command.LiteralNode;
import org.leavesmc.leaves.command.WrappedArgument;
import org.leavesmc.leaves.entity.bot.action.custom.BukkitLikeProcessor;
import org.leavesmc.leaves.entity.bot.action.custom.CustomAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

import static io.papermc.paper.adventure.PaperAdventure.asAdventure;
Expand All @@ -33,6 +44,7 @@ public class StartCommand extends LiteralNode {
public StartCommand() {
super("start");
Actions.getAll().stream().map(this::actionNodeCreator).forEach(this::children);
this.children.add(new CustomActionNode());
}

private boolean handleStartCommand(CommandContext context, @NotNull AbstractBotAction<?> action) throws CommandSyntaxException {
Expand Down Expand Up @@ -109,4 +121,61 @@ private ActionLiteralNode(@NotNull AbstractBotAction<?> action) {
return builder;
}
}

private static class CustomActionNode extends ArgumentNode<String> {

protected CustomActionNode() {
super("custom", StringArgumentType.greedyString());
}

@Override
protected boolean execute(CommandContext context) {
try {
ServerBot bot = getBot(context);
CommandSender sender = context.getSender();
String[] args = StringUtils.split(context.getArgument("custom", String.class), ' ');
CustomActionProvider provider = Actions.getCustom(args[0]);
if (provider == null || !(provider.processor() instanceof BukkitLikeProcessor processor)) {
return false;
}
String[] realArg = Arrays.copyOfRange(args, 1, args.length);
ServerCustomAction action = new ServerCustomAction(provider);
processor.loadAction(sender, realArg, (CustomAction) action.asCraft());
if (bot.addBotAction(action, sender)) {
sender.sendMessage(join(spaces(),
text("Action", GRAY),
text(action.getName(), AQUA).hoverEvent(showText(text(action.getActionDataString()))),
text("has been issued to", GRAY),
asAdventure(bot.getDisplayName())
));
}
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}

@Override
protected CompletableFuture<Suggestions> getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException {
try {
String[] args = builder.getRemaining().split(" ", -1);
if (args.length <= 1) {
Actions.getCustomActions().forEach(builder::suggest);
} else {
CustomActionProvider provider = Actions.getCustom(args[0]);
if (provider == null || !(provider.processor() instanceof BukkitLikeProcessor processor)) {
return builder.buildFuture();
}
String[] realArg = Arrays.copyOfRange(args, 1, args.length);
List<String> suggestion = processor.getSuggestion(context.getSender(), realArg);
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
suggestion.forEach(builder::suggest);
}
} catch (Exception e) {
e.printStackTrace();
}
return builder.buildFuture();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.bot.agent.actions.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction;
import org.leavesmc.leaves.entity.bot.action.BotAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomActionProvider;
import org.leavesmc.leaves.event.bot.BotCreateEvent;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

public class CraftBotManager implements BotManager {
Expand Down Expand Up @@ -67,6 +71,30 @@ public <T extends BotAction<T>> T newAction(@NotNull Class<T> type) {
}
}

@Override
public CustomAction newCustomAction(String actionId) {
CustomActionProvider provider = Actions.getCustom(actionId);
if (provider == null) {
throw new IllegalArgumentException("Can't find custom action " + actionId);
}
return (CustomAction) new ServerCustomAction(provider).asCraft();
}

@Override
public void registerAction(CustomActionProvider provider) {
Actions.addCustom(provider);
}

@Override
public void unregisterAction(String id) {
Actions.removeCustom(id);
}

@Override
public List<String> getCustomActions() {
return List.of();
}

@Override
public BotCreator botCreator(@NotNull String realName, @NotNull Location location) {
return BotCreateState.builder(realName, location).createReason(BotCreateEvent.CreateReason.PLUGIN);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.leavesmc.leaves.entity.bot.actions;

import org.leavesmc.leaves.bot.agent.actions.custom.ServerCustomAction;
import org.leavesmc.leaves.entity.bot.action.custom.CustomAction;

public class CraftCustomAction extends CraftBotAction<CustomAction, ServerCustomAction> implements CustomAction {

public CraftCustomAction(ServerCustomAction serverAction) {
super(serverAction, CraftCustomAction::new);
}

@Override
public <T> T getMeta(String key) {
return serverAction.getMeta(key);
}

@Override
public <T> void setMeta(String key, T meta) {
serverAction.setMeta(key, meta);
}
}