public override object[] GetStructures()
        {
            object[] Res = new object[cTotalStructCount];
            
            int SizeOfItem = Marshal.SizeOf(typeof(MuDef.MUFile_BuffEffect));
            MuDef.MUFile_BuffEffect CurrentItem = new MuDef.MUFile_BuffEffect();

            m_FileBuffer = new byte[SizeOfItem * cTotalStructCount];

            try
            {
              //6  ReadInt(m_FileStream);
                ReadInt(m_FileStream);

                while ((m_FileStream.Read(m_FileBuffer, SizeOfItem * m_CurrentLine, SizeOfItem)) == SizeOfItem)
                {
                    object Item = Marshal.PtrToStructure(
                        Marshal.UnsafeAddrOfPinnedArrayElement(m_FileBuffer, SizeOfItem * m_CurrentLine++),
                        typeof(MuDef.MUFile_BuffEffect));
                    XorFilter(ref Item);
                    
                    CurrentItem = (MuDef.MUFile_BuffEffect)Item;
                    
                    Res[m_CurrentLine] = (object)CurrentItem;
                }
            }
            //todo: prevent
            catch (IndexOutOfRangeException)
            {

            }
            catch (Exception)
            {
                MessageBox.Show("Failed to read file structures.");
            }
            CloseSourceFile();
            return Res;
        }
        public override void SaveAsBmd(string OutputPath, DataGridView dgv)
        {
            try
            {
                //last row is null
                int FilledRowCount = dgv.Rows.Count - 1;
                FileStream OutputStream = File.Open(OutputPath, FileMode.Create, FileAccess.Write);
                List<MuDef.MUFile_BuffEffect> TmpList = new List<MuDef.MUFile_BuffEffect>(dgv.Rows.Count);
                MuDef.MUFile_BuffEffect CurrentItem = new MuDef.MUFile_BuffEffect();

                //last row is null
                for (int i = 0; i < FilledRowCount; i++)
                {
                    //if (dgv.Rows[i].Cells[0].Value != null)
                    {
                        CurrentItem.Index = ushort.Parse(dgv.Rows[i].Cells[0].Value.ToString());
                        CurrentItem.Group = byte.Parse(dgv.Rows[i].Cells[1].Value.ToString());
                        CurrentItem.ItemIndex = byte.Parse(dgv.Rows[i].Cells[2].Value.ToString());
                        CurrentItem.ItemNumber = byte.Parse(dgv.Rows[i].Cells[3].Value.ToString());
                        CurrentItem.Name = dgv.Rows[i].Cells[4].Value.ToString();
                        CurrentItem.State1 = byte.Parse(dgv.Rows[i].Cells[5].Value.ToString());
                        CurrentItem.State2 = byte.Parse(dgv.Rows[i].Cells[6].Value.ToString());
                        CurrentItem.State3 = byte.Parse(dgv.Rows[i].Cells[7].Value.ToString());
                        CurrentItem.Description = dgv.Rows[i].Cells[8].Value.ToString();

                        TmpList.Add(CurrentItem);
                    }

                }
                int ItemSize = Marshal.SizeOf(typeof(MuDef.MUFile_BuffEffect));

                int TotalSize = ItemSize * FilledRowCount;

                byte[] FileBuffer = new byte[TotalSize];

                //write
                for (int i = 0; i < FilledRowCount; i++)
                {
                    byte[] buf = StructureToByteArray(TmpList[i]);
                    XorFilter(ref buf, Marshal.SizeOf(typeof(MuDef.MUFile_BuffEffect)));
                    buf.CopyTo(FileBuffer, i * ItemSize);
                }

                OutputStream.Write(BitConverter.GetBytes(FilledRowCount), 0, 4);
                OutputStream.Write(FileBuffer, 0, TotalSize);

                byte[] crc_bytes = BitConverter.GetBytes(GetCRC(FileBuffer, TotalSize));
                OutputStream.Write(crc_bytes, 0, sizeof(int));

                OutputStream.Flush();
                OutputStream.Close();
            }
            catch { MessageBox.Show("Failed to save file."); }
        }