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

Allow URL argument in setSkullTexture() #213

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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 @@ -24,6 +24,8 @@
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Collection;
import java.util.UUID;
import java.util.function.Function;
Expand Down Expand Up @@ -118,17 +120,32 @@ public static String getTexture(@NonNull ItemStack itemStack) {
* Set the Base64 texture of the given skull ItemStack.
*
* @param itemStack The ItemStack.
* @param texture The new skull texture (Base64).
* @param texture The new skull texture (Base64 or URL).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really "or URL". It can either be a very specific URL: http://textures.minecraft.net/texture/ or a hexidecimal id? of a texture on the same site. Just mentioning URL can be misleading here.

*/
public static void setSkullTexture(@NonNull ItemStack itemStack, @NonNull String texture) {
try {
ItemMeta meta = itemStack.getItemMeta();
if (meta instanceof SkullMeta) {
GameProfile profile = new GameProfile(UUID.randomUUID(), "");
Property property = new Property("textures", texture);

PropertyMap properties = profile.getProperties();
properties.put("textures", property);
String json;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment below; you can also move this in the try block.


try{
json = Base64.getDecoder().decode(texture);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if I'm doing something wrong, but doesn't decode return a byte[] here?

}
catch(IllegalArgumentException ex){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, adhere to some unified code style. The formatting of this code is completely different from the rest of the project. This applies to all new code.

json = "invalid";
}
if(!json.contains("\"url\":\"http://textures.minecraft.net/texture/")){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this if inside the try block above. There is no need to put it outside, it just makes it more complicated. If you put it in the try block, you can avoid re-assigning the json variable to "invalid".

// Decoded json does not contain a valid skin URL, so check if the 'texture' argument is a valid URL.
if(texture.startsWith("http://textures.minecraft.net/texture/")); // We are all set.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check should be done before trying to decode texture as json. You actually don't really need to decode it at all. Just check if texture is a URL, and if it is, do whatever you do here. Otherwise just skip this and don't do anything.

// Check if the texture is a hexidecimal (like the skinfiles on Minecraft's servers)
else if(texture.matches("^[0-9a-fA-F]+$")) texture = "http://textures.minecraft.net/texture/"+texture;
else; // TODO: Texture invalid, print a warning or something?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't log anything. The method is called frequently and we don't want it to spam the console.

json = "{\"textures\":{\"SKIN\":{\"url\":\""+texture+"\"}}}"; // (Stable for all MC versions with custom skins.)
texture = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.ISO_8859_1));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After you move the if block into the try block, the entirety of this "texture-modification" logic should be moved into a private method. By moving it out, we simplify this method and make everything easier to read. The private method could be, for example:

private String normalizeTextureURL(String texture) {
    // ...
}

profile.getProperties().put("textures", new Property("textures", texture));

if (SET_PROFILE_METHOD == null && !INITIALIZED) {
try {
Expand Down