Skip to content

Commit 07ef82b

Browse files
authored
Fixes to player head loading and the friends system/tab (#6237)
1 parent 73496d7 commit 07ef82b

File tree

11 files changed

+112
-74
lines changed

11 files changed

+112
-74
lines changed

src/main/java/meteordevelopment/meteorclient/gui/screens/accounts/AccountsScreen.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList;
1313
import meteordevelopment.meteorclient.gui.widgets.pressable.WButton;
1414
import meteordevelopment.meteorclient.systems.accounts.Account;
15+
import meteordevelopment.meteorclient.systems.accounts.AccountType;
1516
import meteordevelopment.meteorclient.systems.accounts.Accounts;
1617
import meteordevelopment.meteorclient.utils.misc.NbtUtils;
1718
import meteordevelopment.meteorclient.utils.network.MeteorExecutor;
@@ -50,23 +51,28 @@ public static void addAccount(@Nullable AddAccountScreen screen, AccountsScreen
5051
if (screen != null) screen.locked = true;
5152

5253
MeteorExecutor.execute(() -> {
53-
if (account.fetchInfo()) {
54-
account.getCache().loadHead();
54+
if (!account.fetchInfo()) {
55+
mc.execute(() -> {
56+
if (screen != null) screen.locked = false;
57+
});
58+
return;
59+
}
5560

56-
Accounts.get().add(account);
57-
if (account.login()) Accounts.get().save();
61+
Accounts.get().add(account);
62+
63+
if (account.login()) {
64+
if (account.getType() != AccountType.Cracked) account.getCache().loadHead(parent::reload);
65+
Accounts.get().save();
66+
}
5867

68+
mc.execute(() -> {
5969
if (screen != null) {
6070
screen.locked = false;
6171
screen.close();
6272
}
6373

6474
parent.reload();
65-
66-
return;
67-
}
68-
69-
if (screen != null) screen.locked = false;
75+
});
7076
});
7177
}
7278

src/main/java/meteordevelopment/meteorclient/gui/screens/accounts/AddCrackedAccountScreen.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,21 @@ public void initWidgets() {
2323
// Name
2424
t.add(theme.label("Name: "));
2525
WTextBox name = t.add(theme.textBox("", "seasnail8169", (text, c) ->
26-
// Username can't contain spaces
27-
c != ' '
26+
/** @see net.minecraft.util.StringHelper#isValidPlayerName */
27+
c > 32 && c < 127
2828
)).minWidth(400).expandX().widget();
2929
name.setFocused(true);
3030
t.row();
3131

3232
// Add
3333
add = t.add(theme.button("Add")).expandX().widget();
3434
add.action = () -> {
35-
if (!name.get().isEmpty() && name.get().length() < 17) {
36-
CrackedAccount account = new CrackedAccount(name.get());
37-
if (!(Accounts.get().exists(account))) {
38-
AccountsScreen.addAccount(this, parent, account);
39-
}
35+
String username = name.get().trim();
36+
if (username.length() > 16) return;
37+
38+
CrackedAccount account = new CrackedAccount(username);
39+
if (!(Accounts.get().exists(account))) {
40+
AccountsScreen.addAccount(this, parent, account);
4041
}
4142
};
4243

src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,15 @@ public void initWidgets() {
6262

6363
if (Friends.get().add(friend)) {
6464
nameW.set("");
65-
reload();
65+
initTable(table);
66+
nameW.setFocused(true);
6667

6768
MeteorExecutor.execute(() -> {
6869
friend.updateInfo();
69-
mc.execute(this::reload);
70+
mc.execute(() -> {
71+
initTable(table);
72+
nameW.setFocused(true);
73+
});
7074
});
7175
}
7276
};
@@ -93,7 +97,7 @@ private void initTable(WTable table) {
9397
WMinus remove = table.add(theme.minus()).expandCellX().right().widget();
9498
remove.action = () -> {
9599
Friends.get().remove(friend);
96-
reload();
100+
initTable(table);
97101
};
98102

99103
table.row();

src/main/java/meteordevelopment/meteorclient/systems/accounts/AccountCache.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package meteordevelopment.meteorclient.systems.accounts;
77

88
import com.mojang.util.UndashedUuid;
9+
import meteordevelopment.meteorclient.utils.network.MeteorExecutor;
910
import meteordevelopment.meteorclient.utils.misc.ISerializable;
1011
import meteordevelopment.meteorclient.utils.misc.NbtException;
1112
import meteordevelopment.meteorclient.utils.render.PlayerHeadTexture;
@@ -18,14 +19,35 @@ public class AccountCache implements ISerializable<AccountCache> {
1819
public String username = "";
1920
public String uuid = "";
2021
private PlayerHeadTexture headTexture;
22+
private volatile boolean loadingHead;
2123

2224
public PlayerHeadTexture getHeadTexture() {
2325
return headTexture != null ? headTexture : PlayerHeadUtils.STEVE_HEAD;
2426
}
2527

2628
public void loadHead() {
27-
if (uuid == null || uuid.isBlank()) return;
28-
mc.execute(() -> headTexture = PlayerHeadUtils.fetchHead(UndashedUuid.fromStringLenient(uuid)));
29+
loadHead(null);
30+
}
31+
32+
public void loadHead(Runnable callback) {
33+
if (headTexture != null || uuid == null || uuid.isBlank()) {
34+
if (callback != null) mc.execute(callback);
35+
return;
36+
}
37+
38+
if (loadingHead) return;
39+
40+
loadingHead = true;
41+
42+
MeteorExecutor.execute(() -> {
43+
byte[] head = PlayerHeadUtils.fetchHead(UndashedUuid.fromStringLenient(uuid));
44+
45+
mc.execute(() -> {
46+
if (head != null) headTexture = new PlayerHeadTexture(head, true);
47+
loadingHead = false;
48+
if (callback != null) callback.run();
49+
});
50+
});
2951
}
3052

3153
@Override

src/main/java/meteordevelopment/meteorclient/systems/accounts/types/CrackedAccount.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ public boolean fetchInfo() {
2727
public boolean login() {
2828
super.login();
2929

30-
cache.loadHead();
3130
setSession(new Session(name, Uuids.getOfflinePlayerUuid(name), "", Optional.empty(), Optional.empty()));
3231
return true;
3332
}

src/main/java/meteordevelopment/meteorclient/systems/accounts/types/MicrosoftAccount.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ public boolean login() {
3131
if (token == null) return false;
3232

3333
super.login();
34-
cache.loadHead();
3534

3635
setSession(new Session(cache.username, UndashedUuid.fromStringLenient(cache.uuid), token, Optional.empty(), Optional.empty()));
3736
return true;

src/main/java/meteordevelopment/meteorclient/systems/accounts/types/SessionAccount.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public boolean login() {
6666
if (accessToken == null || accessToken.isBlank()) return false;
6767

6868
super.login();
69-
cache.loadHead();
7069

7170
setSession(new Session(cache.username, UndashedUuid.fromStringLenient(cache.uuid), accessToken, Optional.empty(), Optional.empty()));
7271
return true;

src/main/java/meteordevelopment/meteorclient/systems/friends/Friend.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ public void updateInfo() {
7070
if (res != null && res.statusCode() == 200) {
7171
name = res.body().name;
7272
id = UndashedUuid.fromStringLenient(res.body().id);
73-
mc.execute(() -> headTexture = PlayerHeadUtils.fetchHead(id));
73+
74+
byte[] head = PlayerHeadUtils.fetchHead(id);
75+
mc.execute(() -> {
76+
if (head != null) headTexture = new PlayerHeadTexture(head, true);
77+
});
7478
}
7579

7680
// cracked accounts shouldn't be assigned ids

src/main/java/meteordevelopment/meteorclient/systems/friends/Friends.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,12 @@ public static Friends get() {
3434

3535
public boolean add(Friend friend) {
3636
if (friend.name.isEmpty() || friend.name.contains(" ")) return false;
37+
if (get(friend.name) != null) return false;
3738

38-
if (!friends.contains(friend)) {
39-
friends.add(friend);
40-
save();
41-
42-
return true;
43-
}
39+
friends.add(friend);
40+
save();
4441

45-
return false;
42+
return true;
4643
}
4744

4845
public boolean remove(Friend friend) {

src/main/java/meteordevelopment/meteorclient/utils/render/PlayerHeadTexture.java

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,48 @@
2323
public class PlayerHeadTexture extends Texture {
2424
private boolean needsRotate;
2525

26-
public PlayerHeadTexture(String url) {
26+
public PlayerHeadTexture(byte[] head, boolean needsRotate) {
2727
super(8, 8, TextureFormat.RGBA8, FilterMode.NEAREST, FilterMode.NEAREST);
2828

29-
BufferedImage skin;
30-
try {
31-
skin = ImageIO.read(Http.get(url).sendInputStream());
32-
} catch (IOException e) {
29+
upload(BufferUtils.createByteBuffer(head.length).put(head));
30+
this.needsRotate = needsRotate;
31+
}
32+
33+
public PlayerHeadTexture() {
34+
super(8, 8, TextureFormat.RGBA8, FilterMode.NEAREST, FilterMode.NEAREST);
35+
36+
try (InputStream inputStream = mc.getResourceManager().getResource(MeteorClient.identifier("textures/steve.png")).get().getInputStream()) {
37+
ByteBuffer data = TextureUtil.readResource(inputStream);
38+
data.rewind();
39+
40+
try (MemoryStack stack = MemoryStack.stackPush()) {
41+
IntBuffer width = stack.mallocInt(1);
42+
IntBuffer height = stack.mallocInt(1);
43+
IntBuffer comp = stack.mallocInt(1);
44+
45+
ByteBuffer image = STBImage.stbi_load_from_memory(data, width, height, comp, 4);
46+
upload(image);
47+
STBImage.stbi_image_free(image);
48+
}
49+
MemoryUtil.memFree(data);
50+
}
51+
catch (IOException e) {
3352
e.printStackTrace();
34-
return;
53+
}
54+
}
55+
56+
public boolean needsRotate() {
57+
return needsRotate;
58+
}
59+
60+
public static byte[] downloadHead(String url) throws IOException {
61+
BufferedImage skin;
62+
try (InputStream in = Http.get(url).sendInputStream()) {
63+
skin = ImageIO.read(in);
3564
}
3665

66+
if (skin == null) throw new IOException("Failed to decode skin image.");
67+
3768
byte[] head = new byte[8 * 8 * 4];
3869
int[] pixel = new int[4];
3970

@@ -43,8 +74,7 @@ public PlayerHeadTexture(String url) {
4374
skin.getData().getPixel(x, y, pixel);
4475

4576
for (int j = 0; j < 4; j++) {
46-
head[i] = (byte) pixel[j];
47-
i++;
77+
head[i++] = (byte) pixel[j];
4878
}
4979
}
5080
}
@@ -56,43 +86,13 @@ public PlayerHeadTexture(String url) {
5686

5787
if (pixel[3] != 0) {
5888
for (int j = 0; j < 4; j++) {
59-
head[i] = (byte) pixel[j];
60-
i++;
89+
head[i++] = (byte) pixel[j];
6190
}
6291
}
6392
else i += 4;
6493
}
6594
}
6695

67-
upload(BufferUtils.createByteBuffer(head.length).put(head));
68-
69-
needsRotate = true;
70-
}
71-
72-
public PlayerHeadTexture() {
73-
super(8, 8, TextureFormat.RGBA8, FilterMode.NEAREST, FilterMode.NEAREST);
74-
75-
try (InputStream inputStream = mc.getResourceManager().getResource(MeteorClient.identifier("textures/steve.png")).get().getInputStream()) {
76-
ByteBuffer data = TextureUtil.readResource(inputStream);
77-
data.rewind();
78-
79-
try (MemoryStack stack = MemoryStack.stackPush()) {
80-
IntBuffer width = stack.mallocInt(1);
81-
IntBuffer height = stack.mallocInt(1);
82-
IntBuffer comp = stack.mallocInt(1);
83-
84-
ByteBuffer image = STBImage.stbi_load_from_memory(data, width, height, comp, 4);
85-
upload(image);
86-
STBImage.stbi_image_free(image);
87-
}
88-
MemoryUtil.memFree(data);
89-
}
90-
catch (IOException e) {
91-
e.printStackTrace();
92-
}
93-
}
94-
95-
public boolean needsRotate() {
96-
return needsRotate;
96+
return head;
9797
}
9898
}

0 commit comments

Comments
 (0)