11package anticope .rejects .gui .screens ;
22
33import anticope .rejects .utils .GiveUtils ;
4+ import anticope .rejects .utils .NetworkUtils ;
45import com .google .common .reflect .TypeToken ;
6+ import com .google .gson .JsonArray ;
7+ import com .google .gson .JsonElement ;
8+ import com .google .gson .JsonObject ;
9+ import com .mojang .authlib .GameProfile ;
10+ import com .mojang .authlib .properties .Property ;
511import com .mojang .brigadier .exceptions .CommandSyntaxException ;
612import meteordevelopment .meteorclient .gui .GuiTheme ;
713import meteordevelopment .meteorclient .gui .WindowScreen ;
1521import meteordevelopment .meteorclient .utils .network .MeteorExecutor ;
1622import meteordevelopment .meteorclient .utils .player .ChatUtils ;
1723import net .minecraft .component .DataComponentTypes ;
18- import net .minecraft .component .type .NbtComponent ;
24+ import net .minecraft .component .type .ProfileComponent ;
1925import net .minecraft .item .ItemStack ;
2026import net .minecraft .item .Items ;
2127import net .minecraft .nbt .NbtCompound ;
2228import net .minecraft .nbt .NbtList ;
2329import net .minecraft .text .Text ;
24-
2530import java .lang .reflect .Type ;
2631import java .util .ArrayList ;
2732import java .util .List ;
@@ -50,15 +55,19 @@ public enum Categories {
5055 private final SettingGroup sgGeneral = settings .getDefaultGroup ();
5156 private static Categories category = Categories .Decoration ;
5257 private final Setting <Categories > categorySetting = sgGeneral .add (new EnumSetting .Builder <Categories >()
53- .name ("Category" )
54- .defaultValue (category )
55- .description ("Category" )
56- .onChanged ((v ) -> this .loadHeads ())
57- .build ()
58+ .name ("Category" )
59+ .defaultValue (category )
60+ .description ("Category" )
61+ .onChanged ((v ) -> {
62+ category = v ;
63+ this .loadHeads ();
64+ })
65+ .build ()
5866 );
5967
6068 public HeadScreen (GuiTheme theme ) {
6169 super (theme , "Heads" );
70+ set (); // Initialize UI first
6271 loadHeads ();
6372 }
6473
@@ -69,62 +78,103 @@ private void set() {
6978 }
7079
7180 private String getCat () {
72- category = categorySetting .get ();
7381 return category .toString ().replace ("_" , "-" );
7482 }
7583
7684 private void loadHeads () {
85+ ChatUtils .info ("Heads" , "Loading heads from category: " + getCat ());
86+
7787 MeteorExecutor .execute (() -> {
78- List <Map <String , String >> res = Http .get ("https://minecraft-heads.com/scripts/api.php?cat=" +getCat ()).sendJson (gsonType );
79- List <ItemStack > heads = new ArrayList <>();
80- res .forEach (a -> {
81- try {
82- heads .add (createHeadStack (a .get ("uuid" ), a .get ("value" ), a .get ("name" )));
83- } catch (Exception e ) { }
84- });
85-
86- WTable t = theme .table ();
87- for (ItemStack head : heads ) {
88- t .add (theme .item (head ));
89- t .add (theme .label (head .getName ().getString ()));
90- WButton give = t .add (theme .button ("Give" )).widget ();
91- give .action = () -> {
88+ try {
89+ String url = "https://minecraft-heads.com/scripts/api.php?cat=" + getCat ();
90+ List <Map <String , String >> res = Http .get (url ).sendJson (gsonType );
91+
92+ if (res == null || res .isEmpty ()) {
93+ ChatUtils .error ("Heads" , "Failed to load heads or no heads found in category: " + getCat ());
94+ return ;
95+ }
96+
97+ List <ItemStack > heads = new ArrayList <>();
98+ for (Map <String , String > headData : res ) {
9299 try {
93- GiveUtils .giveItem (head );
94- } catch (CommandSyntaxException e ) {
95- ChatUtils .errorPrefix ("Heads" , e .getMessage ());
100+ String uuid = headData .get ("uuid" );
101+ String value = headData .get ("value" );
102+ String name = headData .get ("name" );
103+
104+ if (uuid != null && value != null && name != null ) {
105+ ItemStack head = createHeadStack (uuid , value , name );
106+ if (head != null ) {
107+ heads .add (head );
108+ }
109+ }
110+ } catch (Exception e ) {
111+ ChatUtils .error ("Heads" , "Error processing head: " + e .getMessage ());
112+ }
113+ }
114+
115+ if (heads .isEmpty ()) {
116+ ChatUtils .error ("Heads" , "No valid heads found in category: " + getCat ());
117+ return ;
118+ }
119+
120+ // Update UI on the main thread
121+ mc .execute (() -> {
122+ set ();
123+ WTable t = theme .table ();
124+ for (ItemStack head : heads ) {
125+ t .add (theme .item (head ));
126+ t .add (theme .label (head .getName ().getString ()));
127+ WButton give = t .add (theme .button ("Give" )).widget ();
128+ give .action = () -> {
129+ try {
130+ GiveUtils .giveItem (head );
131+ } catch (CommandSyntaxException e ) {
132+ ChatUtils .errorPrefix ("Heads" , e .getMessage ());
133+ }
134+ };
135+ WButton equip = t .add (theme .button ("Equip" )).widget ();
136+ equip .tooltip = "Equip client-side." ;
137+ equip .action = () -> {
138+ mc .player .getInventory ().setStack (39 , head );
139+ };
140+ t .row ();
96141 }
97- };
98- WButton equip = t .add (theme .button ("Equip" )).widget ();
99- equip .tooltip = "Equip client-side." ;
100- equip .action = () -> {
101- mc .player .getInventory ().armor .set (3 , head );
102- };
103- t .row ();
142+ add (t ).expandX ().minWidth (400 ).widget ();
143+ });
144+ } catch (Exception e ) {
145+ ChatUtils .error ("Heads" , "Failed to load heads: " + e .getMessage ());
146+ e .printStackTrace ();
104147 }
105- set ();
106- add (t ).expandX ().minWidth (400 ).widget ();
107148 });
108149 }
109-
150+ // Using a method for heads from one of my personal mods
110151 private ItemStack createHeadStack (String uuid , String value , String name ) {
111- ItemStack head = Items .PLAYER_HEAD .getDefaultStack ();
112- NbtCompound tag = new NbtCompound ();
113- NbtCompound skullOwner = new NbtCompound ();
114- skullOwner .putUuid ("Id" , UUID .fromString (uuid ));
115- NbtCompound properties = new NbtCompound ();
116- NbtList textures = new NbtList ();
117- NbtCompound Value = new NbtCompound ();
118- Value .putString ("Value" , value );
119- textures .add (Value );
120- properties .put ("textures" , textures );
121- skullOwner .put ("Properties" , properties );
122- tag .put ("SkullOwner" , skullOwner );
123- head .set (DataComponentTypes .CUSTOM_DATA , NbtComponent .of (tag ));
124- head .set (DataComponentTypes .CUSTOM_NAME , Text .literal (name ));
125- return head ;
152+ try {
153+ ItemStack head = Items .PLAYER_HEAD .getDefaultStack ();
154+
155+ // Format UUID properly if needed
156+ String formattedUuid = uuid ;
157+ if (!uuid .contains ("-" )) {
158+ formattedUuid = uuid .replaceAll ("(\\ w{8})(\\ w{4})(\\ w{4})(\\ w{4})(\\ w{12})" , "$1-$2-$3-$4-$5" );
159+ }
160+
161+ // Create game profile directly
162+ GameProfile gameProfile = new GameProfile (UUID .fromString (formattedUuid ), name );
163+ gameProfile .getProperties ().put ("textures" , new Property ("textures" , value ));
164+
165+ // Set profile component
166+ head .set (DataComponentTypes .PROFILE , new ProfileComponent (gameProfile ));
167+ head .set (DataComponentTypes .CUSTOM_NAME , Text .literal (name ));
168+
169+ return head ;
170+ } catch (Exception e ) {
171+ ChatUtils .error ("Heads" , "Error creating head: " + e .getMessage ());
172+ return null ;
173+ }
126174 }
127175
128176 @ Override
129- public void initWidgets () {}
177+ public void initWidgets () {
178+ // This method should be implemented if WindowScreen requires it
179+ }
130180}
0 commit comments