Example #1
0
        /// <summary>
        /// Parses a GW2 string file.
        /// </summary>
        /// <param name="file">Raw string file extracted from GW2.dat or Local.dat</param>
        /// <param name="timestamp">Mark entries with custom timestamp</param>
        /// <returns>Number of strings in collection</returns>
        public int Read(string file, DateTime timestamp)
        {
            Items.Clear();
            Filename = Path.GetFileName(file);

            // Open the string file.
            byte[] fileBuffer = System.IO.File.ReadAllBytes(file);

            // Byte 00 + 01 = string length
            // Byte 04      = string type
            byte[] header = new byte[6];
            byte[] strs = new byte[4];

            // Start reading after strs
            long position = 4;

            // Stores blocksize
            long blocksize = 0;

            // Stores row number in file
            int row = 0;

            // Make sure your file is at least 6 bytes
            if (fileBuffer.Length > 6)
            {
                Array.Copy(fileBuffer, 0, strs, 0, 4);

                // Check FourCC and make sure the file uses a valid language
                if (fileBuffer[fileBuffer.Length - 2] < 5 && FourCC.SequenceEqual(strs))
                {
                    // Set language
                    Language = (GW2Language) fileBuffer[fileBuffer.Length - 2];

                    // Keep reading the file, we don't need the last 2 language bytes.
                    while (position < fileBuffer.Length - 2)
                    {
                        // Create a new entry
                        GW2Entry entry = new GW2Entry();
                        entry.row = row;
                        entry.stamp = timestamp;

                        // Read block header
                        Array.Copy(fileBuffer, position, header, 0, 6);
                        position += 6;

                        // Get the string size
                        blocksize = header[0] + (header[1] * 256) - 6;
                        
                        if (blocksize <= 0)
                        {
                            // Empty block
                            entry.type = GW2EntryType.Empty;
                            entry.value = string.Empty;
                        }
                        else
                        {
                            // Read the block
                            if (header[4] == 16)
                            {
                                // UTF-16 String
                                entry.value = Encoding.Unicode.GetString(fileBuffer, (int)position, (int)blocksize);
                                entry.type = GW2EntryType.String;
                            }
                            else
                            {
                                // Other String
                                entry.type = GW2EntryType.Other;
                            }

                            // Moving on...
                            position += blocksize;
                        }

                        // Add entry
                        // NOTE: I've only set it to store actual strings to save all types change this line to:
                        //
                        //      Items.Add(entry);
                        //
                        if (entry.type == GW2EntryType.String) Items.Add(entry);

                        // Next row
                        row++;
                    }
                }
            }

            fileBuffer = null;

            // Done!
            return Items.Count;
        }
Example #2
0
        /// <summary>
        /// Parses a GW2 string file.
        /// </summary>
        /// <param name="file">Raw string file extracted from GW2.dat or Local.dat</param>
        /// <param name="timestamp">Mark entries with custom timestamp</param>
        /// <returns>Number of strings in collection</returns>
        public int Read(string file, DateTime timestamp)
        {
            Items.Clear();
            Filename = Path.GetFileName(file);

            // Open the string file.
            byte[] fileBuffer = System.IO.File.ReadAllBytes(file);

            // Byte 00 + 01 = string length
            // Byte 04      = string type
            byte[] header = new byte[6];
            byte[] strs   = new byte[4];

            // Start reading after strs
            long position = 4;

            // Stores blocksize
            long blocksize = 0;

            // Stores row number in file
            int row = 0;

            // Make sure your file is at least 6 bytes
            if (fileBuffer.Length > 6)
            {
                Array.Copy(fileBuffer, 0, strs, 0, 4);

                // Check FourCC and make sure the file uses a valid language
                if (fileBuffer[fileBuffer.Length - 2] < 5 && FourCC.SequenceEqual(strs))
                {
                    // Set language
                    Language = (GW2Language)fileBuffer[fileBuffer.Length - 2];

                    // Keep reading the file, we don't need the last 2 language bytes.
                    while (position < fileBuffer.Length - 2)
                    {
                        // Create a new entry
                        GW2Entry entry = new GW2Entry();
                        entry.row   = row;
                        entry.stamp = timestamp;

                        // Read block header
                        Array.Copy(fileBuffer, position, header, 0, 6);
                        position += 6;

                        // Get the string size
                        blocksize = header[0] + (header[1] * 256) - 6;

                        if (blocksize <= 0)
                        {
                            // Empty block
                            entry.type  = GW2EntryType.Empty;
                            entry.value = string.Empty;
                        }
                        else
                        {
                            // Read the block
                            if (header[4] == 16)
                            {
                                // UTF-16 String
                                entry.value = Encoding.Unicode.GetString(fileBuffer, (int)position, (int)blocksize);
                                entry.type  = GW2EntryType.String;
                            }
                            else
                            {
                                // Other String
                                entry.type = GW2EntryType.Other;
                            }

                            // Moving on...
                            position += blocksize;
                        }

                        // Add entry
                        // NOTE: I've only set it to store actual strings to save all types change this line to:
                        //
                        //      Items.Add(entry);
                        //
                        if (entry.type == GW2EntryType.String)
                        {
                            Items.Add(entry);
                        }

                        // Next row
                        row++;
                    }
                }
            }

            fileBuffer = null;

            // Done!
            return(Items.Count);
        }
Example #3
0
        private void updateFromFileList(string[] files)
        {
            // Set the timestamp for new / altered items.
            DateTime timestamp = DateTime.Now;

            // Make sure your UI will update
            this.BeginInvoke((MethodInvoker) delegate()
            {
                toolstrip.Enabled = false;
                progress.Maximum  = files.Length;
                progress.Value    = 0;
                status.Text       = "0 / " + files.Length.ToString();
            });

            // Create data directory if necessary
            if (!Directory.Exists(datafolder + "data"))
            {
                Directory.CreateDirectory(datafolder + "data");
            }

            // Loop through the files
            for (int i = 0; i < files.Length; i++)
            {
                // Thread sometimes likes to go out of sync... dirty fix
                if (i < (files.Length - 1))
                {
                    string output = "";

                    // Update UI
                    this.BeginInvoke((MethodInvoker) delegate()
                    {
                        if (i < files.Length)
                        {
                            progress.Value = i;
                            status.Text    = "Updating: " + (i + 1).ToString() + " / " + files.Length.ToString() + " - " + files[i].ToString();
                        }
                    });

                    // Read new file, and deserialize current file
                    GW2StringFile newFile = new GW2StringFile(files[i], timestamp);
                    GW2StringFile oldFile = new GW2StringFile();

                    // Make sure your new file actually has data
                    if (newFile.Items.Count > 0)
                    {
                        // Create language directory if necessary
                        output = datafolder + @"data\" + newFile.Language.ToString() + @"\";
                        if (!Directory.Exists(output))
                        {
                            Directory.CreateDirectory(output);
                        }

                        // Deserialize old data if availible
                        if (File.Exists(output + Path.GetFileNameWithoutExtension(newFile.Filename) + ".gw2"))
                        {
                            using (FileStream filestream = new FileStream(output + Path.GetFileNameWithoutExtension(newFile.Filename) + ".gw2", FileMode.Open))
                            {
                                BinaryFormatter serializer = new BinaryFormatter();
                                oldFile = (GW2StringFile)serializer.Deserialize(filestream);
                            }
                        }

                        // Make sure the language and filename are reset (it tends to forget this one)
                        oldFile.Language = newFile.Language;
                        oldFile.Filename = newFile.Filename;

                        // Loop through new items
                        foreach (GW2Entry item in newFile.Items)
                        {
                            // Check if row is already present
                            GW2Entry oldEntry = oldFile.Items.FirstOrDefault(a => a.row == item.row);

                            if (oldEntry != null)
                            {
                                // Check if row has changed
                                if (oldEntry.value != item.value)
                                {
                                    // Row has changed, update.
                                    oldEntry.value = item.value;
                                    oldEntry.stamp = item.stamp;
                                }
                            }
                            else
                            {
                                // No row found, add it.
                                oldFile.Items.Add(item);
                            }
                        }

                        // Serialize back to file.
                        using (FileStream filestream = new FileStream(output + Path.GetFileNameWithoutExtension(newFile.Filename) + ".gw2", FileMode.Create))
                        {
                            BinaryFormatter serializer = new BinaryFormatter();
                            serializer.Serialize(filestream, oldFile);
                        }

                        oldFile = null;
                        newFile = null;
                    }
                }
            }

            // Restore UI to previous state and reload grid.
            this.BeginInvoke((MethodInvoker) delegate()
            {
                toolstrip.Enabled = true;
                progress.Value    = 0;
                status.Text       = "";
                refreshGridAsync();
            });
        }