/// <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); }
/// <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(); } }