mirror of
https://github.com/GeyserMC/MCProtocolLib.git
synced 2024-12-04 12:51:09 -05:00
Move authentication code to MCAuthLib
This commit is contained in:
parent
fdbb8168c5
commit
91d8f0f57c
76 changed files with 54 additions and 1889 deletions
|
@ -7,7 +7,6 @@
|
||||||
--------
|
--------
|
||||||
|
|
||||||
MCProtocolLib is a simple library for communicating with a Minecraft client/server. It aims to allow people to make custom bots, clients, or servers for Minecraft easily.
|
MCProtocolLib is a simple library for communicating with a Minecraft client/server. It aims to allow people to make custom bots, clients, or servers for Minecraft easily.
|
||||||
The library is split into two packages, org.spacehq.mc.auth and org.spacehq.mc.protocol. The auth package contains some classes to work with Mojang's auth servers and the protocol package contains the protocol library.
|
|
||||||
|
|
||||||
|
|
||||||
<b>Example Code</b>
|
<b>Example Code</b>
|
||||||
|
|
|
@ -9,7 +9,11 @@ import org.spacehq.mc.protocol.ServerLoginHandler;
|
||||||
import org.spacehq.mc.protocol.data.game.values.entity.player.GameMode;
|
import org.spacehq.mc.protocol.data.game.values.entity.player.GameMode;
|
||||||
import org.spacehq.mc.protocol.data.game.values.setting.Difficulty;
|
import org.spacehq.mc.protocol.data.game.values.setting.Difficulty;
|
||||||
import org.spacehq.mc.protocol.data.game.values.world.WorldType;
|
import org.spacehq.mc.protocol.data.game.values.world.WorldType;
|
||||||
import org.spacehq.mc.protocol.data.message.*;
|
import org.spacehq.mc.protocol.data.message.ChatColor;
|
||||||
|
import org.spacehq.mc.protocol.data.message.ChatFormat;
|
||||||
|
import org.spacehq.mc.protocol.data.message.Message;
|
||||||
|
import org.spacehq.mc.protocol.data.message.MessageStyle;
|
||||||
|
import org.spacehq.mc.protocol.data.message.TextMessage;
|
||||||
import org.spacehq.mc.protocol.data.status.PlayerInfo;
|
import org.spacehq.mc.protocol.data.status.PlayerInfo;
|
||||||
import org.spacehq.mc.protocol.data.status.ServerStatusInfo;
|
import org.spacehq.mc.protocol.data.status.ServerStatusInfo;
|
||||||
import org.spacehq.mc.protocol.data.status.VersionInfo;
|
import org.spacehq.mc.protocol.data.status.VersionInfo;
|
||||||
|
@ -24,6 +28,7 @@ import org.spacehq.packetlib.Server;
|
||||||
import org.spacehq.packetlib.Session;
|
import org.spacehq.packetlib.Session;
|
||||||
import org.spacehq.packetlib.event.server.ServerAdapter;
|
import org.spacehq.packetlib.event.server.ServerAdapter;
|
||||||
import org.spacehq.packetlib.event.server.SessionAddedEvent;
|
import org.spacehq.packetlib.event.server.SessionAddedEvent;
|
||||||
|
import org.spacehq.packetlib.event.server.SessionRemovedEvent;
|
||||||
import org.spacehq.packetlib.event.session.DisconnectedEvent;
|
import org.spacehq.packetlib.event.session.DisconnectedEvent;
|
||||||
import org.spacehq.packetlib.event.session.PacketReceivedEvent;
|
import org.spacehq.packetlib.event.session.PacketReceivedEvent;
|
||||||
import org.spacehq.packetlib.event.session.SessionAdapter;
|
import org.spacehq.packetlib.event.session.SessionAdapter;
|
||||||
|
@ -78,6 +83,15 @@ public class Test {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sessionRemoved(SessionRemovedEvent event) {
|
||||||
|
MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol();
|
||||||
|
if(protocol.getMode() == ProtocolMode.GAME) {
|
||||||
|
System.out.println("Closing server.");
|
||||||
|
event.getServer().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.bind();
|
server.bind();
|
||||||
|
|
13
pom.xml
13
pom.xml
|
@ -76,22 +76,15 @@
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>org.spacehq</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>mcauthlib</artifactId>
|
||||||
<version>2.2.4</version>
|
<version>1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<defaultGoal>clean install</defaultGoal>
|
<defaultGoal>clean install</defaultGoal>
|
||||||
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||||
<!-- Resources -->
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>${basedir}/src/main/resources</directory>
|
|
||||||
<filtering>false</filtering>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.properties.PropertyMap;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class GameProfile {
|
|
||||||
|
|
||||||
private UUID id;
|
|
||||||
private String name;
|
|
||||||
private PropertyMap properties = new PropertyMap();
|
|
||||||
private boolean legacy;
|
|
||||||
|
|
||||||
public GameProfile(String id, String name) {
|
|
||||||
this(id == null || id.equals("") ? null : UUID.fromString(id), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile(UUID id, String name) {
|
|
||||||
if(id == null && (name == null || name.equals(""))) {
|
|
||||||
throw new IllegalArgumentException("Name and ID cannot both be blank");
|
|
||||||
} else {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIdAsString() {
|
|
||||||
return this.id != null ? this.id.toString() : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyMap getProperties() {
|
|
||||||
return this.properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLegacy() {
|
|
||||||
return this.legacy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isComplete() {
|
|
||||||
return this.id != null && this.name != null && !this.name.equals("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if(this == o) {
|
|
||||||
return true;
|
|
||||||
} else if(o != null && this.getClass() == o.getClass()) {
|
|
||||||
GameProfile that = (GameProfile) o;
|
|
||||||
return (this.id != null ? this.id.equals(that.id) : that.id == null) && (this.name != null ? this.name.equals(that.name) : that.name == null);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = this.id != null ? this.id.hashCode() : 0;
|
|
||||||
result = 31 * result + (this.name != null ? this.name.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "GameProfile{id=" + this.id + ", name=" + this.name + ", properties=" + this.properties + ", legacy=" + this.legacy + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.exception.AuthenticationException;
|
|
||||||
import org.spacehq.mc.auth.exception.ProfileNotFoundException;
|
|
||||||
import org.spacehq.mc.auth.response.ProfileSearchResultsResponse;
|
|
||||||
import org.spacehq.mc.util.URLUtils;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class GameProfileRepository {
|
|
||||||
|
|
||||||
private static final String BASE_URL = "https://api.mojang.com/";
|
|
||||||
private static final String SEARCH_PAGE_URL = "https://api.mojang.com/profiles/page/";
|
|
||||||
private static final int MAX_FAIL_COUNT = 3;
|
|
||||||
private static final int DELAY_BETWEEN_PAGES = 100;
|
|
||||||
private static final int DELAY_BETWEEN_FAILURES = 750;
|
|
||||||
|
|
||||||
public void findProfilesByNames(String[] names, ProfileLookupCallback callback) {
|
|
||||||
Set<ProfileCriteria> criteria = new HashSet<ProfileCriteria>();
|
|
||||||
for(String name : names) {
|
|
||||||
if(name != null && !name.isEmpty()) {
|
|
||||||
criteria.add(new ProfileCriteria(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<ProfileCriteria> request = new HashSet<ProfileCriteria>(criteria);
|
|
||||||
int page = 1;
|
|
||||||
Exception error = null;
|
|
||||||
int failCount = 0;
|
|
||||||
while(failCount < MAX_FAIL_COUNT && !criteria.isEmpty()) {
|
|
||||||
try {
|
|
||||||
ProfileSearchResultsResponse response = (ProfileSearchResultsResponse) URLUtils.makeRequest(URLUtils.constantURL("https://api.mojang.com/profiles/page/" + page), request, ProfileSearchResultsResponse.class);
|
|
||||||
failCount = 0;
|
|
||||||
error = null;
|
|
||||||
if(response.getSize() != 0 && response.getProfiles().length != 0) {
|
|
||||||
for(GameProfile profile : response.getProfiles()) {
|
|
||||||
criteria.remove(new ProfileCriteria(profile.getName()));
|
|
||||||
callback.onProfileLookupSucceeded(profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
page++;
|
|
||||||
try {
|
|
||||||
Thread.sleep(DELAY_BETWEEN_PAGES);
|
|
||||||
} catch(InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(AuthenticationException e) {
|
|
||||||
error = e;
|
|
||||||
failCount++;
|
|
||||||
try {
|
|
||||||
Thread.sleep(DELAY_BETWEEN_FAILURES);
|
|
||||||
} catch(InterruptedException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!criteria.isEmpty()) {
|
|
||||||
if(error == null) {
|
|
||||||
error = new ProfileNotFoundException("Server did not find the requested profile");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(ProfileCriteria profileCriteria : criteria) {
|
|
||||||
callback.onProfileLookupFailed(new GameProfile((UUID) null, profileCriteria.getName()), error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
public class ProfileCriteria {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public ProfileCriteria(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if(this == o) {
|
|
||||||
return true;
|
|
||||||
} else if(o != null && this.getClass() == o.getClass()) {
|
|
||||||
ProfileCriteria that = (ProfileCriteria) o;
|
|
||||||
return this.name.toLowerCase().equals(that.name.toLowerCase());
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
return 31 * this.name.toLowerCase().hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "GameProfileRepository{name=" + this.name + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
public interface ProfileLookupCallback {
|
|
||||||
|
|
||||||
public void onProfileLookupSucceeded(GameProfile profile);
|
|
||||||
|
|
||||||
public void onProfileLookupFailed(GameProfile profile, Exception e);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
public class ProfileTexture {
|
|
||||||
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
public ProfileTexture(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return this.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHash() {
|
|
||||||
String url = this.url.endsWith("/") ? this.url.substring(0, this.url.length() - 1) : this.url;
|
|
||||||
int slash = url.lastIndexOf("/");
|
|
||||||
int dot = url.lastIndexOf(".", slash);
|
|
||||||
return url.substring(slash + 1, dot != -1 ? dot : url.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ProfileTexture{url=" + this.url + ", hash=" + this.getHash() + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
public enum ProfileTextureType {
|
|
||||||
|
|
||||||
SKIN,
|
|
||||||
CAPE;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import org.spacehq.mc.auth.exception.*;
|
|
||||||
import org.spacehq.mc.auth.properties.Property;
|
|
||||||
import org.spacehq.mc.auth.request.JoinServerRequest;
|
|
||||||
import org.spacehq.mc.auth.response.HasJoinedResponse;
|
|
||||||
import org.spacehq.mc.auth.response.MinecraftProfilePropertiesResponse;
|
|
||||||
import org.spacehq.mc.auth.response.MinecraftTexturesPayload;
|
|
||||||
import org.spacehq.mc.auth.response.Response;
|
|
||||||
import org.spacehq.mc.auth.serialize.UUIDSerializer;
|
|
||||||
import org.spacehq.mc.util.Base64;
|
|
||||||
import org.spacehq.mc.util.IOUtils;
|
|
||||||
import org.spacehq.mc.util.URLUtils;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class SessionService {
|
|
||||||
|
|
||||||
private static final String BASE_URL = "https://sessionserver.mojang.com/session/minecraft/";
|
|
||||||
private static final URL JOIN_URL = URLUtils.constantURL(BASE_URL + "join");
|
|
||||||
private static final URL CHECK_URL = URLUtils.constantURL(BASE_URL + "hasJoined");
|
|
||||||
|
|
||||||
private static final PublicKey SIGNATURE_KEY;
|
|
||||||
private static final Gson GSON = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDSerializer()).create();
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
X509EncodedKeySpec spec = new X509EncodedKeySpec(IOUtils.toByteArray(SessionService.class.getResourceAsStream("/yggdrasil_session_pubkey.der")));
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
||||||
SIGNATURE_KEY = keyFactory.generatePublic(spec);
|
|
||||||
} catch(Exception var4) {
|
|
||||||
throw new ExceptionInInitializerError("Missing/invalid yggdrasil public key.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void joinServer(GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
|
|
||||||
JoinServerRequest request = new JoinServerRequest(authenticationToken, profile.getId(), serverId);
|
|
||||||
URLUtils.makeRequest(JOIN_URL, request, Response.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile hasJoinedServer(GameProfile user, String serverId) throws AuthenticationUnavailableException {
|
|
||||||
Map<String, Object> arguments = new HashMap<String, Object>();
|
|
||||||
arguments.put("username", user.getName());
|
|
||||||
arguments.put("serverId", serverId);
|
|
||||||
URL url = URLUtils.concatenateURL(CHECK_URL, URLUtils.buildQuery(arguments));
|
|
||||||
try {
|
|
||||||
HasJoinedResponse response = URLUtils.makeRequest(url, null, HasJoinedResponse.class);
|
|
||||||
if(response != null && response.getId() != null) {
|
|
||||||
GameProfile result = new GameProfile(response.getId(), user.getName());
|
|
||||||
if(response.getProperties() != null) {
|
|
||||||
result.getProperties().putAll(response.getProperties());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch(AuthenticationUnavailableException e) {
|
|
||||||
throw e;
|
|
||||||
} catch(AuthenticationException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<ProfileTextureType, ProfileTexture> getTextures(GameProfile profile, boolean requireSecure) throws PropertyException {
|
|
||||||
Property textures = profile.getProperties().get("textures");
|
|
||||||
if(textures != null) {
|
|
||||||
if(!textures.hasSignature()) {
|
|
||||||
throw new ProfileTextureException("Signature is missing from textures payload.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!textures.isSignatureValid(SIGNATURE_KEY)) {
|
|
||||||
throw new ProfileTextureException("Textures payload has been tampered with. (signature invalid)");
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftTexturesPayload result;
|
|
||||||
try {
|
|
||||||
String json = new String(Base64.decode(textures.getValue().getBytes("UTF-8")));
|
|
||||||
result = GSON.fromJson(json, MinecraftTexturesPayload.class);
|
|
||||||
} catch(Exception e) {
|
|
||||||
throw new ProfileTextureException("Could not decode texture payload.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result.getProfileId() == null || !result.getProfileId().equals(profile.getId())) {
|
|
||||||
throw new ProfileTextureException("Decrypted textures payload was for another user. (expected id " + profile.getId() + " but was for " + result.getProfileId() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result.getProfileName() == null || !result.getProfileName().equals(profile.getName())) {
|
|
||||||
throw new ProfileTextureException("Decrypted textures payload was for another user. (expected name " + profile.getName() + " but was for " + result.getProfileName() + ")");
|
|
||||||
}
|
|
||||||
if(requireSecure) {
|
|
||||||
if(result.isPublic()) {
|
|
||||||
throw new ProfileTextureException("Decrypted textures payload was public when secure data is required.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Calendar limit = Calendar.getInstance();
|
|
||||||
limit.add(5, -1);
|
|
||||||
Date validFrom = new Date(result.getTimestamp());
|
|
||||||
if(validFrom.before(limit.getTime())) {
|
|
||||||
throw new ProfileTextureException("Decrypted textures payload is too old. (" + validFrom + ", needs to be at least " + limit + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.getTextures() == null ? new HashMap<ProfileTextureType, ProfileTexture>() : result.getTextures();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new HashMap<ProfileTextureType, ProfileTexture>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile fillProfileProperties(GameProfile profile) throws ProfileException {
|
|
||||||
if(profile.getId() == null) {
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
URL url = URLUtils.constantURL("https://sessionserver.mojang.com/session/minecraft/profile/" + UUIDSerializer.fromUUID(profile.getId()));
|
|
||||||
MinecraftProfilePropertiesResponse response = URLUtils.makeRequest(url, null, MinecraftProfilePropertiesResponse.class);
|
|
||||||
if(response == null) {
|
|
||||||
throw new ProfileNotFoundException("Couldn't fetch profile properties for " + profile + " as the profile does not exist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
GameProfile result = new GameProfile(response.getId(), response.getName());
|
|
||||||
result.getProperties().putAll(response.getProperties());
|
|
||||||
profile.getProperties().putAll(response.getProperties());
|
|
||||||
return result;
|
|
||||||
} catch(AuthenticationException e) {
|
|
||||||
throw new ProfileLookupException("Couldn't look up profile properties for " + profile, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SessionService{}";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,345 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.exception.AuthenticationException;
|
|
||||||
import org.spacehq.mc.auth.exception.InvalidCredentialsException;
|
|
||||||
import org.spacehq.mc.auth.exception.PropertyDeserializeException;
|
|
||||||
import org.spacehq.mc.auth.properties.Property;
|
|
||||||
import org.spacehq.mc.auth.properties.PropertyMap;
|
|
||||||
import org.spacehq.mc.auth.request.AuthenticationRequest;
|
|
||||||
import org.spacehq.mc.auth.request.RefreshRequest;
|
|
||||||
import org.spacehq.mc.auth.response.AuthenticationResponse;
|
|
||||||
import org.spacehq.mc.auth.response.RefreshResponse;
|
|
||||||
import org.spacehq.mc.auth.response.User;
|
|
||||||
import org.spacehq.mc.util.URLUtils;
|
|
||||||
import org.spacehq.mc.auth.serialize.UUIDSerializer;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class UserAuthentication {
|
|
||||||
|
|
||||||
private static final String BASE_URL = "https://authserver.mojang.com/";
|
|
||||||
private static final URL ROUTE_AUTHENTICATE = URLUtils.constantURL(BASE_URL + "authenticate");
|
|
||||||
private static final URL ROUTE_REFRESH = URLUtils.constantURL(BASE_URL + "refresh");
|
|
||||||
private static final String STORAGE_KEY_PROFILE_NAME = "displayName";
|
|
||||||
private static final String STORAGE_KEY_PROFILE_ID = "uuid";
|
|
||||||
private static final String STORAGE_KEY_PROFILE_PROPERTIES = "profileProperties";
|
|
||||||
private static final String STORAGE_KEY_USER_NAME = "username";
|
|
||||||
private static final String STORAGE_KEY_USER_ID = "userid";
|
|
||||||
private static final String STORAGE_KEY_USER_PROPERTIES = "userProperties";
|
|
||||||
private static final String STORAGE_KEY_ACCESS_TOKEN = "accessToken";
|
|
||||||
|
|
||||||
private String clientToken;
|
|
||||||
private PropertyMap userProperties = new PropertyMap();
|
|
||||||
private String userId;
|
|
||||||
private String username;
|
|
||||||
private String password;
|
|
||||||
private String accessToken;
|
|
||||||
private boolean isOnline;
|
|
||||||
private List<GameProfile> profiles = new ArrayList<GameProfile>();
|
|
||||||
private GameProfile selectedProfile;
|
|
||||||
private UserType userType;
|
|
||||||
|
|
||||||
public UserAuthentication(String clientToken) {
|
|
||||||
if(clientToken == null) {
|
|
||||||
throw new IllegalArgumentException("ClientToken cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.clientToken = clientToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientToken() {
|
|
||||||
return this.clientToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserID() {
|
|
||||||
return this.userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return this.accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GameProfile> getAvailableProfiles() {
|
|
||||||
return this.profiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile getSelectedProfile() {
|
|
||||||
return this.selectedProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserType getUserType() {
|
|
||||||
return this.isLoggedIn() ? (this.userType == null ? UserType.LEGACY : this.userType) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyMap getUserProperties() {
|
|
||||||
return this.isLoggedIn() ? new PropertyMap(this.userProperties) : new PropertyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLoggedIn() {
|
|
||||||
return this.accessToken != null && !this.accessToken.equals("");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canPlayOnline() {
|
|
||||||
return this.isLoggedIn() && this.getSelectedProfile() != null && this.isOnline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canLogIn() {
|
|
||||||
return !this.canPlayOnline() && this.username != null && !this.username.equals("") && ((this.password != null && !this.password.equals("")) || (this.accessToken != null && !this.accessToken.equals("")));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
if(this.isLoggedIn() && this.canPlayOnline()) {
|
|
||||||
throw new IllegalStateException("Cannot change username whilst logged in & online");
|
|
||||||
} else {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
if(this.isLoggedIn() && this.canPlayOnline() && this.password != null && !this.password.equals("")) {
|
|
||||||
throw new IllegalStateException("Cannot set password whilst logged in & online");
|
|
||||||
} else {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
if(this.isLoggedIn() && this.canPlayOnline()) {
|
|
||||||
throw new IllegalStateException("Cannot change accessToken whilst logged in & online");
|
|
||||||
} else {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadFromStorage(Map<String, Object> credentials) throws PropertyDeserializeException {
|
|
||||||
this.logout();
|
|
||||||
this.setUsername((String) credentials.get(STORAGE_KEY_USER_NAME));
|
|
||||||
if(credentials.containsKey(STORAGE_KEY_USER_ID)) {
|
|
||||||
this.userId = (String) credentials.get(STORAGE_KEY_USER_ID);
|
|
||||||
} else {
|
|
||||||
this.userId = this.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(credentials.containsKey(STORAGE_KEY_USER_PROPERTIES)) {
|
|
||||||
try {
|
|
||||||
List<Map<String, String>> list = (List<Map<String, String>>) credentials.get(STORAGE_KEY_USER_PROPERTIES);
|
|
||||||
for(Map<String, String> propertyMap : list) {
|
|
||||||
String name = propertyMap.get("name");
|
|
||||||
String value = propertyMap.get("value");
|
|
||||||
String signature = propertyMap.get("signature");
|
|
||||||
if(signature == null) {
|
|
||||||
this.userProperties.put(name, new Property(name, value));
|
|
||||||
} else {
|
|
||||||
this.userProperties.put(name, new Property(name, value, signature));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(Throwable t) {
|
|
||||||
throw new PropertyDeserializeException("Couldn't deserialize user properties", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(credentials.containsKey(STORAGE_KEY_PROFILE_NAME) && credentials.containsKey(STORAGE_KEY_PROFILE_ID)) {
|
|
||||||
GameProfile profile = new GameProfile(UUIDSerializer.fromString((String) credentials.get(STORAGE_KEY_PROFILE_ID)), (String) credentials.get(STORAGE_KEY_PROFILE_NAME));
|
|
||||||
if(credentials.containsKey(STORAGE_KEY_PROFILE_PROPERTIES)) {
|
|
||||||
try {
|
|
||||||
List<Map<String, String>> list = (List<Map<String, String>>) credentials.get(STORAGE_KEY_PROFILE_PROPERTIES);
|
|
||||||
for(Map<String, String> propertyMap : list) {
|
|
||||||
String name = propertyMap.get("name");
|
|
||||||
String value = propertyMap.get("value");
|
|
||||||
String signature = propertyMap.get("signature");
|
|
||||||
if(signature == null) {
|
|
||||||
profile.getProperties().put(name, new Property(name, value));
|
|
||||||
} else {
|
|
||||||
profile.getProperties().put(name, new Property(name, value, signature));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(Throwable t) {
|
|
||||||
throw new PropertyDeserializeException("Couldn't deserialize profile properties", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectedProfile = profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.accessToken = (String) credentials.get(STORAGE_KEY_ACCESS_TOKEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Object> saveForStorage() {
|
|
||||||
Map<String, Object> result = new HashMap<String, Object>();
|
|
||||||
if(this.username != null) {
|
|
||||||
result.put(STORAGE_KEY_USER_NAME, this.username);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.getUserID() != null) {
|
|
||||||
result.put(STORAGE_KEY_USER_ID, this.userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.getUserProperties().isEmpty()) {
|
|
||||||
List<Map<String, String>> properties = new ArrayList<Map<String, String>>();
|
|
||||||
for(Property userProperty : this.getUserProperties().values()) {
|
|
||||||
Map<String, String> property = new HashMap<String, String>();
|
|
||||||
property.put("name", userProperty.getName());
|
|
||||||
property.put("value", userProperty.getValue());
|
|
||||||
property.put("signature", userProperty.getSignature());
|
|
||||||
properties.add(property);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.put(STORAGE_KEY_USER_PROPERTIES, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
GameProfile selectedProfile = this.getSelectedProfile();
|
|
||||||
if(selectedProfile != null) {
|
|
||||||
result.put(STORAGE_KEY_PROFILE_NAME, selectedProfile.getName());
|
|
||||||
result.put(STORAGE_KEY_PROFILE_ID, selectedProfile.getId());
|
|
||||||
List<Map<String, String>> properties = new ArrayList<Map<String, String>>();
|
|
||||||
for(Property profileProperty : selectedProfile.getProperties().values()) {
|
|
||||||
Map<String, String> property = new HashMap<String, String>();
|
|
||||||
property.put("name", profileProperty.getName());
|
|
||||||
property.put("value", profileProperty.getValue());
|
|
||||||
property.put("signature", profileProperty.getSignature());
|
|
||||||
properties.add(property);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!properties.isEmpty()) {
|
|
||||||
result.put(STORAGE_KEY_PROFILE_PROPERTIES, properties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.accessToken != null && !this.accessToken.equals("")) {
|
|
||||||
result.put(STORAGE_KEY_ACCESS_TOKEN, this.accessToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void login() throws AuthenticationException {
|
|
||||||
if(this.username == null || this.username.equals("")) {
|
|
||||||
throw new InvalidCredentialsException("Invalid username");
|
|
||||||
} else {
|
|
||||||
if(this.accessToken != null && !this.accessToken.equals("")) {
|
|
||||||
this.loginWithToken();
|
|
||||||
} else {
|
|
||||||
if(this.password == null || this.password.equals("")) {
|
|
||||||
throw new InvalidCredentialsException("Invalid password");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loginWithPassword();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loginWithPassword() throws AuthenticationException {
|
|
||||||
if(this.username == null || this.username.equals("")) {
|
|
||||||
throw new InvalidCredentialsException("Invalid username");
|
|
||||||
} else if(this.password == null || this.password.equals("")) {
|
|
||||||
throw new InvalidCredentialsException("Invalid password");
|
|
||||||
} else {
|
|
||||||
AuthenticationRequest request = new AuthenticationRequest(this, this.username, this.password);
|
|
||||||
AuthenticationResponse response = URLUtils.makeRequest(ROUTE_AUTHENTICATE, request, AuthenticationResponse.class);
|
|
||||||
if(!response.getClientToken().equals(this.getClientToken())) {
|
|
||||||
throw new AuthenticationException("Server requested we change our client token. Don't know how to handle this!");
|
|
||||||
} else {
|
|
||||||
if(response.getSelectedProfile() != null) {
|
|
||||||
this.userType = response.getSelectedProfile().isLegacy() ? UserType.LEGACY : UserType.MOJANG;
|
|
||||||
} else if(response.getAvailableProfiles() != null && response.getAvailableProfiles().length != 0) {
|
|
||||||
this.userType = response.getAvailableProfiles()[0].isLegacy() ? UserType.LEGACY : UserType.MOJANG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(response.getUser() != null && response.getUser().getId() != null) {
|
|
||||||
this.userId = response.getUser().getId();
|
|
||||||
} else {
|
|
||||||
this.userId = this.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isOnline = true;
|
|
||||||
this.accessToken = response.getAccessToken();
|
|
||||||
this.profiles = Arrays.asList(response.getAvailableProfiles());
|
|
||||||
this.selectedProfile = response.getSelectedProfile();
|
|
||||||
this.updateProperties(response.getUser());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loginWithToken() throws AuthenticationException {
|
|
||||||
if(this.userId == null || this.userId.equals("")) {
|
|
||||||
if(this.username == null || this.username.equals("")) {
|
|
||||||
throw new InvalidCredentialsException("Invalid uuid & username");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.userId = this.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.accessToken == null || this.accessToken.equals("")) {
|
|
||||||
throw new InvalidCredentialsException("Invalid access token");
|
|
||||||
} else {
|
|
||||||
RefreshRequest request = new RefreshRequest(this);
|
|
||||||
RefreshResponse response = URLUtils.makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
|
|
||||||
if(!response.getClientToken().equals(this.getClientToken())) {
|
|
||||||
throw new AuthenticationException("Server requested we change our client token. Don't know how to handle this!");
|
|
||||||
} else {
|
|
||||||
if(response.getSelectedProfile() != null) {
|
|
||||||
this.userType = response.getSelectedProfile().isLegacy() ? UserType.LEGACY : UserType.MOJANG;
|
|
||||||
} else if(response.getAvailableProfiles() != null && response.getAvailableProfiles().length != 0) {
|
|
||||||
this.userType = response.getAvailableProfiles()[0].isLegacy() ? UserType.LEGACY : UserType.MOJANG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(response.getUser() != null && response.getUser().getId() != null) {
|
|
||||||
this.userId = response.getUser().getId();
|
|
||||||
} else {
|
|
||||||
this.userId = this.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isOnline = true;
|
|
||||||
this.accessToken = response.getAccessToken();
|
|
||||||
this.profiles = Arrays.asList(response.getAvailableProfiles());
|
|
||||||
this.selectedProfile = response.getSelectedProfile();
|
|
||||||
this.updateProperties(response.getUser());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void logout() {
|
|
||||||
this.password = null;
|
|
||||||
this.userId = null;
|
|
||||||
this.selectedProfile = null;
|
|
||||||
this.userProperties.clear();
|
|
||||||
this.accessToken = null;
|
|
||||||
this.profiles = null;
|
|
||||||
this.isOnline = false;
|
|
||||||
this.userType = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void selectGameProfile(GameProfile profile) throws AuthenticationException {
|
|
||||||
if(!this.isLoggedIn()) {
|
|
||||||
throw new AuthenticationException("Cannot change game profile whilst not logged in");
|
|
||||||
} else if(this.getSelectedProfile() != null) {
|
|
||||||
throw new AuthenticationException("Cannot change game profile. You must log out and back in.");
|
|
||||||
} else if(profile != null && this.profiles.contains(profile)) {
|
|
||||||
RefreshRequest request = new RefreshRequest(this, profile);
|
|
||||||
RefreshResponse response = URLUtils.makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
|
|
||||||
if(!response.getClientToken().equals(this.getClientToken())) {
|
|
||||||
throw new AuthenticationException("Server requested we change our client token. Don't know how to handle this!");
|
|
||||||
} else {
|
|
||||||
this.isOnline = true;
|
|
||||||
this.accessToken = response.getAccessToken();
|
|
||||||
this.selectedProfile = response.getSelectedProfile();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Invalid profile '" + profile + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "UserAuthentication{profiles=" + this.profiles + ", selectedProfile=" + this.getSelectedProfile() + ", username=" + this.username + ", isLoggedIn=" + this.isLoggedIn() + ", canPlayOnline=" + this.canPlayOnline() + ", accessToken=" + this.accessToken + ", clientToken=" + this.getClientToken() + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateProperties(User user) {
|
|
||||||
this.userProperties.clear();
|
|
||||||
if(user != null && user.getProperties() != null) {
|
|
||||||
this.userProperties.putAll(user.getProperties());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.spacehq.mc.auth;
|
|
||||||
|
|
||||||
public enum UserType {
|
|
||||||
|
|
||||||
LEGACY,
|
|
||||||
MOJANG;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class AuthenticationException extends Exception {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public AuthenticationException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class AuthenticationUnavailableException extends AuthenticationException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public AuthenticationUnavailableException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationUnavailableException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationUnavailableException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationUnavailableException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class InvalidCredentialsException extends AuthenticationException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public InvalidCredentialsException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidCredentialsException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidCredentialsException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidCredentialsException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class ProfileException extends Exception {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public ProfileException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class ProfileLookupException extends ProfileException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public ProfileLookupException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileLookupException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileLookupException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileLookupException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class ProfileNotFoundException extends ProfileException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public ProfileNotFoundException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileNotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileNotFoundException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileNotFoundException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class ProfileTextureException extends PropertyException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public ProfileTextureException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileTextureException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileTextureException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileTextureException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class PropertyDeserializeException extends PropertyException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public PropertyDeserializeException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyDeserializeException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyDeserializeException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyDeserializeException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class PropertyException extends Exception {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public PropertyException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class SignatureValidateException extends PropertyException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public SignatureValidateException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignatureValidateException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignatureValidateException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignatureValidateException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.spacehq.mc.auth.exception;
|
|
||||||
|
|
||||||
public class UserMigratedException extends InvalidCredentialsException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public UserMigratedException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserMigratedException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserMigratedException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserMigratedException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package org.spacehq.mc.auth.properties;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.exception.SignatureValidateException;
|
|
||||||
import org.spacehq.mc.util.Base64;
|
|
||||||
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.Signature;
|
|
||||||
|
|
||||||
public class Property {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private String value;
|
|
||||||
private String signature;
|
|
||||||
|
|
||||||
public Property(String value, String name) {
|
|
||||||
this(value, name, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Property(String name, String value, String signature) {
|
|
||||||
this.name = name;
|
|
||||||
this.value = value;
|
|
||||||
this.signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignature() {
|
|
||||||
return this.signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasSignature() {
|
|
||||||
return this.signature != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSignatureValid(PublicKey key) throws SignatureValidateException {
|
|
||||||
try {
|
|
||||||
Signature sig = Signature.getInstance("SHA1withRSA");
|
|
||||||
sig.initVerify(key);
|
|
||||||
sig.update(this.value.getBytes());
|
|
||||||
return sig.verify(Base64.decode(this.signature.getBytes("UTF-8")));
|
|
||||||
} catch(Exception e) {
|
|
||||||
throw new SignatureValidateException("Could not validate property signature.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package org.spacehq.mc.auth.properties;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class PropertyMap extends HashMap<String, Property> {
|
|
||||||
|
|
||||||
public PropertyMap() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyMap(Map<String, Property> copy) {
|
|
||||||
super(copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.spacehq.mc.auth.request;
|
|
||||||
|
|
||||||
public class Agent {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private int version;
|
|
||||||
|
|
||||||
public Agent(String name, int version) {
|
|
||||||
this.name = name;
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVersion() {
|
|
||||||
return this.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.spacehq.mc.auth.request;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.UserAuthentication;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class AuthenticationRequest {
|
|
||||||
|
|
||||||
private Agent agent;
|
|
||||||
private String username;
|
|
||||||
private String password;
|
|
||||||
private String clientToken;
|
|
||||||
private boolean requestUser = true;
|
|
||||||
|
|
||||||
public AuthenticationRequest(UserAuthentication auth, String username, String password) {
|
|
||||||
this.agent = new Agent("Minecraft", 1);
|
|
||||||
this.username = username;
|
|
||||||
this.clientToken = auth.getClientToken();
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package org.spacehq.mc.auth.request;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class JoinServerRequest {
|
|
||||||
|
|
||||||
private String accessToken;
|
|
||||||
private UUID selectedProfile;
|
|
||||||
private String serverId;
|
|
||||||
|
|
||||||
public JoinServerRequest(String accessToken, UUID id, String serverId) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
this.selectedProfile = id;
|
|
||||||
this.serverId = serverId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package org.spacehq.mc.auth.request;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
|
||||||
import org.spacehq.mc.auth.UserAuthentication;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class RefreshRequest {
|
|
||||||
|
|
||||||
private String clientToken;
|
|
||||||
private String accessToken;
|
|
||||||
private GameProfile selectedProfile;
|
|
||||||
private boolean requestUser;
|
|
||||||
|
|
||||||
public RefreshRequest(UserAuthentication authService) {
|
|
||||||
this(authService, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RefreshRequest(UserAuthentication authService, GameProfile profile) {
|
|
||||||
this.requestUser = true;
|
|
||||||
this.clientToken = authService.getClientToken();
|
|
||||||
this.accessToken = authService.getAccessToken();
|
|
||||||
this.selectedProfile = profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
|
||||||
|
|
||||||
public class AuthenticationResponse extends Response {
|
|
||||||
|
|
||||||
private String accessToken;
|
|
||||||
private String clientToken;
|
|
||||||
private GameProfile selectedProfile;
|
|
||||||
private GameProfile[] availableProfiles;
|
|
||||||
private User user;
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return this.accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientToken() {
|
|
||||||
return this.clientToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile[] getAvailableProfiles() {
|
|
||||||
return this.availableProfiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile getSelectedProfile() {
|
|
||||||
return this.selectedProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getUser() {
|
|
||||||
return this.user;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.properties.PropertyMap;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class HasJoinedResponse extends Response {
|
|
||||||
|
|
||||||
private UUID id;
|
|
||||||
private PropertyMap properties;
|
|
||||||
|
|
||||||
public UUID getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyMap getProperties() {
|
|
||||||
return this.properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.properties.PropertyMap;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MinecraftProfilePropertiesResponse extends Response {
|
|
||||||
|
|
||||||
private UUID id;
|
|
||||||
private String name;
|
|
||||||
private PropertyMap properties;
|
|
||||||
|
|
||||||
public UUID getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyMap getProperties() {
|
|
||||||
return this.properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.ProfileTexture;
|
|
||||||
import org.spacehq.mc.auth.ProfileTextureType;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MinecraftTexturesPayload {
|
|
||||||
|
|
||||||
private long timestamp;
|
|
||||||
private UUID profileId;
|
|
||||||
private String profileName;
|
|
||||||
private boolean isPublic;
|
|
||||||
private Map<ProfileTextureType, ProfileTexture> textures;
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
|
||||||
return this.timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getProfileId() {
|
|
||||||
return this.profileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProfileName() {
|
|
||||||
return this.profileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPublic() {
|
|
||||||
return this.isPublic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<ProfileTextureType, ProfileTexture> getTextures() {
|
|
||||||
return this.textures;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
|
||||||
|
|
||||||
public class ProfileSearchResultsResponse extends Response {
|
|
||||||
|
|
||||||
private GameProfile[] profiles;
|
|
||||||
private int size;
|
|
||||||
|
|
||||||
public GameProfile[] getProfiles() {
|
|
||||||
return this.profiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return this.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
|
||||||
|
|
||||||
public class RefreshResponse extends Response {
|
|
||||||
|
|
||||||
private String accessToken;
|
|
||||||
private String clientToken;
|
|
||||||
private GameProfile selectedProfile;
|
|
||||||
private GameProfile[] availableProfiles;
|
|
||||||
private User user;
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return this.accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientToken() {
|
|
||||||
return this.clientToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile[] getAvailableProfiles() {
|
|
||||||
return this.availableProfiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameProfile getSelectedProfile() {
|
|
||||||
return this.selectedProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getUser() {
|
|
||||||
return this.user;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
public class Response {
|
|
||||||
|
|
||||||
private String error;
|
|
||||||
private String errorMessage;
|
|
||||||
private String cause;
|
|
||||||
|
|
||||||
public String getError() {
|
|
||||||
return this.error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCause() {
|
|
||||||
return this.cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrorMessage() {
|
|
||||||
return this.errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package org.spacehq.mc.auth.response;
|
|
||||||
|
|
||||||
import org.spacehq.mc.auth.properties.PropertyMap;
|
|
||||||
|
|
||||||
public class User {
|
|
||||||
|
|
||||||
private String id;
|
|
||||||
private PropertyMap properties;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyMap getProperties() {
|
|
||||||
return this.properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package org.spacehq.mc.auth.serialize;
|
|
||||||
|
|
||||||
import com.google.gson.*;
|
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class GameProfileSerializer implements JsonSerializer<GameProfile>, JsonDeserializer<GameProfile> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GameProfile deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
JsonObject object = (JsonObject) json;
|
|
||||||
UUID id = object.has("id") ? (UUID) context.deserialize(object.get("id"), UUID.class) : null;
|
|
||||||
String name = object.has("name") ? object.getAsJsonPrimitive("name").getAsString() : null;
|
|
||||||
return new GameProfile(id, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(GameProfile src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
JsonObject result = new JsonObject();
|
|
||||||
if(src.getId() != null) {
|
|
||||||
result.add("id", context.serialize(src.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(src.getName() != null) {
|
|
||||||
result.addProperty("name", src.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package org.spacehq.mc.auth.serialize;
|
|
||||||
|
|
||||||
import com.google.gson.*;
|
|
||||||
import org.spacehq.mc.auth.properties.Property;
|
|
||||||
import org.spacehq.mc.auth.properties.PropertyMap;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class PropertyMapSerializer implements JsonSerializer<PropertyMap>, JsonDeserializer<PropertyMap> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyMap deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
PropertyMap result = new PropertyMap();
|
|
||||||
if(json instanceof JsonObject) {
|
|
||||||
JsonObject object = (JsonObject) json;
|
|
||||||
for(Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
|
||||||
if(entry.getValue() instanceof JsonArray) {
|
|
||||||
for(JsonElement element : (JsonArray) entry.getValue()) {
|
|
||||||
result.put(entry.getKey(), new Property(entry.getKey(), element.getAsString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(json instanceof JsonArray) {
|
|
||||||
for(JsonElement element : (JsonArray) json) {
|
|
||||||
if((element instanceof JsonObject)) {
|
|
||||||
JsonObject object = (JsonObject) element;
|
|
||||||
String name = object.getAsJsonPrimitive("name").getAsString();
|
|
||||||
String value = object.getAsJsonPrimitive("value").getAsString();
|
|
||||||
if(object.has("signature")) {
|
|
||||||
result.put(name, new Property(name, value, object.getAsJsonPrimitive("signature").getAsString()));
|
|
||||||
} else {
|
|
||||||
result.put(name, new Property(name, value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(PropertyMap src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
JsonArray result = new JsonArray();
|
|
||||||
for(Property property : src.values()) {
|
|
||||||
JsonObject object = new JsonObject();
|
|
||||||
object.addProperty("name", property.getName());
|
|
||||||
object.addProperty("value", property.getValue());
|
|
||||||
if(property.hasSignature()) {
|
|
||||||
object.addProperty("signature", property.getSignature());
|
|
||||||
}
|
|
||||||
|
|
||||||
result.add(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package org.spacehq.mc.auth.serialize;
|
|
||||||
|
|
||||||
import com.google.gson.TypeAdapter;
|
|
||||||
import com.google.gson.stream.JsonReader;
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class UUIDSerializer extends TypeAdapter<UUID> {
|
|
||||||
|
|
||||||
public void write(JsonWriter out, UUID value) throws IOException {
|
|
||||||
out.value(fromUUID(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID read(JsonReader in) throws IOException {
|
|
||||||
return fromString(in.nextString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fromUUID(UUID value) {
|
|
||||||
return value.toString().replace("-", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UUID fromString(String input) {
|
|
||||||
return UUID.fromString(input.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -22,7 +22,7 @@ import org.spacehq.mc.protocol.packet.status.client.StatusPingPacket;
|
||||||
import org.spacehq.mc.protocol.packet.status.client.StatusQueryPacket;
|
import org.spacehq.mc.protocol.packet.status.client.StatusQueryPacket;
|
||||||
import org.spacehq.mc.protocol.packet.status.server.StatusPongPacket;
|
import org.spacehq.mc.protocol.packet.status.server.StatusPongPacket;
|
||||||
import org.spacehq.mc.protocol.packet.status.server.StatusResponsePacket;
|
import org.spacehq.mc.protocol.packet.status.server.StatusResponsePacket;
|
||||||
import org.spacehq.mc.util.CryptUtil;
|
import org.spacehq.mc.protocol.util.CryptUtil;
|
||||||
import org.spacehq.packetlib.event.session.ConnectedEvent;
|
import org.spacehq.packetlib.event.session.ConnectedEvent;
|
||||||
import org.spacehq.packetlib.event.session.PacketReceivedEvent;
|
import org.spacehq.packetlib.event.session.PacketReceivedEvent;
|
||||||
import org.spacehq.packetlib.event.session.PacketSentEvent;
|
import org.spacehq.packetlib.event.session.PacketSentEvent;
|
||||||
|
|
|
@ -18,7 +18,7 @@ import org.spacehq.mc.protocol.packet.status.client.StatusPingPacket;
|
||||||
import org.spacehq.mc.protocol.packet.status.client.StatusQueryPacket;
|
import org.spacehq.mc.protocol.packet.status.client.StatusQueryPacket;
|
||||||
import org.spacehq.mc.protocol.packet.status.server.StatusPongPacket;
|
import org.spacehq.mc.protocol.packet.status.server.StatusPongPacket;
|
||||||
import org.spacehq.mc.protocol.packet.status.server.StatusResponsePacket;
|
import org.spacehq.mc.protocol.packet.status.server.StatusResponsePacket;
|
||||||
import org.spacehq.mc.util.CryptUtil;
|
import org.spacehq.mc.protocol.util.CryptUtil;
|
||||||
import org.spacehq.packetlib.Session;
|
import org.spacehq.packetlib.Session;
|
||||||
import org.spacehq.packetlib.event.session.DisconnectingEvent;
|
import org.spacehq.packetlib.event.session.DisconnectingEvent;
|
||||||
import org.spacehq.packetlib.event.session.PacketReceivedEvent;
|
import org.spacehq.packetlib.event.session.PacketReceivedEvent;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.protocol.data.game.values.Face;
|
import org.spacehq.mc.protocol.data.game.values.Face;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.entity.player.PlayerAction;
|
import org.spacehq.mc.protocol.data.game.values.entity.player.PlayerAction;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.spacehq.mc.protocol.data.game.ItemStack;
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.protocol.data.game.values.Face;
|
import org.spacehq.mc.protocol.data.game.values.Face;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.client.window;
|
package org.spacehq.mc.protocol.packet.ingame.client.window;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.ItemStack;
|
import org.spacehq.mc.protocol.data.game.ItemStack;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.client.window;
|
||||||
import org.spacehq.mc.protocol.data.game.ItemStack;
|
import org.spacehq.mc.protocol.data.game.ItemStack;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.window.*;
|
import org.spacehq.mc.protocol.data.game.values.window.*;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.client.world;
|
package org.spacehq.mc.protocol.packet.ingame.client.world;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.entity;
|
package org.spacehq.mc.protocol.packet.ingame.server.entity;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.ItemStack;
|
import org.spacehq.mc.protocol.data.game.ItemStack;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.entity;
|
package org.spacehq.mc.protocol.packet.ingame.server.entity;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.EntityMetadata;
|
import org.spacehq.mc.protocol.data.game.EntityMetadata;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.entity.player;
|
package org.spacehq.mc.protocol.packet.ingame.server.entity.player;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.server.entity.spawn;
|
||||||
import org.spacehq.mc.protocol.data.game.EntityMetadata;
|
import org.spacehq.mc.protocol.data.game.EntityMetadata;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.entity.MobType;
|
import org.spacehq.mc.protocol.data.game.values.entity.MobType;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.entity.Art;
|
import org.spacehq.mc.protocol.data.game.values.entity.Art;
|
||||||
import org.spacehq.mc.protocol.data.game.values.entity.HangingDirection;
|
import org.spacehq.mc.protocol.data.game.values.entity.HangingDirection;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.server.entity.spawn;
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
import org.spacehq.mc.auth.GameProfile;
|
||||||
import org.spacehq.mc.auth.properties.Property;
|
import org.spacehq.mc.auth.properties.Property;
|
||||||
import org.spacehq.mc.protocol.data.game.EntityMetadata;
|
import org.spacehq.mc.protocol.data.game.EntityMetadata;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.window;
|
package org.spacehq.mc.protocol.packet.ingame.server.window;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.ItemStack;
|
import org.spacehq.mc.protocol.data.game.ItemStack;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.window;
|
package org.spacehq.mc.protocol.packet.ingame.server.window;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.ItemStack;
|
import org.spacehq.mc.protocol.data.game.ItemStack;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.entity.player.BlockBreakStage;
|
import org.spacehq.mc.protocol.data.game.values.entity.player.BlockBreakStage;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.values.world.block.BlockChangeRecord;
|
import org.spacehq.mc.protocol.data.game.values.world.block.BlockChangeRecord;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.world.block.value.*;
|
import org.spacehq.mc.protocol.data.game.values.world.block.value.*;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Chunk;
|
import org.spacehq.mc.protocol.data.game.Chunk;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.mc.util.NetworkChunkData;
|
import org.spacehq.mc.protocol.util.NetworkChunkData;
|
||||||
import org.spacehq.mc.util.ParsedChunkData;
|
import org.spacehq.mc.protocol.util.ParsedChunkData;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Chunk;
|
import org.spacehq.mc.protocol.data.game.Chunk;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.mc.util.NetworkChunkData;
|
import org.spacehq.mc.protocol.util.NetworkChunkData;
|
||||||
import org.spacehq.mc.util.ParsedChunkData;
|
import org.spacehq.mc.protocol.util.ParsedChunkData;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.world.effect.*;
|
import org.spacehq.mc.protocol.data.game.values.world.effect.*;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.server.world;
|
||||||
import org.spacehq.mc.protocol.data.game.Position;
|
import org.spacehq.mc.protocol.data.game.Position;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
||||||
import org.spacehq.mc.protocol.data.game.values.world.block.UpdatedTileType;
|
import org.spacehq.mc.protocol.data.game.values.world.block.UpdatedTileType;
|
||||||
import org.spacehq.mc.util.NetUtil;
|
import org.spacehq.mc.protocol.util.NetUtil;
|
||||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.spacehq.mc.protocol.packet.login.client;
|
package org.spacehq.mc.protocol.packet.login.client;
|
||||||
|
|
||||||
import org.spacehq.mc.util.CryptUtil;
|
import org.spacehq.mc.protocol.util.CryptUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.spacehq.mc.protocol.packet.login.server;
|
package org.spacehq.mc.protocol.packet.login.server;
|
||||||
|
|
||||||
import org.spacehq.mc.util.CryptUtil;
|
import org.spacehq.mc.protocol.util.CryptUtil;
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -5,11 +5,11 @@ import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
import org.spacehq.mc.auth.GameProfile;
|
||||||
|
import org.spacehq.mc.auth.util.Base64;
|
||||||
import org.spacehq.mc.protocol.data.message.Message;
|
import org.spacehq.mc.protocol.data.message.Message;
|
||||||
import org.spacehq.mc.protocol.data.status.PlayerInfo;
|
import org.spacehq.mc.protocol.data.status.PlayerInfo;
|
||||||
import org.spacehq.mc.protocol.data.status.ServerStatusInfo;
|
import org.spacehq.mc.protocol.data.status.ServerStatusInfo;
|
||||||
import org.spacehq.mc.protocol.data.status.VersionInfo;
|
import org.spacehq.mc.protocol.data.status.VersionInfo;
|
||||||
import org.spacehq.mc.util.Base64;
|
|
||||||
import org.spacehq.packetlib.io.NetInput;
|
import org.spacehq.packetlib.io.NetInput;
|
||||||
import org.spacehq.packetlib.io.NetOutput;
|
import org.spacehq.packetlib.io.NetOutput;
|
||||||
import org.spacehq.packetlib.packet.Packet;
|
import org.spacehq.packetlib.packet.Packet;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.spacehq.mc.util;
|
package org.spacehq.mc.protocol.util;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.KeyGenerator;
|
import javax.crypto.KeyGenerator;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.spacehq.mc.util;
|
package org.spacehq.mc.protocol.util;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.*;
|
import org.spacehq.mc.protocol.data.game.*;
|
||||||
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
import org.spacehq.mc.protocol.data.game.values.MagicValues;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.spacehq.mc.util;
|
package org.spacehq.mc.protocol.util;
|
||||||
|
|
||||||
public class NetworkChunkData {
|
public class NetworkChunkData {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.spacehq.mc.util;
|
package org.spacehq.mc.protocol.util;
|
||||||
|
|
||||||
import org.spacehq.mc.protocol.data.game.Chunk;
|
import org.spacehq.mc.protocol.data.game.Chunk;
|
||||||
|
|
|
@ -1,176 +0,0 @@
|
||||||
package org.spacehq.mc.util;
|
|
||||||
|
|
||||||
public class Base64 {
|
|
||||||
|
|
||||||
private final static byte EQUALS_SIGN = (byte) '=';
|
|
||||||
private final static byte WHITE_SPACE_ENC = -5;
|
|
||||||
private final static byte EQUALS_SIGN_ENC = -1;
|
|
||||||
private final static byte[] _STANDARD_ALPHABET = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/' };
|
|
||||||
private final static byte[] _STANDARD_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -5, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -5, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, 62, -9, -9, -9, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -9, -9, -9, -1, -9, -9, -9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -9, -9, -9, -9, -9, -9, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 };
|
|
||||||
|
|
||||||
private static byte[] getAlphabet() {
|
|
||||||
return _STANDARD_ALPHABET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] getDecodabet() {
|
|
||||||
return _STANDARD_DECODABET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset) {
|
|
||||||
byte[] ALPHABET = getAlphabet();
|
|
||||||
int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
|
|
||||||
switch(numSigBytes) {
|
|
||||||
case 3:
|
|
||||||
destination[destOffset] = ALPHABET[(inBuff >>> 18)];
|
|
||||||
destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
|
|
||||||
destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
|
|
||||||
destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f];
|
|
||||||
return destination;
|
|
||||||
case 2:
|
|
||||||
destination[destOffset] = ALPHABET[(inBuff >>> 18)];
|
|
||||||
destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
|
|
||||||
destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
|
|
||||||
destination[destOffset + 3] = EQUALS_SIGN;
|
|
||||||
return destination;
|
|
||||||
case 1:
|
|
||||||
destination[destOffset] = ALPHABET[(inBuff >>> 18)];
|
|
||||||
destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
|
|
||||||
destination[destOffset + 2] = EQUALS_SIGN;
|
|
||||||
destination[destOffset + 3] = EQUALS_SIGN;
|
|
||||||
return destination;
|
|
||||||
default:
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] encode(byte[] source) {
|
|
||||||
return encode(source, 0, source.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] encode(byte[] source, int off, int len) {
|
|
||||||
if(source == null) {
|
|
||||||
throw new NullPointerException("Cannot serialize a null array.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(off < 0) {
|
|
||||||
throw new IllegalArgumentException("Cannot have negative offset: " + off);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(len < 0) {
|
|
||||||
throw new IllegalArgumentException("Cannot have length offset: " + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(off + len > source.length) {
|
|
||||||
throw new IllegalArgumentException(String.format("Cannot have offset of %d and length of %d with array of length %d", off, len, source.length));
|
|
||||||
}
|
|
||||||
|
|
||||||
int encLen = (len / 3) * 4 + (len % 3 > 0 ? 4 : 0);
|
|
||||||
byte[] outBuff = new byte[encLen];
|
|
||||||
int d = 0;
|
|
||||||
int e = 0;
|
|
||||||
int len2 = len - 2;
|
|
||||||
for(; d < len2; d += 3, e += 4) {
|
|
||||||
encode3to4(source, d + off, 3, outBuff, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(d < len) {
|
|
||||||
encode3to4(source, d + off, len - d, outBuff, e);
|
|
||||||
e += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e <= outBuff.length - 1) {
|
|
||||||
byte[] finalOut = new byte[e];
|
|
||||||
System.arraycopy(outBuff, 0, finalOut, 0, e);
|
|
||||||
return finalOut;
|
|
||||||
} else {
|
|
||||||
return outBuff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int decode4to3(byte[] source, int srcOffset, byte[] destination, int destOffset) {
|
|
||||||
if(source == null) {
|
|
||||||
throw new NullPointerException("Source array was null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destination == null) {
|
|
||||||
throw new NullPointerException("Destination array was null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(srcOffset < 0 || srcOffset + 3 >= source.length) {
|
|
||||||
throw new IllegalArgumentException(String.format("Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destOffset < 0 || destOffset + 2 >= destination.length) {
|
|
||||||
throw new IllegalArgumentException(String.format("Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] DECODABET = getDecodabet();
|
|
||||||
if(source[srcOffset + 2] == EQUALS_SIGN) {
|
|
||||||
int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12);
|
|
||||||
destination[destOffset] = (byte) (outBuff >>> 16);
|
|
||||||
return 1;
|
|
||||||
} else if(source[srcOffset + 3] == EQUALS_SIGN) {
|
|
||||||
int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6);
|
|
||||||
destination[destOffset] = (byte) (outBuff >>> 16);
|
|
||||||
destination[destOffset + 1] = (byte) (outBuff >>> 8);
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) | ((DECODABET[source[srcOffset + 3]] & 0xFF));
|
|
||||||
destination[destOffset] = (byte) (outBuff >> 16);
|
|
||||||
destination[destOffset + 1] = (byte) (outBuff >> 8);
|
|
||||||
destination[destOffset + 2] = (byte) (outBuff);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] decode(byte[] source) throws java.io.IOException {
|
|
||||||
return decode(source, 0, source.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] decode(byte[] source, int off, int len) throws java.io.IOException {
|
|
||||||
if(source == null) {
|
|
||||||
throw new NullPointerException("Cannot decode null source array.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(off < 0 || off + len > source.length) {
|
|
||||||
throw new IllegalArgumentException(String.format("Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(len == 0) {
|
|
||||||
return new byte[0];
|
|
||||||
} else if(len < 4) {
|
|
||||||
throw new IllegalArgumentException("Base64-encoded string must have at least four characters, but length specified was " + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] DECODABET = getDecodabet();
|
|
||||||
int len34 = len * 3 / 4;
|
|
||||||
byte[] outBuff = new byte[len34];
|
|
||||||
int outBuffPosn = 0;
|
|
||||||
byte[] b4 = new byte[4];
|
|
||||||
int b4Posn = 0;
|
|
||||||
int i = 0;
|
|
||||||
byte sbiDecode = 0;
|
|
||||||
for(i = off; i < off + len; i++) {
|
|
||||||
sbiDecode = DECODABET[source[i] & 0xFF];
|
|
||||||
if(sbiDecode >= WHITE_SPACE_ENC) {
|
|
||||||
if(sbiDecode >= EQUALS_SIGN_ENC) {
|
|
||||||
b4[b4Posn++] = source[i];
|
|
||||||
if(b4Posn > 3) {
|
|
||||||
outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn);
|
|
||||||
b4Posn = 0;
|
|
||||||
if(source[i] == EQUALS_SIGN) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new java.io.IOException(String.format("Bad Base64 input character decimal %d in array position %d", source[i] & 0xFF, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] out = new byte[outBuffPosn];
|
|
||||||
System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package org.spacehq.mc.util;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
public class IOUtils {
|
|
||||||
|
|
||||||
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
|
|
||||||
|
|
||||||
public static void closeQuietly(Closeable close) {
|
|
||||||
try {
|
|
||||||
if(close != null) {
|
|
||||||
close.close();
|
|
||||||
}
|
|
||||||
} catch(IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(InputStream input, String encoding) throws IOException {
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
InputStreamReader in = encoding != null ? new InputStreamReader(input, encoding) : new InputStreamReader(input);
|
|
||||||
char[] buffer = new char[DEFAULT_BUFFER_SIZE];
|
|
||||||
int n = 0;
|
|
||||||
while(-1 != (n = in.read(buffer))) {
|
|
||||||
writer.write(buffer, 0, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
return writer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] toByteArray(InputStream in) throws IOException {
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
byte buffer[] = new byte[DEFAULT_BUFFER_SIZE];
|
|
||||||
int n = 0;
|
|
||||||
while(-1 != (n = in.read(buffer))) {
|
|
||||||
out.write(buffer, 0, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
return out.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,187 +0,0 @@
|
||||||
package org.spacehq.mc.util;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import org.spacehq.mc.auth.GameProfile;
|
|
||||||
import org.spacehq.mc.auth.exception.AuthenticationException;
|
|
||||||
import org.spacehq.mc.auth.exception.AuthenticationUnavailableException;
|
|
||||||
import org.spacehq.mc.auth.exception.InvalidCredentialsException;
|
|
||||||
import org.spacehq.mc.auth.exception.UserMigratedException;
|
|
||||||
import org.spacehq.mc.auth.properties.PropertyMap;
|
|
||||||
import org.spacehq.mc.auth.response.Response;
|
|
||||||
import org.spacehq.mc.auth.serialize.GameProfileSerializer;
|
|
||||||
import org.spacehq.mc.auth.serialize.PropertyMapSerializer;
|
|
||||||
import org.spacehq.mc.auth.serialize.UUIDSerializer;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class URLUtils {
|
|
||||||
|
|
||||||
private static final Gson GSON;
|
|
||||||
|
|
||||||
static {
|
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
builder.registerTypeAdapter(GameProfile.class, new GameProfileSerializer());
|
|
||||||
builder.registerTypeAdapter(PropertyMap.class, new PropertyMapSerializer());
|
|
||||||
builder.registerTypeAdapter(UUID.class, new UUIDSerializer());
|
|
||||||
GSON = builder.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static URL constantURL(String url) {
|
|
||||||
try {
|
|
||||||
return new URL(url);
|
|
||||||
} catch(MalformedURLException e) {
|
|
||||||
throw new Error("Malformed constant url: " + url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static URL concatenateURL(URL url, String query) {
|
|
||||||
try {
|
|
||||||
return url.getQuery() != null && url.getQuery().length() > 0 ? new URL(url.getProtocol(), url.getHost(), url.getFile() + "&" + query) : new URL(url.getProtocol(), url.getHost(), url.getFile() + "?" + query);
|
|
||||||
} catch(MalformedURLException e) {
|
|
||||||
throw new IllegalArgumentException("Concatenated URL was malformed: " + url.toString() + ", " + query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String buildQuery(Map<String, Object> query) {
|
|
||||||
if(query == null) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
Iterator<Entry<String, Object>> it = query.entrySet().iterator();
|
|
||||||
while(it.hasNext()) {
|
|
||||||
Entry<String, Object> entry = it.next();
|
|
||||||
if(builder.length() > 0) {
|
|
||||||
builder.append("&");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
builder.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
|
|
||||||
} catch(UnsupportedEncodingException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if(entry.getValue() != null) {
|
|
||||||
builder.append("=");
|
|
||||||
try {
|
|
||||||
builder.append(URLEncoder.encode(entry.getValue().toString(), "UTF-8"));
|
|
||||||
} catch(UnsupportedEncodingException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends Response> T makeRequest(URL url, Object input, Class<T> clazz) throws AuthenticationException {
|
|
||||||
try {
|
|
||||||
String jsonString = input == null ? performGetRequest(url) : performPostRequest(url, GSON.toJson(input), "application/json");
|
|
||||||
T result = GSON.fromJson(jsonString, clazz);
|
|
||||||
if(result == null) {
|
|
||||||
return null;
|
|
||||||
} else if(result.getError() != null && !result.getError().equals("")) {
|
|
||||||
if(result.getCause() != null && result.getCause().equals("UserMigratedException")) {
|
|
||||||
throw new UserMigratedException(result.getErrorMessage());
|
|
||||||
} else if(result.getError().equals("ForbiddenOperationException")) {
|
|
||||||
throw new InvalidCredentialsException(result.getErrorMessage());
|
|
||||||
} else {
|
|
||||||
throw new AuthenticationException(result.getErrorMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
} catch(Exception e) {
|
|
||||||
throw new AuthenticationUnavailableException("Could not make request to auth server.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpURLConnection createUrlConnection(URL url) throws IOException {
|
|
||||||
if(url == null) {
|
|
||||||
throw new IllegalArgumentException("URL cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
||||||
connection.setConnectTimeout(15000);
|
|
||||||
connection.setReadTimeout(15000);
|
|
||||||
connection.setUseCaches(false);
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String performPostRequest(URL url, String post, String type) throws IOException {
|
|
||||||
if(url == null) {
|
|
||||||
throw new IllegalArgumentException("URL cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(post == null) {
|
|
||||||
throw new IllegalArgumentException("Post cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(type == null) {
|
|
||||||
throw new IllegalArgumentException("Type cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpURLConnection connection = createUrlConnection(url);
|
|
||||||
byte[] bytes = post.getBytes("UTF-8");
|
|
||||||
connection.setRequestProperty("Content-Type", type + "; charset=utf-8");
|
|
||||||
connection.setRequestProperty("Content-Length", "" + bytes.length);
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
OutputStream outputStream = null;
|
|
||||||
try {
|
|
||||||
outputStream = connection.getOutputStream();
|
|
||||||
outputStream.write(bytes);
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(outputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = connection.getInputStream();
|
|
||||||
return IOUtils.toString(inputStream, "UTF-8");
|
|
||||||
} catch(IOException e) {
|
|
||||||
IOUtils.closeQuietly(inputStream);
|
|
||||||
inputStream = connection.getErrorStream();
|
|
||||||
if(inputStream == null) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IOUtils.toString(inputStream, "UTF-8");
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(inputStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String performGetRequest(URL url) throws IOException {
|
|
||||||
if(url == null) {
|
|
||||||
throw new IllegalArgumentException("URL cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpURLConnection connection = createUrlConnection(url);
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = connection.getInputStream();
|
|
||||||
return IOUtils.toString(inputStream, "UTF-8");
|
|
||||||
} catch(IOException e) {
|
|
||||||
IOUtils.closeQuietly(inputStream);
|
|
||||||
inputStream = connection.getErrorStream();
|
|
||||||
if(inputStream == null) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IOUtils.toString(inputStream, "UTF-8");
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(inputStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Binary file not shown.
Loading…
Reference in a new issue