public GamePresetContainer(GamePresetContainer objToCopy) { Presets = new WaymarkPreset[objToCopy.Presets.Length]; for (uint i = 0u; i < Presets.Length; ++i) { Presets[i] = new WaymarkPreset(objToCopy.Presets[i]); } }
// Fill an unencoded byte array with the provided waymark data. public byte[] ConstructGameData(GamePresetContainer presets) { // Memory to hold the new data. byte[] newData = new byte[mGameDataConfig.NumberOfPresets * mGameDataConfig.BytesPerPreset()]; // Process the data. for (uint presetNumber = 0; presetNumber < mGameDataConfig.NumberOfPresets; ++presetNumber) { uint offset = presetNumber * mGameDataConfig.BytesPerPreset(); // Waymark coordinates. for (uint waymarkNumber = 0u; waymarkNumber < presets[presetNumber].Waymarks.Length; ++waymarkNumber) { // Make sure to write zeros if the waymark is active in order to keep the same format as the game itself writes. WriteBytes(BitConverter.GetBytes(presets[presetNumber][waymarkNumber].IsEnabled ? (Int32)(presets[presetNumber][waymarkNumber].Pos.X * 1000.0) : 0), newData, offset + 0u, !BitConverter.IsLittleEndian); WriteBytes(BitConverter.GetBytes(presets[presetNumber][waymarkNumber].IsEnabled ? (Int32)(presets[presetNumber][waymarkNumber].Pos.Y * 1000.0) : 0), newData, offset + 4u, !BitConverter.IsLittleEndian); WriteBytes(BitConverter.GetBytes(presets[presetNumber][waymarkNumber].IsEnabled ? (Int32)(presets[presetNumber][waymarkNumber].Pos.Z * 1000.0) : 0), newData, offset + 8u, !BitConverter.IsLittleEndian); offset += 12u; } // Which waymarks are active. byte activeMask = 0x00; for (uint i = 0u; i < presets[presetNumber].Waymarks.Length; ++i) { if (presets[presetNumber][i].IsEnabled) { uint tempMask = 0x01; tempMask <<= (int)i; activeMask |= (byte)tempMask; } } WriteBytes(new byte[] { activeMask }, newData, offset, !BitConverter.IsLittleEndian); // Skip reserved byte. // Territory ID. WriteBytes(BitConverter.GetBytes(presets[presetNumber].ZoneID), newData, offset + 2u, !BitConverter.IsLittleEndian); // Time last modified. WriteBytes(BitConverter.GetBytes((Int32)presets[presetNumber].LastModified.ToUnixTimeSeconds()), newData, offset + 4u, !BitConverter.IsLittleEndian); } // Don't correct it here; let the actual write function do that. return(newData); }
private void CharacterListDropdown_SelectedIndexChanged(object sender, EventArgs e) { if (CharacterListDropdown.SelectedIndex > -1 && CharacterListDropdown.SelectedIndex < mCharacterFolderList.Length) { try { mGamePresetContainer = mGameDataHandler.ReadGameData(mCharacterFolderList[CharacterListDropdown.SelectedIndex] + '\\' + mSettings.GameDataSettings.WaymarkDataFileName); PopulateGamePresetListBox(); } catch (Exception exception) { MessageBox.Show("An error has occured while reading the file for character \"" + mSettings.CharacterAliasSettings.GetAlias(mCharacterFolderList[CharacterListDropdown.SelectedIndex].Split('\\').Last()) + "\": " + exception.Message, "Failure!"); PopulateGamePresetListBox(true); } } else { PopulateGamePresetListBox(true); } }
// Read and decode the waymark section of the game file. public GamePresetContainer ReadGameData(string fileName) { // Object to populate with the game data. GamePresetContainer presets = new GamePresetContainer(mGameDataConfig.NumberOfPresets); // Read the raw data from the file. if (!File.Exists(fileName)) { throw new Exception("File does not exist (" + fileName + ")"); } FileStream fs = File.OpenRead(fileName); if (fs.Length != mGameDataConfig.ExpectedFileLength_Bytes) { throw new Exception("Error while reading game data file: Unexpected file size. You may not have logged on with this character since the latest patch, or this program may not have been updated for the current patch."); } byte[] rawData = new byte[mGameDataConfig.NumberOfPresets * mGameDataConfig.BytesPerPreset()]; int numBytesToRead = (int)mGameDataConfig.NumberOfPresets * (int)mGameDataConfig.BytesPerPreset(); fs.Seek((int)mGameDataConfig.WaymarkDataOffset, SeekOrigin.Begin); uint bytesRead = (uint)fs.Read(rawData, 0, numBytesToRead); if (bytesRead != (mGameDataConfig.NumberOfPresets * mGameDataConfig.BytesPerPreset())) { throw new Exception("Unexpected number of bytes read from file: " + bytesRead.ToString()); } fs.Close(); // Process the data. byte[] correctedData = CorrectData(rawData); for (uint presetNumber = 0; presetNumber < mGameDataConfig.NumberOfPresets; ++presetNumber) { uint offset = presetNumber * mGameDataConfig.BytesPerPreset(); // Waymark coordinates. for (uint waymarkNumber = 0u; waymarkNumber < presets[presetNumber].Waymarks.Length; ++waymarkNumber) { presets[presetNumber][waymarkNumber].Pos.X = BitConverter.ToInt32(ReadBytes(correctedData, offset + 0u, sizeof(Int32), !BitConverter.IsLittleEndian), 0) / 1000.0; presets[presetNumber][waymarkNumber].Pos.Y = BitConverter.ToInt32(ReadBytes(correctedData, offset + 4u, sizeof(Int32), !BitConverter.IsLittleEndian), 0) / 1000.0; presets[presetNumber][waymarkNumber].Pos.Z = BitConverter.ToInt32(ReadBytes(correctedData, offset + 8u, sizeof(Int32), !BitConverter.IsLittleEndian), 0) / 1000.0; offset += 12u; } // Which waymarks are active. byte activeMask = correctedData[offset]; for (uint i = 0u; i < presets[presetNumber].Waymarks.Length; ++i) { uint testMask = 0x01; presets[presetNumber][i].IsEnabled = ((uint)activeMask & (testMask << (int)i)) > 0; } // Skip reserved byte. // Territory ID. presets[presetNumber].ZoneID = BitConverter.ToUInt16(ReadBytes(correctedData, offset + 2u, sizeof(Int16), !BitConverter.IsLittleEndian), 0); // Time last modified. presets[presetNumber].LastModified = DateTimeOffset.FromUnixTimeSeconds(BitConverter.ToInt32(ReadBytes(correctedData, offset + 4u, sizeof(Int32), !BitConverter.IsLittleEndian), 0)); } // Return the processed data. return(presets); }