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

Truncate tags command clipboard text within 32k string limit #1546

Merged
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 @@ -11,9 +11,9 @@
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import java.util.Iterator;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
Expand Down Expand Up @@ -51,6 +51,10 @@
* </ul>
*/
class TagsCommand {
// The limit of how long the clipboard text can be; no more elements are added to the text if they would push it over this limit
// This is roughly below 32767, the default limit for UTF-8 strings in FriendlyByteBuf. When adjusting this, make sure to leave
// ample room for the explanatory text (see #createMessage() below).
private static final long CLIPBOARD_TEXT_LIMIT = 32600;
private static final long PAGE_SIZE = 8;
private static final ResourceKey<Registry<Registry<?>>> ROOT_REGISTRY_KEY = ResourceKey.createRegistryKey(ResourceLocation.withDefaultNamespace("root"));

Expand Down Expand Up @@ -171,16 +175,45 @@ private static MutableComponent createMessage(final MutableComponent header,
final long currentPage,
final ChatFormatting elementColor,
final Supplier<Stream<String>> names) {
final String allElementNames = names.get().sorted().collect(Collectors.joining("\n"));
final long totalPages = (count - 1) / PAGE_SIZE + 1;
final long actualPage = (long) Mth.clamp(currentPage, 1, totalPages);

MutableComponent containsComponent = Component.translatable(containsText, count);
if (count > 0) // Highlight the count text, make it clickable, and append page counters
{
final String clipboardText;
final StringBuilder clipboardTextBuilder = new StringBuilder();
boolean reachedLimit = false;
int countedLines = 0;

Iterator<String> iterator = names.get().sorted().iterator();
while (iterator.hasNext()) {
final String line = iterator.next();
if (clipboardTextBuilder.length() + line.length() > CLIPBOARD_TEXT_LIMIT) {
// The to-be-added line puts us over the limit, so stop adding lines
reachedLimit = true;
break;
}
clipboardTextBuilder.append(line).append('\n');
countedLines++;
}
// Remove the trailing newline if present
if (!clipboardTextBuilder.isEmpty()) {
clipboardTextBuilder.deleteCharAt(clipboardTextBuilder.length() - 1);
}

if (reachedLimit) {
// Almost went over the limit; add additional info to clipboard text
clipboardText = "(Too many entries to fit in clipboard, showing only first " + countedLines + " entries...)" + '\n'
Technici4n marked this conversation as resolved.
Show resolved Hide resolved
+ clipboardTextBuilder + '\n'
+ "(..." + (count - countedLines) + " more entries not shown)";
} else {
clipboardText = clipboardTextBuilder.toString();
}

containsComponent = ComponentUtils.wrapInSquareBrackets(containsComponent.withStyle(s -> s
.withColor(ChatFormatting.GREEN)
.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, allElementNames))
.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, clipboardText))
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
Component.translatable(copyHoverText)))));
containsComponent = Component.translatable("commands.neoforge.tags.page_info",
Expand Down