/// <summary> /// Write the table obj to the binary writer output. /// </summary> /// <param name="output">BinaryWriter to write the table to.</param> /// <param name="obj">Table to write to binary writer.</param> private void writeTable(BinaryWriter output, LuaDataContainer obj) { output.Write((byte)5); var entry = obj.GetEnumerator(); while (entry.MoveNext()) { // Save key if (entry.Key is bool) { output.Write((byte)1); output.Write((bool)entry.Key ? (byte)1 : (byte)0); } if (entry.Key is double) { output.Write((byte)2); output.Write((double)entry.Key); } if (entry.Key is string) { output.Write((byte)3); writeString(output, (string)entry.Key); } // Save value if (entry.Value == null) { // Write false for null output.Write((byte)1); output.Write((byte)0); } if (entry.Value is bool) { output.Write((byte)1); output.Write((bool)entry.Value ? (byte)1 : (byte)0); } if (entry.Value is double || entry.Value is int) { output.Write((byte)2); output.Write((double)entry.Value); } if (entry.Value is string) { output.Write((byte)3); writeByteArray(output, obj.GetByteArray(entry.Key)); } if (entry.Value is LuaDataProvider) { output.Write((byte)4); byte[] array = toArray(_dataFactory.GetProviderAt("string.dump").FirstOrDefault <string>(entry.Value)); output.Write(array.Length); output.Write(array); } if (entry.Value is LuaDataContainer) { LuaDataContainer dc = (LuaDataContainer)entry.Value; string className = dc.GetString("ClassName"); if (className != null && (className.Equals("Distance") || className.Equals("ZonePoint") || className.Equals("ZCommand") || className.Equals("ZReciprocalCommand"))) { output.Write((byte)8); writeString(output, className); LuaDataContainer data = dc.CallSelf("serialize"); writeTable(output, data); } else if (className != null && (className.Equals("ZCartridge") || className.Equals("ZCharacter") || className.Equals("ZInput") || className.Equals("ZItem") || className.Equals("ZMedia") || className.Equals("Zone") || className.Equals("ZTask") || className.Equals("ZTimer"))) { output.Write((byte)7); output.Write(Convert.ToInt16(dc.GetInt("ObjIndex").Value)); } else { // New: It is a normal LuaTable or an unknown new ZObject type LuaDataContainer data = dc; if (className != null) { // New: If we are here, than this is a new ZObject class, so call serialize before. // New: That means, that it is a normal LuaTable, so save it LuaDataProvider lf = dc.GetProvider("serialize", true); if (lf != null) { data = lf.FirstContainerOrDefault(); } } writeTable(output, data); } } } output.Write((byte)6); }
private void readTable(BinaryReader input, LuaDataContainer obj) { string className = "unknown"; IDataProvider rawset = null; LuaDataContainer tab; object key = 1; if (obj != null) { className = obj.GetString("ClassName"); if (className != null) { rawset = obj.GetProvider("rawset", false); } } byte b = input.ReadByte(); while (b != 6) { // Key switch (b) { case 1: key = input.ReadByte() == 0 ? false : true; break; case 2: key = input.ReadDouble(); break; case 3: key = readString(input); break; default: throw new Exception(String.Format("Unsupported table key: {0} at byte {1}", b, input.BaseStream.Position)); } b = input.ReadByte(); // Value switch (b) { case 1: SetField(obj, key, input.ReadBoolean(), rawset); break; case 2: SetField(obj, key, input.ReadDouble(), rawset); break; case 3: SetField(obj, key, readByteArray(input), rawset); break; case 4: byte[] chunk = input.ReadBytes(input.ReadInt32()); SetField(obj, key, _dataFactory.LoadProvider(chunk, key.ToString()), rawset); break; case 5: tab = _dataFactory.CreateContainer(); SetField(obj, key, tab, rawset); readTable(input, tab); break; case 6: // End of table return; case 7: var objIndex = input.ReadInt16(); if (objIndex == -21555) { SetField(obj, key, _player, rawset); } else { SetField(obj, key, _allZObjects.GetContainer(objIndex), rawset); } break; case 8: tab = (LuaDataContainer)_dataFactory.CreateWherigoObject(readString(input)).DataContainer; SetField(obj, key, tab, rawset); // After an object, there is always a table with the content input.ReadByte(); readTable(input, tab); break; } b = input.ReadByte(); } }
/// <summary> /// Saves the current cartridge to a GWS file. /// </summary> /// <param name="stream">Stream to write the data to.</param> /// <param name="saveName">Description for the save file, which is put into the file.</param> public void Save(Stream stream, string saveName = "UI initiated sync") { using (BinaryWriter output = new BinaryWriter(stream)) { // Write signature and version output.Write(Signature); output.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 }); int lengthOfHeader = 0; lengthOfHeader += writeCString(output, _cartridgeEntity.Name); output.Write(BitConverter.GetBytes((long)((_cartridgeEntity.CreateDate.Ticks - new DateTime(2004, 02, 10, 01, 00, 00).Ticks) / TimeSpan.TicksPerSecond))); lengthOfHeader += 8; lengthOfHeader += writeCString(output, _cartridgeEntity.Player); // MUST be "Windows PPC" for Emulator lengthOfHeader += writeCString(output, _platformHelper.Device); // MUST be "Desktop" for Emulator lengthOfHeader += writeCString(output, _platformHelper.DeviceId); output.Write(BitConverter.GetBytes((long)((DateTime.Now.Ticks - new DateTime(2004, 02, 10, 01, 00, 00).Ticks) / TimeSpan.TicksPerSecond))); lengthOfHeader += 8; lengthOfHeader += writeCString(output, saveName); output.Write(BitConverter.GetBytes(_latitude)); lengthOfHeader += 8; output.Write(BitConverter.GetBytes(_longitude)); lengthOfHeader += 8; output.Write(BitConverter.GetBytes(_altitude)); lengthOfHeader += 8; var pos = output.BaseStream.Position; output.BaseStream.Position = 7; output.Write(BitConverter.GetBytes(lengthOfHeader)); output.BaseStream.Position = pos; _allZObjects = _cartridge.GetContainer("AllZObjects"); int numAllZObjects = _allZObjects.Count; output.Write(numAllZObjects); for (int i = 1; i < numAllZObjects; i++) { writeString(output, _allZObjects.GetContainer(i).GetString("ClassName")); } LuaDataContainer obj = _player; writeString(output, obj.GetString("ClassName")); LuaDataContainer data = obj.CallSelf("serialize"); writeTable(output, data); for (int i = 0; i < numAllZObjects; i++) { obj = (LuaDataContainer)_allZObjects.GetContainer(i); writeString(output, obj.GetString("ClassName")); data = obj.CallSelf("serialize"); writeTable(output, data); } output.Flush(); output.Close(); } }
private void readTable(BinaryReader input, LuaDataContainer obj) { string className = "unknown"; IDataProvider rawset = null; LuaDataContainer tab; object key = 1; if (obj != null) { className = obj.GetString("ClassName"); if (className != null) rawset = obj.GetProvider("rawset", false); } byte b = input.ReadByte(); while (b != 6) { // Key switch (b) { case 1: key = input.ReadByte() == 0 ? false : true; break; case 2: key = input.ReadDouble(); break; case 3: key = readString(input); break; default: throw new Exception(String.Format("Unsupported table key: {0} at byte {1}", b, input.BaseStream.Position)); } b = input.ReadByte(); // Value switch (b) { case 1: SetField(obj, key, input.ReadBoolean(), rawset); break; case 2: SetField(obj, key, input.ReadDouble(), rawset); break; case 3: SetField(obj, key, readByteArray(input), rawset); break; case 4: byte[] chunk = input.ReadBytes(input.ReadInt32()); SetField(obj, key, _dataFactory.LoadProvider(chunk, key.ToString()), rawset); break; case 5: tab = _dataFactory.CreateContainer(); SetField(obj, key, tab, rawset); readTable(input, tab); break; case 6: // End of table return; case 7: var objIndex = input.ReadInt16 (); if (objIndex == -21555) SetField (obj, key, _player, rawset); else SetField(obj, key, _allZObjects.GetContainer(objIndex), rawset); break; case 8: tab = (LuaDataContainer)_dataFactory.CreateWherigoObject(readString(input)).DataContainer; SetField(obj, key, tab, rawset); // After an object, there is always a table with the content input.ReadByte(); readTable(input, tab); break; } b = input.ReadByte(); } }