2020import java .util .Random ;
2121import java .util .Set ;
2222
23+ import net .minecraft .core .BlockPos ;
24+ import net .minecraft .core .Direction ;
2325import net .minecraft .core .component .DataComponents ;
2426import net .minecraft .network .chat .Component ;
2527import net .minecraft .server .network .Filterable ;
2628import net .minecraft .world .item .component .WrittenBookContent ;
2729import net .minecraft .network .protocol .game .ServerboundEditBookPacket ;
30+ import net .minecraft .network .protocol .game .ServerboundPlayerActionPacket ;
2831import net .minecraft .world .item .ItemStack ;
2932import net .minecraft .world .item .Items ;
3033import net .wurstclient .Category ;
@@ -78,6 +81,16 @@ private enum RandomType
7881 private final CheckboxSetting sign =
7982 new CheckboxSetting ("Sign" , "Whether to sign the book." , true );
8083
84+ private final CheckboxSetting dropAfterWrite =
85+ new CheckboxSetting ("Drop after write" ,
86+ "Drops each finished book on the ground right after it's written." ,
87+ false );
88+
89+ private final CheckboxSetting autoCraft = new CheckboxSetting ("Auto-craft" ,
90+ "When you run out of book & quills, craft one from a book, a feather"
91+ + " and an ink sac in your inventory." ,
92+ false );
93+
8194 private final TextFieldSetting name = new TextFieldSetting ("Name" ,
8295 "The name you want to give your books." , "I Love Cevapi!" );
8396
@@ -119,6 +132,8 @@ public BookBotHack()
119132 addSetting (randomType );
120133 addSetting (delay );
121134 addSetting (sign );
135+ addSetting (dropAfterWrite );
136+ addSetting (autoCraft );
122137 addSetting (name );
123138 addSetting (appendCount );
124139 addSetting (wordWrap );
@@ -168,6 +183,9 @@ public void onUpdate()
168183 int slot = findWritableBookSlot ();
169184 if (slot == -1 )
170185 {
186+ if (autoCraft .isChecked () && tryCraftBookAndQuill ())
187+ return ;
188+
171189 setEnabled (false );
172190 return ;
173191 }
@@ -287,6 +305,54 @@ private void swapWithMainHand(int slot)
287305 inventoryCooldown = 2 ;
288306 }
289307
308+ private boolean tryCraftBookAndQuill ()
309+ {
310+ if (MC .player == null )
311+ return false ;
312+
313+ if (MC .player .containerMenu != MC .player .inventoryMenu )
314+ return false ;
315+
316+ if (!MC .player .inventoryMenu .getCarried ().isEmpty ())
317+ return false ;
318+
319+ var im = IMC .getInteractionManager ();
320+
321+ for (int gridSlot = 1 ; gridSlot <= 4 ; gridSlot ++)
322+ if (!MC .player .inventoryMenu .getSlot (gridSlot ).getItem ().isEmpty ())
323+ im .windowClick_QUICK_MOVE (gridSlot );
324+
325+ int bookSlot = InventoryUtils .indexOf (Items .BOOK , 36 );
326+ int featherSlot = InventoryUtils .indexOf (Items .FEATHER , 36 );
327+ int inkSlot = InventoryUtils .indexOf (Items .INK_SAC , 36 );
328+ if (bookSlot == -1 || featherSlot == -1 || inkSlot == -1 )
329+ return false ;
330+
331+ placeStackInGrid (im , bookSlot , 1 );
332+ placeStackInGrid (im , featherSlot , 2 );
333+ placeStackInGrid (im , inkSlot , 3 );
334+
335+ im .windowClick_PICKUP (0 );
336+
337+ int freeSlot = MC .player .getInventory ().getFreeSlot ();
338+ if (freeSlot != -1 )
339+ im .windowClick_PICKUP (InventoryUtils .toNetworkSlot (freeSlot ));
340+
341+ for (int gridSlot = 1 ; gridSlot <= 3 ; gridSlot ++)
342+ im .windowClick_QUICK_MOVE (gridSlot );
343+
344+ inventoryCooldown = 2 ;
345+ return true ;
346+ }
347+
348+ private void placeStackInGrid (
349+ net .wurstclient .mixinterface .IMultiPlayerGameMode im , int inventorySlot ,
350+ int gridSlot )
351+ {
352+ im .windowClick_PICKUP (InventoryUtils .toNetworkSlot (inventorySlot ));
353+ im .windowClick_PICKUP (gridSlot );
354+ }
355+
290356 private List <String > randomPages (PrimitiveIterator .OfInt chars )
291357 {
292358 ArrayList <String > outPages = new ArrayList <>();
@@ -422,7 +488,11 @@ private void writeBook(List<String> pages)
422488 MC .player .getInventory ().getSelectedSlot (), pages ,
423489 sign .isChecked () ? Optional .of (title ) : Optional .empty ()));
424490
425- if (!sign .isChecked ())
491+ if (dropAfterWrite .isChecked ())
492+ {
493+ dropMainHand ();
494+
495+ }else if (!sign .isChecked ())
426496 {
427497 int selectedSlot = MC .player .getInventory ().getSelectedSlot ();
428498 unsignedWrittenSlots .add (selectedSlot );
@@ -439,6 +509,23 @@ private void writeBook(List<String> pages)
439509 bookCount ++;
440510 }
441511
512+ private void dropMainHand ()
513+ {
514+ if (MC .getConnection () == null )
515+ return ;
516+
517+ int selectedSlot = MC .player .getInventory ().getSelectedSlot ();
518+
519+ MC .getConnection ()
520+ .send (new ServerboundPlayerActionPacket (
521+ ServerboundPlayerActionPacket .Action .DROP_ALL_ITEMS ,
522+ BlockPos .ZERO , Direction .DOWN ));
523+
524+ MC .player .getInventory ().setItem (selectedSlot , ItemStack .EMPTY );
525+ unsignedWrittenSlots .remove (selectedSlot );
526+ inventoryCooldown = 2 ;
527+ }
528+
442529 private void logBookPayloadEstimate (List <String > pages , String title )
443530 {
444531 long totalJavaChars = 0 ;
0 commit comments