/// <summary> /// Saves track as SOL at location /// </summary> public SOL(string location, Track export) { BigEndianWriter bw = new BigEndianWriter(); bw.WriteShort(0x00BF); //sol version bw.WriteInt(0); //length, placeholder bw.WriteString("TCSO"); bw.WriteBytes(new byte[] { 0, 4, 0, 0, 0, 0 }); bw.WriteMapleString("savedLines"); bw.WriteInt(0); //padding Amf0Object rootobj = new Amf0Object(); rootobj.name = "trackList"; rootobj.type = Amf0Object.Amf0Type.AMF0_ECMA_ARRAY; var tracks = new List <Amf0Object>(); rootobj.data = tracks; WriteTrack(tracks, export); Amf0 amf = new Amf0(bw); amf.WriteAmf0Object(rootobj); bw.WriteByte(0); bw.Reset(2); bw.WriteInt(bw.Length - 6); File.WriteAllBytes(location, bw.ToArray()); }
public List <Amf0Object> ReadAmf0(bool rootobject = false) { List <Amf0Object> retlist = new List <Amf0Object>(); while (true) { Amf0Object ret = new Amf0Object(); if (br.Remaining < 2 && rootobject) { return(retlist); } ret.name = Encoding.ASCII.GetString(br.ReadBytes(br.ReadInt16())); //object name ret.type = (Amf0Object.Amf0Type)br.ReadByte(); //type switch (ret.type) { case Amf0Object.Amf0Type.AMF0_NUMBER: //NUMBER ret.data = br.ReadDouble(); break; case Amf0Object.Amf0Type.AMF0_BOOLEAN: //BOOLEAN ret.data = br.ReadBoolean(); break; case Amf0Object.Amf0Type.AMF0_STRING: ret.data = Encoding.UTF8.GetString(br.ReadBytes(br.ReadInt16())); break; case Amf0Object.Amf0Type.AMF0_OBJECT: //OBJECT { ret.data = ReadAmf0(); } break; case Amf0Object.Amf0Type.AMF0_NULL: case Amf0Object.Amf0Type.AMF0_UNDEFINED: ret.data = null; break; case Amf0Object.Amf0Type.AMF0_ECMA_ARRAY: //ecma array { br.ReadInt32(); var ecma = ReadAmf0(); ret.data = ecma; // if (ecma.Count != l) // throw new Exception("Corrupt ECMA array in SOL file"); } break; case Amf0Object.Amf0Type.AMF0_OBJECT_END: return(retlist); default: throw new Exception("Error reading SOL file (40)"); } retlist.Add(ret); } }
public void WriteAmf0Object(Amf0Object obj) { bw.WriteMapleString(obj.name); if (obj.data == null) { bw.WriteByte(5); } else if (obj.data is List <Amf0Object> ) { if (obj.type == Amf0Object.Amf0Type.AMF0_ECMA_ARRAY) { bw.WriteByte((byte)obj.type); var list = obj.data as List <Amf0Object>; bw.WriteInt(list.Count); int counter = 0; foreach (var lobj in list) { if (lobj.name == null) { lobj.name = counter++.ToString(Program.Culture); } WriteAmf0Object(lobj); } bw.WriteShort(0); bw.WriteByte(9); } else //OBJECT { obj.type = Amf0Object.Amf0Type.AMF0_OBJECT; bw.WriteByte((byte)obj.type); var list = obj.data as List <Amf0Object>; int counter = 0; foreach (var lobj in list) { if (lobj.name == null) { lobj.name = counter++.ToString(Program.Culture); } WriteAmf0Object(lobj); } bw.WriteShort(0); bw.WriteByte(9); } } else if (obj.data is int || obj.data is double || obj.data is float) { if (!(obj.data is double)) { var data = Convert.ToDouble(obj.data); obj.data = data; } obj.type = Amf0Object.Amf0Type.AMF0_NUMBER; bw.WriteByte((byte)obj.type); bw.WriteDouble((double)obj.data); } else if (obj.data is string) { obj.type = Amf0Object.Amf0Type.AMF0_STRING; bw.WriteByte((byte)obj.type); bw.WriteMapleString((string)obj.data); } else if (obj.data is bool) { bw.WriteByte((byte)Amf0Object.Amf0Type.AMF0_BOOLEAN); bw.WriteByte(Convert.ToByte(obj.data)); } else { throw new Exception("Unable to write type to sol file"); } }
private void WriteTrack(List <Amf0Object> parent, Track trk) { Amf0Object track = new Amf0Object(parent.Count); parent.Add(track); var trackdata = new List <Amf0Object>(); track.data = trackdata; trackdata.Add(new Amf0Object("label", trk.Name)); trackdata.Add(new Amf0Object("version", "6.2")); trackdata.Add(new Amf0Object("level", trk.Lines.Count)); var sl = new Amf0Object("startLine"); var dataobj = new Amf0Object("data") { type = Amf0Object.Amf0Type.AMF0_ECMA_ARRAY }; var data = new List <Amf0Object>(); dataobj.data = data; sl.data = new List <Amf0Object>() { new Amf0Object(0, trk.Start.X), new Amf0Object(1, trk.Start.Y) }; trackdata.Add(sl); trackdata.Add(dataobj); SortedList <int, Line> list = new SortedList <int, Line>(); for (int i = trk.Lines.Count - 1; i >= 0; i--) { var id = trk.Lines[i].ID; if (id < 0) { id = Math.Abs(id) + trk._idcounter + 100; } list.Add(id, trk.Lines[i]); } int counter = 0; for (int i = list.Values.Count - 1; i >= 0; i--) { var line = list.Values[i]; var stl = line as StandardLine; var lineobj = new Amf0Object(counter++); var linedata = new List <Amf0Object>(); linedata.Add(new Amf0Object(0, line.Position.X)); linedata.Add(new Amf0Object(1, line.Position.Y)); linedata.Add(new Amf0Object(2, line.Position2.X)); linedata.Add(new Amf0Object(3, line.Position2.Y)); linedata.Add(new Amf0Object(4, stl != null ? (int)((StandardLine)line).Extension : 0)); linedata.Add(new Amf0Object(5, stl != null ? (bool)((StandardLine)line).inv : false)); linedata.Add(new Amf0Object(6, stl?.Prev?.ID)); linedata.Add(new Amf0Object(7, stl?.Next?.ID)); linedata.Add(new Amf0Object(8, list.Keys[i])); linedata.Add(new Amf0Object(9, TrackLoader.LineTypeForSOL(line.GetLineType()))); lineobj.type = Amf0Object.Amf0Type.AMF0_ECMA_ARRAY; lineobj.data = linedata; data.Add(lineobj); } if (trk.ZeroStart) { List <Amf0Object> kevans = new List <Amf0Object>(); kevans.Add(new Amf0Object(0) { type = Amf0Object.Amf0Type.AMF0_NULL }); List <Amf0Object> in1 = new List <Amf0Object>(); in1.Add(new Amf0Object(0) { type = Amf0Object.Amf0Type.AMF0_NULL }); in1.Add(new Amf0Object(1) { type = Amf0Object.Amf0Type.AMF0_NULL }); in1.Add(new Amf0Object(2) { type = Amf0Object.Amf0Type.AMF0_NULL }); kevans.Add(new Amf0Object(1) { type = Amf0Object.Amf0Type.AMF0_ECMA_ARRAY, data = in1 }); List <Amf0Object> importantpart = new List <Amf0Object>(3); importantpart.Add(new Amf0Object(0) { type = Amf0Object.Amf0Type.AMF0_NULL }); importantpart.Add(new Amf0Object(1) { type = Amf0Object.Amf0Type.AMF0_NULL }); importantpart.Add(new Amf0Object(2) { type = Amf0Object.Amf0Type.AMF0_NULL }); importantpart.Add(new Amf0Object(3) { type = Amf0Object.Amf0Type.AMF0_NULL }); importantpart.Add(new Amf0Object(4) { type = Amf0Object.Amf0Type.AMF0_NULL }); importantpart.Add(new Amf0Object(5, true)); kevans.Add(new Amf0Object(2) { type = Amf0Object.Amf0Type.AMF0_ECMA_ARRAY, data = importantpart }); trackdata.Add(new Amf0Object("trackData") { data = kevans, type = Amf0Object.Amf0Type.AMF0_ECMA_ARRAY }); } }