Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added creply / cr #648

Open
wants to merge 29 commits into
base: fabric
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a380113
added creply / cr
RealRTTV Jun 23, 2024
bb269be
Made changes in response to review
RealRTTV Jun 23, 2024
2c75477
fine then earth
RealRTTV Jun 23, 2024
bc45c41
changed it to not crash cross-dimensionally, and to allow for max len…
RealRTTV Jun 29, 2024
5cdff65
ok thats fine
RealRTTV Jun 30, 2024
b2d19e3
Merge remote-tracking branch 'upstream/fabric' into creply
RealRTTV Jul 9, 2024
a2f70db
Update ReplyCommand.java
RealRTTV Jul 19, 2024
519fe59
Update ReplyCommand.java
RealRTTV Jul 19, 2024
9c1db38
Update en_us.json
RealRTTV Jul 19, 2024
9a889d5
Update ReplyCommand.java
RealRTTV Jul 19, 2024
a2891bb
Update ReplyCommand.java
RealRTTV Jul 19, 2024
75b9f47
Update ReplyCommand.java
RealRTTV Jul 19, 2024
2aeee65
Update ReplyCommand.java
RealRTTV Jul 19, 2024
9b76e03
Update ReplyCommand.java
RealRTTV Jul 19, 2024
cdae378
Add intellij project icon
Earthcomputer Jul 19, 2024
1cfe279
Remove incompatibility with seedcrackerx. Closes #653
Earthcomputer Jul 24, 2024
ab058ac
Merge branch 'Earthcomputer:fabric' into creply
RealRTTV Aug 6, 2024
41f09eb
Merge remote-tracking branch 'upstream/fabric' into creply
RealRTTV Aug 9, 2024
3227e53
np
RealRTTV Sep 28, 2024
e1ca3e6
made the code a bit prettier
RealRTTV Sep 28, 2024
13235aa
ok
RealRTTV Sep 29, 2024
39bd27d
ok
RealRTTV Sep 29, 2024
837c679
ok
RealRTTV Sep 29, 2024
670e0b8
Merge remote-tracking branch 'upstream/fabric' into creply
RealRTTV Oct 5, 2024
aa1eec0
Merge remote-tracking branch 'upstream/fabric' into creply
RealRTTV Oct 22, 2024
b7e51a3
Merge remote-tracking branch 'upstream/fabric' into creply
RealRTTV Nov 21, 2024
e821565
Merge remote-tracking branch 'upstream/fabric' into creply
RealRTTV Nov 22, 2024
11e5f0f
Merge remote-tracking branch 'upstream/fabric' into creply
RealRTTV Nov 28, 2024
5a0d641
changed it to be a 0.5 second threshold
RealRTTV Nov 28, 2024
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 @@ -158,6 +158,7 @@ public static void registerCommands(CommandDispatcher<FabricClientCommandSource>
PosCommand.register(dispatcher);
RelogCommand.register(dispatcher);
RenderCommand.register(dispatcher);
ReplyCommand.register(dispatcher);
ShrugCommand.register(dispatcher);
SignSearchCommand.register(dispatcher);
SnakeCommand.register(dispatcher);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/net/earthcomputer/clientcommands/Configs.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,10 @@ public enum PacketDumpMethod {

@Config
public static int maximumPacketFieldDepth = 10;

@Config(temporary = true, setter = @Config.Setter("setMinimumReplyDelaySeconds"))
public static float minimumReplyDelaySeconds = 0.5f;
public static void setMinimumReplyDelaySeconds(float minimumReplyDelaySeconds) {
Configs.minimumReplyDelaySeconds = Math.clamp(minimumReplyDelaySeconds, 0.0f, 10.0f);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package net.earthcomputer.clientcommands.command;

import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
RealRTTV marked this conversation as resolved.
Show resolved Hide resolved
import net.earthcomputer.clientcommands.Configs;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.SharedConstants;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

import static dev.xpple.clientarguments.arguments.CMessageArgument.getMessage;
import static dev.xpple.clientarguments.arguments.CMessageArgument.message;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;

public class ReplyCommand {
public static final float MAXIMUM_REPLY_DELAY_SECONDS = 10.0f;

private static final SimpleCommandExceptionType NO_TARGET_FOUND_EXCEPTION = new SimpleCommandExceptionType(Component.translatable("commands.creply.noTargetFound"));
private static final Dynamic2CommandExceptionType MESSAGE_TOO_LONG_EXCEPTION = new Dynamic2CommandExceptionType((a, b) -> Component.translatable("commands.creply.messageTooLong", a, b));

private static final List<ReplyCandidate> replyCandidates = new ArrayList<>();

@Nullable
public static String getCurrentTarget() {
long now = System.currentTimeMillis();

for (int i = 0; i < replyCandidates.size(); i++) {
ReplyCandidate candidate = replyCandidates.get(i);
if ((now - candidate.timestampMs) / 1_000.0f > MAXIMUM_REPLY_DELAY_SECONDS) {
replyCandidates.remove(i--);
}
}

for (int i = replyCandidates.size() - 1; i >= 0; i--) {
ReplyCandidate candidate = replyCandidates.get(i);
if ((now - candidate.timestampMs) / 1_000.0f >= Configs.minimumReplyDelaySeconds) {
return candidate.username;
}
}

return null;
}

public static void addReplyCandidate(String username, long timestamp) {
replyCandidates.add(new ReplyCandidate(username, timestamp));
}

public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
var command = dispatcher.register(literal("creply")
.then(argument("message", message())
.executes(ctx -> reply(ctx.getSource(), getMessage(ctx, "message")))));
dispatcher.register(literal("cr").redirect(command));
}

public static int reply(FabricClientCommandSource source, Component message) throws CommandSyntaxException {
@Nullable String target = ReplyCommand.getCurrentTarget();
if (target == null) {
throw NO_TARGET_FOUND_EXCEPTION.create();
}

String text = message.getString();
String command = String.format("w %s %s", target, text);

if (command.length() > SharedConstants.MAX_CHAT_LENGTH) {
throw MESSAGE_TOO_LONG_EXCEPTION.create(SharedConstants.MAX_CHAT_LENGTH - (command.length() - text.length()), text.length());
}

source.getClient().getConnection().sendCommand(command);

return Command.SINGLE_SUCCESS;
}

private record ReplyCandidate(String username, long timestampMs) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.earthcomputer.clientcommands.mixin.commands.reply;

import net.earthcomputer.clientcommands.command.ReplyCommand;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.multiplayer.PlayerInfo;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket;
import org.jetbrains.annotations.Nullable;
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.UUID;

@Mixin(ClientPacketListener.class)
public abstract class ClientPacketListenerMixin {
@Shadow public abstract @Nullable PlayerInfo getPlayerInfo(UUID uniqueId);

@Inject(method = "handlePlayerChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/PacketUtils;ensureRunningOnSameThread(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketListener;Lnet/minecraft/util/thread/BlockableEventLoop;)V", shift = At.Shift.AFTER))
private void onHandlePlayerChat(ClientboundPlayerChatPacket packet, CallbackInfo ci) {
if (packet.chatType().chatType().is(ChatType.MSG_COMMAND_INCOMING) || packet.chatType().chatType().is(ChatType.MSG_COMMAND_OUTGOING)) {
PlayerInfo info = getPlayerInfo(packet.sender());
if (info != null) {
ReplyCommand.addReplyCandidate(info.getProfile().getName(), System.currentTimeMillis());
}
}
}
}
3 changes: 3 additions & 0 deletions src/main/resources/assets/clientcommands/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@

"commands.crender.entities.success": "Entity rendering rules have been updated",

"commands.creply.noTargetFound": "Could not find a target to reply to",
RealRTTV marked this conversation as resolved.
Show resolved Hide resolved
"commands.creply.messageTooLong": "Your reply was too long (maximum: %d, given: %d)",

"commands.csignsearch.starting": "Searching signs",

"commands.csnap.airborne": "You cannot snap while airborne",
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/mixins.clientcommands.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"commands.alias.ClientSuggestionProviderMixin",
"commands.enchant.MultiPlayerGameModeMixin",
"commands.findblock.ClientLevelMixin",
"commands.reply.ClientPacketListenerMixin",
"commands.generic.CommandSuggestionsMixin",
"commands.glow.LivingEntityRenderStateMixin",
"commands.snap.MinecraftMixin",
Expand Down