use chipmunk cloop and sync some stuff
This commit is contained in:
parent
ee22870183
commit
ae6f3b21ac
5 changed files with 148 additions and 159 deletions
|
@ -3,127 +3,102 @@ package land.chipmunk.chipmunkmod.commands;
|
||||||
import com.mojang.brigadier.Command;
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import land.chipmunk.chipmunkmod.data.CommandLoop;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import land.chipmunk.chipmunkmod.modules.CommandLooper;
|
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||||
|
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
||||||
|
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
||||||
|
import static com.mojang.brigadier.arguments.LongArgumentType.longArg;
|
||||||
|
import static com.mojang.brigadier.arguments.LongArgumentType.getLong;
|
||||||
|
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
||||||
|
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||||
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||||
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
import net.minecraft.text.MutableText;
|
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Formatting;
|
import land.chipmunk.chipmunkmod.modules.CommandLoopManager;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
|
||||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
|
||||||
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
|
||||||
|
|
||||||
public class CloopCommand {
|
public class CloopCommand {
|
||||||
|
private static final DynamicCommandExceptionType INVALID_CLOOP_ID_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("Invalid cloop id: %s", Text.literal(String.valueOf(id))));
|
||||||
|
|
||||||
public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||||
dispatcher.register(
|
dispatcher.register(
|
||||||
literal("cloop")
|
literal("cloop")
|
||||||
.then(
|
.then(
|
||||||
literal("add")
|
literal("add")
|
||||||
.then(
|
.then(
|
||||||
argument("interval", integer())
|
argument("interval", longArg())
|
||||||
.then(
|
.then(
|
||||||
argument("command", greedyString())
|
argument("command", greedyString())
|
||||||
.executes(c -> add(c))
|
.executes(c -> addCloop(c))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("remove")
|
literal("remove")
|
||||||
.then(
|
.then(
|
||||||
argument("index", integer())
|
argument("id", integer())
|
||||||
.executes(c -> remove(c))
|
.executes(c -> removeCloop(c))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("clear")
|
literal("clear")
|
||||||
.executes(c -> clear(c))
|
.executes(c -> clearCloops(c))
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("list")
|
literal("list")
|
||||||
.executes(c -> list(c))
|
.executes(c -> listCloops(c))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int add (CommandContext<FabricClientCommandSource> context) {
|
public static int addCloop (CommandContext<FabricClientCommandSource> context) {
|
||||||
final FabricClientCommandSource source = context.getSource();
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
final long interval = getLong(context, "interval");
|
||||||
final String command = getString(context, "command");
|
final String command = getString(context, "command");
|
||||||
final int interval = getInteger(context, "interval");
|
|
||||||
|
|
||||||
CommandLooper.INSTANCE.addLoop(command, interval);
|
int id = CommandLoopManager.INSTANCE.loopCommand(command, interval);
|
||||||
|
|
||||||
source.sendFeedback(
|
|
||||||
Text.translatable(
|
|
||||||
"Added command %s with interval %s to the command loops",
|
|
||||||
Text.literal(command).formatted(Formatting.AQUA),
|
|
||||||
Text.literal(String.valueOf(interval)).formatted(Formatting.GOLD)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
source.sendFeedback(Text.translatable("Successfully created a loop for command '%s' with id %s", Text.literal(command), Text.literal(String.valueOf(id))));
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int remove (CommandContext<FabricClientCommandSource> context) {
|
public static int removeCloop (CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
|
||||||
final FabricClientCommandSource source = context.getSource();
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
final CommandLoopManager manager = CommandLoopManager.INSTANCE;
|
||||||
|
final int id = getInteger(context, "id");
|
||||||
|
|
||||||
final int index = getInteger(context, "index");
|
if (id < 0 || id >= manager.commandLoops().size()) throw INVALID_CLOOP_ID_EXCEPTION.create(id);
|
||||||
|
|
||||||
CommandLooper.INSTANCE.removeLoop(index);
|
manager.removeAndStop(id);
|
||||||
|
|
||||||
source.sendFeedback(
|
|
||||||
Text.translatable(
|
|
||||||
"Removed command loop %s",
|
|
||||||
Text.literal(String.valueOf(index)).formatted(Formatting.GOLD)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
source.sendFeedback(Text.translatable("Successfully removed loop with id %s", Text.literal(String.valueOf(id))));
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int list (CommandContext<FabricClientCommandSource> context) {
|
public static int clearCloops (CommandContext<FabricClientCommandSource> context) {
|
||||||
final FabricClientCommandSource source = context.getSource();
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
final CommandLoopManager manager = CommandLoopManager.INSTANCE;
|
||||||
|
|
||||||
final List<CommandLoop> cloops = CommandLooper.INSTANCE.loops();
|
manager.clearLoops();
|
||||||
|
|
||||||
MutableText text = Text.empty();
|
source.sendFeedback(Text.translatable("Successfully cleared all command loops"));
|
||||||
text.append(Text.literal("Command Loops:").formatted(Formatting.GREEN));
|
return Command.SINGLE_SUCCESS;
|
||||||
text.append("\n"); // should i use Text.literal("\n")?
|
}
|
||||||
|
|
||||||
for (int i = 0; i < cloops.size(); i++) {
|
public static int listCloops (CommandContext<FabricClientCommandSource> context) {
|
||||||
final CommandLoop cloop = cloops.get(i);
|
final FabricClientCommandSource source = context.getSource();
|
||||||
text.append(
|
final List<CommandLoopManager.CommandLoop> loops = CommandLoopManager.INSTANCE.commandLoops();
|
||||||
Text.translatable(
|
|
||||||
"%s > %s - %s", // should i use \u203a?
|
|
||||||
Text.literal(String.valueOf(i)).formatted(Formatting.GREEN),
|
|
||||||
Text.literal(cloop.command()).formatted(Formatting.AQUA),
|
|
||||||
Text.literal(String.valueOf(cloop.interval())).formatted(Formatting.GOLD)
|
|
||||||
).formatted(Formatting.GRAY)
|
|
||||||
);
|
|
||||||
|
|
||||||
// PLS TELL ME HOW TO REMOVE THE LAST ONE OF MutableText SPLSPLpLSLPsSSPLPSPLSPSL
|
int id = 0;
|
||||||
// btw is this the best way to do it lol
|
for (CommandLoopManager.CommandLoop loop : loops) {
|
||||||
final int lastIndex = cloops.size() - 1;
|
source.sendFeedback(Text.translatable("%s: %s (%s)", Text.literal(String.valueOf(id)), Text.literal(loop.command()), Text.literal(String.valueOf(loop.interval()))));
|
||||||
if (i < lastIndex) { text.append("\n"); }
|
id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
source.sendFeedback(text);
|
if (id == 0) {
|
||||||
|
source.sendFeedback(Text.translatable("No command loops are currently running"));
|
||||||
return Command.SINGLE_SUCCESS;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static int clear (CommandContext<FabricClientCommandSource> context) {
|
|
||||||
final FabricClientCommandSource source = context.getSource();
|
|
||||||
|
|
||||||
CommandLooper.INSTANCE.clearLoops();
|
|
||||||
|
|
||||||
source.sendFeedback(Text.literal("Cleared all command loops"));
|
|
||||||
|
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,36 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
import com.mojang.brigadier.StringReader;
|
||||||
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
|
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||||
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
|
||||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
|
||||||
import com.mojang.brigadier.StringReader;
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
|
||||||
|
|
||||||
@Mixin(net.minecraft.client.gui.screen.ChatInputSuggestor.class)
|
@Mixin(net.minecraft.client.gui.screen.ChatInputSuggestor.class)
|
||||||
public class ChatInputSuggestorMixin {
|
public class ChatInputSuggestorMixin {
|
||||||
@Shadow
|
@Shadow
|
||||||
CompletableFuture<Suggestions> pendingSuggestions;
|
private CompletableFuture<Suggestions> pendingSuggestions;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private boolean slashOptional;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public void show (boolean narrateFirstSuggestion) {}
|
public void show (boolean narrateFirstSuggestion) {}
|
||||||
|
|
||||||
|
@Mutable
|
||||||
|
@Final
|
||||||
@Shadow
|
@Shadow
|
||||||
final TextFieldWidget textField;
|
final TextFieldWidget textField;
|
||||||
|
|
||||||
|
@ -31,7 +39,9 @@ public class ChatInputSuggestorMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("TAIL"), method = "refresh()V")
|
@Inject(at = @At("TAIL"), method = "refresh()V")
|
||||||
public void onRefresh (CallbackInfo ci) {
|
public void refresh (CallbackInfo ci) {
|
||||||
|
if (slashOptional) return;
|
||||||
|
|
||||||
final String text = this.textField.getText();
|
final String text = this.textField.getText();
|
||||||
final int cursor = this.textField.getCursor();
|
final int cursor = this.textField.getCursor();
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ public class ClientPlayNetworkHandlerMixin {
|
||||||
@Inject(method = "onGameJoin", at = @At("TAIL"))
|
@Inject(method = "onGameJoin", at = @At("TAIL"))
|
||||||
private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) {
|
private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) {
|
||||||
SelfCare.INSTANCE.init();
|
SelfCare.INSTANCE.init();
|
||||||
CommandLooper.INSTANCE.init();
|
|
||||||
SongPlayer.INSTANCE.coreReady();
|
SongPlayer.INSTANCE.coreReady();
|
||||||
RainbowName.INSTANCE.init();
|
RainbowName.INSTANCE.init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package land.chipmunk.chipmunkmod.modules;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
public class CommandLoopManager {
|
||||||
|
private final CommandCore core;
|
||||||
|
@Getter @Setter private List<CommandLoop> commandLoops = new ArrayList<>();
|
||||||
|
|
||||||
|
public CommandLoopManager (CommandCore core) {
|
||||||
|
this.core = core;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final CommandLoopManager INSTANCE = new CommandLoopManager(CommandCore.INSTANCE);
|
||||||
|
|
||||||
|
public int loopCommand (String command, long interval) {
|
||||||
|
final CommandLoop loop = new CommandLoop(this.core, command, interval);
|
||||||
|
if (!commandLoops.add(loop)) return -1;
|
||||||
|
return commandLoops.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeAndStop (CommandLoop loop) {
|
||||||
|
loop.stop();
|
||||||
|
return commandLoops.remove(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeAndStop (int id) {
|
||||||
|
return removeAndStop(commandLoops.get(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearLoops () {
|
||||||
|
for (CommandLoop loop : this.commandLoops) loop.stop();
|
||||||
|
commandLoops.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup () { this.clearLoops(); }
|
||||||
|
|
||||||
|
public static class CommandLoop {
|
||||||
|
@Getter @Setter private CommandCore core;
|
||||||
|
@Getter @Setter private String command;
|
||||||
|
@Getter private long interval;
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
public CommandLoop (CommandCore core, String command, long interval) {
|
||||||
|
this.core = core;
|
||||||
|
this.command = command;
|
||||||
|
this.interval = interval;
|
||||||
|
this.timer = new Timer();
|
||||||
|
timer.schedule(this.createTimerTask(), interval, interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long interval (long interval) {
|
||||||
|
if (timer == null) throw new IllegalStateException("Attempted to set the interval of a stopped command loop");
|
||||||
|
|
||||||
|
timer.cancel();
|
||||||
|
timer.purge();
|
||||||
|
|
||||||
|
this.interval = interval;
|
||||||
|
this.timer = new Timer();
|
||||||
|
timer.schedule(this.createTimerTask(), interval, interval);
|
||||||
|
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stop () {
|
||||||
|
timer.cancel();
|
||||||
|
timer.purge();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimerTask createTimerTask () {
|
||||||
|
return new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run () {
|
||||||
|
core.run(command);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,78 +0,0 @@
|
||||||
package land.chipmunk.chipmunkmod.modules;
|
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.data.CommandLoop;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
public class CommandLooper {
|
|
||||||
private final MinecraftClient client;
|
|
||||||
|
|
||||||
// sus
|
|
||||||
private final List<TimerTask> loopTasks = new ArrayList<>();
|
|
||||||
@Getter private final List<CommandLoop> loops = new ArrayList<>();
|
|
||||||
|
|
||||||
private Timer timer = null;
|
|
||||||
|
|
||||||
public static CommandLooper INSTANCE = new CommandLooper(MinecraftClient.getInstance());
|
|
||||||
|
|
||||||
public CommandLooper (MinecraftClient client) {
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init () {
|
|
||||||
TimerTask task = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run () {
|
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
|
||||||
|
|
||||||
if (networkHandler == null) { cleanup(); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (timer != null) cleanup();
|
|
||||||
|
|
||||||
timer = new Timer();
|
|
||||||
timer.schedule(task, 0, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanup() {
|
|
||||||
if (timer == null) return;
|
|
||||||
clearLoops();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLoop(String command, long interval) {
|
|
||||||
TimerTask loopTask = new TimerTask() {
|
|
||||||
public void run() {
|
|
||||||
CommandCore.INSTANCE.run(command);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
loopTasks.add(loopTask);
|
|
||||||
loops.add(new CommandLoop(command, interval)); // mabe,.,..
|
|
||||||
// should i use 50 or 0?
|
|
||||||
timer.scheduleAtFixedRate(loopTask, 0, interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeLoop(int index) {
|
|
||||||
TimerTask loopTask = loopTasks.remove(index);
|
|
||||||
if (loopTask != null) {
|
|
||||||
loopTask.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
loops.remove(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearLoops() {
|
|
||||||
for (TimerTask loopTask : loopTasks) {
|
|
||||||
loopTask.cancel();
|
|
||||||
}
|
|
||||||
loopTasks.clear();
|
|
||||||
|
|
||||||
loops.clear();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue