Rewrite of library for 1.7.2. Javadocs coming soon

This commit is contained in:
Steveice10 2013-12-14 16:40:30 -08:00
parent cea0d82ed4
commit 4088aacd0a
279 changed files with 11865 additions and 10032 deletions

View file

@ -1,4 +1,4 @@
Copyright (C) 2012 Steveice10
Copyright (C) 2013 Steveice10
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View file

@ -1,37 +1,28 @@
<b><center><h1>mc-protocol-lib</h></center></b>
<b><center><h1>MCProtocolLib</h></center></b>
==========
<b>About mc-protocol-lib</b>
<b>About MCProtocolLib</b>
--------
mc-protocol-lib 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, ch.spacebase.mc.auth and ch.spacebase.mc.protocol. The auth package contains some classes to work with Mojang's auth servers and the protocol package contains the protocol library.
<b>Server List Ping</b>
<b>Example Code</b>
--------
When you receive a server list ping packet when listening to a server, respond by calling connection.disconnect(Util.formatPingResponse(motd, players, maxplayers));
When you are sending a ping request, do the following:
connection.send(new PacketServerPing());
connection.send(Util.prepareClientPingData(connection.getHost(), connection.getPort()));
<b>Chat Bot Example</b>
--------
See ch.spacebase.mcprotocol.example.ChatBot
See ch.spacebase.mc.protocol.test.Test.
<b>Building the Source</b>
--------
mc-protocol-lib uses Maven to manage dependencies. Simply run 'mvn clean install' in the source's directory.
MCProtocolLib uses Maven to manage dependencies. Simply run 'mvn clean install' in the source's directory.
<b>License</b>
---------
mc-protocol-lib is licensed under the <b>[MIT license](http://www.opensource.org/licenses/mit-license.html)</b>.
MCProtocolLib is licensed under the <b>[MIT license](http://www.opensource.org/licenses/mit-license.html)</b>.

47
pom.xml
View file

@ -1,13 +1,15 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.spacebase</groupId>
<artifactId>mc-protocol-lib</artifactId>
<version>dev-SNAPSHOT</version>
<artifactId>mcprotocollib</artifactId>
<version>1.7.2-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mc-protocol-lib</name>
<name>MCProtocolLib</name>
<description>A library for communicating with a Minecraft client or server.</description>
<url>http://github.com/Steveice10/mc-protocol-lib/</url>
<url>http://github.com/Steveice10/MCProtocolLib/</url>
<licenses>
<license>
@ -18,9 +20,9 @@
</licenses>
<scm>
<connection>scm:git:git@github.com:Steveice10/mc-protocol-lib.git</connection>
<developerConnection>scm:git:git@github.com:Steveice10/mc-protocol-lib.git</developerConnection>
<url>git@github.com:Steveice10/mc-protocol-lib/</url>
<connection>scm:git:git@github.com:Steveice10/MCProtocolLib.git</connection>
<developerConnection>scm:git:git@github.com:Steveice10/MCProtocolLib.git</developerConnection>
<url>git@github.com:Steveice10/MCProtocolLib/</url>
</scm>
<distributionManagement>
@ -44,6 +46,17 @@
</developer>
</developers>
<repositories>
<repository>
<id>spacebase-releases</id>
<url>http://repo.spacebase.ch/content/repositories/release/</url>
</repository>
<repository>
<id>spacebase-snapshots</id>
<url>http://repo.spacebase.ch/content/repositories/snapshots/</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@ -51,9 +64,21 @@
<!-- Dependencies -->
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.47</version>
<groupId>ch.spacebase</groupId>
<artifactId>opennbt</artifactId>
<version>1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.spacebase</groupId>
<artifactId>packetlib</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
</dependencies>

View file

@ -0,0 +1,141 @@
package ch.spacebase.mc.auth;
import ch.spacebase.mc.auth.SessionService;
import ch.spacebase.mc.auth.UserAuthentication;
import ch.spacebase.mc.auth.exceptions.AuthenticationException;
import ch.spacebase.mc.auth.exceptions.AuthenticationUnavailableException;
import ch.spacebase.mc.auth.exceptions.InvalidCredentialsException;
import ch.spacebase.mc.auth.exceptions.UserMigratedException;
import ch.spacebase.mc.auth.response.Response;
import ch.spacebase.mc.util.IOUtils;
import com.google.gson.Gson;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class AuthenticationService {
private String clientToken;
private Gson gson = new Gson();
public AuthenticationService(String clientToken) {
this.clientToken = clientToken;
}
public UserAuthentication createUserAuthentication() {
return new UserAuthentication(this);
}
public SessionService createMinecraftSessionService() {
return new SessionService(this);
}
public String getClientToken() {
return this.clientToken;
}
public <T extends Response> T makeRequest(URL url, Object input, Class<T> clazz) throws AuthenticationException {
try {
String jsonString = input == null ? this.performGetRequest(url) : this.performPostRequest(url, this.gson.toJson(input), "application/json");
T result = this.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 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 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 = this.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 String performGetRequest(URL url) throws IOException {
if(url == null) {
throw new IllegalArgumentException("URL cannot be null.");
}
HttpURLConnection connection = this.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);
}
}
}

View file

@ -0,0 +1,53 @@
package ch.spacebase.mc.auth;
public class GameProfile {
private String id;
private String name;
public GameProfile(String id, String name) {
if((id == null || id.equals("")) && (name == null || name.equals(""))) {
throw new IllegalArgumentException("Name and ID cannot both be blank");
} else {
this.id = id;
this.name = name;
}
}
public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
public boolean isComplete() {
return this.id != null && !this.id.equals("") && 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.equals(that.id) ? false : this.name.equals(that.name);
} else {
return false;
}
}
@Override
public int hashCode() {
int result = this.id.hashCode();
result = 31 * result + this.name.hashCode();
return result;
}
@Override
public String toString() {
return "GameProfile{id=\'" + this.id + '\'' + ", name=\'" + this.name + '\'' + '}';
}
}

View file

@ -0,0 +1,51 @@
package ch.spacebase.mc.auth;
import ch.spacebase.mc.auth.AuthenticationService;
import ch.spacebase.mc.auth.exceptions.AuthenticationException;
import ch.spacebase.mc.auth.exceptions.AuthenticationUnavailableException;
import ch.spacebase.mc.auth.request.JoinServerRequest;
import ch.spacebase.mc.auth.response.HasJoinedResponse;
import ch.spacebase.mc.auth.response.Response;
import ch.spacebase.mc.util.URLUtils;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
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 AuthenticationService authService;
protected SessionService(AuthenticationService authService) {
this.authService = authService;
}
public void joinServer(GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
JoinServerRequest request = new JoinServerRequest(authenticationToken, profile.getId(), serverId);
this.getAuthenticationService().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 e = this.getAuthenticationService().makeRequest(url, null, HasJoinedResponse.class);
return e != null && e.getId() != null ? new GameProfile(e.getId(), user.getName()) : null;
} catch(AuthenticationUnavailableException var6) {
throw var6;
} catch(AuthenticationException var7) {
return null;
}
}
public AuthenticationService getAuthenticationService() {
return this.authService;
}
}

View file

@ -0,0 +1,264 @@
package ch.spacebase.mc.auth;
import ch.spacebase.mc.auth.AuthenticationService;
import ch.spacebase.mc.auth.exceptions.AuthenticationException;
import ch.spacebase.mc.auth.exceptions.InvalidCredentialsException;
import ch.spacebase.mc.auth.request.AuthenticationRequest;
import ch.spacebase.mc.auth.request.RefreshRequest;
import ch.spacebase.mc.auth.response.AuthenticationResponse;
import ch.spacebase.mc.auth.response.RefreshResponse;
import ch.spacebase.mc.auth.response.User;
import ch.spacebase.mc.util.URLUtils;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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_USER_NAME = "username";
private static final String STORAGE_KEY_USER_ID = "userid";
private static final String STORAGE_KEY_ACCESS_TOKEN = "accessToken";
private AuthenticationService authService;
private Map<String, String> userProperties = new HashMap<String, String>();
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;
public UserAuthentication(AuthenticationService authService) {
if(authService == null) {
throw new IllegalArgumentException("AuthService cannot be null.");
}
this.authService = authService;
}
public AuthenticationService getAuthenticationService() {
return this.authService;
}
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 Map<String, String> getUserProperties() {
return this.isLoggedIn() ? Collections.unmodifiableMap(this.userProperties) : Collections.unmodifiableMap(new HashMap<String, String>());
}
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 loadFromStorage(Map<String, String> credentials) {
this.logOut();
this.setUsername(credentials.get(STORAGE_KEY_USER_NAME));
if(credentials.containsKey(STORAGE_KEY_USER_ID)) {
this.userId = credentials.get(STORAGE_KEY_USER_ID);
} else {
this.userId = this.username;
}
if(credentials.containsKey(STORAGE_KEY_PROFILE_NAME) && credentials.containsKey(STORAGE_KEY_PROFILE_ID)) {
this.selectedProfile = new GameProfile(credentials.get(STORAGE_KEY_PROFILE_ID), credentials.get(STORAGE_KEY_PROFILE_NAME));
}
this.accessToken = credentials.get(STORAGE_KEY_ACCESS_TOKEN);
}
public Map<String, String> saveForStorage() {
Map<String, String> result = new HashMap<String, String>();
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.selectedProfile != null) {
result.put(STORAGE_KEY_PROFILE_NAME, this.selectedProfile.getName());
result.put(STORAGE_KEY_PROFILE_ID, this.selectedProfile.getId());
}
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();
}
}
}
protected 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 = this.authService.makeRequest(ROUTE_AUTHENTICATE, request, AuthenticationResponse.class);
if(!response.getClientToken().equals(this.getAuthenticationService().getClientToken())) {
throw new AuthenticationException("Server requested we change our client token. Don\'t know how to handle this!");
} else {
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.userProperties.clear();
if(response.getUser() != null && response.getUser().getProperties() != null) {
Iterator<User.Property> it = response.getUser().getProperties().iterator();
while(it.hasNext()) {
User.Property property = it.next();
this.userProperties.put(property.getKey(), property.getValue());
}
}
}
}
}
protected 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 = this.getAuthenticationService().makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
if(!response.getClientToken().equals(this.getAuthenticationService().getClientToken())) {
throw new AuthenticationException("Server requested we change our client token. Don\'t know how to handle this!");
} else {
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.userProperties.clear();
if(response.getUser() != null && response.getUser().getProperties() != null) {
Iterator<User.Property> it = response.getUser().getProperties().iterator();
while(it.hasNext()) {
User.Property property = it.next();
this.userProperties.put(property.getKey(), property.getValue());
}
}
}
}
}
public void logOut() {
this.password = null;
this.userId = null;
this.selectedProfile = null;
this.userProperties.clear();
this.accessToken = null;
this.profiles = null;
this.isOnline = false;
}
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 = this.getAuthenticationService().makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
if(!response.getClientToken().equals(this.getAuthenticationService().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 "AuthenticationService{profiles=" + this.profiles + ", selectedProfile=" + this.getSelectedProfile() + ", username=" + this.username + ", isLoggedIn=" + this.isLoggedIn() + ", canPlayOnline=" + this.canPlayOnline() + ", accessToken=" + this.accessToken + ", clientToken=" + this.authService.getClientToken() + "}";
}
}

View file

@ -0,0 +1,22 @@
package ch.spacebase.mc.auth.exceptions;
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);
}
}

View file

@ -0,0 +1,23 @@
package ch.spacebase.mc.auth.exceptions;
import ch.spacebase.mc.auth.exceptions.AuthenticationException;
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);
}
}

View file

@ -0,0 +1,23 @@
package ch.spacebase.mc.auth.exceptions;
import ch.spacebase.mc.auth.exceptions.AuthenticationException;
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);
}
}

View file

@ -0,0 +1,23 @@
package ch.spacebase.mc.auth.exceptions;
import ch.spacebase.mc.auth.exceptions.InvalidCredentialsException;
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);
}
}

View file

@ -0,0 +1,25 @@
package ch.spacebase.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;
}
public String toString() {
return "Agent{name=\'" + this.name + '\'' + ", version=" + this.version + '}';
}
}

View file

@ -0,0 +1,21 @@
package ch.spacebase.mc.auth.request;
import ch.spacebase.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.getAuthenticationService().getClientToken();
this.password = password;
}
}

View file

@ -0,0 +1,16 @@
package ch.spacebase.mc.auth.request;
@SuppressWarnings("unused")
public class JoinServerRequest {
private String accessToken;
private String selectedProfile;
private String serverId;
public JoinServerRequest(String accessToken, String id, String serverId) {
this.accessToken = accessToken;
this.selectedProfile = id;
this.serverId = serverId;
}
}

View file

@ -0,0 +1,25 @@
package ch.spacebase.mc.auth.request;
import ch.spacebase.mc.auth.GameProfile;
import ch.spacebase.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.getAuthenticationService().getClientToken();
this.accessToken = authService.getAccessToken();
this.selectedProfile = profile;
}
}

View file

@ -0,0 +1,35 @@
package ch.spacebase.mc.auth.response;
import ch.spacebase.mc.auth.GameProfile;
import ch.spacebase.mc.auth.response.Response;
import ch.spacebase.mc.auth.response.User;
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;
}
}

View file

@ -0,0 +1,13 @@
package ch.spacebase.mc.auth.response;
import ch.spacebase.mc.auth.response.Response;
public class HasJoinedResponse extends Response {
private String id;
public String getId() {
return this.id;
}
}

View file

@ -0,0 +1,35 @@
package ch.spacebase.mc.auth.response;
import ch.spacebase.mc.auth.GameProfile;
import ch.spacebase.mc.auth.response.Response;
import ch.spacebase.mc.auth.response.User;
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;
}
}

View file

@ -0,0 +1,21 @@
package ch.spacebase.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;
}
}

View file

@ -0,0 +1,31 @@
package ch.spacebase.mc.auth.response;
import java.util.List;
public class User {
private String id;
private List<Property> properties;
public String getId() {
return this.id;
}
public List<Property> getProperties() {
return this.properties;
}
public class Property {
private String name;
private String value;
public String getKey() {
return this.name;
}
public String getValue() {
return this.value;
}
}
}

View file

@ -0,0 +1,133 @@
package ch.spacebase.mc.protocol;
import java.math.BigInteger;
import javax.crypto.SecretKey;
import ch.spacebase.mc.auth.AuthenticationService;
import ch.spacebase.mc.auth.GameProfile;
import ch.spacebase.mc.auth.exceptions.AuthenticationException;
import ch.spacebase.mc.auth.exceptions.AuthenticationUnavailableException;
import ch.spacebase.mc.auth.exceptions.InvalidCredentialsException;
import ch.spacebase.mc.protocol.data.status.ServerStatusInfo;
import ch.spacebase.mc.protocol.data.status.handler.ServerInfoHandler;
import ch.spacebase.mc.protocol.data.status.handler.ServerPingTimeHandler;
import ch.spacebase.mc.protocol.packet.handshake.client.HandshakePacket;
import ch.spacebase.mc.protocol.packet.ingame.client.ClientKeepAlivePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerDisconnectPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerKeepAlivePacket;
import ch.spacebase.mc.protocol.packet.login.client.EncryptionResponsePacket;
import ch.spacebase.mc.protocol.packet.login.client.LoginStartPacket;
import ch.spacebase.mc.protocol.packet.login.server.EncryptionRequestPacket;
import ch.spacebase.mc.protocol.packet.login.server.LoginDisconnectPacket;
import ch.spacebase.mc.protocol.packet.login.server.LoginSuccessPacket;
import ch.spacebase.mc.protocol.packet.status.client.StatusPingPacket;
import ch.spacebase.mc.protocol.packet.status.client.StatusQueryPacket;
import ch.spacebase.mc.protocol.packet.status.server.StatusPongPacket;
import ch.spacebase.mc.protocol.packet.status.server.StatusResponsePacket;
import ch.spacebase.mc.util.CryptUtil;
import ch.spacebase.packetlib.event.session.ConnectedEvent;
import ch.spacebase.packetlib.event.session.PacketReceivedEvent;
import ch.spacebase.packetlib.event.session.PacketSentEvent;
import ch.spacebase.packetlib.event.session.SessionAdapter;
public class ClientListener extends SessionAdapter {
private SecretKey key;
private String accessToken;
private String clientToken;
public ClientListener(String accessToken, String clientToken) {
this.accessToken = accessToken;
this.clientToken = clientToken;
}
@Override
public void packetReceived(PacketReceivedEvent event) {
MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol();
if(protocol.getMode() == ProtocolMode.LOGIN) {
if(event.getPacket() instanceof EncryptionRequestPacket) {
EncryptionRequestPacket packet = event.getPacket();
this.key = CryptUtil.generateSharedKey();
GameProfile profile = event.getSession().getFlag(ProtocolConstants.PROFILE_KEY);
String serverHash = new BigInteger(CryptUtil.getServerIdHash(packet.getServerId(), packet.getPublicKey(), this.key)).toString(16);
try {
new AuthenticationService(this.clientToken).createMinecraftSessionService().joinServer(profile, this.accessToken, serverHash);
} catch(AuthenticationUnavailableException e) {
event.getSession().disconnect("Login failed: Authentication service unavailable.");
return;
} catch(InvalidCredentialsException e) {
event.getSession().disconnect("Login failed: Invalid login session.");
return;
} catch(AuthenticationException e) {
event.getSession().disconnect("Login failed: Authentication error: " + e.getMessage());
return;
}
event.getSession().send(new EncryptionResponsePacket(this.key, packet.getPublicKey(), packet.getVerifyToken()));
} else if(event.getPacket() instanceof LoginSuccessPacket) {
LoginSuccessPacket packet = event.getPacket();
event.getSession().setFlag(ProtocolConstants.PROFILE_KEY, new GameProfile(packet.getPlayerId(), packet.getUsername()));
protocol.setMode(ProtocolMode.GAME, true, event.getSession());
} else if(event.getPacket() instanceof LoginDisconnectPacket) {
LoginDisconnectPacket packet = event.getPacket();
event.getSession().disconnect(packet.getReason().toString());
}
}
if(protocol.getMode() == ProtocolMode.STATUS) {
if(event.getPacket() instanceof StatusResponsePacket) {
ServerStatusInfo info = event.<StatusResponsePacket>getPacket().getInfo();
ServerInfoHandler handler = event.getSession().getFlag(ProtocolConstants.SERVER_INFO_HANDLER_KEY);
if(handler != null) {
handler.handle(info);
}
event.getSession().send(new StatusPingPacket(System.nanoTime() / 1000000));
} else if(event.getPacket() instanceof StatusPongPacket) {
long time = System.nanoTime() / 1000000 - event.<StatusPongPacket>getPacket().getPingTime();
ServerPingTimeHandler handler = event.getSession().getFlag(ProtocolConstants.SERVER_PING_TIME_HANDLER_KEY);
if(handler != null) {
handler.handle(time);
}
event.getSession().disconnect("Finished");
}
}
if(protocol.getMode() == ProtocolMode.GAME) {
if(event.getPacket() instanceof ServerKeepAlivePacket) {
event.getSession().send(new ClientKeepAlivePacket(event.<ServerKeepAlivePacket>getPacket().getPingId()));
} else if(event.getPacket() instanceof ServerDisconnectPacket) {
event.getSession().disconnect(event.<ServerDisconnectPacket>getPacket().getReason().toString());
}
}
}
@Override
public void packetSent(PacketSentEvent event) {
MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol();
if(protocol.getMode() == ProtocolMode.LOGIN && event.getPacket() instanceof EncryptionResponsePacket) {
protocol.enableEncryption(this.key);
}
}
@Override
public void connected(ConnectedEvent event) {
MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol();
if(protocol.getMode() == ProtocolMode.LOGIN) {
GameProfile profile = event.getSession().getFlag(ProtocolConstants.PROFILE_KEY);
protocol.setMode(ProtocolMode.HANDSHAKE, true, event.getSession());
event.getSession().send(new HandshakePacket(ProtocolConstants.PROTOCOL_VERSION, event.getSession().getHost(), event.getSession().getPort(), 2));
protocol.setMode(ProtocolMode.LOGIN, true, event.getSession());
event.getSession().send(new LoginStartPacket(profile != null ? profile.getName() : ""));
} else if(protocol.getMode() == ProtocolMode.STATUS) {
protocol.setMode(ProtocolMode.HANDSHAKE, true, event.getSession());
event.getSession().send(new HandshakePacket(ProtocolConstants.PROTOCOL_VERSION, event.getSession().getHost(), event.getSession().getPort(), 1));
protocol.setMode(ProtocolMode.STATUS, true, event.getSession());
event.getSession().send(new StatusQueryPacket());
}
}
}

View file

@ -0,0 +1,461 @@
package ch.spacebase.mc.protocol;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.util.UUID;
import ch.spacebase.mc.auth.AuthenticationService;
import ch.spacebase.mc.auth.GameProfile;
import ch.spacebase.mc.auth.UserAuthentication;
import ch.spacebase.mc.auth.exceptions.AuthenticationException;
import ch.spacebase.mc.protocol.packet.handshake.client.HandshakePacket;
import ch.spacebase.mc.protocol.packet.ingame.client.ClientChatPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.ClientKeepAlivePacket;
import ch.spacebase.mc.protocol.packet.ingame.client.ClientPluginMessagePacket;
import ch.spacebase.mc.protocol.packet.ingame.client.ClientRequestPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.ClientSettingsPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.ClientTabCompletePacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.ClientAnimationPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.ClientEntityActionPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.ClientEntityInteractPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientChangeHeldItemPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientPlayerAbilitiesPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientPlayerDigPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientPlayerMovementPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientPlayerPlaceBlockPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientPlayerPositionPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientPlayerPositionRotationPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientPlayerRotationPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.entity.player.ClientSteerVehiclePacket;
import ch.spacebase.mc.protocol.packet.ingame.client.window.ClientCloseWindowPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.window.ClientConfirmTransactionPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.window.ClientCreativeInventoryActionPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.window.ClientEnchantItemPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.window.ClientWindowActionPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.world.ClientUpdateSignPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerChatPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerDisconnectPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerKeepAlivePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerPlayerListEntryPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerPluginMessagePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerRespawnPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerStatisticsPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerTabCompletePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerAnimationPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerCollectItemPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerDestroyEntitiesPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityAttachPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityEffectPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityEquipmentPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityHeadLookPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityMetadataPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityMovementPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityPositionPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityPropertiesPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityRotationPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.ServerRemoveEffectPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.player.ServerChangeHeldItemPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.player.ServerPlayerAbilitiesPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.player.ServerPlayerUseBedPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.player.ServerSetExperiencePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.player.ServerUpdateHealthPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnExpOrbPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnGlobalEntityPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnMobPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnObjectPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPaintingPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPlayerPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.scoreboard.ServerDisplayScoreboardPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.scoreboard.ServerScoreboardObjectivePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.scoreboard.ServerTeamPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.scoreboard.ServerUpdateScorePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.window.ServerCloseWindowPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.window.ServerConfirmTransactionPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.window.ServerOpenWindowPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.window.ServerSetSlotPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.window.ServerWindowItemsPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.window.ServerWindowPropertyPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerBlockBreakAnimPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerBlockChangePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerBlockValuePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerChunkDataPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerExplosionPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerMapDataPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerMultiBlockChangePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerMultiChunkDataPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerOpenTileEntityEditorPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerPlayEffectPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerPlaySoundPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerUpdateSignPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerSpawnPositionPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerUpdateTileEntityPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.world.ServerUpdateTimePacket;
import ch.spacebase.mc.protocol.packet.login.client.EncryptionResponsePacket;
import ch.spacebase.mc.protocol.packet.login.client.LoginStartPacket;
import ch.spacebase.mc.protocol.packet.login.server.EncryptionRequestPacket;
import ch.spacebase.mc.protocol.packet.login.server.LoginDisconnectPacket;
import ch.spacebase.mc.protocol.packet.login.server.LoginSuccessPacket;
import ch.spacebase.mc.protocol.packet.status.client.StatusPingPacket;
import ch.spacebase.mc.protocol.packet.status.client.StatusQueryPacket;
import ch.spacebase.mc.protocol.packet.status.server.StatusPongPacket;
import ch.spacebase.mc.protocol.packet.status.server.StatusResponsePacket;
import ch.spacebase.packetlib.Client;
import ch.spacebase.packetlib.Server;
import ch.spacebase.packetlib.Session;
import ch.spacebase.packetlib.crypt.AESEncryption;
import ch.spacebase.packetlib.crypt.PacketEncryption;
import ch.spacebase.packetlib.packet.PacketProtocol;
public class MinecraftProtocol extends PacketProtocol {
private ProtocolMode mode = ProtocolMode.HANDSHAKE;
private AESEncryption encrypt = null;
private GameProfile profile = null;
private ClientListener clientListener = null;
@SuppressWarnings("unused")
private MinecraftProtocol() {
}
public MinecraftProtocol(ProtocolMode mode) {
if(mode != ProtocolMode.LOGIN && mode != ProtocolMode.STATUS) {
throw new IllegalArgumentException("Only login and status modes are permitted.");
}
this.mode = mode;
if(mode == ProtocolMode.LOGIN) {
this.profile = new GameProfile("", "Player");
}
this.clientListener = new ClientListener("", UUID.randomUUID().toString());
}
public MinecraftProtocol(String username) {
this(ProtocolMode.LOGIN);
this.profile = new GameProfile("", username);
this.clientListener = new ClientListener("", UUID.randomUUID().toString());
}
public MinecraftProtocol(String username, String password) throws AuthenticationException {
this(ProtocolMode.LOGIN);
String clientToken = UUID.randomUUID().toString();
UserAuthentication auth = new AuthenticationService(clientToken).createUserAuthentication();
auth.setUsername(username);
auth.setPassword(password);
auth.logIn();
this.profile = auth.getSelectedProfile();
this.clientListener = new ClientListener(auth.getAccessToken(), clientToken);
}
@Override
public PacketEncryption getEncryption() {
return this.encrypt;
}
@Override
public void newClientSession(Client client, Session session) {
if(this.profile != null) {
session.setFlag(ProtocolConstants.PROFILE_KEY, this.profile);
}
this.setMode(this.mode, true, session);
session.addListener(this.clientListener);
}
@Override
public void newServerSession(Server server, Session session) {
this.setMode(ProtocolMode.HANDSHAKE, false, session);
session.addListener(new ServerListener());
}
protected void enableEncryption(Key key) {
try {
this.encrypt = new AESEncryption(key);
} catch(GeneralSecurityException e) {
System.err.println("Could not enable protocol encryption!");
e.printStackTrace();
}
}
public ProtocolMode getMode() {
return this.mode;
}
protected void setMode(ProtocolMode mode, boolean client, Session session) {
this.clearPackets();
switch(mode) {
case HANDSHAKE:
if(client) {
this.initClientHandshake(session);
} else {
this.initServerHandshake(session);
}
break;
case LOGIN:
if(client) {
this.initClientLogin(session);
} else {
this.initServerLogin(session);
}
break;
case GAME:
if(client) {
this.initClientGame(session);
} else {
this.initServerGame(session);
}
break;
case STATUS:
if(client) {
this.initClientStatus(session);
} else {
this.initServerStatus(session);
}
break;
}
this.mode = mode;
}
private void initClientHandshake(Session session) {
this.registerOutgoing(0, HandshakePacket.class);
}
private void initServerHandshake(Session session) {
this.registerIncoming(0, HandshakePacket.class);
}
private void initClientLogin(Session session) {
this.registerIncoming(0, LoginDisconnectPacket.class);
this.registerIncoming(1, EncryptionRequestPacket.class);
this.registerIncoming(2, LoginSuccessPacket.class);
this.registerOutgoing(0, LoginStartPacket.class);
this.registerOutgoing(1, EncryptionResponsePacket.class);
}
private void initServerLogin(Session session) {
this.registerIncoming(0, LoginStartPacket.class);
this.registerIncoming(1, EncryptionResponsePacket.class);
this.registerOutgoing(0, LoginDisconnectPacket.class);
this.registerOutgoing(1, EncryptionRequestPacket.class);
this.registerOutgoing(2, LoginSuccessPacket.class);
}
private void initClientGame(Session session) {
this.registerIncoming(0, ServerKeepAlivePacket.class);
this.registerIncoming(1, ServerJoinGamePacket.class);
this.registerIncoming(2, ServerChatPacket.class);
this.registerIncoming(3, ServerUpdateTimePacket.class);
this.registerIncoming(4, ServerEntityEquipmentPacket.class);
this.registerIncoming(5, ServerSpawnPositionPacket.class);
this.registerIncoming(6, ServerUpdateHealthPacket.class);
this.registerIncoming(7, ServerRespawnPacket.class);
this.registerIncoming(8, ServerPlayerPositionRotationPacket.class);
this.registerIncoming(9, ServerChangeHeldItemPacket.class);
this.registerIncoming(10, ServerPlayerUseBedPacket.class);
this.registerIncoming(11, ServerAnimationPacket.class);
this.registerIncoming(12, ServerSpawnPlayerPacket.class);
this.registerIncoming(13, ServerCollectItemPacket.class);
this.registerIncoming(14, ServerSpawnObjectPacket.class);
this.registerIncoming(15, ServerSpawnMobPacket.class);
this.registerIncoming(16, ServerSpawnPaintingPacket.class);
this.registerIncoming(17, ServerSpawnExpOrbPacket.class);
this.registerIncoming(18, ServerEntityVelocityPacket.class);
this.registerIncoming(19, ServerDestroyEntitiesPacket.class);
this.registerIncoming(20, ServerEntityMovementPacket.class);
this.registerIncoming(21, ServerEntityPositionPacket.class);
this.registerIncoming(22, ServerEntityRotationPacket.class);
this.registerIncoming(23, ServerEntityPositionRotationPacket.class);
this.registerIncoming(24, ServerEntityTeleportPacket.class);
this.registerIncoming(25, ServerEntityHeadLookPacket.class);
this.registerIncoming(26, ServerEntityStatusPacket.class);
this.registerIncoming(27, ServerEntityAttachPacket.class);
this.registerIncoming(28, ServerEntityMetadataPacket.class);
this.registerIncoming(29, ServerEntityEffectPacket.class);
this.registerIncoming(30, ServerRemoveEffectPacket.class);
this.registerIncoming(31, ServerSetExperiencePacket.class);
this.registerIncoming(32, ServerEntityPropertiesPacket.class);
this.registerIncoming(33, ServerChunkDataPacket.class);
this.registerIncoming(34, ServerMultiBlockChangePacket.class);
this.registerIncoming(35, ServerBlockChangePacket.class);
this.registerIncoming(36, ServerBlockValuePacket.class);
this.registerIncoming(37, ServerBlockBreakAnimPacket.class);
this.registerIncoming(38, ServerMultiChunkDataPacket.class);
this.registerIncoming(39, ServerExplosionPacket.class);
this.registerIncoming(40, ServerPlayEffectPacket.class);
this.registerIncoming(41, ServerPlaySoundPacket.class);
this.registerIncoming(42, ServerSpawnParticlePacket.class);
this.registerIncoming(43, ServerNotifyClientPacket.class);
this.registerIncoming(44, ServerSpawnGlobalEntityPacket.class);
this.registerIncoming(45, ServerOpenWindowPacket.class);
this.registerIncoming(46, ServerCloseWindowPacket.class);
this.registerIncoming(47, ServerSetSlotPacket.class);
this.registerIncoming(48, ServerWindowItemsPacket.class);
this.registerIncoming(49, ServerWindowPropertyPacket.class);
this.registerIncoming(50, ServerConfirmTransactionPacket.class);
this.registerIncoming(51, ServerUpdateSignPacket.class);
this.registerIncoming(52, ServerMapDataPacket.class);
this.registerIncoming(53, ServerUpdateTileEntityPacket.class);
this.registerIncoming(54, ServerOpenTileEntityEditorPacket.class);
this.registerIncoming(55, ServerStatisticsPacket.class);
this.registerIncoming(56, ServerPlayerListEntryPacket.class);
this.registerIncoming(57, ServerPlayerAbilitiesPacket.class);
this.registerIncoming(58, ServerTabCompletePacket.class);
this.registerIncoming(59, ServerScoreboardObjectivePacket.class);
this.registerIncoming(60, ServerUpdateScorePacket.class);
this.registerIncoming(61, ServerDisplayScoreboardPacket.class);
this.registerIncoming(62, ServerTeamPacket.class);
this.registerIncoming(63, ServerPluginMessagePacket.class);
this.registerIncoming(64, ServerDisconnectPacket.class);
this.registerOutgoing(0, ClientKeepAlivePacket.class);
this.registerOutgoing(1, ClientChatPacket.class);
this.registerOutgoing(2, ClientEntityInteractPacket.class);
this.registerOutgoing(3, ClientPlayerMovementPacket.class);
this.registerOutgoing(4, ClientPlayerPositionPacket.class);
this.registerOutgoing(5, ClientPlayerRotationPacket.class);
this.registerOutgoing(6, ClientPlayerPositionRotationPacket.class);
this.registerOutgoing(7, ClientPlayerDigPacket.class);
this.registerOutgoing(8, ClientPlayerPlaceBlockPacket.class);
this.registerOutgoing(9, ClientChangeHeldItemPacket.class);
this.registerOutgoing(10, ClientAnimationPacket.class);
this.registerOutgoing(11, ClientEntityActionPacket.class);
this.registerOutgoing(12, ClientSteerVehiclePacket.class);
this.registerOutgoing(13, ClientCloseWindowPacket.class);
this.registerOutgoing(14, ClientWindowActionPacket.class);
this.registerOutgoing(15, ClientConfirmTransactionPacket.class);
this.registerOutgoing(16, ClientCreativeInventoryActionPacket.class);
this.registerOutgoing(17, ClientEnchantItemPacket.class);
this.registerOutgoing(18, ClientUpdateSignPacket.class);
this.registerOutgoing(19, ClientPlayerAbilitiesPacket.class);
this.registerOutgoing(20, ClientTabCompletePacket.class);
this.registerOutgoing(21, ClientSettingsPacket.class);
this.registerOutgoing(22, ClientRequestPacket.class);
this.registerOutgoing(23, ClientPluginMessagePacket.class);
}
private void initServerGame(Session session) {
this.registerIncoming(0, ClientKeepAlivePacket.class);
this.registerIncoming(1, ClientChatPacket.class);
this.registerIncoming(2, ClientEntityInteractPacket.class);
this.registerIncoming(3, ClientPlayerMovementPacket.class);
this.registerIncoming(4, ClientPlayerPositionPacket.class);
this.registerIncoming(5, ClientPlayerRotationPacket.class);
this.registerIncoming(6, ClientPlayerPositionRotationPacket.class);
this.registerIncoming(7, ClientPlayerDigPacket.class);
this.registerIncoming(8, ClientPlayerPlaceBlockPacket.class);
this.registerIncoming(9, ClientChangeHeldItemPacket.class);
this.registerIncoming(10, ClientAnimationPacket.class);
this.registerIncoming(11, ClientEntityActionPacket.class);
this.registerIncoming(12, ClientSteerVehiclePacket.class);
this.registerIncoming(13, ClientCloseWindowPacket.class);
this.registerIncoming(14, ClientWindowActionPacket.class);
this.registerIncoming(15, ClientConfirmTransactionPacket.class);
this.registerIncoming(16, ClientCreativeInventoryActionPacket.class);
this.registerIncoming(17, ClientEnchantItemPacket.class);
this.registerIncoming(18, ClientUpdateSignPacket.class);
this.registerIncoming(19, ClientPlayerAbilitiesPacket.class);
this.registerIncoming(20, ClientTabCompletePacket.class);
this.registerIncoming(21, ClientSettingsPacket.class);
this.registerIncoming(22, ClientRequestPacket.class);
this.registerIncoming(23, ClientPluginMessagePacket.class);
this.registerOutgoing(0, ServerKeepAlivePacket.class);
this.registerOutgoing(1, ServerJoinGamePacket.class);
this.registerOutgoing(2, ServerChatPacket.class);
this.registerOutgoing(3, ServerUpdateTimePacket.class);
this.registerOutgoing(4, ServerEntityEquipmentPacket.class);
this.registerOutgoing(5, ServerSpawnPositionPacket.class);
this.registerOutgoing(6, ServerUpdateHealthPacket.class);
this.registerOutgoing(7, ServerRespawnPacket.class);
this.registerOutgoing(8, ServerPlayerPositionRotationPacket.class);
this.registerOutgoing(9, ServerChangeHeldItemPacket.class);
this.registerOutgoing(10, ServerPlayerUseBedPacket.class);
this.registerOutgoing(11, ServerAnimationPacket.class);
this.registerOutgoing(12, ServerSpawnPlayerPacket.class);
this.registerOutgoing(13, ServerCollectItemPacket.class);
this.registerOutgoing(14, ServerSpawnObjectPacket.class);
this.registerOutgoing(15, ServerSpawnMobPacket.class);
this.registerOutgoing(16, ServerSpawnPaintingPacket.class);
this.registerOutgoing(17, ServerSpawnExpOrbPacket.class);
this.registerOutgoing(18, ServerEntityVelocityPacket.class);
this.registerOutgoing(19, ServerDestroyEntitiesPacket.class);
this.registerOutgoing(20, ServerEntityMovementPacket.class);
this.registerOutgoing(21, ServerEntityPositionPacket.class);
this.registerOutgoing(22, ServerEntityRotationPacket.class);
this.registerOutgoing(23, ServerEntityPositionRotationPacket.class);
this.registerOutgoing(24, ServerEntityTeleportPacket.class);
this.registerOutgoing(25, ServerEntityHeadLookPacket.class);
this.registerOutgoing(26, ServerEntityStatusPacket.class);
this.registerOutgoing(27, ServerEntityAttachPacket.class);
this.registerOutgoing(28, ServerEntityMetadataPacket.class);
this.registerOutgoing(29, ServerEntityEffectPacket.class);
this.registerOutgoing(30, ServerRemoveEffectPacket.class);
this.registerOutgoing(31, ServerSetExperiencePacket.class);
this.registerOutgoing(32, ServerEntityPropertiesPacket.class);
this.registerOutgoing(33, ServerChunkDataPacket.class);
this.registerOutgoing(34, ServerMultiBlockChangePacket.class);
this.registerOutgoing(35, ServerBlockChangePacket.class);
this.registerOutgoing(36, ServerBlockValuePacket.class);
this.registerOutgoing(37, ServerBlockBreakAnimPacket.class);
this.registerOutgoing(38, ServerMultiChunkDataPacket.class);
this.registerOutgoing(39, ServerExplosionPacket.class);
this.registerOutgoing(40, ServerPlayEffectPacket.class);
this.registerOutgoing(41, ServerPlaySoundPacket.class);
this.registerOutgoing(42, ServerSpawnParticlePacket.class);
this.registerOutgoing(43, ServerNotifyClientPacket.class);
this.registerOutgoing(44, ServerSpawnGlobalEntityPacket.class);
this.registerOutgoing(45, ServerOpenWindowPacket.class);
this.registerOutgoing(46, ServerCloseWindowPacket.class);
this.registerOutgoing(47, ServerSetSlotPacket.class);
this.registerOutgoing(48, ServerWindowItemsPacket.class);
this.registerOutgoing(49, ServerWindowPropertyPacket.class);
this.registerOutgoing(50, ServerConfirmTransactionPacket.class);
this.registerOutgoing(51, ServerUpdateSignPacket.class);
this.registerOutgoing(52, ServerMapDataPacket.class);
this.registerOutgoing(53, ServerUpdateTileEntityPacket.class);
this.registerOutgoing(54, ServerOpenTileEntityEditorPacket.class);
this.registerOutgoing(55, ServerStatisticsPacket.class);
this.registerOutgoing(56, ServerPlayerListEntryPacket.class);
this.registerOutgoing(57, ServerPlayerAbilitiesPacket.class);
this.registerOutgoing(58, ServerTabCompletePacket.class);
this.registerOutgoing(59, ServerScoreboardObjectivePacket.class);
this.registerOutgoing(60, ServerUpdateScorePacket.class);
this.registerOutgoing(61, ServerDisplayScoreboardPacket.class);
this.registerOutgoing(62, ServerTeamPacket.class);
this.registerOutgoing(63, ServerPluginMessagePacket.class);
this.registerOutgoing(64, ServerDisconnectPacket.class);
}
private void initClientStatus(Session session) {
this.registerIncoming(0, StatusResponsePacket.class);
this.registerIncoming(1, StatusPongPacket.class);
this.registerOutgoing(0, StatusQueryPacket.class);
this.registerOutgoing(1, StatusPingPacket.class);
}
private void initServerStatus(Session session) {
this.registerIncoming(0, StatusQueryPacket.class);
this.registerIncoming(1, StatusPingPacket.class);
this.registerOutgoing(0, StatusResponsePacket.class);
this.registerOutgoing(1, StatusPongPacket.class);
}
}

View file

@ -0,0 +1,22 @@
package ch.spacebase.mc.protocol;
public class ProtocolConstants {
// General Constants
public static final String GAME_VERSION = "1.7.2";
public static final int PROTOCOL_VERSION = 4;
// General Key Constants
public static final String PROFILE_KEY = "profile";
// Client Key Constants
public static final String PING_KEY = "ping";
public static final String SERVER_INFO_HANDLER_KEY = "server-info-handler";
public static final String SERVER_PING_TIME_HANDLER_KEY = "server-ping-time-handler";
// Server Key Constants
public static final String VERIFY_USERS_KEY = "verify-users";
public static final String SERVER_INFO_BUILDER_KEY = "info-builder";
public static final String SERVER_LOGIN_HANDLER_KEY = "login-handler";
}

View file

@ -0,0 +1,8 @@
package ch.spacebase.mc.protocol;
public enum ProtocolMode {
HANDSHAKE,
LOGIN,
GAME,
STATUS;
}

View file

@ -0,0 +1,157 @@
package ch.spacebase.mc.protocol;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.util.Arrays;
import java.util.Random;
import java.util.UUID;
import javax.crypto.SecretKey;
import ch.spacebase.mc.auth.AuthenticationService;
import ch.spacebase.mc.auth.GameProfile;
import ch.spacebase.mc.auth.SessionService;
import ch.spacebase.mc.auth.exceptions.AuthenticationUnavailableException;
import ch.spacebase.mc.protocol.data.status.ServerStatusInfo;
import ch.spacebase.mc.protocol.data.status.handler.ServerInfoBuilder;
import ch.spacebase.mc.protocol.packet.handshake.client.HandshakePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerDisconnectPacket;
import ch.spacebase.mc.protocol.packet.login.client.EncryptionResponsePacket;
import ch.spacebase.mc.protocol.packet.login.client.LoginStartPacket;
import ch.spacebase.mc.protocol.packet.login.server.EncryptionRequestPacket;
import ch.spacebase.mc.protocol.packet.login.server.LoginDisconnectPacket;
import ch.spacebase.mc.protocol.packet.login.server.LoginSuccessPacket;
import ch.spacebase.mc.protocol.packet.status.client.StatusPingPacket;
import ch.spacebase.mc.protocol.packet.status.client.StatusQueryPacket;
import ch.spacebase.mc.protocol.packet.status.server.StatusPongPacket;
import ch.spacebase.mc.protocol.packet.status.server.StatusResponsePacket;
import ch.spacebase.mc.util.CryptUtil;
import ch.spacebase.packetlib.Session;
import ch.spacebase.packetlib.event.session.DisconnectingEvent;
import ch.spacebase.packetlib.event.session.PacketReceivedEvent;
import ch.spacebase.packetlib.event.session.SessionAdapter;
public class ServerListener extends SessionAdapter {
private static KeyPair pair = CryptUtil.generateKeyPair();
private byte verifyToken[] = new byte[4];
private String serverId = "";
private String username = "";
public ServerListener() {
new Random().nextBytes(this.verifyToken);
}
@Override
public void packetReceived(PacketReceivedEvent event) {
MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol();
if(protocol.getMode() == ProtocolMode.HANDSHAKE) {
if(event.getPacket() instanceof HandshakePacket) {
HandshakePacket packet = event.getPacket();
switch(packet.getIntent()) {
case 1:
protocol.setMode(ProtocolMode.STATUS, false, event.getSession());
break;
case 2:
protocol.setMode(ProtocolMode.LOGIN, false, event.getSession());
if(packet.getProtocolVersion() > ProtocolConstants.PROTOCOL_VERSION) {
event.getSession().disconnect("Outdated server! I'm still on " + ProtocolConstants.GAME_VERSION + ".");
} else if(packet.getProtocolVersion() < ProtocolConstants.PROTOCOL_VERSION) {
event.getSession().disconnect("Outdated client! Please use " + ProtocolConstants.GAME_VERSION + ".");
}
break;
default:
throw new UnsupportedOperationException("Invalid client intent: " + packet.getIntent());
}
}
}
if(protocol.getMode() == ProtocolMode.LOGIN) {
if(event.getPacket() instanceof LoginStartPacket) {
this.username = event.<LoginStartPacket>getPacket().getUsername();
boolean verify = event.getSession().getFlag(ProtocolConstants.VERIFY_USERS_KEY);
if(verify) {
event.getSession().send(new EncryptionRequestPacket(this.serverId, pair.getPublic(), this.verifyToken));
} else {
event.getSession().send(new LoginSuccessPacket("", this.username));
event.getSession().setFlag(ProtocolConstants.PROFILE_KEY, new GameProfile("", this.username));
protocol.setMode(ProtocolMode.GAME, false, event.getSession());
ServerLoginHandler handler = event.getSession().getFlag(ProtocolConstants.SERVER_LOGIN_HANDLER_KEY);
if(handler != null) {
handler.loggedIn(event.getSession());
}
}
} else if(event.getPacket() instanceof EncryptionResponsePacket) {
EncryptionResponsePacket packet = event.getPacket();
PrivateKey privateKey = pair.getPrivate();
if(!Arrays.equals(this.verifyToken, packet.getVerifyToken(privateKey))) {
throw new IllegalStateException("Invalid nonce!");
} else {
SecretKey key = packet.getSecretKey(privateKey);
protocol.enableEncryption(key);
new UserAuthThread(event.getSession(), key).start();
}
}
}
if(protocol.getMode() == ProtocolMode.STATUS) {
if(event.getPacket() instanceof StatusQueryPacket) {
ServerInfoBuilder builder = event.getSession().getFlag(ProtocolConstants.SERVER_INFO_BUILDER_KEY);
if(builder == null) {
event.getSession().disconnect("No server info builder set.");
}
ServerStatusInfo info = builder.buildInfo();
event.getSession().send(new StatusResponsePacket(info));
} else if(event.getPacket() instanceof StatusPingPacket) {
event.getSession().send(new StatusPongPacket(event.<StatusPingPacket>getPacket().getPingTime()));
}
}
}
@Override
public void disconnecting(DisconnectingEvent event) {
MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol();
if(protocol.getMode() == ProtocolMode.LOGIN) {
event.getSession().send(new LoginDisconnectPacket(event.getReason()));
} else if(protocol.getMode() == ProtocolMode.GAME) {
event.getSession().send(new ServerDisconnectPacket(event.getReason()));
}
}
private class UserAuthThread extends Thread {
private Session session;
private SecretKey key;
public UserAuthThread(Session session, SecretKey key) {
this.key = key;
this.session = session;
}
public void run() {
MinecraftProtocol protocol = (MinecraftProtocol) this.session.getPacketProtocol();
try {
String serverHash = new BigInteger(CryptUtil.getServerIdHash(serverId, pair.getPublic(), this.key)).toString(16);
SessionService service = new AuthenticationService(UUID.randomUUID().toString()).createMinecraftSessionService();
GameProfile profile = service.hasJoinedServer(new GameProfile(null, username), serverHash);
if(profile != null) {
this.session.send(new LoginSuccessPacket(profile.getId(), profile.getName()));
this.session.setFlag(ProtocolConstants.PROFILE_KEY, profile);
protocol.setMode(ProtocolMode.GAME, false, this.session);
ServerLoginHandler handler = this.session.getFlag(ProtocolConstants.SERVER_LOGIN_HANDLER_KEY);
if(handler != null) {
handler.loggedIn(this.session);
}
} else {
this.session.disconnect("Failed to verify username!");
}
} catch(AuthenticationUnavailableException e) {
this.session.disconnect("Authentication servers are down. Please try again later, sorry!");
}
}
}
}

View file

@ -0,0 +1,9 @@
package ch.spacebase.mc.protocol;
import ch.spacebase.packetlib.Session;
public interface ServerLoginHandler {
public void loggedIn(Session session);
}

View file

@ -0,0 +1,34 @@
package ch.spacebase.mc.protocol.data.game;
import java.util.ArrayList;
import java.util.List;
public class Attribute {
private String key;
private double value;
private List<AttributeModifier> modifiers;
public Attribute(String key, double value) {
this(key, value, new ArrayList<AttributeModifier>());
}
public Attribute(String key, double value, List<AttributeModifier> modifiers) {
this.key = key;
this.value = value;
this.modifiers = modifiers;
}
public String getKey() {
return this.key;
}
public double getValue() {
return this.value;
}
public List<AttributeModifier> getModifiers() {
return this.modifiers;
}
}

View file

@ -0,0 +1,50 @@
package ch.spacebase.mc.protocol.data.game;
import java.util.UUID;
public class AttributeModifier {
private UUID uuid;
private double amount;
private int operation;
public AttributeModifier(UUID uuid, double amount, int operation) {
this.uuid = uuid;
this.amount = amount;
this.operation = operation;
}
public UUID getUUID() {
return this.uuid;
}
public double getAmount() {
return this.amount;
}
public int getOperation() {
return this.operation;
}
public static class Operations {
public static final int ADD = 0;
public static final int ADD_MULTIPLIED = 1;
public static final int MULTIPLY = 2;
}
public static class UUIDs {
public static final UUID CREATURE_FLEE_SPEED_BONUS = UUID.fromString("E199AD21-BA8A-4C53-8D13-6182D5C69D3A");
public static final UUID ENDERMAN_ATTACK_SPEED_BOOST = UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0");
public static final UUID SPRINT_SPEED_BOOST = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D");
public static final UUID PIGZOMBIE_ATTACK_SPEED_BOOST = UUID.fromString("49455A49-7EC5-45BA-B886-3B90B23A1718");
public static final UUID WITCH_DRINKING_SPEED_PENALTY = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E");
public static final UUID ZOMBIE_BABY_SPEED_BOOST = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836");
public static final UUID ITEM_MODIFIER = UUID.fromString("CB3F55D3-645C-4F38-A497-9C13A33DB5CF");
public static final UUID SPEED_POTION_MODIFIER = UUID.fromString("91AEAA56-376B-4498-935B-2F7F68070635");
public static final UUID HEALTH_BOOST_POTION_MODIFIER = UUID.fromString("5D6F0BA2-1186-46AC-B896-C61C5CEE99CC");
public static final UUID SLOW_POTION_MODIFIER = UUID.fromString("7107DE5E-7CE8-4030-940E-514C1F160890");
public static final UUID STRENGTH_POTION_MODIFIER = UUID.fromString("648D7064-6A60-4F59-8ABE-C2C23A6DD7A9");
public static final UUID WEAKNESS_POTION_MODIFIER = UUID.fromString("22653B89-116E-49DC-9B6B-9971489B5BE5");
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.data.game;
public class BlockChangeRecord {
private int x;
private int y;
private int z;
private int id;
private int metadata;
public BlockChangeRecord(int x, int y, int z, int id, int metadata) {
this.x = x;
this.y = y;
this.z = z;
this.id = id;
this.metadata = metadata;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
public int getId() {
return this.id;
}
public int getMetadata() {
return this.metadata;
}
}

View file

@ -0,0 +1,66 @@
package ch.spacebase.mc.protocol.data.game;
public class Chunk {
private int x;
private int z;
private byte blocks[];
private NibbleArray metadata;
private NibbleArray blocklight;
private NibbleArray skylight;
private NibbleArray extendedBlocks;
public Chunk(int x, int z, byte blocks[], NibbleArray metadata, NibbleArray blocklight, NibbleArray skylight, NibbleArray extendedBlocks) {
this.x = x;
this.z = z;
this.blocks = blocks;
this.metadata = metadata;
this.blocklight = blocklight;
this.skylight = skylight;
this.extendedBlocks = extendedBlocks;
}
public int getX() {
return this.x;
}
public int getZ() {
return this.z;
}
public byte[] getBlocks() {
return this.blocks;
}
public NibbleArray getMetadata() {
return this.metadata;
}
public NibbleArray getBlockLight() {
return this.blocklight;
}
public NibbleArray getSkyLight() {
return this.skylight;
}
public NibbleArray getExtendedBlocks() {
return this.extendedBlocks;
}
public void deleteExtendedBlocks() {
this.extendedBlocks = null;
}
public boolean isEmpty() {
for(byte block : this.blocks) {
if(block != 0) {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,27 @@
package ch.spacebase.mc.protocol.data.game;
public class Coordinates {
private int x;
private int y;
private int z;
public Coordinates(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
}

View file

@ -0,0 +1,41 @@
package ch.spacebase.mc.protocol.data.game;
public class DefaultAttribute {
public static final DefaultAttribute MAX_HEALTH = new DefaultAttribute("generic.maxHealth", 20, 0, Double.MAX_VALUE);
public static final DefaultAttribute FOLLOW_RANGE = new DefaultAttribute("generic.followRange", 32, 0, 2048);
public static final DefaultAttribute KNOCKBACK_RESISTANCE = new DefaultAttribute("generic.knockbackResistance", 0, 0, 1);
public static final DefaultAttribute MOVEMENT_SPEED = new DefaultAttribute("generic.movementSpeed", 0.699999988079071, 0, Double.MAX_VALUE);
public static final DefaultAttribute ATTACK_DAMAGE = new DefaultAttribute("generic.attackStrength", 2, 0, Double.MAX_VALUE);
public static final DefaultAttribute HORSE_JUMP_STRENGTH = new DefaultAttribute("generic.maxHealth", 0.7, 0, 2);
public static final DefaultAttribute ZOMBIE_SPAWN_REINFORCEMENTS_CHANCE = new DefaultAttribute("generic.maxHealth", 0, 0, 1);
private String key;
private double def;
private double min;
private double max;
private DefaultAttribute(String key, double def, double min, double max) {
this.key = key;
this.def = def;
this.min = min;
this.max = max;
}
public String getKey() {
return this.key;
}
public double getDefault() {
return this.def;
}
public double getMin() {
return this.min;
}
public double getMax() {
return this.max;
}
}

View file

@ -0,0 +1,37 @@
package ch.spacebase.mc.protocol.data.game;
public class EntityMetadata {
private int id;
private Type type;
private Object value;
public EntityMetadata(int id, Type type, Object value) {
this.id = id;
this.type = type;
this.value = value;
}
public int getId() {
return this.id;
}
public Type getType() {
return this.type;
}
public Object getValue() {
return this.value;
}
public static enum Type {
BYTE,
SHORT,
INT,
FLOAT,
STRING,
ITEM,
COORDINATES;
}
}

View file

@ -0,0 +1,47 @@
package ch.spacebase.mc.protocol.data.game;
import ch.spacebase.opennbt.tag.CompoundTag;
public class ItemStack {
private int id;
private int amount;
private int data;
private CompoundTag nbt;
public ItemStack(int id) {
this(id, 1);
}
public ItemStack(int id, int amount) {
this(id, amount, 0);
}
public ItemStack(int id, int amount, int data) {
this(id, amount, data, null);
}
public ItemStack(int id, int amount, int data, CompoundTag nbt) {
this.id = id;
this.amount = amount;
this.data = data;
this.nbt = nbt;
}
public int getId() {
return this.id;
}
public int getAmount() {
return this.amount;
}
public int getData() {
return this.data;
}
public CompoundTag getNBT() {
return this.nbt;
}
}

View file

@ -0,0 +1,49 @@
package ch.spacebase.mc.protocol.data.game;
public class NibbleArray {
private byte[] data;
public NibbleArray(int size) {
this.data = new byte[size >> 1];
}
public NibbleArray(byte[] array) {
this.data = array;
}
public byte[] getData() {
return this.data;
}
public int get(int x, int y, int z) {
int key = y << 8 | z << 4 | x;
int index = key >> 1;
int part = key & 1;
return part == 0 ? this.data[index] & 15 : this.data[index] >> 4 & 15;
}
public void set(int x, int y, int z, int val) {
int key = y << 8 | z << 4 | x;
int index = key >> 1;
int part = key & 1;
if(part == 0) {
this.data[index] = (byte) (this.data[index] & 240 | val & 15);
} else {
this.data[index] = (byte) (this.data[index] & 15 | (val & 15) << 4);
}
}
public void fill(int val) {
for(int index = 0; index < this.data.length << 1; index++) {
int ind = index >> 1;
int part = index & 1;
if(part == 0) {
this.data[ind] = (byte) (this.data[ind] & 240 | val & 15);
} else {
this.data[ind] = (byte) (this.data[ind] & 15 | (val & 15) << 4);
}
}
}
}

View file

@ -0,0 +1,29 @@
package ch.spacebase.mc.protocol.data.status;
import ch.spacebase.mc.auth.GameProfile;
public class PlayerInfo {
private int max;
private int online;
private GameProfile players[];
public PlayerInfo(int max, int online, GameProfile players[]) {
this.max = max;
this.online = online;
this.players = players;
}
public int getMaxPlayers() {
return this.max;
}
public int getOnlinePlayers() {
return this.online;
}
public GameProfile[] getPlayers() {
return this.players;
}
}

View file

@ -0,0 +1,37 @@
package ch.spacebase.mc.protocol.data.status;
import java.awt.image.BufferedImage;
import ch.spacebase.mc.util.message.Message;
public class ServerStatusInfo {
private VersionInfo version;
private PlayerInfo players;
private Message description;
private BufferedImage icon;
public ServerStatusInfo(VersionInfo version, PlayerInfo players, Message description, BufferedImage icon) {
this.version = version;
this.players = players;
this.description = description;
this.icon = icon;
}
public VersionInfo getVersionInfo() {
return this.version;
}
public PlayerInfo getPlayerInfo() {
return this.players;
}
public Message getDescription() {
return this.description;
}
public BufferedImage getIcon() {
return this.icon;
}
}

View file

@ -0,0 +1,21 @@
package ch.spacebase.mc.protocol.data.status;
public class VersionInfo {
private String name;
private int protocol;
public VersionInfo(String name, int protocol) {
this.name = name;
this.protocol = protocol;
}
public String getVersionName() {
return this.name;
}
public int getProtocolVersion() {
return this.protocol;
}
}

View file

@ -0,0 +1,9 @@
package ch.spacebase.mc.protocol.data.status.handler;
import ch.spacebase.mc.protocol.data.status.ServerStatusInfo;
public interface ServerInfoBuilder {
public ServerStatusInfo buildInfo();
}

View file

@ -0,0 +1,10 @@
package ch.spacebase.mc.protocol.data.status.handler;
import ch.spacebase.mc.protocol.data.status.ServerStatusInfo;
public interface ServerInfoHandler {
public void handle(ServerStatusInfo info);
}

View file

@ -0,0 +1,7 @@
package ch.spacebase.mc.protocol.data.status.handler;
public interface ServerPingTimeHandler {
public void handle(long pingTime);
}

View file

@ -0,0 +1,63 @@
package ch.spacebase.mc.protocol.packet.handshake.client;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class HandshakePacket implements Packet {
private int protocolVersion;
private String hostname;
private int port;
private int intent;
public HandshakePacket() {
}
public HandshakePacket(int protocolVersion, String hostname, int port, int nextState) {
this.protocolVersion = protocolVersion;
this.hostname = hostname;
this.port = port;
this.intent = nextState;
}
public int getProtocolVersion() {
return this.protocolVersion;
}
public String getHostName() {
return this.hostname;
}
public int getPort() {
return this.port;
}
public int getIntent() {
return this.intent;
}
@Override
public void read(NetInput in) throws IOException {
this.protocolVersion = in.readVarInt();
this.hostname = in.readString();
this.port = in.readUnsignedShort();
this.intent = in.readVarInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeVarInt(this.protocolVersion);
out.writeString(this.hostname);
out.writeShort(this.port);
out.writeVarInt(this.intent);
}
@Override
public boolean isPriority() {
return true;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.client;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientChatPacket implements Packet {
private String message;
public ClientChatPacket() {
}
public ClientChatPacket(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
@Override
public void read(NetInput in) throws IOException {
this.message = in.readString();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.message);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.client;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientKeepAlivePacket implements Packet {
private int id;
public ClientKeepAlivePacket() {
}
public ClientKeepAlivePacket(int id) {
this.id = id;
}
public int getPingId() {
return this.id;
}
@Override
public void read(NetInput in) throws IOException {
this.id = in.readInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.id);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,48 @@
package ch.spacebase.mc.protocol.packet.ingame.client;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientPluginMessagePacket implements Packet {
private String channel;
private byte data[];
public ClientPluginMessagePacket() {
}
public ClientPluginMessagePacket(String channel, byte data[]) {
this.channel = channel;
this.data = data;
}
public String getChannel() {
return this.channel;
}
public byte[] getData() {
return this.data;
}
@Override
public void read(NetInput in) throws IOException {
this.channel = in.readString();
this.data = in.readBytes(in.readShort());
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.channel);
out.writeShort(this.data.length);
out.writeBytes(this.data);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,45 @@
package ch.spacebase.mc.protocol.packet.ingame.client;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientRequestPacket implements Packet {
private Request request;
public ClientRequestPacket() {
}
public ClientRequestPacket(Request request) {
this.request = request;
}
public Request getRequest() {
return this.request;
}
@Override
public void read(NetInput in) throws IOException {
this.request = Request.values()[in.readByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.request.ordinal());
}
@Override
public boolean isPriority() {
return false;
}
public static enum Request {
RESPAWN,
STATS,
OPEN_INVENTORY_ACHIEVEMENT;
}
}

View file

@ -0,0 +1,92 @@
package ch.spacebase.mc.protocol.packet.ingame.client;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientSettingsPacket implements Packet {
private String locale;
private int renderDistance;
private ChatVisibility chatVisibility;
private boolean chatColors;
private Difficulty difficulty;
private boolean capes;
public ClientSettingsPacket() {
}
public ClientSettingsPacket(String locale, int renderDistance, ChatVisibility chatVisibility, boolean chatColors, Difficulty difficulty, boolean capes) {
this.locale = locale;
this.renderDistance = renderDistance;
this.chatVisibility = chatVisibility;
this.chatColors = chatColors;
this.difficulty = difficulty;
this.capes = capes;
}
public String getLocale() {
return this.locale;
}
public int getRenderDistance() {
return this.renderDistance;
}
public ChatVisibility getChatVisibility() {
return this.chatVisibility;
}
public boolean getUseChatColors() {
return this.chatColors;
}
public Difficulty getDifficulty() {
return this.difficulty;
}
public boolean getShowCapes() {
return this.capes;
}
@Override
public void read(NetInput in) throws IOException {
this.locale = in.readString();
this.renderDistance = in.readByte();
this.chatVisibility = ChatVisibility.values()[in.readByte()];
this.chatColors = in.readBoolean();
this.difficulty = Difficulty.values()[in.readByte()];
this.capes = in.readBoolean();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.locale);
out.writeByte(this.renderDistance);
out.writeByte(this.chatVisibility.ordinal());
out.writeBoolean(this.chatColors);
out.writeByte(this.difficulty.ordinal());
out.writeBoolean(this.capes);
}
@Override
public boolean isPriority() {
return false;
}
public static enum ChatVisibility {
FULL,
SYSTEM,
HIDDEN;
}
public static enum Difficulty {
PEACEFUL,
EASY,
NORMAL,
HARD;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.client;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientTabCompletePacket implements Packet {
private String text;
public ClientTabCompletePacket() {
}
public ClientTabCompletePacket(String text) {
this.text = text;
}
public String getText() {
return this.text;
}
@Override
public void read(NetInput in) throws IOException {
this.text = in.readString();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.text);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,51 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientAnimationPacket implements Packet {
private int entityId;
private Animation animation;
public ClientAnimationPacket() {
}
public ClientAnimationPacket(int entityId, Animation animation) {
this.entityId = entityId;
this.animation = animation;
}
public int getEntityId() {
return this.entityId;
}
public Animation getAnimation() {
return this.animation;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.animation = Animation.values()[in.readByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(this.animation.ordinal());
}
@Override
public boolean isPriority() {
return false;
}
public static enum Animation {
SWING_ARM;
}
}

View file

@ -0,0 +1,67 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientEntityActionPacket implements Packet {
private int entityId;
private Action action;
private int jumpBoost;
public ClientEntityActionPacket() {
}
public ClientEntityActionPacket(int entityId, Action action) {
this(entityId, action, 0);
}
public ClientEntityActionPacket(int entityId, Action action, int jumpBoost) {
this.entityId = entityId;
this.action = action;
this.jumpBoost = jumpBoost;
}
public int getEntityId() {
return this.entityId;
}
public Action getAction() {
return this.action;
}
public int getJumpBoost() {
return this.jumpBoost;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.action = Action.values()[in.readByte()];
this.jumpBoost = in.readInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(this.action.ordinal());
out.writeInt(this.jumpBoost);
}
@Override
public boolean isPriority() {
return false;
}
public static enum Action {
CROUCH,
UNCROUCH,
LEAVE_BED,
START_SPRINTING,
STOP_SPRINTING;
}
}

View file

@ -0,0 +1,52 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientEntityInteractPacket implements Packet {
private int entityId;
private Action action;
public ClientEntityInteractPacket() {
}
public ClientEntityInteractPacket(int entityId, Action action) {
this.entityId = entityId;
this.action = action;
}
public int getEntityId() {
return this.entityId;
}
public Action getAction() {
return this.action;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.action = Action.values()[in.readByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(this.action.ordinal());
}
@Override
public boolean isPriority() {
return false;
}
public static enum Action {
INTERACT,
ATTACK;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientChangeHeldItemPacket implements Packet {
private int slot;
public ClientChangeHeldItemPacket() {
}
public ClientChangeHeldItemPacket(int slot) {
this.slot = slot;
}
public int getSlot() {
return this.slot;
}
@Override
public void read(NetInput in) throws IOException {
this.slot = in.readShort();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeShort(this.slot);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,94 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientPlayerAbilitiesPacket implements Packet {
private boolean invincible;
private boolean canFly;
private boolean flying;
private boolean creative;
private float flySpeed;
private float walkSpeed;
public ClientPlayerAbilitiesPacket() {
}
public ClientPlayerAbilitiesPacket(boolean invincible, boolean canFly, boolean flying, boolean creative, float flySpeed, float walkSpeed) {
this.invincible = invincible;
this.canFly = canFly;
this.flying = flying;
this.creative = creative;
this.flySpeed = flySpeed;
this.walkSpeed = walkSpeed;
}
public boolean getInvincible() {
return this.invincible;
}
public boolean getCanFly() {
return this.canFly;
}
public boolean getFlying() {
return this.flying;
}
public boolean getCreative() {
return this.creative;
}
public float getFlySpeed() {
return this.flySpeed;
}
public float getWalkSpeed() {
return this.walkSpeed;
}
@Override
public void read(NetInput in) throws IOException {
byte flags = in.readByte();
this.invincible = (flags & 1) > 0;
this.canFly = (flags & 2) > 0;
this.flying = (flags & 4) > 0;
this.creative = (flags & 8) > 0;
this.flySpeed = in.readFloat();
this.walkSpeed = in.readFloat();
}
@Override
public void write(NetOutput out) throws IOException {
byte flags = 0;
if(this.invincible) {
flags = (byte) (flags | 1);
}
if(this.canFly) {
flags = (byte) (flags | 2);
}
if(this.flying) {
flags = (byte) (flags | 4);
}
if(this.creative) {
flags = (byte) (flags | 8);
}
out.writeByte(flags);
out.writeFloat(this.flySpeed);
out.writeFloat(this.walkSpeed);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,89 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientPlayerDigPacket implements Packet {
private Status status;
private int x;
private int y;
private int z;
private Face face;
public ClientPlayerDigPacket() {
}
public ClientPlayerDigPacket(Status status, int x, int y, int z, Face face) {
this.status = status;
this.x = x;
this.y = y;
this.z = z;
this.face = face;
}
public Status getStatus() {
return this.status;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
public Face getFace() {
return this.face;
}
@Override
public void read(NetInput in) throws IOException {
this.status = Status.values()[in.readUnsignedByte()];
this.x = in.readInt();
this.y = in.readUnsignedByte();
this.z = in.readInt();
this.face = Face.values()[in.readUnsignedByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.status.ordinal());
out.writeInt(this.x);
out.writeByte(this.y);
out.writeInt(this.z);
out.writeByte(this.face.ordinal());
}
@Override
public boolean isPriority() {
return false;
}
public static enum Status {
START_DIGGING,
CANCEL_DIGGING,
FINISH_DIGGING,
DROP_ITEM_STACK,
DROP_ITEM,
SHOOT_ARROW_OR_FINISH_EATING;
}
public static enum Face {
BOTTOM,
TOP,
EAST,
WEST,
NORTH,
SOUTH;
}
}

View file

@ -0,0 +1,96 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientPlayerMovementPacket implements Packet {
protected double x;
protected double stance;
protected double y;
protected double z;
protected double yaw;
protected double pitch;
protected boolean onGround;
protected boolean pos = false;
protected boolean rot = false;
public ClientPlayerMovementPacket() {
}
public ClientPlayerMovementPacket(boolean onGround) {
this.onGround = onGround;
}
public double getX() {
return this.x;
}
public double getStance() {
return this.stance;
}
public double getY() {
return this.y;
}
public double getZ() {
return this.z;
}
public double getYaw() {
return this.yaw;
}
public double getPitch() {
return this.pitch;
}
public boolean isOnGround() {
return this.onGround;
}
@Override
public void read(NetInput in) throws IOException {
if(this.pos) {
this.x = in.readDouble();
this.stance = in.readDouble();
this.y = in.readDouble();
this.z = in.readDouble();
}
if(this.rot) {
this.yaw = in.readDouble();
this.pitch = in.readDouble();
}
this.onGround = in.readBoolean();
}
@Override
public void write(NetOutput out) throws IOException {
if(this.pos) {
out.writeDouble(this.x);
out.writeDouble(this.stance);
out.writeDouble(this.y);
out.writeDouble(this.z);
}
if(this.rot) {
out.writeDouble(this.yaw);
out.writeDouble(this.pitch);
}
out.writeBoolean(this.onGround);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,106 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
import java.io.IOException;
import ch.spacebase.mc.protocol.data.game.ItemStack;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientPlayerPlaceBlockPacket implements Packet {
private int x;
private int y;
private int z;
private Face face;
private ItemStack held;
private float cursorX;
private float cursorY;
private float cursorZ;
public ClientPlayerPlaceBlockPacket() {
}
public ClientPlayerPlaceBlockPacket(int x, int y, int z, Face face, ItemStack held, float cursorX, float cursorY, float cursorZ) {
this.x = x;
this.y = y;
this.z = z;
this.face = face;
this.held = held;
this.cursorX = cursorX;
this.cursorY = cursorY;
this.cursorZ = cursorZ;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
public Face getFace() {
return this.face;
}
public ItemStack getHeldItem() {
return this.held;
}
public float getCursorX() {
return this.cursorX;
}
public float getCursorY() {
return this.cursorY;
}
public float getCursorZ() {
return this.cursorZ;
}
@Override
public void read(NetInput in) throws IOException {
this.x = in.readInt();
this.y = in.readUnsignedByte();
this.z = in.readInt();
this.face = Face.values()[in.readUnsignedByte()];
this.held = NetUtil.readItem(in);
this.cursorX = in.readByte() / 16f;
this.cursorY = in.readByte() / 16f;
this.cursorZ = in.readByte() / 16f;
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.x);
out.writeByte(this.y);
out.writeInt(this.z);
out.writeByte(this.face.ordinal());
NetUtil.writeItem(out, this.held);
out.writeByte((int) (this.cursorX * 16));
out.writeByte((int) (this.cursorY * 16));
out.writeByte((int) (this.cursorZ * 16));
}
@Override
public boolean isPriority() {
return false;
}
public static enum Face {
BOTTOM,
TOP,
EAST,
WEST,
NORTH,
SOUTH;
}
}

View file

@ -0,0 +1,18 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
public class ClientPlayerPositionPacket extends ClientPlayerMovementPacket {
public ClientPlayerPositionPacket() {
this.pos = true;
}
public ClientPlayerPositionPacket(boolean onGround, double x, double stance, double y, double z) {
super(onGround);
this.pos = true;
this.x = x;
this.stance = stance;
this.y = y;
this.z = z;
}
}

View file

@ -0,0 +1,22 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
public class ClientPlayerPositionRotationPacket extends ClientPlayerMovementPacket {
public ClientPlayerPositionRotationPacket() {
this.pos = true;
this.rot = true;
}
public ClientPlayerPositionRotationPacket(boolean onGround, double x, double stance, double y, double z, double yaw, double pitch) {
super(onGround);
this.pos = true;
this.rot = true;
this.x = x;
this.stance = stance;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
}
}

View file

@ -0,0 +1,16 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
public class ClientPlayerRotationPacket extends ClientPlayerMovementPacket {
public ClientPlayerRotationPacket() {
this.rot = true;
}
public ClientPlayerRotationPacket(boolean onGround, double yaw, double pitch) {
super(onGround);
this.rot = true;
this.yaw = yaw;
this.pitch = pitch;
}
}

View file

@ -0,0 +1,63 @@
package ch.spacebase.mc.protocol.packet.ingame.client.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientSteerVehiclePacket implements Packet {
private float sideways;
private float forward;
private boolean jump;
private boolean dismount;
public ClientSteerVehiclePacket() {
}
public ClientSteerVehiclePacket(float sideways, float forward, boolean jump, boolean dismount) {
this.sideways = sideways;
this.forward = forward;
this.jump = jump;
this.dismount = dismount;
}
public float getSideways() {
return this.sideways;
}
public float getForward() {
return this.forward;
}
public boolean getJumping() {
return this.jump;
}
public boolean getDismounting() {
return this.dismount;
}
@Override
public void read(NetInput in) throws IOException {
this.sideways = in.readFloat();
this.forward = in.readFloat();
this.jump = in.readBoolean();
this.dismount = in.readBoolean();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeFloat(this.sideways);
out.writeFloat(this.forward);
out.writeBoolean(this.jump);
out.writeBoolean(this.dismount);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.client.window;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientCloseWindowPacket implements Packet {
private int windowId;
public ClientCloseWindowPacket() {
}
public ClientCloseWindowPacket(int windowId) {
this.windowId = windowId;
}
public int getWindowId() {
return this.windowId;
}
@Override
public void read(NetInput in) throws IOException {
this.windowId = in.readByte();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.windowId);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,55 @@
package ch.spacebase.mc.protocol.packet.ingame.client.window;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientConfirmTransactionPacket implements Packet {
private int windowId;
private int actionId;
private boolean accepted;
public ClientConfirmTransactionPacket() {
}
public ClientConfirmTransactionPacket(int windowId, int actionId, boolean accepted) {
this.windowId = windowId;
this.actionId = actionId;
this.accepted = accepted;
}
public int getWindowId() {
return this.windowId;
}
public int getActionId() {
return this.actionId;
}
public boolean getAccepted() {
return this.accepted;
}
@Override
public void read(NetInput in) throws IOException {
this.windowId = in.readByte();
this.actionId = in.readShort();
this.accepted = in.readBoolean();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.windowId);
out.writeShort(this.actionId);
out.writeBoolean(this.accepted);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,49 @@
package ch.spacebase.mc.protocol.packet.ingame.client.window;
import java.io.IOException;
import ch.spacebase.mc.protocol.data.game.ItemStack;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientCreativeInventoryActionPacket implements Packet {
private int slot;
private ItemStack clicked;
public ClientCreativeInventoryActionPacket() {
}
public ClientCreativeInventoryActionPacket(int slot, ItemStack clicked) {
this.slot = slot;
this.clicked = clicked;
}
public int getSlot() {
return this.slot;
}
public ItemStack getClickedItem() {
return this.clicked;
}
@Override
public void read(NetInput in) throws IOException {
this.slot = in.readShort();
this.clicked = NetUtil.readItem(in);
}
@Override
public void write(NetOutput out) throws IOException {
out.writeShort(this.slot);
NetUtil.writeItem(out, this.clicked);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,47 @@
package ch.spacebase.mc.protocol.packet.ingame.client.window;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientEnchantItemPacket implements Packet {
private int windowId;
private int enchantment;
public ClientEnchantItemPacket() {
}
public ClientEnchantItemPacket(int windowId, int enchantment) {
this.windowId = windowId;
this.enchantment = enchantment;
}
public int getWindowId() {
return this.windowId;
}
public int getEnchantment() {
return this.enchantment;
}
@Override
public void read(NetInput in) throws IOException {
this.windowId = in.readByte();
this.enchantment = in.readByte();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.windowId);
out.writeByte(this.enchantment);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,296 @@
package ch.spacebase.mc.protocol.packet.ingame.client.window;
import java.io.IOException;
import ch.spacebase.mc.protocol.data.game.ItemStack;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientWindowActionPacket implements Packet {
private int windowId;
private int slot;
private ActionParam param;
private int actionId;
private Action action;
private ItemStack clicked;
public ClientWindowActionPacket() {
}
public ClientWindowActionPacket(int windowId, int actionId, int slot, ItemStack clicked, Action action, ActionParam param) {
this.windowId = windowId;
this.actionId = actionId;
this.slot = slot;
this.clicked = clicked;
this.action = action;
this.param = param;
}
public int getWindowId() {
return this.windowId;
}
public int getActionId() {
return this.actionId;
}
public int getSlot() {
return this.slot;
}
public ItemStack getClickedItem() {
return this.clicked;
}
public Action getAction() {
return this.action;
}
public ActionParam getParam() {
return this.param;
}
@Override
public void read(NetInput in) throws IOException {
this.windowId = in.readByte();
this.slot = in.readShort();
byte param = in.readByte();
this.actionId = in.readShort();
byte id = in.readByte();
this.action = Action.values()[id];
this.clicked = NetUtil.readItem(in);
this.param = this.valueToParam(param);
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.windowId);
out.writeShort(this.slot);
out.writeByte(this.paramToValue(this.param));
out.writeShort(this.actionId);
out.writeByte(this.action.ordinal());
NetUtil.writeItem(out, this.clicked);
}
@Override
public boolean isPriority() {
return false;
}
private byte paramToValue(ActionParam param) throws IOException {
if(param == ClickItemParam.LEFT_CLICK) {
return 0;
} else if(param == ClickItemParam.RIGHT_CLICK) {
return 1;
}
if(param == ShiftClickItemParam.LEFT_CLICK) {
return 0;
} else if(param == ShiftClickItemParam.RIGHT_CLICK) {
return 1;
}
if(param == MoveToHotbarParam.SLOT_1) {
return 0;
} else if(param == MoveToHotbarParam.SLOT_2) {
return 1;
} else if(param == MoveToHotbarParam.SLOT_3) {
return 2;
} else if(param == MoveToHotbarParam.SLOT_4) {
return 3;
} else if(param == MoveToHotbarParam.SLOT_5) {
return 4;
} else if(param == MoveToHotbarParam.SLOT_6) {
return 5;
} else if(param == MoveToHotbarParam.SLOT_7) {
return 6;
} else if(param == MoveToHotbarParam.SLOT_8) {
return 7;
} else if(param == MoveToHotbarParam.SLOT_9) {
return 8;
}
if(param == CreativeGrabParam.GRAB) {
return 2;
}
if(param == DropItemParam.DROP_FROM_SELECTED) {
return 0;
} else if(param == DropItemParam.DROP_SELECTED_STACK) {
return 1;
} else if(param == DropItemParam.LEFT_CLICK_OUTSIDE_NOT_HOLDING) {
return 0;
} else if(param == DropItemParam.RIGHT_CLICK_OUTSIDE_NOT_HOLDING) {
return 1;
}
if(param == SpreadItemParam.LEFT_MOUSE_BEGIN_DRAG) {
return 0;
} else if(param == SpreadItemParam.LEFT_MOUSE_ADD_SLOT) {
return 1;
} else if(param == SpreadItemParam.LEFT_MOUSE_END_DRAG) {
return 2;
} else if(param == SpreadItemParam.RIGHT_MOUSE_BEGIN_DRAG) {
return 4;
} else if(param == SpreadItemParam.RIGHT_MOUSE_ADD_SLOT) {
return 5;
} else if(param == SpreadItemParam.RIGHT_MOUSE_END_DRAG) {
return 6;
}
if(param == FillStackParam.FILL) {
return 0;
}
throw new IOException("Unmapped action param: " + param);
}
private ActionParam valueToParam(byte value) throws IOException {
if(this.action == Action.CLICK_ITEM) {
if(value == 0) {
return ClickItemParam.LEFT_CLICK;
} else if(value == 1) {
return ClickItemParam.RIGHT_CLICK;
}
}
if(this.action == Action.SHIFT_CLICK_ITEM) {
if(value == 0) {
return ShiftClickItemParam.LEFT_CLICK;
} else if(value == 1) {
return ShiftClickItemParam.RIGHT_CLICK;
}
}
if(this.action == Action.MOVE_TO_HOTBAR_SLOT) {
if(value == 0) {
return MoveToHotbarParam.SLOT_1;
} else if(value == 1) {
return MoveToHotbarParam.SLOT_2;
} else if(value == 2) {
return MoveToHotbarParam.SLOT_3;
} else if(value == 3) {
return MoveToHotbarParam.SLOT_4;
} else if(value == 4) {
return MoveToHotbarParam.SLOT_5;
} else if(value == 5) {
return MoveToHotbarParam.SLOT_6;
} else if(value == 6) {
return MoveToHotbarParam.SLOT_7;
} else if(value == 7) {
return MoveToHotbarParam.SLOT_8;
} else if(value == 8) {
return MoveToHotbarParam.SLOT_9;
}
}
if(this.action == Action.CREATIVE_GRAB_MAX_STACK) {
if(value == 2) {
return CreativeGrabParam.GRAB;
}
}
if(this.action == Action.DROP_ITEM) {
if(this.slot == -999) {
if(value == 0) {
return DropItemParam.LEFT_CLICK_OUTSIDE_NOT_HOLDING;
} else if(value == 1) {
return DropItemParam.RIGHT_CLICK_OUTSIDE_NOT_HOLDING;
}
} else {
if(value == 0) {
return DropItemParam.DROP_FROM_SELECTED;
} else if(value == 1) {
return DropItemParam.DROP_SELECTED_STACK;
}
}
}
if(this.action == Action.SPREAD_ITEM) {
if(value == 0) {
return SpreadItemParam.LEFT_MOUSE_BEGIN_DRAG;
} else if(value == 1) {
return SpreadItemParam.LEFT_MOUSE_ADD_SLOT;
} else if(value == 2) {
return SpreadItemParam.LEFT_MOUSE_END_DRAG;
} else if(value == 4) {
return SpreadItemParam.RIGHT_MOUSE_BEGIN_DRAG;
} else if(value == 5) {
return SpreadItemParam.RIGHT_MOUSE_ADD_SLOT;
} else if(value == 6) {
return SpreadItemParam.RIGHT_MOUSE_END_DRAG;
}
}
if(this.action == Action.FILL_STACK) {
if(value == 0) {
return FillStackParam.FILL;
}
}
throw new IOException("Unknown action param value: " + value);
}
public static enum Action {
CLICK_ITEM,
SHIFT_CLICK_ITEM,
MOVE_TO_HOTBAR_SLOT,
CREATIVE_GRAB_MAX_STACK,
DROP_ITEM,
SPREAD_ITEM,
FILL_STACK;
}
public static interface ActionParam {
}
public static enum ClickItemParam implements ActionParam {
LEFT_CLICK,
RIGHT_CLICK;
}
public static enum ShiftClickItemParam implements ActionParam {
LEFT_CLICK,
RIGHT_CLICK;
}
public static enum MoveToHotbarParam implements ActionParam {
SLOT_1,
SLOT_2,
SLOT_3,
SLOT_4,
SLOT_5,
SLOT_6,
SLOT_7,
SLOT_8,
SLOT_9;
}
public static enum CreativeGrabParam implements ActionParam {
GRAB;
}
public static enum DropItemParam implements ActionParam {
DROP_FROM_SELECTED,
DROP_SELECTED_STACK,
LEFT_CLICK_OUTSIDE_NOT_HOLDING,
RIGHT_CLICK_OUTSIDE_NOT_HOLDING;
}
public static enum SpreadItemParam implements ActionParam {
LEFT_MOUSE_BEGIN_DRAG,
LEFT_MOUSE_ADD_SLOT,
LEFT_MOUSE_END_DRAG,
RIGHT_MOUSE_BEGIN_DRAG,
RIGHT_MOUSE_ADD_SLOT,
RIGHT_MOUSE_END_DRAG;
}
public static enum FillStackParam implements ActionParam {
FILL;
}
}

View file

@ -0,0 +1,72 @@
package ch.spacebase.mc.protocol.packet.ingame.client.world;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ClientUpdateSignPacket implements Packet {
private int x;
private int y;
private int z;
private String lines[];
public ClientUpdateSignPacket() {
}
public ClientUpdateSignPacket(int x, int y, int z, String lines[]) {
if(lines.length != 4) {
throw new IllegalArgumentException("Lines must contain exactly 4 strings!");
}
this.x = x;
this.y = y;
this.z = z;
this.lines = lines;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
public String[] getLines() {
return this.lines;
}
@Override
public void read(NetInput in) throws IOException {
this.x = in.readInt();
this.y = in.readShort();
this.z = in.readInt();
this.lines = new String[4];
for(int count = 0; count < this.lines.length; count++) {
this.lines[count] = in.readString();
}
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.x);
out.writeShort(this.y);
out.writeInt(this.z);
for(String line : this.lines) {
out.writeString(line);
}
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,48 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.mc.util.message.Message;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerChatPacket implements Packet {
private Message message;
public ServerChatPacket() {
}
public ServerChatPacket(String message) {
this(new Message(message));
}
public ServerChatPacket(Message message) {
this.message = message;
}
public String getRawMessage() {
return this.message.getRawText();
}
public Message getMessage() {
return this.message;
}
@Override
public void read(NetInput in) throws IOException {
this.message = new Message(in.readString(), true);
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.message.toString());
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,48 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.mc.util.message.Message;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerDisconnectPacket implements Packet {
private Message message;
public ServerDisconnectPacket() {
}
public ServerDisconnectPacket(String message) {
this(new Message(message));
}
public ServerDisconnectPacket(Message message) {
this.message = message;
}
public String getRawReason() {
return this.message.getRawText();
}
public Message getReason() {
return this.message;
}
@Override
public void read(NetInput in) throws IOException {
this.message = new Message(in.readString(), true);
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.message.toString());
}
@Override
public boolean isPriority() {
return true;
}
}

View file

@ -0,0 +1,149 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerJoinGamePacket implements Packet {
private int entityId;
private boolean hardcore;
private GameMode gamemode;
private int dimension;
private Difficulty difficulty;
private int maxPlayers;
private WorldType worldType;
public ServerJoinGamePacket() {
}
public ServerJoinGamePacket(int entityId, boolean hardcore, GameMode gamemode, int dimension, Difficulty difficulty, int maxPlayers, WorldType worldType) {
this.entityId = entityId;
this.hardcore = hardcore;
this.gamemode = gamemode;
this.dimension = dimension;
this.difficulty = difficulty;
this.maxPlayers = maxPlayers;
this.worldType = worldType;
}
public int getEntityId() {
return this.entityId;
}
public boolean getHardcore() {
return this.hardcore;
}
public GameMode getGameMode() {
return this.gamemode;
}
public int getDimension() {
return this.dimension;
}
public Difficulty getDifficulty() {
return this.difficulty;
}
public int getMaxPlayers() {
return this.maxPlayers;
}
public WorldType getWorldType() {
return this.worldType;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
int gamemode = in.readUnsignedByte();
this.hardcore = (gamemode & 8) == 8;
gamemode = gamemode & -9;
this.gamemode = GameMode.values()[gamemode];
this.dimension = in.readByte();
this.difficulty = Difficulty.values()[in.readUnsignedByte()];
this.maxPlayers = in.readUnsignedByte();
this.worldType = nameToType(in.readString());
// Unfortunately this is needed to check whether to read skylight values in chunk data packets.
NetUtil.hasSky = this.dimension != -1 && this.dimension != 1;
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
int gamemode = this.gamemode.ordinal();
if(this.hardcore) {
gamemode |= 8;
}
out.writeByte(gamemode);
out.writeByte(this.dimension);
out.writeByte(this.difficulty.ordinal());
out.writeByte(this.maxPlayers);
out.writeString(typeToName(this.worldType));
}
@Override
public boolean isPriority() {
return false;
}
private static String typeToName(WorldType type) throws IOException {
if(type == WorldType.DEFAULT) {
return "default";
} else if(type == WorldType.FLAT) {
return "flat";
} else if(type == WorldType.LARGE_BIOMES) {
return "largeBiomes";
} else if(type == WorldType.AMPLIFIED) {
return "amplified";
} else if(type == WorldType.DEFAULT_1_1) {
return "default_1_1";
} else {
throw new IOException("Unmapped world type: " + type);
}
}
private static WorldType nameToType(String name) throws IOException {
if(name.equals("default")) {
return WorldType.DEFAULT;
} else if(name.equals("flat")) {
return WorldType.FLAT;
} else if(name.equals("largeBiomes")) {
return WorldType.LARGE_BIOMES;
} else if(name.equals("amplified")) {
return WorldType.AMPLIFIED;
} else if(name.equals("default_1_1")) {
return WorldType.DEFAULT_1_1;
} else {
throw new IOException("Unknown world type: " + name);
}
}
public static enum GameMode {
SURVIVAL,
CREATIVE,
ADVENTURE;
}
public static enum Difficulty {
PEACEFUL,
EASY,
NORMAL,
HARD;
}
public static enum WorldType {
DEFAULT,
FLAT,
LARGE_BIOMES,
AMPLIFIED,
DEFAULT_1_1;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerKeepAlivePacket implements Packet {
private int id;
public ServerKeepAlivePacket() {
}
public ServerKeepAlivePacket(int id) {
this.id = id;
}
public int getPingId() {
return this.id;
}
@Override
public void read(NetInput in) throws IOException {
this.id = in.readInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.id);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,55 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerPlayerListEntryPacket implements Packet {
private String name;
private boolean online;
private int ping;
public ServerPlayerListEntryPacket() {
}
public ServerPlayerListEntryPacket(String name, boolean online, int ping) {
this.name = name;
this.online = online;
this.ping = ping;
}
public String getName() {
return this.name;
}
public boolean getOnline() {
return this.online;
}
public int getPing() {
return this.ping;
}
@Override
public void read(NetInput in) throws IOException {
this.name = in.readString();
this.online = in.readBoolean();
this.ping = in.readShort();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.name);
out.writeBoolean(this.online);
out.writeShort(this.ping);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,48 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerPluginMessagePacket implements Packet {
private String channel;
private byte data[];
public ServerPluginMessagePacket() {
}
public ServerPluginMessagePacket(String channel, byte data[]) {
this.channel = channel;
this.data = data;
}
public String getChannel() {
return this.channel;
}
public byte[] getData() {
return this.data;
}
@Override
public void read(NetInput in) throws IOException {
this.channel = in.readString();
this.data = in.readBytes(in.readShort());
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.channel);
out.writeShort(this.data.length);
out.writeBytes(this.data);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,119 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerRespawnPacket implements Packet {
private int dimension;
private Difficulty difficulty;
private GameMode gamemode;
private WorldType worldType;
public ServerRespawnPacket() {
}
public ServerRespawnPacket(int dimension, Difficulty difficulty, GameMode gamemode, WorldType worldType) {
this.dimension = dimension;
this.difficulty = difficulty;
this.gamemode = gamemode;
this.worldType = worldType;
}
public int getDimension() {
return this.dimension;
}
public Difficulty getDifficulty() {
return this.difficulty;
}
public GameMode getGameMode() {
return this.gamemode;
}
public WorldType getWorldType() {
return this.worldType;
}
@Override
public void read(NetInput in) throws IOException {
this.dimension = in.readInt();
this.difficulty = Difficulty.values()[in.readUnsignedByte()];
this.gamemode = GameMode.values()[in.readUnsignedByte()];
this.worldType = nameToType(in.readString());
// Unfortunately this is needed to check whether to read skylight values in chunk data packets.
NetUtil.hasSky = this.dimension != -1 && this.dimension != 1;
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.dimension);
out.writeByte(this.difficulty.ordinal());
out.writeByte(this.gamemode.ordinal());
out.writeString(typeToName(this.worldType));
}
@Override
public boolean isPriority() {
return false;
}
private static String typeToName(WorldType type) throws IOException {
if(type == WorldType.DEFAULT) {
return "default";
} else if(type == WorldType.FLAT) {
return "flat";
} else if(type == WorldType.LARGE_BIOMES) {
return "largeBiomes";
} else if(type == WorldType.AMPLIFIED) {
return "amplified";
} else if(type == WorldType.DEFAULT_1_1) {
return "default_1_1";
} else {
throw new IOException("Unmapped world type: " + type);
}
}
private static WorldType nameToType(String name) throws IOException {
if(name.equals("default")) {
return WorldType.DEFAULT;
} else if(name.equals("flat")) {
return WorldType.FLAT;
} else if(name.equals("largeBiomes")) {
return WorldType.LARGE_BIOMES;
} else if(name.equals("amplified")) {
return WorldType.AMPLIFIED;
} else if(name.equals("default_1_1")) {
return WorldType.DEFAULT_1_1;
} else {
throw new IOException("Unknown world type: " + name);
}
}
public static enum GameMode {
SURVIVAL,
CREATIVE,
ADVENTURE;
}
public static enum Difficulty {
PEACEFUL,
EASY,
NORMAL,
HARD;
}
public static enum WorldType {
DEFAULT,
FLAT,
LARGE_BIOMES,
AMPLIFIED,
DEFAULT_1_1;
}
}

View file

@ -0,0 +1,129 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerStatisticsPacket implements Packet {
private Map<String, Integer> statistics = new HashMap<String, Integer>();
public ServerStatisticsPacket() {
}
public ServerStatisticsPacket(Map<String, Integer> statistics) {
this.statistics = statistics;
}
public Map<String, Integer> getStatistics() {
return this.statistics;
}
@Override
public void read(NetInput in) throws IOException {
int length = in.readVarInt();
for(int index = 0; index < length; index++) {
this.statistics.put(in.readString(), in.readVarInt());
}
}
@Override
public void write(NetOutput out) throws IOException {
for(String statistic : this.statistics.keySet()) {
out.writeString(statistic);
out.writeVarInt(this.statistics.get(statistic));
}
}
@Override
public boolean isPriority() {
return false;
}
public static class Achievement {
public static final String OPEN_INVENTORY = "achievement.openInventory";
public static final String GET_WOOD = "achievement.mineWood";
public static final String MAKE_WORKBENCH = "achievement.buildWorkBench";
public static final String MAKE_PICKAXE = "achievement.buildPickaxe";
public static final String MAKE_FURNACE = "achievement.buildFurnace";
public static final String GET_IRON = "achievement.acquireIron";
public static final String MAKE_HOE = "achievement.buildHoe";
public static final String MAKE_BREAD = "achievement.makeBread";
public static final String MAKE_CAKE = "achievement.bakeCake";
public static final String MAKE_IRON_PICKAXE = "achievement.buildBetterPickaxe";
public static final String COOK_FISH = "achievement.cookFish";
public static final String RIDE_MINECART_1000_BLOCKS = "achievement.onARail";
public static final String MAKE_SWORD = "achievement.buildSword";
public static final String KILL_ENEMY = "achievement.killEnemy";
public static final String KILL_COW = "achievement.killCow";
public static final String FLY_PIG = "achievement.flyPig";
public static final String SNIPE_SKELETON = "achievement.snipeSkeleton";
public static final String GET_DIAMONDS = "achievement.diamonds";
public static final String GIVE_DIAMONDS = "achievement.diamondsToYou";
public static final String ENTER_PORTAL = "achievement.portal";
public static final String ATTACKED_BY_GHAST = "achievement.ghast";
public static final String GET_BLAZE_ROD = "achievement.blazeRod";
public static final String MAKE_POTION = "achievement.potion";
public static final String GO_TO_THE_END = "achievement.theEnd";
public static final String DEFEAT_ENDER_DRAGON = "achievement.theEnd2";
public static final String DEAL_18_OR_MORE_DAMAGE = "achievement.overkill";
public static final String MAKE_BOOKCASE = "achievement.bookcase";
public static final String BREED_COW = "achievement.breedCow";
public static final String SPAWN_WITHER = "achievement.spawnWither";
public static final String KILL_WITHER = "achievement.killWither";
public static final String MAKE_FULL_BEACON = "achievement.fullBeacon";
public static final String EXPLORE_ALL_BIOMES = "achievement.exploreAllBiomes";
}
public static class Statistic {
public static final String TIMES_LEFT_GAME = "stat.leaveGame";
public static final String MINUTES_PLAYED = "stat.playOneMinute";
public static final String BLOCKS_WALKED = "stat.walkOneCm";
public static final String BLOCKS_SWAM = "stat.swimOneCm";
public static final String BLOCKS_FALLEN = "stat.fallOneCm";
public static final String BLOCKS_CLIMBED = "stat.climbOneCm";
public static final String BLOCKS_FLOWN = "stat.flyOneCm";
public static final String BLOCKS_DOVE = "stat.diveOneCm";
public static final String BLOCKS_TRAVELLED_IN_MINECART = "stat.minecartOneCm";
public static final String BLOCKS_TRAVELLED_IN_BOAT = "stat.boatOneCm";
public static final String BLOCKS_RODE_ON_PIG = "stat.pigOneCm";
public static final String BLOCKS_RODE_ON_HORSE = "stat.horseOneCm";
public static final String TIMES_JUMPED = "stat.jump";
public static final String TIMES_DROPPED_ITEMS = "stat.drop";
public static final String TIMES_DEALT_DAMAGE = "stat.damageDealt";
public static final String DAMAGE_TAKEN = "stat.damageTaken";
public static final String DEATHS = "stat.deaths";
public static final String MOB_KILLS = "stat.mobKills";
public static final String ANIMALS_BRED = "stat.animalsBred";
public static final String PLAYERS_KILLED = "stat.playerKills";
public static final String FISH_CAUGHT = "stat.fishCaught";
public static final String JUNK_FISHED = "stat.junkFished";
public static final String TREASURE_FISHED = "stat.treasureFished";
private static final String CRAFT_ITEM_BASE = "stat.craftItem.";
private static final String BREAK_BLOCK_BASE = "stat.mineBlock.";
private static final String USE_ITEM_BASE = "stat.useItem.";
private static final String BREAK_ITEM_BASE = "stat.breakItem.";
public static final String CRAFT_ITEM(int id) {
return CRAFT_ITEM_BASE + id;
}
public static final String BREAK_BLOCK(int id) {
return BREAK_BLOCK_BASE + id;
}
public static final String USE_ITEM(int id) {
return USE_ITEM_BASE + id;
}
public static final String BREAK_ITEM(int id) {
return BREAK_ITEM_BASE + id;
}
}
}

View file

@ -0,0 +1,45 @@
package ch.spacebase.mc.protocol.packet.ingame.server;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerTabCompletePacket implements Packet {
private String matches[];
public ServerTabCompletePacket() {
}
public ServerTabCompletePacket(String matches[]) {
this.matches = matches;
}
public String[] getMatches() {
return this.matches;
}
@Override
public void read(NetInput in) throws IOException {
this.matches = new String[in.readVarInt()];
for(int index = 0; index < this.matches.length; index++) {
this.matches[index] = in.readString();
}
}
@Override
public void write(NetOutput out) throws IOException {
out.writeVarInt(this.matches.length);
for(String match : this.matches) {
out.writeString(match);
}
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,56 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerAnimationPacket implements Packet {
private int entityId;
private Animation animation;
public ServerAnimationPacket() {
}
public ServerAnimationPacket(int entityId, Animation animation) {
this.entityId = entityId;
this.animation = animation;
}
public int getEntityId() {
return this.entityId;
}
public Animation getAnimation() {
return this.animation;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.animation = Animation.values()[in.readByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(this.animation.ordinal());
}
@Override
public boolean isPriority() {
return false;
}
public static enum Animation {
SWING_ARM,
DAMAGE,
LEAVE_BED,
EAT_FOOD,
CRITICAL_HIT,
ENCHANTMENT_CRITICAL_HIT;
}
}

View file

@ -0,0 +1,47 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerCollectItemPacket implements Packet {
private int collectedEntityId;
private int collectorEntityId;
public ServerCollectItemPacket() {
}
public ServerCollectItemPacket(int collectedEntityId, int collectorEntityId) {
this.collectedEntityId = collectedEntityId;
this.collectorEntityId = collectorEntityId;
}
public int getCollectedEntityId() {
return this.collectedEntityId;
}
public int getCollectorEntityId() {
return this.collectorEntityId;
}
@Override
public void read(NetInput in) throws IOException {
this.collectedEntityId = in.readInt();
this.collectorEntityId = in.readInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.collectedEntityId);
out.writeInt(this.collectorEntityId);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,45 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerDestroyEntitiesPacket implements Packet {
private int entityIds[];
public ServerDestroyEntitiesPacket() {
}
public ServerDestroyEntitiesPacket(int... entityIds) {
this.entityIds = entityIds;
}
public int[] getEntityIds() {
return this.entityIds;
}
@Override
public void read(NetInput in) throws IOException {
this.entityIds = new int[in.readByte()];
for(int index = 0; index < this.entityIds.length; index++) {
this.entityIds[index] = in.readInt();
}
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.entityIds.length);
for(int entityId : this.entityIds) {
out.writeInt(entityId);
}
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,55 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityAttachPacket implements Packet {
private int entityId;
private int attachedToId;
private boolean leash;
public ServerEntityAttachPacket() {
}
public ServerEntityAttachPacket(int entityId, int attachedToId, boolean leash) {
this.entityId = entityId;
this.attachedToId = attachedToId;
this.leash = leash;
}
public int getEntityId() {
return this.entityId;
}
public int getAttachedToId() {
return this.attachedToId;
}
public boolean getLeash() {
return this.leash;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.attachedToId = in.readInt();
this.leash = in.readBoolean();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeInt(this.attachedToId);
out.writeBoolean(this.leash);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,89 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityEffectPacket implements Packet {
private int entityId;
private Effect effect;
private int amplifier;
private int duration;
public ServerEntityEffectPacket() {
}
public ServerEntityEffectPacket(int entityId, Effect effect, int amplifier, int duration) {
this.entityId = entityId;
this.effect = effect;
this.amplifier = amplifier;
this.duration = duration;
}
public int getEntityId() {
return this.entityId;
}
public Effect getEffect() {
return this.effect;
}
public int getAmplifier() {
return this.amplifier;
}
public int getDuration() {
return this.duration;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.effect = Effect.values()[in.readByte()];
this.amplifier = in.readByte();
this.duration = in.readShort();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(this.effect.ordinal());
out.writeByte(this.amplifier);
out.writeShort(this.duration);
}
@Override
public boolean isPriority() {
return false;
}
public static enum Effect {
SPEED,
SLOWNESS,
DIG_SPEED,
DIG_SLOWNESS,
DAMAGE_BOOST,
HEAL,
DAMAGE,
ENHANCED_JUMP,
CONFUSION,
REGENERATION,
RESISTANCE,
FIRE_RESISTANCE,
WATER_BREATHING,
INVISIBILITY,
BLINDNESS,
NIGHT_VISION,
HUNGER,
WEAKNESS,
POISON,
WITHER_EFFECT,
HEALTH_BOOST,
ABSORPTION,
SATURATION;
}
}

View file

@ -0,0 +1,57 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.mc.protocol.data.game.ItemStack;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityEquipmentPacket implements Packet {
private int entityId;
private int slot;
private ItemStack item;
public ServerEntityEquipmentPacket() {
}
public ServerEntityEquipmentPacket(int entityId, int slot, ItemStack item) {
this.entityId = entityId;
this.slot = slot;
this.item = item;
}
public int getEntityId() {
return this.entityId;
}
public int getSlot() {
return this.slot;
}
public ItemStack getItem() {
return this.item;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.slot = in.readShort();
this.item = NetUtil.readItem(in);
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeShort(this.slot);
NetUtil.writeItem(out, this.item);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,43 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityHeadLookPacket implements Packet {
protected int entityId;
protected float headYaw;
public ServerEntityHeadLookPacket() {
}
public ServerEntityHeadLookPacket(int entityId, float headYaw) {
this.entityId = entityId;
this.headYaw = headYaw;
}
public float getHeadYaw() {
return this.headYaw;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.headYaw = in.readByte() * 360 / 256f;
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte((byte) (this.headYaw * 256 / 360));
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,49 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.mc.protocol.data.game.EntityMetadata;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityMetadataPacket implements Packet {
private int entityId;
private EntityMetadata metadata[];
public ServerEntityMetadataPacket() {
}
public ServerEntityMetadataPacket(int entityId, EntityMetadata metadata[]) {
this.entityId = entityId;
this.metadata = metadata;
}
public int getEntityId() {
return this.entityId;
}
public EntityMetadata[] getMetadata() {
return this.metadata;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.metadata = NetUtil.readEntityMetadata(in);
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
NetUtil.writeEntityMetadata(out, this.metadata);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,87 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityMovementPacket implements Packet {
protected int entityId;
protected double moveX;
protected double moveY;
protected double moveZ;
protected float yaw;
protected float pitch;
protected boolean pos = false;
protected boolean rot = false;
public ServerEntityMovementPacket() {
}
public ServerEntityMovementPacket(int entityId) {
this.entityId = entityId;
}
public int getEntityId() {
return this.entityId;
}
public double getMovementX() {
return this.moveX;
}
public double getMovementY() {
return this.moveY;
}
public double getMovementZ() {
return this.moveZ;
}
public float getYaw() {
return this.yaw;
}
public float getPitch() {
return this.pitch;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
if(this.pos) {
this.moveX = in.readByte() / 32D;
this.moveY = in.readByte() / 32D;
this.moveZ = in.readByte() / 32D;
}
if(this.rot) {
this.yaw = in.readByte() * 360 / 256f;
this.pitch = in.readByte() * 360 / 256f;
}
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
if(this.pos) {
out.writeByte((int) (this.moveX * 32));
out.writeByte((int) (this.moveY * 32));
out.writeByte((int) (this.moveZ * 32));
}
if(this.rot) {
out.writeByte((byte) (this.yaw * 256 / 360));
out.writeByte((byte) (this.pitch * 256 / 360));
}
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,17 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
public class ServerEntityPositionPacket extends ServerEntityMovementPacket {
public ServerEntityPositionPacket() {
this.pos = true;
}
public ServerEntityPositionPacket(int entityId, double moveX, double moveY, double moveZ) {
super(entityId);
this.pos = true;
this.moveX = moveX;
this.moveY = moveY;
this.moveZ = moveZ;
}
}

View file

@ -0,0 +1,21 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
public class ServerEntityPositionRotationPacket extends ServerEntityMovementPacket {
public ServerEntityPositionRotationPacket() {
this.pos = true;
this.rot = true;
}
public ServerEntityPositionRotationPacket(int entityId, double moveX, double moveY, double moveZ, float yaw, float pitch) {
super(entityId);
this.pos = true;
this.rot = true;
this.moveX = moveX;
this.moveY = moveY;
this.moveZ = moveZ;
this.yaw = yaw;
this.pitch = pitch;
}
}

View file

@ -0,0 +1,75 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import ch.spacebase.mc.protocol.data.game.Attribute;
import ch.spacebase.mc.protocol.data.game.AttributeModifier;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityPropertiesPacket implements Packet {
private int entityId;
private List<Attribute> attributes;
public ServerEntityPropertiesPacket() {
}
public ServerEntityPropertiesPacket(int entityId, List<Attribute> attributes) {
this.entityId = entityId;
this.attributes = attributes;
}
public int getEntityId() {
return this.entityId;
}
public List<Attribute> getAttributes() {
return this.attributes;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.attributes = new ArrayList<Attribute>();
int length = in.readInt();
for(int index = 0; index < length; index++) {
String key = in.readString();
double value = in.readDouble();
List<AttributeModifier> modifiers = new ArrayList<AttributeModifier>();
short len = in.readShort();
for(int ind = 0; ind < len; ind++) {
modifiers.add(new AttributeModifier(new UUID(in.readLong(), in.readLong()), in.readDouble(), in.readByte()));
}
this.attributes.add(new Attribute(key, value, modifiers));
}
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeInt(this.attributes.size());
for(Attribute attribute : this.attributes) {
out.writeString(attribute.getKey());
out.writeDouble(attribute.getValue());
out.writeShort(attribute.getModifiers().size());
for(AttributeModifier modifier : attribute.getModifiers()) {
out.writeLong(modifier.getUUID().getMostSignificantBits());
out.writeLong(modifier.getUUID().getLeastSignificantBits());
out.writeDouble(modifier.getAmount());
out.writeByte(modifier.getOperation());
}
}
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,89 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityRemoveEffectPacket implements Packet {
private int entityId;
private Effect effect;
private int amplifier;
private int duration;
public ServerEntityRemoveEffectPacket() {
}
public ServerEntityRemoveEffectPacket(int entityId, Effect effect, int amplifier, int duration) {
this.entityId = entityId;
this.effect = effect;
this.amplifier = amplifier;
this.duration = duration;
}
public int getEntityId() {
return this.entityId;
}
public Effect getEffect() {
return this.effect;
}
public int getAmplifier() {
return this.amplifier;
}
public int getDuration() {
return this.duration;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.effect = Effect.values()[in.readByte()];
this.amplifier = in.readByte();
this.duration = in.readShort();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(this.effect.ordinal());
out.writeByte(this.amplifier);
out.writeShort(this.duration);
}
@Override
public boolean isPriority() {
return false;
}
public static enum Effect {
SPEED,
SLOWNESS,
DIG_SPEED,
DIG_SLOWNESS,
DAMAGE_BOOST,
HEAL,
DAMAGE,
ENHANCED_JUMP,
CONFUSION,
REGENERATION,
RESISTANCE,
FIRE_RESISTANCE,
WATER_BREATHING,
INVISIBILITY,
BLINDNESS,
NIGHT_VISION,
HUNGER,
WEAKNESS,
POISON,
WITHER_EFFECT,
HEALTH_BOOST,
ABSORPTION,
SATURATION;
}
}

View file

@ -0,0 +1,16 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
public class ServerEntityRotationPacket extends ServerEntityMovementPacket {
public ServerEntityRotationPacket() {
this.rot = true;
}
public ServerEntityRotationPacket(int entityId, float yaw, float pitch) {
super(entityId);
this.rot = true;
this.yaw = yaw;
this.pitch = pitch;
}
}

View file

@ -0,0 +1,145 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityStatusPacket implements Packet {
protected int entityId;
protected Status status;
public ServerEntityStatusPacket() {
}
public ServerEntityStatusPacket(int entityId, Status status) {
this.entityId = entityId;
this.status = status;
}
public Status getStatus() {
return this.status;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.status = valueToStatus(in.readByte());
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(statusToValue(this.status));
}
@Override
public boolean isPriority() {
return false;
}
private static byte statusToValue(Status status) throws IOException {
switch(status) {
case HURT_OR_MINECART_SPAWNER_DELAY_RESET:
return 1;
case LIVING_HURT:
return 2;
case DEAD:
return 3;
case IRON_GOLEM_THROW:
return 4;
case TAMING:
return 6;
case TAMED:
return 7;
case WOLF_SHAKING:
return 8;
case FINISHED_EATING:
return 9;
case SHEEP_GRAZING_OR_TNT_CART_EXPLODING:
return 10;
case IRON_GOLEM_ROSE:
return 11;
case VILLAGER_HEARTS:
return 12;
case VILLAGER_ANGRY:
return 13;
case VILLAGER_HAPPY:
return 14;
case WITCH_MAGIC_PARTICLES:
return 15;
case ZOMBIE_VILLAGER_SHAKING:
return 16;
case FIREWORK_EXPLODING:
return 17;
case ANIMAL_HEARTS:
return 18;
default:
throw new IOException("Unmapped entity status: " + status);
}
}
private static Status valueToStatus(byte value) throws IOException {
switch(value) {
case 1:
return Status.HURT_OR_MINECART_SPAWNER_DELAY_RESET;
case 2:
return Status.LIVING_HURT;
case 3:
return Status.DEAD;
case 4:
return Status.IRON_GOLEM_THROW;
case 6:
return Status.TAMING;
case 7:
return Status.TAMED;
case 8:
return Status.WOLF_SHAKING;
case 9:
return Status.FINISHED_EATING;
case 10:
return Status.SHEEP_GRAZING_OR_TNT_CART_EXPLODING;
case 11:
return Status.IRON_GOLEM_ROSE;
case 12:
return Status.VILLAGER_HEARTS;
case 13:
return Status.VILLAGER_ANGRY;
case 14:
return Status.VILLAGER_HAPPY;
case 15:
return Status.WITCH_MAGIC_PARTICLES;
case 16:
return Status.ZOMBIE_VILLAGER_SHAKING;
case 17:
return Status.FIREWORK_EXPLODING;
case 18:
return Status.ANIMAL_HEARTS;
default:
throw new IOException("Unknown entity status value: " + value);
}
}
public static enum Status {
HURT_OR_MINECART_SPAWNER_DELAY_RESET,
LIVING_HURT,
DEAD,
IRON_GOLEM_THROW,
TAMING,
TAMED,
WOLF_SHAKING,
FINISHED_EATING,
SHEEP_GRAZING_OR_TNT_CART_EXPLODING,
IRON_GOLEM_ROSE,
VILLAGER_HEARTS,
VILLAGER_ANGRY,
VILLAGER_HAPPY,
WITCH_MAGIC_PARTICLES,
ZOMBIE_VILLAGER_SHAKING,
FIREWORK_EXPLODING,
ANIMAL_HEARTS;
}
}

View file

@ -0,0 +1,79 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityTeleportPacket implements Packet {
protected int entityId;
protected double x;
protected double y;
protected double z;
protected float yaw;
protected float pitch;
public ServerEntityTeleportPacket() {
}
public ServerEntityTeleportPacket(int entityId, double x, double y, double z, float yaw, float pitch) {
this.entityId = entityId;
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
}
public int getEntityId() {
return this.entityId;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public double getZ() {
return this.z;
}
public float getYaw() {
return this.yaw;
}
public float getPitch() {
return this.pitch;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.x = in.readInt() / 32D;
this.y = in.readInt() / 32D;
this.z = in.readInt() / 32D;
this.yaw = in.readByte() * 360 / 256f;
this.pitch = in.readByte() * 360 / 256f;
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeInt((int) (this.x * 32));
out.writeInt((int) (this.y * 32));
out.writeInt((int) (this.z * 32));
out.writeByte((byte) (this.yaw * 256 / 360));
out.writeByte((byte) (this.pitch * 256 / 360));
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,63 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerEntityVelocityPacket implements Packet {
private int entityId;
private double motX;
private double motY;
private double motZ;
public ServerEntityVelocityPacket() {
}
public ServerEntityVelocityPacket(int entityId, double motX, double motY, double motZ) {
this.entityId = entityId;
this.motX = motX;
this.motY = motY;
this.motZ = motZ;
}
public int getEntityId() {
return this.entityId;
}
public double getMotionX() {
return this.motX;
}
public double getMotionY() {
return this.motY;
}
public double getMotionZ() {
return this.motZ;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.motX = in.readShort() / 8000D;
this.motY = in.readShort() / 8000D;
this.motZ = in.readShort() / 8000D;
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeShort((int) (this.motX * 8000));
out.writeShort((int) (this.motY * 8000));
out.writeShort((int) (this.motZ * 8000));
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,73 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerRemoveEffectPacket implements Packet {
private int entityId;
private Effect effect;
public ServerRemoveEffectPacket() {
}
public ServerRemoveEffectPacket(int entityId, Effect effect) {
this.entityId = entityId;
this.effect = effect;
}
public int getEntityId() {
return this.entityId;
}
public Effect getEffect() {
return this.effect;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.effect = Effect.values()[in.readByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeByte(this.effect.ordinal());
}
@Override
public boolean isPriority() {
return false;
}
public static enum Effect {
SPEED,
SLOWNESS,
DIG_SPEED,
DIG_SLOWNESS,
DAMAGE_BOOST,
HEAL,
DAMAGE,
ENHANCED_JUMP,
CONFUSION,
REGENERATION,
RESISTANCE,
FIRE_RESISTANCE,
WATER_BREATHING,
INVISIBILITY,
BLINDNESS,
NIGHT_VISION,
HUNGER,
WEAKNESS,
POISON,
WITHER_EFFECT,
HEALTH_BOOST,
ABSORPTION,
SATURATION;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerChangeHeldItemPacket implements Packet {
private int slot;
public ServerChangeHeldItemPacket() {
}
public ServerChangeHeldItemPacket(int slot) {
this.slot = slot;
}
public int getSlot() {
return this.slot;
}
@Override
public void read(NetInput in) throws IOException {
this.slot = in.readByte();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.slot);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,94 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerPlayerAbilitiesPacket implements Packet {
private boolean invincible;
private boolean canFly;
private boolean flying;
private boolean creative;
private float flySpeed;
private float walkSpeed;
public ServerPlayerAbilitiesPacket() {
}
public ServerPlayerAbilitiesPacket(boolean invincible, boolean canFly, boolean flying, boolean creative, float flySpeed, float walkSpeed) {
this.invincible = invincible;
this.canFly = canFly;
this.flying = flying;
this.creative = creative;
this.flySpeed = flySpeed;
this.walkSpeed = walkSpeed;
}
public boolean getInvincible() {
return this.invincible;
}
public boolean getCanFly() {
return this.canFly;
}
public boolean getFlying() {
return this.flying;
}
public boolean getCreative() {
return this.creative;
}
public float getFlySpeed() {
return this.flySpeed;
}
public float getWalkSpeed() {
return this.walkSpeed;
}
@Override
public void read(NetInput in) throws IOException {
byte flags = in.readByte();
this.invincible = (flags & 1) > 0;
this.canFly = (flags & 2) > 0;
this.flying = (flags & 4) > 0;
this.creative = (flags & 8) > 0;
this.flySpeed = in.readFloat();
this.walkSpeed = in.readFloat();
}
@Override
public void write(NetOutput out) throws IOException {
byte flags = 0;
if(this.invincible) {
flags = (byte) (flags | 1);
}
if(this.canFly) {
flags = (byte) (flags | 2);
}
if(this.flying) {
flags = (byte) (flags | 4);
}
if(this.creative) {
flags = (byte) (flags | 8);
}
out.writeByte(flags);
out.writeFloat(this.flySpeed);
out.writeFloat(this.walkSpeed);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,79 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerPlayerPositionRotationPacket implements Packet {
protected double x;
protected double y;
protected double z;
protected float yaw;
protected float pitch;
protected boolean onGround;
public ServerPlayerPositionRotationPacket() {
}
public ServerPlayerPositionRotationPacket(double x, double y, double z, float yaw, float pitch, boolean onGround) {
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
this.onGround = onGround;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public double getZ() {
return this.z;
}
public float getYaw() {
return this.yaw;
}
public float getPitch() {
return this.pitch;
}
public boolean isOnGround() {
return this.onGround;
}
@Override
public void read(NetInput in) throws IOException {
this.x = in.readDouble();
this.y = in.readDouble();
this.z = in.readDouble();
this.yaw = in.readFloat();
this.pitch = in.readFloat();
this.onGround = in.readBoolean();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeDouble(this.x);
out.writeDouble(this.y);
out.writeDouble(this.z);
out.writeFloat(this.yaw);
out.writeFloat(this.pitch);
out.writeBoolean(this.onGround);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,63 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerPlayerUseBedPacket implements Packet {
private int entityId;
private int x;
private int y;
private int z;
public ServerPlayerUseBedPacket() {
}
public ServerPlayerUseBedPacket(int entityId, int x, int y, int z) {
this.entityId = entityId;
this.x = x;
this.y = y;
this.z = z;
}
public int getEntityId() {
return this.entityId;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readInt();
this.x = in.readInt();
this.y = in.readUnsignedByte();
this.z = in.readInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeInt(this.entityId);
out.writeInt(this.x);
out.writeByte(this.y);
out.writeInt(this.z);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,39 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerSetExperiencePacket implements Packet {
private int slot;
public ServerSetExperiencePacket() {
}
public ServerSetExperiencePacket(int slot) {
this.slot = slot;
}
public int getSlot() {
return this.slot;
}
@Override
public void read(NetInput in) throws IOException {
this.slot = in.readByte();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeByte(this.slot);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,55 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity.player;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerUpdateHealthPacket implements Packet {
private float health;
private int food;
private float saturation;
public ServerUpdateHealthPacket() {
}
public ServerUpdateHealthPacket(float health, int food, float saturation) {
this.health = health;
this.food = food;
this.saturation = saturation;
}
public float getHealth() {
return this.health;
}
public int getFood() {
return this.food;
}
public float getSaturation() {
return this.saturation;
}
@Override
public void read(NetInput in) throws IOException {
this.health = in.readFloat();
this.food = in.readShort();
this.saturation = in.readFloat();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeFloat(this.health);
out.writeShort(this.food);
out.writeFloat(this.saturation);
}
@Override
public boolean isPriority() {
return false;
}
}

View file

@ -0,0 +1,71 @@
package ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn;
import java.io.IOException;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
public class ServerSpawnExpOrbPacket implements Packet {
private int entityId;
private double x;
private double y;
private double z;
private int exp;
public ServerSpawnExpOrbPacket() {
}
public ServerSpawnExpOrbPacket(int entityId, double x, double y, double z, int exp) {
this.entityId = entityId;
this.x = x;
this.y = y;
this.z = z;
this.exp = exp;
}
public int getEntityId() {
return this.entityId;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public double getZ() {
return this.z;
}
public int getExp() {
return this.exp;
}
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readVarInt();
this.x = in.readInt() / 32D;
this.y = in.readInt() / 32D;
this.z = in.readInt() / 32D;
this.exp = in.readShort();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeVarInt(this.entityId);
out.writeInt((int) (this.x * 32));
out.writeInt((int) (this.y * 32));
out.writeInt((int) (this.z * 32));
out.writeShort(this.exp);
}
@Override
public boolean isPriority() {
return false;
}
}

Some files were not shown because too many files have changed in this diff Show more