/// <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(); } }
/// <summary> /// Loads a save game for the current cartridge from a stream. /// </summary> /// <param name="stream">Stream to load the game from.</param> /// <returns>The metadata of the file.</returns> public Metadata Load(Stream stream) { int numAllZObjects; Metadata metadata; using (BinaryReader input = new BinaryReader(stream)) { // Loads the GWS metadata. metadata = LoadMetadata(input); // Belongs this GWS file to the cartridge if (!metadata.CartridgeCreateDate.Equals(_cartridgeEntity.CreateDate)) { throw new Exception("Trying to load a GWS file with different creation date of cartridge."); } // TODO // Check, if all fields are the same as the fields from the GWC cartridge. // If not, than ask, if we should go on, even it could get problems. int numOfObjects = input.ReadInt32(); _allZObjects = _cartridge.GetContainer("AllZObjects"); numAllZObjects = _allZObjects.Count; string objectType = null; for (int i = 1; i < numOfObjects; i++) { objectType = readString(input); if (i > numAllZObjects - 1) { // Object creation can be done using: WherigoObject wo = _dataFactory.CreateWherigoObject(objectType, _cartridge); } else { // TODO: Check, if objectType and real type of object are the same } } // Now update allZObjects, because it could be, that new ones are created _allZObjects = _cartridge.GetContainer("AllZObjects"); numAllZObjects = _allZObjects.Count; //LuaTable obj = _player; LuaDataContainer obj = _player; objectType = readString(input); // Read begin table (5) for player byte b = input.ReadByte(); // Read data for player readTable(input, obj); for (int i = 0; i < numAllZObjects; i++) { objectType = readString(input); b = input.ReadByte(); if (b != 5) { // error throw new InvalidOperationException(); } else { obj = (LuaDataContainer)_allZObjects.GetContainer(i); readTable(input, obj); } } input.Close(); } // Now deserialize all ZObjects for (int i = 0; i < numAllZObjects; i++) { ((LuaDataContainer)_allZObjects.GetContainer(i)).CallSelf("deserialize"); } // TODO: Update all lists return(metadata); }
/// <summary> /// Loads a save game for the current cartridge from a stream. /// </summary> /// <param name="stream">Stream to load the game from.</param> /// <returns>The metadata of the file.</returns> public Metadata Load(Stream stream) { int numAllZObjects; Metadata metadata; using (BinaryReader input = new BinaryReader(stream)) { // Loads the GWS metadata. metadata = LoadMetadata(input); // Belongs this GWS file to the cartridge if (!metadata.CartridgeCreateDate.Equals(_cartridgeEntity.CreateDate)) throw new Exception("Trying to load a GWS file with different creation date of cartridge."); // TODO // Check, if all fields are the same as the fields from the GWC cartridge. // If not, than ask, if we should go on, even it could get problems. int numOfObjects = input.ReadInt32(); _allZObjects = _cartridge.GetContainer("AllZObjects"); numAllZObjects = _allZObjects.Count; string objectType = null; for (int i = 1; i < numOfObjects; i++) { objectType = readString(input); if (i > numAllZObjects - 1) { // Object creation can be done using: WherigoObject wo = _dataFactory.CreateWherigoObject(objectType, _cartridge); } else { // TODO: Check, if objectType and real type of object are the same } } // Now update allZObjects, because it could be, that new ones are created _allZObjects = _cartridge.GetContainer("AllZObjects"); numAllZObjects = _allZObjects.Count; //LuaTable obj = _player; LuaDataContainer obj = _player; objectType = readString(input); // Read begin table (5) for player byte b = input.ReadByte(); // Read data for player readTable(input, obj); for (int i = 0; i < numAllZObjects; i++) { objectType = readString(input); b = input.ReadByte(); if (b != 5) { // error throw new InvalidOperationException(); } else { obj = (LuaDataContainer)_allZObjects.GetContainer(i); readTable(input, obj); } } input.Close(); } // Now deserialize all ZObjects for (int i = 0; i < numAllZObjects; i++) { ((LuaDataContainer)_allZObjects.GetContainer(i)).CallSelf("deserialize"); } // TODO: Update all lists return metadata; }