Skip to content

Commit cd670a9

Browse files
authored
Bookbot improvements (#6320)
- Add new settings, allowing much larger books to be written - Dedicated PaperMC mode
1 parent bc0355c commit cd670a9

1 file changed

Lines changed: 75 additions & 62 deletions

File tree

  • src/main/java/meteordevelopment/meteorclient/systems/modules/misc

src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BookBot.java

Lines changed: 75 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@
1212
import meteordevelopment.meteorclient.gui.widgets.WWidget;
1313
import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList;
1414
import meteordevelopment.meteorclient.gui.widgets.pressable.WButton;
15-
import meteordevelopment.meteorclient.mixin.TextHandlerAccessor;
1615
import meteordevelopment.meteorclient.settings.*;
1716
import meteordevelopment.meteorclient.systems.modules.Categories;
1817
import meteordevelopment.meteorclient.systems.modules.Module;
1918
import meteordevelopment.meteorclient.utils.player.FindItemResult;
2019
import meteordevelopment.meteorclient.utils.player.InvUtils;
2120
import meteordevelopment.orbit.EventHandler;
22-
import net.minecraft.client.font.TextHandler;
2321
import net.minecraft.component.DataComponentTypes;
2422
import net.minecraft.component.type.WritableBookContentComponent;
2523
import net.minecraft.component.type.WrittenBookContentComponent;
@@ -56,21 +54,31 @@ public class BookBot extends Module {
5654
.build()
5755
);
5856

57+
private final Setting<RandomType> randomType = sgGeneral.add(new EnumSetting.Builder<RandomType>()
58+
.name("random-type")
59+
.description("What kind of random to use.")
60+
.defaultValue(RandomType.Utf8)
61+
.visible(() -> mode.get() == Mode.Random)
62+
.build()
63+
);
64+
5965
private final Setting<Integer> pages = sgGeneral.add(new IntSetting.Builder()
6066
.name("pages")
6167
.description("The number of pages to write per book.")
6268
.defaultValue(50)
6369
.range(1, 100)
6470
.sliderRange(1, 100)
65-
.visible(() -> mode.get() != Mode.File)
71+
.visible(() -> mode.get() != Mode.File && randomType.get() != RandomType.PaperMC)
6672
.build()
6773
);
6874

69-
private final Setting<Boolean> onlyAscii = sgGeneral.add(new BoolSetting.Builder()
70-
.name("ascii-only")
71-
.description("Only uses the characters in the ASCII charset.")
72-
.defaultValue(false)
73-
.visible(() -> mode.get() == Mode.Random)
75+
private final Setting<Integer> characters = sgGeneral.add(new IntSetting.Builder()
76+
.name("characters")
77+
.description("How many characters to write per page.")
78+
.defaultValue(128)
79+
.range(1, 1024)
80+
.sliderRange(1, 1024)
81+
.visible(() -> mode.get() == Mode.Random && randomType.get() != RandomType.PaperMC)
7482
.build()
7583
);
7684

@@ -207,15 +215,11 @@ private void onTick(TickEvent.Post event) {
207215
// Write book
208216

209217
if (mode.get() == Mode.Random) {
210-
int origin = onlyAscii.get() ? 0x21 : 0x0800;
211-
int bound = onlyAscii.get() ? 0x7E : 0x10FFFF;
212-
213-
writeBook(
214-
// Generate a random load of ints to use as random characters
215-
random.ints(origin, bound)
216-
.filter(i -> !Character.isWhitespace(i) && i != '\r' && i != '\n')
217-
.iterator()
218-
);
218+
switch (randomType.get()) {
219+
case Ascii -> writeBook(random.ints(0x21, 0x80).filter(i -> !Character.isWhitespace(i) && i != '\r' && i != '\n').iterator());
220+
case Utf8 -> writeBook(random.ints(0x21, 0xD800).filter(i -> !Character.isWhitespace(i) && i != '\r' && i != '\n').iterator());
221+
case PaperMC -> writePaperMcBook();
222+
}
219223
} else if (mode.get() == Mode.File) {
220224
// Ignore if somehow the file got deleted
221225
if ((file == null || !file.exists()) && mode.get() == Mode.File) {
@@ -273,61 +277,64 @@ private void writeBook(PrimitiveIterator.OfInt chars) {
273277
List<StringVisitable> wrappedLines = mc.textRenderer.wrapLinesWithoutLanguage(Text.literal(text.toString()), 114);
274278
processLinesToPages(wrappedLines, pages, filteredPages, maxPages);
275279
} else {
276-
// Non-word-wrapping logic
277-
TextHandler.WidthRetriever widthRetriever = ((TextHandlerAccessor) mc.textRenderer.getTextHandler()).meteor$getWidthRetriever();
278280
int pageIndex = 0;
279-
int lineIndex = 0;
280281
final StringBuilder page = new StringBuilder();
281-
float lineWidth = 0;
282282

283-
while (chars.hasNext()) {
284-
int c = chars.nextInt();
285-
286-
if (c == '\r' || c == '\n') {
287-
page.append('\n');
288-
lineWidth = 0;
289-
lineIndex++;
290-
} else {
291-
float charWidth = widthRetriever.getWidth(c, Style.EMPTY);
292-
293-
// Reached end of line
294-
if (lineWidth + charWidth > 114f) {
295-
page.append('\n');
296-
lineWidth = charWidth;
297-
lineIndex++;
298-
// Wrap to next line, unless wrapping to next page
299-
if (lineIndex != 14) page.appendCodePoint(c);
300-
} else if (lineWidth == 0f && c == ' ') {
301-
continue; // Prevent leading space from text wrapping
302-
} else {
303-
lineWidth += charWidth;
304-
page.appendCodePoint(c);
305-
}
283+
while (pageIndex != maxPages) {
284+
for (int i = 0; i < characters.get() && chars.hasNext(); i++) {
285+
page.appendCodePoint(chars.nextInt());
306286
}
307287

308-
// Reached end of page
309-
if (lineIndex == 14) {
310-
filteredPages.add(RawFilteredPair.of(Text.of(page.toString())));
311-
pages.add(page.toString());
288+
if (!page.isEmpty()) {
289+
String builtPage = page.toString();
290+
filteredPages.add(RawFilteredPair.of(Text.of(builtPage)));
291+
pages.add(builtPage);
312292
page.setLength(0);
313-
pageIndex++;
314-
lineIndex = 0;
293+
}
315294

316-
// No more pages
317-
if (pageIndex == maxPages) break;
295+
pageIndex++;
296+
}
297+
}
318298

319-
// Wrap to next page
320-
if (c != '\r' && c != '\n') {
321-
page.appendCodePoint(c);
322-
}
299+
createBook(pages, filteredPages);
300+
}
301+
302+
/**
303+
* @author S
304+
*/
305+
private void writePaperMcBook() {
306+
ArrayList<String> pages = new ArrayList<>();
307+
ArrayList<RawFilteredPair<Text>> filteredPages = new ArrayList<>();
308+
final StringBuilder page = new StringBuilder();
309+
310+
PrimitiveIterator.OfInt oneByte = random.ints(0x21, 0x80).iterator();
311+
PrimitiveIterator.OfInt twoBytes = random.ints(0x0080, 0x0800).iterator();
312+
PrimitiveIterator.OfInt threeBytes = random.ints(0x0800, 0xD800).iterator();
313+
314+
for (int pageIndex = 0; pageIndex < 100; pageIndex++) {
315+
if (pageIndex < 50) {
316+
page.appendCodePoint(threeBytes.nextInt());
317+
for (int i = 1; i < 1024; i++) {
318+
page.appendCodePoint(oneByte.nextInt());
319+
}
320+
} else if (pageIndex == 50) {
321+
for (int i = 0; i < 110; i++) {
322+
page.appendCodePoint(threeBytes.nextInt());
323+
}
324+
page.appendCodePoint(twoBytes.nextInt());
325+
for (int i = 0; i < 913; i++) {
326+
page.appendCodePoint(oneByte.nextInt());
327+
}
328+
} else {
329+
for (int i = 0; i < 1024; i++) {
330+
page.appendCodePoint(threeBytes.nextInt());
323331
}
324332
}
325333

326-
// No more characters, end current page
327-
if (!page.isEmpty() && pageIndex != maxPages) {
328-
filteredPages.add(RawFilteredPair.of(Text.of(page.toString())));
329-
pages.add(page.toString());
330-
}
334+
String builtPage = page.toString();
335+
filteredPages.add(RawFilteredPair.of(Text.of(builtPage)));
336+
pages.add(builtPage);
337+
page.setLength(0);
331338
}
332339

333340
createBook(pages, filteredPages);
@@ -341,7 +348,7 @@ private void processLinesToPages(List<StringVisitable> lines, ArrayList<String>
341348
for (StringVisitable line : lines) {
342349
String lineText = line.getString();
343350

344-
if (currentPage.length() > 0) {
351+
if (!currentPage.isEmpty()) {
345352
currentPage.append('\n');
346353
}
347354
currentPage.append(lineText);
@@ -402,4 +409,10 @@ public enum Mode {
402409
File,
403410
Random
404411
}
412+
413+
public enum RandomType {
414+
Ascii,
415+
Utf8,
416+
PaperMC
417+
}
405418
}

0 commit comments

Comments
 (0)