Add a .non hacky .dat level parser

This commit is contained in:
UnknownShadow200 2018-04-25 16:16:39 +10:00
parent 6a2f7be26e
commit 761c7f4d00
14 changed files with 416 additions and 93 deletions

View File

@ -86,9 +86,10 @@ namespace ClassicalSharp.Gui.Screens {
static string GetJump(Game g) { return g.LocalPlayer.JumpHeight.ToString("F3"); }
static void SetJump(Game g, string v) {
g.LocalPlayer.physics.CalculateJumpVelocity(true, Utils.ParseDecimal(v));
float jumpVel = g.LocalPlayer.physics.jumpVel;
Options.Set(OptionsKey.JumpVelocity, jumpVel.ToString());
PhysicsComponent physics = g.LocalPlayer.physics;
physics.CalculateJumpVelocity(Utils.ParseDecimal(v));
physics.userJumpVel = physics.jumpVel;
Options.Set(OptionsKey.JumpVelocity, physics.jumpVel.ToString());
}
static string GetWOMHacks(Game g) { return GetBool(g.LocalPlayer.Hacks.WOMStyleHacks); }

View File

@ -172,6 +172,7 @@
<Compile Include="Generator\NotchyGenerator.Utils.cs" />
<Compile Include="GraphicsAPI\IGraphicsAPI.Core.cs" />
<Compile Include="GraphicsAPI\OpenGLESApi.cs" />
<Compile Include="Map\Formats\MapDat2.Importer.cs" />
<Compile Include="Map\Formats\MapSchematic.Exporter.cs" />
<Compile Include="Map\Formats\MapLvl.Importer.cs" />
<Compile Include="Map\Formats\NbtFile.cs" />

View File

@ -253,7 +253,7 @@ namespace ClassicalSharp.Entities {
/// <summary> Calculates the jump velocity required such that when a client presses
/// the jump binding they will be able to jump up to the given height. </summary>
internal void CalculateJumpVelocity(bool userVel, float jumpHeight) {
internal void CalculateJumpVelocity(float jumpHeight) {
jumpVel = 0;
if (jumpHeight == 0) return;
@ -262,7 +262,6 @@ namespace ClassicalSharp.Entities {
if (jumpHeight >= 768) jumpVel = 22.5f;
while (GetMaxHeight(jumpVel) <= jumpHeight) { jumpVel += 0.001f; }
if (userVel) userJumpVel = jumpVel;
}
public static double GetMaxHeight(float u) {

View File

@ -0,0 +1,319 @@
#if FALSEEE
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using ClassicalSharp.Entities;
using ClassicalSharp.Network;
using OpenTK;
namespace ClassicalSharp.Map {
/// <summary> Imports a world from a dat map file (original minecraft classic map) </summary>
public sealed class MapDat2Importer : IMapFormatImporter {
const byte TC_NULL = 0x70;
const byte TC_REFERENCE = 0x71;
const byte TC_CLASSDESC = 0x72;
const byte TC_OBJECT = 0x73;
const byte TC_STRING = 0x74;
const byte TC_ARRAY = 0x75;
const byte TC_CLASS = 0x76;
const byte TC_BLOCKDATA = 0x77;
const byte TC_ENDBLOCKDATA = 0x78;
const byte TC_RESET = 0x79;
const byte TC_BLOCKDATALONG = 0x7A;
const byte TC_EXCEPTION = 0x7B;
const byte TC_LONGSTRING = 0x7C;
const byte TC_PROXYCLASSDESC = 0x7D;
const byte TC_ENUM = 0x7E;
const int baseWireHandle = 0x7E0000;
const byte SC_WRITE_METHOD = 0x01, SC_SERIALIZABLE = 0x02;
byte ReadUInt8() { return reader.ReadByte(); }
short ReadInt16() { return IPAddress.HostToNetworkOrder(reader.ReadInt16()); }
ushort ReadUInt16() { return (ushort)IPAddress.HostToNetworkOrder(reader.ReadInt16()); }
int ReadInt32() { return IPAddress.HostToNetworkOrder(reader.ReadInt32()); }
long ReadInt64() { return IPAddress.HostToNetworkOrder(reader.ReadInt64()); }
string ReadUtf8() { return Encoding.UTF8.GetString(reader.ReadBytes(ReadUInt16())); }
BinaryReader reader;
List<object> handles = new List<object>();
public byte[] Load(Stream stream, Game game, out int width, out int height, out int length) {
byte[] map = null;
width = 0;
height = 0;
length = 0;
GZipHeaderReader gsHeader = new GZipHeaderReader();
while (!gsHeader.ReadHeader(stream)) { }
LocalPlayer p = game.LocalPlayer;
p.Spawn = Vector3.Zero;
using (DeflateStream gs = new DeflateStream(stream, CompressionMode.Decompress)) {
reader = new BinaryReader(gs);
if (ReadInt32() != 0x271BB788 || reader.ReadByte() != 0x02) {
throw new InvalidDataException("Unexpected constant in .dat file");
}
JObject obj = (JObject)ReadStream();
JFieldDesc[] fields = obj.Desc.Info.Fields;
object[] values = obj.ClassData[0].Values;
for (int i = 0; i < fields.Length; i++) {
JFieldDesc field = fields[i];
object value = values[i];
if (field.Name == "width")
width = (int)value;
else if (field.Name == "height")
length = (int)value;
else if (field.Name == "depth")
height = (int)value;
else if (field.Name == "blocks")
map = (byte[])((JArray)value).Values;
else if (field.Name == "xSpawn")
p.Spawn.X = (int)value;
else if (field.Name == "ySpawn")
p.Spawn.Y = (int)value;
else if (field.Name == "zSpawn")
p.Spawn.Z = (int)value;
}
}
return map;
}
object ReadStream() {
if (ReadUInt16() != 0xACED) throw new InvalidDataException("Invalid stream magic");
if (ReadUInt16() != 0x0005) throw new InvalidDataException("Invalid stream version");
byte typeCode = ReadUInt8();
return ReadContent(typeCode);
}
object ReadContent(byte typeCode) {
if (typeCode == TC_BLOCKDATA) {
return reader.ReadBytes(ReadUInt8());
} else if (typeCode == TC_BLOCKDATALONG) {
return reader.ReadBytes(ReadInt32());
} else {
return ReadObject(typeCode);
}
}
object ReadObject() { return ReadObject(ReadUInt8()); }
object ReadObject(byte typeCode) {
switch (typeCode) {
case TC_STRING:
return NewString();
case TC_LONGSTRING:
return NewLongString();
case TC_RESET:
handles.Clear();
return null;
case TC_NULL:
return null;
case TC_REFERENCE:
return PrevObject();
case TC_CLASS:
return NewClass();
case TC_ENUM:
return NewEnum();
case TC_OBJECT:
return NewObject();
case TC_ARRAY:
return NewArray();
case TC_CLASSDESC:
return NewClassDesc();
case TC_EXCEPTION:
return NewException();
}
throw new InvalidDataException("Invalid typecode: " + typeCode);
}
string NewString() {
string value = ReadUtf8();
handles.Add(value);
return value;
}
string NewLongString() {
long len = ReadInt16();
string value = Encoding.UTF8.GetString(reader.ReadBytes((int)len));
handles.Add(value);
return value;
}
object PrevObject() {
int handle = ReadInt32() - baseWireHandle;
if (handle >= 0 && handle < handles.Count) return handles[handle];
throw new InvalidDataException("Invalid stream handle: " + handle);
}
object NewException() {
handles.Clear();
object exception = ReadObject();
handles.Clear();
return exception;
}
JClassDesc NewClass() {
JClassDesc classDesc = ClassDesc();
handles.Add(classDesc);
return classDesc;
}
class JEnum { public JClassDesc Desc; public string ConstName; }
JEnum NewEnum() {
JEnum value = new JEnum();
value.Desc = ClassDesc();
handles.Add(value);
value.ConstName = (string)ReadObject();
return value;
}
class JObject { public JClassDesc Desc; public List<JClassData> ClassData; }
JObject NewObject() {
JObject obj = new JObject();
obj.Desc = ClassDesc();
handles.Add(obj);
List<JClassDesc> classDescs = new List<JClassDesc>();
List<JClassData> classDatas = new List<JClassData>();
JClassDesc tmp = obj.Desc;
// most superclass data is first
while (tmp != null) {
classDescs.Add(tmp);
tmp = tmp.Info.SuperClass;
}
classDescs.Reverse();
for (int i = 0; i < classDescs.Count; i++) {
JClassData classData = ClassData(classDescs[i].Info);
classDatas.Add(classData);
}
// reverse order so least superclass is first
classDatas.Reverse();
obj.ClassData = classDatas;
return obj;
}
class JArray { public JClassDesc Desc; public object Values; }
JArray NewArray() {
JArray array = new JArray();
array.Desc = ClassDesc();
handles.Add(array);
char type = array.Desc.Name[1];
int size = ReadInt32();
if (type == 'B') {
array.Values = reader.ReadBytes(size);
} else {
object[] values = new object[size];
for (int i = 0; i < values.Length; i++) {
values[i] = Value(type);
}
array.Values = values;
}
return array;
}
class JClassDesc { public string Name; public long SerialUID; public JClassDescInfo Info; }
JClassDesc NewClassDesc() {
JClassDesc desc = new JClassDesc();
desc.Name = ReadUtf8();
desc.SerialUID = ReadInt64();
handles.Add(desc);
desc.Info = ClassDescInfo();
return desc;
}
JClassDesc ClassDesc() {
byte typeCode = ReadUInt8();
if (typeCode == TC_CLASSDESC) return NewClassDesc();
if (typeCode == TC_NULL) return null;
if (typeCode == TC_REFERENCE) return (JClassDesc)PrevObject();
throw new InvalidDataException("Invalid type code: " + typeCode);
}
class JClassData { public object[] Values; public object Annotation; }
JClassData ClassData(JClassDescInfo info) {
if ((info.Flags & SC_SERIALIZABLE) == 0) {
throw new InvalidDataException("Invalid class data flags: " + info.Flags);
}
JClassData data = new JClassData();
data.Values = new object[info.Fields.Length];
for (int i = 0; i < data.Values.Length; i++) {
data.Values[i] = Value(info.Fields[i].Type);
}
if ((info.Flags & SC_WRITE_METHOD) != 0) {
data.Annotation = Annotation();
}
return data;
}
class JClassDescInfo { public byte Flags; public JFieldDesc[] Fields; public object Annotation; public JClassDesc SuperClass; }
JClassDescInfo ClassDescInfo() {
JClassDescInfo info = new JClassDescInfo();
info.Flags = ReadUInt8();
info.Fields = new JFieldDesc[ReadUInt16()];
for (int i = 0; i < info.Fields.Length; i++) {
info.Fields[i] = FieldDesc();
}
info.Annotation = Annotation();
info.SuperClass = ClassDesc();
return info;
}
unsafe object Value(char type) {
if (type == 'B') return ReadUInt8();
if (type == 'C') return (char)ReadUInt16();
if (type == 'D') { long tmp = ReadInt64(); return *(double*)(&tmp); }
if (type == 'F') { int tmp = ReadInt32(); return *(float*)(&tmp); }
if (type == 'I') return ReadInt32();
if (type == 'J') return ReadInt64();
if (type == 'S') return ReadInt16();
if (type == 'Z') return ReadUInt8() != 0;
if (type == 'L') return ReadObject();
if (type == '[') return ReadObject();
throw new InvalidDataException("Invalid value code: " + type);
}
class JFieldDesc { public char Type; public string Name; public string ClassName; public override string ToString() { return Name; } }
JFieldDesc FieldDesc() {
JFieldDesc desc = new JFieldDesc();
byte type = ReadUInt8();
desc.Type = (char)type;
if (type == 'B' || type == 'C' || type == 'D' || type == 'F' || type == 'I' || type == 'J' || type == 'S' || type == 'Z') {
desc.Name = ReadUtf8();
} else if (type == '[' || type == 'L') {
desc.Name = ReadUtf8();
desc.ClassName = (string)ReadObject();
} else {
throw new InvalidDataException("Invalid field type: " + type);
}
return desc;
}
object Annotation() {
List<object> parts = new List<object>();
byte typeCode;
while ((typeCode = ReadUInt8()) != TC_ENDBLOCKDATA) {
parts.Add(ReadContent(typeCode));
}
if (parts.Count > 0) System.Diagnostics.Debugger.Break();
return parts;
}
}
}
#endif

View File

@ -49,12 +49,12 @@ namespace ClassicalSharp.Network.Protocols {
net.Set(Opcode.CpeSetInventoryOrder, HandleSetInventoryOrder, 3);
}
public override void Tick() {
pingTicks++;
if (pingTicks >= 20 && net.cpeData.twoWayPing) {
WriteTwoWayPing(false, PingList.NextTwoWayPingData());
pingTicks = 0;
}
public override void Tick() {
pingTicks++;
if (pingTicks >= 20 && net.cpeData.twoWayPing) {
WriteTwoWayPing(false, PingList.NextTwoWayPingData());
pingTicks = 0;
}
}
#region Read
@ -64,8 +64,8 @@ namespace ClassicalSharp.Network.Protocols {
if (Utils.CaselessStarts(appName, "D3 server"))
net.cpeData.needD3Fix = true;
// Workaround for MCGalaxy that send ExtEntry sync but ExtInfoAsync. This means
// ExtEntry may sometimes arrive before ExtInfo, and thus we have to use += instead of =
// Workaround for old MCGalaxy that send ExtEntry sync but ExtInfo async. This means
// ExtEntry may sometimes arrive before ExtInfo, thus have to use += instead of =
net.cpeData.ServerExtensionsCount += reader.ReadInt16();
SendCpeExtInfoReply();
}
@ -246,7 +246,7 @@ namespace ClassicalSharp.Network.Protocols {
if (jumpHeight == ushort.MaxValue) { // special value of -1 to reset default
p.physics.jumpVel = p.Hacks.CanJumpHigher ? p.physics.userJumpVel : 0.42f;
} else {
p.physics.CalculateJumpVelocity(false, jumpHeight / 32f);
p.physics.CalculateJumpVelocity(jumpHeight / 32f);
}
p.physics.serverJumpVel = p.physics.jumpVel;

View File

@ -50,11 +50,11 @@ namespace ClassicalSharp.Network.Protocols {
net.Set(Opcode.SetPermission, HandleSetPermission, 2);
}
public override void Tick() {
if (receivedFirstPosition) {
LocalPlayer player = game.LocalPlayer;
WritePosition(player.Position, player.HeadY, player.HeadX);
}
public override void Tick() {
if (receivedFirstPosition) {
LocalPlayer player = game.LocalPlayer;
WritePosition(player.Position, player.HeadY, player.HeadX);
}
}
#if !ONLY_8BIT

View File

@ -1,22 +1,22 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
namespace ClassicalSharp.Network.Protocols {
public abstract class IProtocol {
protected Game game;
protected NetworkProcessor net;
protected NetReader reader;
protected NetWriter writer;
public IProtocol(Game game) {
this.game = game;
net = (NetworkProcessor)game.Server;
reader = net.reader;
writer = net.writer;
}
public abstract void Reset();
public abstract void Tick();
}
}
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
namespace ClassicalSharp.Network.Protocols {
public abstract class IProtocol {
protected Game game;
protected NetworkProcessor net;
protected NetReader reader;
protected NetWriter writer;
public IProtocol(Game game) {
this.game = game;
net = (NetworkProcessor)game.Server;
reader = net.reader;
writer = net.writer;
}
public abstract void Reset();
public abstract void Tick();
}
}

View File

@ -15,10 +15,10 @@ namespace ClassicalSharp.Network.Protocols {
int womCounter;
bool sendWomId, sentWomId;
public override void Reset() {
womEnvIdentifier = "womenv_0";
womCounter = 0;
sendWomId = false; sentWomId = false;
public override void Reset() {
womEnvIdentifier = "womenv_0";
womCounter = 0;
sendWomId = false; sentWomId = false;
}
public override void Tick() {

View File

@ -1142,7 +1142,7 @@ Real64 PhysicsComp_GetMaxHeight(Real32 u) {
/* Calculates the jump velocity required such that when a client presses
the jump binding they will be able to jump up to the given height. */
void PhysicsComp_CalculateJumpVelocity(PhysicsComp* comp, bool userVel, Real32 jumpHeight) {
void PhysicsComp_CalculateJumpVelocity(PhysicsComp* comp, Real32 jumpHeight) {
comp->JumpVel = 0.0f;
if (jumpHeight == 0.0f) return;
@ -1151,7 +1151,6 @@ void PhysicsComp_CalculateJumpVelocity(PhysicsComp* comp, bool userVel, Real32 j
if (jumpHeight >= 768.0f) comp->JumpVel = 22.5f;
while (PhysicsComp_GetMaxHeight(comp->JumpVel) <= jumpHeight) { comp->JumpVel += 0.001f; }
if (userVel) comp->UserJumpVel = comp->JumpVel;
}
void PhysicsComp_DoEntityPush(Entity* entity) {

View File

@ -129,7 +129,7 @@ void PhysicsComp_Init(PhysicsComp* comp, Entity* entity);
void PhysicsComp_UpdateVelocityState(PhysicsComp* comp);
void PhysicsComp_DoNormalJump(PhysicsComp* comp);
void PhysicsComp_PhysicsTick(PhysicsComp* comp, Vector3 vel);
void PhysicsComp_CalculateJumpVelocity(PhysicsComp* comp, bool userVel, Real32 jumpHeight);
void PhysicsComp_CalculateJumpVelocity(PhysicsComp* comp, Real32 jumpHeight);
Real64 PhysicsComp_GetMaxHeight(Real32 u);
void PhysicsComp_DoEntityPush(Entity* entity);

View File

@ -2626,7 +2626,8 @@ void HacksSettingsScreen_SetClipping(STRING_PURE String* v) {
void HacksSettingsScreen_GetJump(STRING_TRANSIENT String* v) { String_AppendReal32(v, LocalPlayer_JumpHeight(), 3); }
void HacksSettingsScreen_SetJump(STRING_PURE String* v) {
PhysicsComp* physics = &LocalPlayer_Instance.Physics;
PhysicsComp_CalculateJumpVelocity(physics, true, Menu_Real32(v));
PhysicsComp_CalculateJumpVelocity(physics, Menu_Real32(v));
physics->UserJumpVel = physics->JumpVel;
UInt8 strBuffer[String_BufferSize(STRING_SIZE)];
String str = String_InitAndClearArray(strBuffer);

View File

@ -11,46 +11,6 @@
#include "Game.h"
int main(int argc, char* argv[]) {
String text1 = String_FromConst("abcd");
String lines1[3] = { 0 };
WordWrap_Do(&text1, lines1, 3, 4);
String text2 = String_FromConst("abcde/fgh");
String lines2[3] = { 0 };
WordWrap_Do(&text2, lines2, 3, 4);
String text3 = String_FromConst("abc/defg");
String lines3[3] = { 0 };
WordWrap_Do(&text3, lines3, 3, 4);
String text4 = String_FromConst("ab/cdef");
String lines4[3] = { 0 };
WordWrap_Do(&text4, lines4, 3, 4);
String text5 = String_FromConst("abcd/efg");
String lines5[3] = { 0 };
WordWrap_Do(&text5, lines5, 3, 4);
String text6 = String_FromConst("abc/efg/hij/");
String lines6[3] = { 0 };
WordWrap_Do(&text6, lines6, 3, 4);
String text7 = String_FromConst("ab cde fgh");
String lines7[3] = { 0 };
WordWrap_Do(&text7, lines7, 3, 4);
String text8 = String_FromConst("ab//cd");
String lines8[3] = { 0 };
WordWrap_Do(&text8, lines8, 3, 4);
String text9 = String_FromConst("a///b");
String lines9[3] = { 0 };
WordWrap_Do(&text9, lines9, 3, 4);
String text10 = String_FromConst("/aaab");
String lines10[3] = { 0 };
WordWrap_Do(&text10, lines10, 3, 4);
ErrorHandler_Init("client.log");
Platform_Init();
@ -126,6 +86,48 @@ int main(int argc, char* argv[]) {
return 0;
}
/*
String text1 = String_FromConst("abcd");
String lines1[3] = { 0 };
WordWrap_Do(&text1, lines1, 3, 4);
String text2 = String_FromConst("abcde/fgh");
String lines2[3] = { 0 };
WordWrap_Do(&text2, lines2, 3, 4);
String text3 = String_FromConst("abc/defg");
String lines3[3] = { 0 };
WordWrap_Do(&text3, lines3, 3, 4);
String text4 = String_FromConst("ab/cdef");
String lines4[3] = { 0 };
WordWrap_Do(&text4, lines4, 3, 4);
String text5 = String_FromConst("abcd/efg");
String lines5[3] = { 0 };
WordWrap_Do(&text5, lines5, 3, 4);
String text6 = String_FromConst("abc/efg/hij/");
String lines6[3] = { 0 };
WordWrap_Do(&text6, lines6, 3, 4);
String text7 = String_FromConst("ab cde fgh");
String lines7[3] = { 0 };
WordWrap_Do(&text7, lines7, 3, 4);
String text8 = String_FromConst("ab//cd");
String lines8[3] = { 0 };
WordWrap_Do(&text8, lines8, 3, 4);
String text9 = String_FromConst("a///b");
String lines9[3] = { 0 };
WordWrap_Do(&text9, lines9, 3, 4);
String text10 = String_FromConst("/aaab");
String lines10[3] = { 0 };
WordWrap_Do(&text10, lines10, 3, 4);
*/
//#include <Windows.h>
int main_test(int argc, char* argv[]) {
return 0;

View File

@ -2,7 +2,6 @@
#define CC_SERVERCONNECTION_H
#include "Input.h"
#include "GameStructs.h"
#include "Picking.h"
/* Represents a connection to either a singleplayer or multiplayer server.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
@ -41,7 +40,7 @@
#define OPCODE_CPE_ENV_SET_MAP_APPERANCE 30
#define OPCODE_CPE_ENV_SET_WEATHER 31
#define OPCODE_CPE_HACK_CONTROL 32
#define OPCODE_CPE_EXT_ADD_ENTITY_2 33
#define OPCODE_CPE_EXT_ADD_ENTITY2 33
#define OPCODE_CPE_PLAYER_CLICK 34
#define OPCODE_CPE_DEFINE_BLOCK 35
#define OPCODE_CPE_UNDEFINE_BLOCK 36
@ -52,7 +51,10 @@
#define OPCODE_CPE_ENV_SET_MAP_PROPERTY 41
#define OPCODE_CPE_SET_ENTITY_PROPERTY 42
#define OPCODE_CPE_TWO_WAY_PING 43
#define Opcode_CPE_SET_INVENTORY_ORDER 44
#define OPCODE_CPE_SET_INVENTORY_ORDER 44
typedef struct PickedPos_ PickedPos;
typedef struct Stream_ Stream;
UInt16 PingList_NextPingData(void);
void PingList_Update(UInt16 data);

View File

@ -32,7 +32,6 @@ GfxResourceID Atlas2D_LoadTextureElement(TextureLoc texLoc) {
Platform_MemFree(&element.Scan0);
return texId;
} else {
// TODO: does this even work??
UInt8 scan0[Bitmap_DataSize(64, 64)];
Bitmap_Create(&element, size, size, scan0);
return Atlas2D_LoadTextureElement_Raw(texLoc, &element);