package info.mineshafter.intercept;
import info.mineshafter.datasources.MineshafterProfileAuthority;
import info.mineshafter.models.Profile;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import biz.source_code.base64Coder.Base64Coder;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
public class ProfileHandler implements Handler {
private static String SEARCH_HOST = "api.mojang.com";
private static String GET_HOST = "sessionserver.mojang.com";
private static Pattern SEARCH_PATH = Pattern.compile("/profiles/page/(.+?)");
private static Pattern GET_PATH = Pattern.compile("/session/minecraft/profile/([0-9a-fA-F]+?)");
private static Pattern BLOCKED_PATH = Pattern.compile("/blockedservers");
private static MineshafterProfileAuthority profiles = MineshafterProfileAuthority.getInstance();
private static ProfileHandler instance;
private ProfileHandler() {}
public static synchronized ProfileHandler getInstance() {
if (instance == null) {
instance = new ProfileHandler();
}
return instance;
}
public boolean canHandle(URL url) {
return (url.getHost().equalsIgnoreCase(SEARCH_HOST) || url.getHost().equalsIgnoreCase(GET_HOST));
}
public Response handle(Request req) {
String r = "";
if (req.getHost().equalsIgnoreCase(GET_HOST)) {
Matcher m = GET_PATH.matcher(req.getPath());
// TODO: Console output
if (m.matches()) {
String uuid = m.group(1);
r = getProfile(uuid);
} else {
m = BLOCKED_PATH.matcher(req.getPath());
if (m.matches()) {
Response res = new Response(new byte[] {});
res.setHeader("content-type", "text/plain; charset=UTF-8");
res.setHeader("content-length", "0");
return res;
}
}
} else if (req.getHost().equalsIgnoreCase(SEARCH_HOST)) {
String body = new String(req.body);
Matcher m = SEARCH_PATH.matcher(req.getPath());
if (m.matches()) {
int page = Integer.parseInt(m.group(1));
r = searchProfile(page, body);
}
}
Response res = new Response(r.getBytes());
res.setHeader("content-type", "application/json");
res.setHeader("content-length", Integer.toString(res.body.length));
return res;
}
private String getProfile(String id) {
System.out.println("ProfileHandler.getProfile " + id);
Profile p = profiles.getProfile(id);
JsonObject textures = new JsonObject();
if (p.getSkin() != null) {
textures.set("SKIN", new JsonObject().add("url", p.getSkin()));
}
if (p.getCape() != null) {
textures.set("CAPE", new JsonObject().add("url", p.getCape()));
}
JsonObject textureProperty = new JsonObject();
textureProperty.set("timestamp", System.currentTimeMillis());
textureProperty.set("profileId", p.getId());
textureProperty.set("profileName", p.getName());
textureProperty.set("isPublic", true);
textureProperty.set("textures", textures);
String textureJSON = textureProperty.toString(); // Build the texture property info
System.out.println("Texture JSON: " + textureJSON);
textureJSON = Base64Coder.encodeString(textureJSON); // Must be base64 encoded
JsonObject profileProperty = new JsonObject();
profileProperty.set("name", "textures");
profileProperty.set("value", textureJSON);
profileProperty.set("signature", "");
JsonObject profileResponse = new JsonObject();
profileResponse.set("id", p.getId());
profileResponse.set("name", p.getName());
profileResponse.set("properties", new JsonArray().add(profileProperty));
String response = profileResponse.toString();
System.out.println("Profile JSON: " + response);
return response;
}
private String searchProfile(int page, String body) {
System.out.println("Proxy: ProfileName");
// Request comes as an array of objects {name: <username>, agent: 'Minecraft'}
JsonArray requests = JsonObject.readFrom(body).asArray();
JsonArray profilesJson = new JsonArray();
for (JsonValue r : requests) {
Profile p = profiles.searchProfile(r.asObject().get("name").asString());
JsonObject profileResult = new JsonObject();
profileResult.set("id", p.getId());
profileResult.set("name", p.getName());
profilesJson.add(profileResult);
}
JsonObject searchResponse = new JsonObject();
searchResponse.set("profiles", profilesJson);
searchResponse.set("size", profilesJson.size());
String response = searchResponse.toString();
return response;
}
}