forked from ChomeNS/chipmunkmod
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.CommandDispatcher;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import land.chipmunk.chipmunkmod.data.CommandLoop;
|
||||
import land.chipmunk.chipmunkmod.modules.CommandLooper;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
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.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import land.chipmunk.chipmunkmod.modules.CommandLoopManager;
|
||||
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 {
|
||||
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) {
|
||||
dispatcher.register(
|
||||
literal("cloop")
|
||||
.then(
|
||||
literal("add")
|
||||
.then(
|
||||
argument("interval", integer())
|
||||
argument("interval", longArg())
|
||||
.then(
|
||||
argument("command", greedyString())
|
||||
.executes(c -> add(c))
|
||||
.executes(c -> addCloop(c))
|
||||
)
|
||||
)
|
||||
)
|
||||
.then(
|
||||
literal("remove")
|
||||
.then(
|
||||
argument("index", integer())
|
||||
.executes(c -> remove(c))
|
||||
argument("id", integer())
|
||||
.executes(c -> removeCloop(c))
|
||||
)
|
||||
)
|
||||
.then(
|
||||
literal("clear")
|
||||
.executes(c -> clear(c))
|
||||
.executes(c -> clearCloops(c))
|
||||
)
|
||||
.then(
|
||||
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 long interval = getLong(context, "interval");
|
||||
final String command = getString(context, "command");
|
||||
final int interval = getInteger(context, "interval");
|
||||
|
||||
CommandLooper.INSTANCE.addLoop(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)
|
||||
)
|
||||
);
|
||||
int id = CommandLoopManager.INSTANCE.loopCommand(command, interval);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static int remove (CommandContext<FabricClientCommandSource> context) {
|
||||
public static int removeCloop (CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
|
||||
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);
|
||||
|
||||
source.sendFeedback(
|
||||
Text.translatable(
|
||||
"Removed command loop %s",
|
||||
Text.literal(String.valueOf(index)).formatted(Formatting.GOLD)
|
||||
)
|
||||
);
|
||||
manager.removeAndStop(id);
|
||||
|
||||
source.sendFeedback(Text.translatable("Successfully removed loop with id %s", Text.literal(String.valueOf(id))));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}
|
||||
|
||||
public static int list (CommandContext<FabricClientCommandSource> context) {
|
||||
public static int clearCloops (CommandContext<FabricClientCommandSource> context) {
|
||||
final FabricClientCommandSource source = context.getSource();
|
||||
final CommandLoopManager manager = CommandLoopManager.INSTANCE;
|
||||
|
||||
final List<CommandLoop> cloops = CommandLooper.INSTANCE.loops();
|
||||
|
||||
MutableText text = Text.empty();
|
||||
text.append(Text.literal("Command Loops:").formatted(Formatting.GREEN));
|
||||
text.append("\n"); // should i use Text.literal("\n")?
|
||||
|
||||
for (int i = 0; i < cloops.size(); i++) {
|
||||
final CommandLoop cloop = cloops.get(i);
|
||||
text.append(
|
||||
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
|
||||
// btw is this the best way to do it lol
|
||||
final int lastIndex = cloops.size() - 1;
|
||||
if (i < lastIndex) { text.append("\n"); }
|
||||
}
|
||||
|
||||
source.sendFeedback(text);
|
||||
manager.clearLoops();
|
||||
|
||||
source.sendFeedback(Text.translatable("Successfully cleared all command loops"));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}
|
||||
|
||||
public static int clear (CommandContext<FabricClientCommandSource> context) {
|
||||
public static int listCloops (CommandContext<FabricClientCommandSource> context) {
|
||||
final FabricClientCommandSource source = context.getSource();
|
||||
final List<CommandLoopManager.CommandLoop> loops = CommandLoopManager.INSTANCE.commandLoops();
|
||||
|
||||
CommandLooper.INSTANCE.clearLoops();
|
||||
int id = 0;
|
||||
for (CommandLoopManager.CommandLoop loop : loops) {
|
||||
source.sendFeedback(Text.translatable("%s: %s (%s)", Text.literal(String.valueOf(id)), Text.literal(loop.command()), Text.literal(String.valueOf(loop.interval()))));
|
||||
id++;
|
||||
}
|
||||
|
||||
source.sendFeedback(Text.literal("Cleared all command loops"));
|
||||
if (id == 0) {
|
||||
source.sendFeedback(Text.translatable("No command loops are currently running"));
|
||||
}
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,28 +1,36 @@
|
|||
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.Mutable;
|
||||
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.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)
|
||||
public class ChatInputSuggestorMixin {
|
||||
@Shadow
|
||||
CompletableFuture<Suggestions> pendingSuggestions;
|
||||
private CompletableFuture<Suggestions> pendingSuggestions;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
private boolean slashOptional;
|
||||
|
||||
@Shadow
|
||||
public void show (boolean narrateFirstSuggestion) {}
|
||||
|
||||
@Mutable
|
||||
@Final
|
||||
@Shadow
|
||||
final TextFieldWidget textField;
|
||||
|
||||
|
@ -31,7 +39,9 @@ public class ChatInputSuggestorMixin {
|
|||
}
|
||||
|
||||
@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 int cursor = this.textField.getCursor();
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ public class ClientPlayNetworkHandlerMixin {
|
|||
@Inject(method = "onGameJoin", at = @At("TAIL"))
|
||||
private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) {
|
||||
SelfCare.INSTANCE.init();
|
||||
CommandLooper.INSTANCE.init();
|
||||
SongPlayer.INSTANCE.coreReady();
|
||||
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