diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index bc13c5e13..8f78fb2b9 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -170,6 +170,7 @@
+
diff --git a/ClassicalSharp/Model/CustomModel.cs b/ClassicalSharp/Model/CustomModel.cs
new file mode 100644
index 000000000..1a0ac5eac
--- /dev/null
+++ b/ClassicalSharp/Model/CustomModel.cs
@@ -0,0 +1,81 @@
+using System;
+using ClassicalSharp.GraphicsAPI;
+using OpenTK;
+
+namespace ClassicalSharp.Model {
+
+ public class CustomModel : IModel {
+
+ public CustomModel( Game window ) : base( window ) {
+ }
+
+ internal bool bobbing;
+ public override bool Bobbing { get { return bobbing; } }
+
+ internal float nameYOffset;
+ public override float NameYOffset { get { return nameYOffset; } }
+
+ internal float eyeY;
+ public override float GetEyeY( Entity entity ) { return eyeY; }
+
+ internal Vector3 collisonSize;
+ public override Vector3 CollisionSize { get { return collisonSize; } }
+
+ internal BoundingBox pickingBounds;
+ public override BoundingBox PickingBounds { get { return pickingBounds; } }
+
+ protected override void DrawModel( Player p ) {
+ int texId = p.PlayerTextureId <= 0 ? cache.HumanoidTexId : p.PlayerTextureId;
+ }
+
+ internal void ReadMetadataPacket( NetReader reader ) {
+ collisonSize = ReadVector( reader );
+ pickingBounds.Min = ReadVector( reader );
+ pickingBounds.Max = ReadVector( reader );
+ nameYOffset = reader.ReadInt16() / 256f;
+ eyeY = reader.ReadInt16() / 256f;
+ bobbing = reader.ReadUInt8() != 0;
+ }
+
+ internal void ReadDefinePartPacket( NetReader reader ) {
+ ushort partId = reader.ReadUInt16();
+ byte type = reader.ReadUInt8();
+ Vector3 min = ReadVector( reader );
+ Vector3 max = ReadVector( reader );
+ }
+
+ internal void ReadRotationPacket( NetReader reader ) {
+ ushort partId = reader.ReadUInt16();
+ byte order = reader.ReadUInt8();
+ RotateData rotX = ReadRotateData( reader );
+ RotateData rotY = ReadRotateData( reader );
+ RotateData rotZ = ReadRotateData( reader );
+ }
+
+ CustomModelPart[] parts;
+ Vector3 ReadVector( NetReader reader ) {
+ return new Vector3( reader.ReadInt16() / 256f, reader.ReadInt16() / 256f,
+ reader.ReadInt16() / 256f );
+ }
+
+ RotateData ReadRotateData( NetReader reader ) {
+ RotateData data = default(RotateData);
+ data.Origin = reader.ReadInt16() / 256f;
+ data.Type = reader.ReadUInt8();
+ data.VarA = reader.ReadInt16() / 512f;
+ data.VarB = reader.ReadInt16() / 512f;
+ return data;
+ }
+
+ struct CustomModelPart {
+ public RotateOrder Order;
+ public RotateData RotX, RotY, RotZ;
+ }
+
+ struct RotateData {
+ public float Origin;
+ public byte Type;
+ public float VarA, VarB;
+ }
+ }
+}
diff --git a/ClassicalSharp/Network/Enums.cs b/ClassicalSharp/Network/Enums.cs
index b8de7f602..f9669e926 100644
--- a/ClassicalSharp/Network/Enums.cs
+++ b/ClassicalSharp/Network/Enums.cs
@@ -44,6 +44,7 @@ namespace ClassicalSharp {
CpeDefineBlockExt = 37,
CpeBulkBlockUpdate = 38,
CpeSetTextColor = 39,
+ CpeDefineModel = 40,
}
public enum MessageType {
diff --git a/ClassicalSharp/Network/NetworkProcessor.CPE.cs b/ClassicalSharp/Network/NetworkProcessor.CPE.cs
index c377814f2..82e6a9199 100644
--- a/ClassicalSharp/Network/NetworkProcessor.CPE.cs
+++ b/ClassicalSharp/Network/NetworkProcessor.CPE.cs
@@ -502,6 +502,23 @@ namespace ClassicalSharp {
game.Events.RaiseColourCodesChanged();
}
+ void HandleDefineModel() {
+ int start = reader.index - 1;
+ byte modelId = reader.ReadUInt8();
+ switch( reader.ReadUInt8() ) {
+ case 0: // setup
+ break;
+ case 1: // metadata
+ break;
+ case 2: // define part
+ break;
+ case 3: // rotation
+ break;
+ }
+ int read = reader.index - start;
+ // TODO: skip remaining data
+ }
+
internal static SoundType[] stepSnds, breakSnds;
static NetworkProcessor() {
stepSnds = new SoundType[10];
diff --git a/ClassicalSharp/Network/Utils/GZipHeaderReader.cs b/ClassicalSharp/Network/Utils/GZipHeaderReader.cs
index f1577966e..f02986a85 100644
--- a/ClassicalSharp/Network/Utils/GZipHeaderReader.cs
+++ b/ClassicalSharp/Network/Utils/GZipHeaderReader.cs
@@ -6,17 +6,9 @@ namespace ClassicalSharp {
internal class GZipHeaderReader {
enum State {
- Header1,
- Header2,
- CompressionMethod,
- Flags,
- LastModifiedTime,
- CompressionFlags,
- OperatingSystem,
- HeaderChecksum,
- Filename,
- Comment,
- Done,
+ Header1, Header2, CompressionMethod, Flags,
+ LastModifiedTime, CompressionFlags, OperatingSystem,
+ HeaderChecksum, Filename, Comment, Done,
}
State state = State.Header1;
diff --git a/ClassicalSharp/Network/Utils/NetReader.cs b/ClassicalSharp/Network/Utils/NetReader.cs
index 3c4843c41..bc54c35e6 100644
--- a/ClassicalSharp/Network/Utils/NetReader.cs
+++ b/ClassicalSharp/Network/Utils/NetReader.cs
@@ -52,6 +52,12 @@ namespace ClassicalSharp {
return value;
}
+ public ushort ReadUInt16() {
+ ushort value = (ushort)(buffer[index] << 8 | buffer[index + 1]);
+ index += 2;
+ return value;
+ }
+
public byte ReadUInt8() {
byte value = buffer[index];
index++;
@@ -66,13 +72,13 @@ namespace ClassicalSharp {
}
public string ReadCp437String() {
- int length = GetString( false );
+ int length = GetString( false, 64 );
index += 64;
return new String( characters, 0, length );
}
public string ReadAsciiString() {
- int length = GetString( true );
+ int length = GetString( true, 64 );
index += 64;
return new String( characters, 0, length );
}
@@ -82,7 +88,7 @@ namespace ClassicalSharp {
return ReadCp437String();
messageType = (byte)MessageType.Normal;
- int length = GetString( false );
+ int length = GetString( false, 64 );
index += 64;
int offset = 0;
@@ -104,9 +110,9 @@ namespace ClassicalSharp {
return true;
}
- int GetString( bool ascii ) {
+ int GetString( bool ascii, int bufferSize ) {
int length = 0;
- for( int i = 63; i >= 0; i-- ) {
+ for( int i = bufferSize - 1; i >= 0; i-- ) {
byte code = buffer[index + i];
if( length == 0 && !( code == 0 || code == 0x20 ) )
length = i + 1;