I think this is enough.

This commit is contained in:
Final Child 2016-05-15 17:30:23 +09:00
parent a1571ed0cb
commit 8ac2ac9a0f
4 changed files with 47 additions and 21 deletions

View file

@ -56,12 +56,12 @@ public class MinecraftProtocol extends PacketProtocol {
} }
public MinecraftProtocol(SubProtocol subProtocol) { public MinecraftProtocol(SubProtocol subProtocol) {
if(subProtocol != SubProtocol.LOGIN && subProtocol != SubProtocol.STATUS) { if (subProtocol != SubProtocol.LOGIN && subProtocol != SubProtocol.STATUS) {
throw new IllegalArgumentException("Only login and status modes are permitted."); throw new IllegalArgumentException("Only login and status modes are permitted.");
} }
this.subProtocol = subProtocol; this.subProtocol = subProtocol;
if(subProtocol == SubProtocol.LOGIN) { if (subProtocol == SubProtocol.LOGIN) {
this.profile = new GameProfile((UUID) null, "Player"); this.profile = new GameProfile((UUID) null, "Player");
} }
} }
@ -84,7 +84,7 @@ public class MinecraftProtocol extends PacketProtocol {
String clientToken = UUID.randomUUID().toString(); String clientToken = UUID.randomUUID().toString();
AuthenticationService auth = new AuthenticationService(clientToken, authProxy); AuthenticationService auth = new AuthenticationService(clientToken, authProxy);
auth.setUsername(username); auth.setUsername(username);
if(token) { if (token) {
auth.setAccessToken(using); auth.setAccessToken(using);
} else { } else {
auth.setPassword(using); auth.setPassword(using);
@ -126,7 +126,7 @@ public class MinecraftProtocol extends PacketProtocol {
@Override @Override
public void newClientSession(Client client, Session session) { public void newClientSession(Client client, Session session) {
if(this.profile != null) { if (this.profile != null) {
session.setFlag(MinecraftConstants.PROFILE_KEY, this.profile); session.setFlag(MinecraftConstants.PROFILE_KEY, this.profile);
session.setFlag(MinecraftConstants.ACCESS_TOKEN_KEY, this.accessToken); session.setFlag(MinecraftConstants.ACCESS_TOKEN_KEY, this.accessToken);
} }
@ -144,7 +144,7 @@ public class MinecraftProtocol extends PacketProtocol {
protected void enableEncryption(Key key) { protected void enableEncryption(Key key) {
try { try {
this.encrypt = new AESEncryption(key); this.encrypt = new AESEncryption(key);
} catch(GeneralSecurityException e) { } catch (GeneralSecurityException e) {
throw new Error("Failed to enable protocol encryption.", e); throw new Error("Failed to enable protocol encryption.", e);
} }
} }
@ -155,9 +155,9 @@ public class MinecraftProtocol extends PacketProtocol {
protected void setSubProtocol(SubProtocol subProtocol, boolean client, Session session) { protected void setSubProtocol(SubProtocol subProtocol, boolean client, Session session) {
this.clearPackets(); this.clearPackets();
switch(subProtocol) { switch (subProtocol) {
case HANDSHAKE: case HANDSHAKE:
if(client) { if (client) {
this.initClientHandshake(session); this.initClientHandshake(session);
} else { } else {
this.initServerHandshake(session); this.initServerHandshake(session);
@ -165,7 +165,7 @@ public class MinecraftProtocol extends PacketProtocol {
break; break;
case LOGIN: case LOGIN:
if(client) { if (client) {
this.initClientLogin(session); this.initClientLogin(session);
} else { } else {
this.initServerLogin(session); this.initServerLogin(session);
@ -173,7 +173,7 @@ public class MinecraftProtocol extends PacketProtocol {
break; break;
case GAME: case GAME:
if(client) { if (client) {
this.initClientGame(session); this.initClientGame(session);
} else { } else {
this.initServerGame(session); this.initServerGame(session);
@ -181,7 +181,7 @@ public class MinecraftProtocol extends PacketProtocol {
break; break;
case STATUS: case STATUS:
if(client) { if (client) {
this.initClientStatus(session); this.initClientStatus(session);
} else { } else {
this.initServerStatus(session); this.initServerStatus(session);

View file

@ -1,19 +1,21 @@
package org.spacehq.mc.protocol.data.game.chunk; package org.spacehq.mc.protocol.data.game.chunk;
//TODO: Chunk Data (0x20) now also sends all tile entities in the chunk (at the end of the packet) import org.spacehq.opennbt.tag.builtin.CompoundTag;
public class Column { public class Column {
private int x; private int x;
private int z; private int z;
private Chunk chunks[]; private Chunk chunks[];
private byte biomeData[]; private byte biomeData[];
private CompoundTag tileEntities[];
private boolean skylight; private boolean skylight;
public Column(int x, int z, Chunk chunks[]) { public Column(int x, int z, Chunk chunks[], CompoundTag tileEntities[]) {
this(x, z, chunks, null); this(x, z, chunks, null, tileEntities);
} }
public Column(int x, int z, Chunk chunks[], byte biomeData[]) { public Column(int x, int z, Chunk chunks[], byte biomeData[], CompoundTag tileEntities[]) {
if(chunks.length != 16) { if(chunks.length != 16) {
throw new IllegalArgumentException("Chunk array length must be 16."); throw new IllegalArgumentException("Chunk array length must be 16.");
} }
@ -24,9 +26,9 @@ public class Column {
this.skylight = false; this.skylight = false;
boolean noSkylight = false; boolean noSkylight = false;
for(int index = 0; index < chunks.length; index++) { for (Chunk chunk : chunks) {
if(chunks[index] != null) { if (chunk != null) {
if(chunks[index].getSkyLight() == null) { if (chunk.getSkyLight() == null) {
noSkylight = true; noSkylight = true;
} else { } else {
this.skylight = true; this.skylight = true;
@ -42,6 +44,7 @@ public class Column {
this.z = z; this.z = z;
this.chunks = chunks; this.chunks = chunks;
this.biomeData = biomeData; this.biomeData = biomeData;
this.tileEntities = tileEntities;
} }
public int getX() { public int getX() {
@ -64,6 +67,10 @@ public class Column {
return this.biomeData; return this.biomeData;
} }
public CompoundTag[] getTileEntities() {
return this.tileEntities;
}
public boolean hasSkylight() { public boolean hasSkylight() {
return this.skylight; return this.skylight;
} }

View file

@ -3,6 +3,7 @@ package org.spacehq.mc.protocol.packet.ingame.server.world;
import org.spacehq.mc.protocol.data.game.chunk.Column; import org.spacehq.mc.protocol.data.game.chunk.Column;
import org.spacehq.mc.protocol.util.NetUtil; import org.spacehq.mc.protocol.util.NetUtil;
import org.spacehq.mc.protocol.util.ReflectionToString; import org.spacehq.mc.protocol.util.ReflectionToString;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import org.spacehq.packetlib.io.NetInput; import org.spacehq.packetlib.io.NetInput;
import org.spacehq.packetlib.io.NetOutput; import org.spacehq.packetlib.io.NetOutput;
import org.spacehq.packetlib.io.stream.StreamNetOutput; import org.spacehq.packetlib.io.stream.StreamNetOutput;
@ -33,8 +34,9 @@ public class ServerChunkDataPacket implements Packet {
boolean fullChunk = in.readBoolean(); boolean fullChunk = in.readBoolean();
int chunkMask = in.readVarInt(); int chunkMask = in.readVarInt();
byte data[] = in.readBytes(in.readVarInt()); byte data[] = in.readBytes(in.readVarInt());
byte tileEntityData[] = in.readBytes(in.readVarInt());
this.column = NetUtil.readColumn(data, x, z, fullChunk, false, chunkMask); this.column = NetUtil.readColumn(data, x, z, fullChunk, false, chunkMask, tileEntityData);
} }
@Override @Override
@ -49,6 +51,16 @@ public class ServerChunkDataPacket implements Packet {
out.writeVarInt(mask); out.writeVarInt(mask);
out.writeVarInt(byteOut.size()); out.writeVarInt(byteOut.size());
out.writeBytes(byteOut.toByteArray(), byteOut.size()); out.writeBytes(byteOut.toByteArray(), byteOut.size());
ByteArrayOutputStream tileEntitiesByteOut = new ByteArrayOutputStream();
NetOutput tileEntitiesNetOut = new StreamNetOutput(tileEntitiesByteOut);
for (CompoundTag compoundTag : column.getTileEntities()) {
NetUtil.writeNBT(tileEntitiesNetOut, compoundTag);
}
out.writeVarInt(tileEntitiesByteOut.size());
out.writeBytes(tileEntitiesByteOut.toByteArray(), tileEntitiesByteOut.size());
} }
@Override @Override

View file

@ -236,8 +236,9 @@ public class NetUtil {
out.writeByte(255); out.writeByte(255);
} }
public static Column readColumn(byte data[], int x, int z, boolean fullChunk, boolean hasSkylight, int mask) throws IOException { public static Column readColumn(byte data[], int x, int z, boolean fullChunk, boolean hasSkylight, int mask, byte tileEntityData[]) throws IOException {
NetInput in = new StreamNetInput(new ByteArrayInputStream(data)); NetInput in = new StreamNetInput(new ByteArrayInputStream(data));
NetInput tileEntityIn = new StreamNetInput(new ByteArrayInputStream(tileEntityData));
Exception ex = null; Exception ex = null;
Column column = null; Column column = null;
try { try {
@ -256,14 +257,20 @@ public class NetUtil {
biomeData = in.readBytes(256); biomeData = in.readBytes(256);
} }
column = new Column(x, z, chunks, biomeData); int available = tileEntityIn.available();
List<CompoundTag> tileEntities = new ArrayList<CompoundTag>();
while (available > 0) {
tileEntities.add(NetUtil.readNBT(tileEntityIn));
available = tileEntityIn.available();
}
column = new Column(x, z, chunks, biomeData, tileEntities.toArray(new CompoundTag[tileEntities.size()]));
} catch(Exception e) { } catch(Exception e) {
ex = e; ex = e;
} }
// Unfortunately, this is needed to detect whether the chunks contain skylight or not. // Unfortunately, this is needed to detect whether the chunks contain skylight or not.
if((in.available() > 0 || ex != null) && !hasSkylight) { if((in.available() > 0 || ex != null) && !hasSkylight) {
return readColumn(data, x, z, fullChunk, true, mask); return readColumn(data, x, z, fullChunk, true, mask, tileEntityData);
} else if(ex != null) { } else if(ex != null) {
throw new IOException("Failed to read chunk data.", ex); throw new IOException("Failed to read chunk data.", ex);
} }