Skip to content

Commit 9e6b272

Browse files
committed
Fix api link
1 parent 6b377ed commit 9e6b272

File tree

175 files changed

+11307
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+11307
-1
lines changed

api

Lines changed: 0 additions & 1 deletion
This file was deleted.

api/commands/build.gradle.kts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
plugins {
2+
id("impactor.base-conventions")
3+
id("impactor.minecraft-conventions")
4+
}
5+
6+
sourceSets {
7+
main {
8+
java.srcDirs(
9+
"src/launcher/java",
10+
"src/mixins/java"
11+
)
12+
13+
resources.srcDirs(
14+
"src/mixins/resources"
15+
)
16+
}
17+
}
18+
19+
dependencies {
20+
api(projects.loader)
21+
api(projects.api.core)
22+
api(projects.api.platform)
23+
implementation(projects.api.text)
24+
25+
api(libs.bundles.cloud.base)
26+
implementation(libs.bundles.mixins)
27+
annotationProcessor(libs.bundles.mixins)
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package net.impactdev.impactor.api.commands.launcher;
2+
3+
import com.google.auto.service.AutoService;
4+
import net.impactdev.impactor.loader.Version;
5+
import net.impactdev.impactor.loader.modules.ImpactorModule;
6+
import net.impactdev.impactor.loader.modules.ModuleMetadata;
7+
8+
@AutoService(ImpactorModule.class)
9+
public final class CommandsModule extends ImpactorModule {
10+
11+
private static final ModuleMetadata METADATA = new ModuleMetadata(
12+
"Commands",
13+
new Version(6, 0, 0)
14+
);
15+
16+
@Override
17+
public ModuleMetadata metadata() {
18+
return METADATA;
19+
}
20+
21+
@Override
22+
public void initialize() throws Exception {
23+
24+
}
25+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package net.impactdev.impactor.api.commands.launcher;
2+
3+
import com.google.common.base.Strings;
4+
import com.google.common.cache.CacheBuilder;
5+
import com.google.common.util.concurrent.ThreadFactoryBuilder;
6+
import net.impactdev.impactor.api.commands.CommandSource;
7+
import net.impactdev.impactor.api.text.TextProcessor;
8+
import net.impactdev.impactor.loader.logging.PrettyPrinter;
9+
import net.kyori.adventure.text.Component;
10+
import net.kyori.adventure.text.event.ClickEvent;
11+
import net.kyori.adventure.text.event.HoverEvent;
12+
import net.kyori.adventure.text.format.NamedTextColor;
13+
import net.kyori.adventure.text.format.Style;
14+
import net.kyori.adventure.text.format.TextColor;
15+
import org.apache.logging.log4j.Level;
16+
import org.apache.logging.log4j.Logger;
17+
import org.incendo.cloud.CommandManager;
18+
import org.incendo.cloud.brigadier.BrigadierManagerHolder;
19+
import org.incendo.cloud.brigadier.BrigadierSetting;
20+
import org.incendo.cloud.brigadier.CloudBrigadierManager;
21+
import org.incendo.cloud.brigadier.argument.BrigadierMappings;
22+
import org.incendo.cloud.context.CommandContext;
23+
import org.incendo.cloud.exception.CommandExecutionException;
24+
import org.incendo.cloud.exception.handling.ExceptionController;
25+
import org.incendo.cloud.execution.ExecutionCoordinator;
26+
import org.incendo.cloud.processors.cache.GuavaCache;
27+
import org.incendo.cloud.processors.confirmation.ConfirmationConfiguration;
28+
import org.incendo.cloud.processors.confirmation.ConfirmationManager;
29+
import org.incendo.cloud.setting.Configurable;
30+
import org.jetbrains.annotations.ApiStatus;
31+
import org.jetbrains.annotations.Nullable;
32+
33+
import java.io.PrintWriter;
34+
import java.io.StringWriter;
35+
import java.util.ServiceLoader;
36+
import java.util.concurrent.ExecutorService;
37+
import java.util.concurrent.Executors;
38+
import java.util.concurrent.TimeUnit;
39+
40+
import static net.kyori.adventure.text.Component.space;
41+
import static net.kyori.adventure.text.Component.text;
42+
43+
@ApiStatus.Internal
44+
public abstract class ImpactorCommands {
45+
46+
private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(
47+
Runtime.getRuntime().availableProcessors(),
48+
new ThreadFactoryBuilder()
49+
.setNameFormat("Impactor Command Executor: %d")
50+
.setDaemon(true)
51+
.build()
52+
);
53+
54+
private final Logger logger;
55+
private final CommandManager<CommandSource> manager;
56+
57+
protected ImpactorCommands(final Logger logger) {
58+
this.logger = logger;
59+
var executor = ExecutionCoordinator.<CommandSource>builder().executor(EXECUTOR).build();
60+
61+
this.manager = this.create(executor);
62+
this.initialize();
63+
}
64+
65+
protected abstract CommandManager<CommandSource> create(ExecutionCoordinator<CommandSource> coordinator);
66+
67+
protected abstract void configure(CommandManager<CommandSource> manager);
68+
69+
private void initialize() {
70+
ConfirmationManager<CommandSource> confirmations = ConfirmationManager.confirmationManager(
71+
ConfirmationConfiguration.<CommandSource>builder()
72+
.cache(GuavaCache.of(CacheBuilder.newBuilder()
73+
.expireAfterWrite(30, TimeUnit.SECONDS)
74+
.build()
75+
))
76+
.noPendingCommandNotifier(source -> source.sendMessage(text("No pending confirmations available...").color(NamedTextColor.RED)))
77+
.confirmationRequiredNotifier((source, ctx) -> source.sendMessage(text("Click to confirm action!").color(NamedTextColor.YELLOW)))
78+
.build()
79+
);
80+
81+
this.manager.registerCommandPostProcessor(confirmations.createPostprocessor());
82+
this.setupBrigadier(this.manager);
83+
84+
ExceptionController<CommandSource> controller = this.manager.exceptionController();
85+
controller.registerHandler(CommandExecutionException.class, context -> {
86+
Component prefix = TextProcessor.mini().parse("<gradient:#ff4c4c:#fbff53>Impactor</gradient> <gray>»");
87+
Component message = prefix.append(space())
88+
.append(text("An internal error occurred while processing that command!")
89+
.color(TextColor.color(0xff4c4c))
90+
);
91+
92+
Style style = message.style();
93+
94+
final StringWriter writer = new StringWriter();
95+
context.exception().getCause().printStackTrace(new PrintWriter(writer));
96+
97+
final String trace = writer.toString().replace("\t", Strings.repeat(" ", 4));
98+
final Component hover = text(trace).append(Component.newline())
99+
.append(text("Click to copy!").color(NamedTextColor.YELLOW));
100+
101+
style = style.hoverEvent(HoverEvent.showText(hover)).clickEvent(ClickEvent.copyToClipboard(trace));
102+
message = message.style(style);
103+
104+
context.context().sender().sendMessage(message);
105+
this.printException(context.exception());
106+
});
107+
}
108+
109+
@SuppressWarnings("unchecked")
110+
private void setupBrigadier(final CommandManager<CommandSource> manager) {
111+
if (manager instanceof BrigadierManagerHolder<?, ?> holder && holder.hasBrigadierManager()) {
112+
CloudBrigadierManager<CommandSource, ?> brigadier = (CloudBrigadierManager<CommandSource, ?>) holder.brigadierManager();
113+
114+
Configurable<BrigadierSetting> settings = brigadier.settings();
115+
settings.set(BrigadierSetting.FORCE_EXECUTABLE, true);
116+
117+
BrigadierMappings<CommandSource, ?> mappings = brigadier.mappings();
118+
// ServiceLoader<BrigadierMappingProvider> mappers = ServiceLoader.load(BrigadierMappingProvider.class);
119+
// for (BrigadierMappingProvider provider : mappers) {
120+
// provider.register(mappings);
121+
// }
122+
}
123+
}
124+
125+
private void printException(final CommandExecutionException exception) {
126+
PrettyPrinter printer = new PrettyPrinter(80).wrapTo(80);
127+
printer.title("Command Execution Exception")
128+
.add("An unexpected error was encountered during command processing. This error")
129+
.consume(p -> {
130+
String contextual = exception.context() != null ? "alongside its relative context" : "";
131+
p.add(contextual + " will now be displayed.");
132+
})
133+
.hr('-')
134+
.consume(p -> {
135+
final @Nullable CommandContext<?> context = exception.context();
136+
if (context != null) {
137+
p.add("Command Input: %s", context.rawInput().input());
138+
p.add("During Suggestions: %b", context.isSuggestions());
139+
140+
p.add("Context:");
141+
context.all().forEach((key, value) -> p.add(" %s: %s", key, value.toString()));
142+
p.newline();
143+
}
144+
})
145+
.add("Encountered Exception Stacktrace:")
146+
.add(exception);
147+
148+
printer.log(this.logger, Level.ERROR);
149+
}
150+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.impactdev.impactor.api.commands;
2+
3+
import org.incendo.cloud.CommandManager;
4+
5+
/**
6+
* Represents the processor responsible for establishing a {@link CommandManager}. This system is effectively
7+
* responsible for establishing how commands are performed. Internally, this should be based on
8+
* <a href="https://cloud.incendo.org/">cloud from the incendo group</a>.
9+
*
10+
* @since 6.0.0
11+
*/
12+
public interface CommandProcessor {
13+
14+
/**
15+
* Provides the {@link CommandManager} associated with this processor.
16+
*
17+
* @return A {@link CommandManager}
18+
* @since 6.0.0
19+
*/
20+
CommandManager<CommandSource> manager();
21+
22+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package net.impactdev.impactor.api.commands;
2+
3+
import net.kyori.adventure.audience.Audience;
4+
import net.kyori.adventure.audience.ForwardingAudience;
5+
import net.minecraft.commands.CommandSourceStack;
6+
import org.jetbrains.annotations.NotNull;
7+
8+
import java.util.Collections;
9+
10+
/**
11+
* Represents a reference to some sort of subject capable of sending commands.
12+
*
13+
* @since 6.0.0
14+
*/
15+
public record CommandSource(Audience source, CommandSourceStack delegate) implements ForwardingAudience.Single {
16+
17+
/**
18+
* Represents the subject bound to this source. This subject is the actual source of execution
19+
* for the command, and can range from a player, an entity, or the server itself.
20+
*
21+
* @return The true subject represented by this source object
22+
* @since 6.0.0
23+
*/
24+
@Override
25+
public Audience source() {
26+
return this.source;
27+
}
28+
29+
@Override
30+
public @NotNull Audience audience() {
31+
return this.source;
32+
}
33+
34+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package net.impactdev.impactor.api.commands;
2+
3+
import net.minecraft.commands.CommandSourceStack;
4+
import org.checkerframework.checker.nullness.qual.NonNull;
5+
import org.incendo.cloud.SenderMapper;
6+
7+
public final class CommandSourceMapper implements SenderMapper<CommandSource, CommandSourceStack> {
8+
9+
@Override
10+
public @NonNull CommandSourceStack map(@NonNull CommandSource base) {
11+
return base.delegate();
12+
}
13+
14+
@Override
15+
public @NonNull CommandSource reverse(@NonNull CommandSourceStack mapped) {
16+
return null;
17+
}
18+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package net.impactdev.impactotr.api.commands.mixins;
2+
3+
import net.impactdev.impactor.api.platform.entity.Subject;
4+
import net.minecraft.commands.CommandSource;
5+
import org.spongepowered.asm.mixin.Implements;
6+
import org.spongepowered.asm.mixin.Interface;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
9+
@Mixin(CommandSource.class)
10+
@Implements(@Interface(iface = Subject.class, prefix = "impactor$"))
11+
public abstract class CommandSourceMixin {
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package net.impactdev.impactotr.api.commands.mixins;
2+
3+
import net.impactdev.impactor.api.commands.CommandSource;
4+
import net.minecraft.commands.CommandSourceStack;
5+
import org.spongepowered.asm.mixin.Mixin;
6+
import org.spongepowered.asm.mixin.Unique;
7+
8+
@Mixin(CommandSourceStack.class)
9+
public abstract class CommandSourceStackMixin implements CommandSource.Stack {
10+
11+
@Unique
12+
private CommandSource impactor$source;
13+
14+
@Override
15+
public CommandSource source() {
16+
return this.impactor$source;
17+
}
18+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"required": true,
3+
"package": "net.impactdev.impactotr.api.commands.mixins",
4+
"compatibilityLevel": "JAVA_21",
5+
"minVersion": "0.8",
6+
"mixins": [
7+
"CommandSourceMixin",
8+
"CommandSourceStackMixin"
9+
]
10+
}

0 commit comments

Comments
 (0)