Skip to content

Instantly share code, notes, and snippets.

@mchorse
Last active September 2, 2018 18:38
Show Gist options
  • Save mchorse/6b814779f113aba0febf5451cdbbb987 to your computer and use it in GitHub Desktop.
Save mchorse/6b814779f113aba0febf5451cdbbb987 to your computer and use it in GitHub Desktop.
Skin fix code (fixing Steves) for Minecraft 1.7.10 and below (requires MCP)
classpackage net.minecraft.src;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* Skin mapper class
*
* This class is responsible for mapping Minecraft username to a
* skin URL. Basically this class can be used to fix Minecraft 1.7.10
* and below issue with players all turning into Steves.
*
* This class uses Mojang and Crafatar's APIs in order to make skins
* ~~great~~ work again. Mojang's API is used for obtaining UUID from
* username, and Crafatar is used to link the actual skin. Why it's
* using Crafatar? Because Crafatar stores skins in Steve format thus
* the code to convert from 64x64 to 64x32 isn't needed.
*
* Feel free to use it anyway you want to.
*
* @author McHorse
* @license MIT
*/
class SkinMapper
{
/**
* Cache which maps player usernames to UUIDs
*/
public final static Map<String, String> USERNAME_TO_UUID = new HashMap<String, String>();
/**
* Get skin URL for given username
*/
public static String getURL(String username)
{
String str = getUUID(username);
if (str != null)
{
str = "https://crafatar.com/skins/" + StringUtils.stripControlCodes(str);
}
return str;
}
/**
* Get UUID from username. This method makes a request to Mojang API
*/
public static String getUUID(String username)
{
String str = USERNAME_TO_UUID.get(username);
if (str == null)
{
str = getPlayerUUID(username);
USERNAME_TO_UUID.put(username, str);
}
return str;
}
private static String getPlayerUUID(String username)
{
String json = request(username);
if (json != null)
{
String uuid = json.substring("{\"id\":\"".length());
int index = uuid.indexOf("\"");
if (index != -1)
{
uuid = uuid.substring(0, index);
if (uuid.length() == 32)
{
return uuid;
}
}
}
return null;
}
/**
* Request
*/
private static String request(String username)
{
HttpURLConnection connection = null;
try
{
URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoOutput(true);
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
StringBuilder response = new StringBuilder();
String line;
while ((line = rd.readLine()) != null)
{
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
finally
{
if (connection != null)
{
connection.disconnect();
}
}
}
}
/**
* And in order to actually fix the issue with skins, you need to
* replace the line into EntityPlayerSP's and EntityPlayerOtherMP's
* which starts with this.skinUrl = ... with:
*
* this.skinUrl = SkinMapper.getURL(par3Session.username);
*
* par3Session.username may vary depending on the class. It's either
* that or par2Str (in EntityPlayerOtherMP).
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment