Exemplo n.º 1
0
        // only works for PW !!!
        public eList[] LoadPW(string elFile, string cfgFile, BackgroundWorker worker)
        {
            eList[] Li = new eList[0];

            // open the element file
            FileStream   fs = File.OpenRead(elFile);
            BinaryReader br = new BinaryReader(fs);

            Version   = br.ReadInt16();
            Signature = br.ReadInt16();

            string myConfig;

            if (cfgFile == null)
            {
                myConfig = "*_*_v" + Version;
            }
            else
            {
                myConfig = cfgFile;
            }

            // check if a corresponding configuration file exists
            string[] configFiles = Directory.GetFiles(Environment.CurrentDirectory + "\\configs", myConfig + ".cfg"); // Application.StartupPath
            if (configFiles.Length > 0)
            {
                // configure an eList array with the configuration file
                ConfigFile = configFiles[0];
                Li         = loadConfiguration(ConfigFile);

                // read the element file
                for (int l = 0; l < Li.Length; l++)
                {
                    if (worker != null)
                    {
                        int percentLoaded = (int)Math.Round((((double)l + 1) / (double)Li.Length) * 100.0);
                        worker.ReportProgress(percentLoaded, new object[] { l, Li.Length });
                    }

                    // read offset
                    if (Li[l].listOffset != null) // if (Li[l].listOffset)
                    {
                        // offset > 0
                        if (Li[l].listOffset.Length > 0)
                        {
                            Li[l].listOffset = br.ReadBytes(Li[l].listOffset.Length);
                        }
                    }
                    // autodetect offset (for list 20 & 100)
                    else
                    {
                        if (l == 20)
                        {
                            byte[] head  = br.ReadBytes(4);
                            byte[] count = br.ReadBytes(4);
                            byte[] body  = br.ReadBytes(BitConverter.ToInt32(count, 0));
                            byte[] tail  = br.ReadBytes(4);
                            Li[l].listOffset = new byte[head.Length + count.Length + body.Length + tail.Length];
                            Array.Copy(head, 0, Li[l].listOffset, 0, head.Length);
                            Array.Copy(count, 0, Li[l].listOffset, 4, count.Length);
                            Array.Copy(body, 0, Li[l].listOffset, 8, body.Length);
                            Array.Copy(tail, 0, Li[l].listOffset, 8 + body.Length, tail.Length);
                        }
                        if (l == 100)
                        {
                            byte[] head  = br.ReadBytes(4);
                            byte[] count = br.ReadBytes(4);
                            byte[] body  = br.ReadBytes(BitConverter.ToInt32(count, 0));
                            Li[l].listOffset = new byte[head.Length + count.Length + body.Length];
                            Array.Copy(head, 0, Li[l].listOffset, 0, head.Length);
                            Array.Copy(count, 0, Li[l].listOffset, 4, count.Length);
                            Array.Copy(body, 0, Li[l].listOffset, 8, body.Length);
                        }
                    }

                    // read conversation list
                    if (l == ConversationListIndex && ConversationListIndex > -1)
                    {
                        // Auto detect only works for Perfect World elements.data !!!
                        if (Li[l].elementTypes[0].Contains("AUTO"))
                        {
                            if (SW != 1)
                            {
                                byte[] pattern        = (Encoding.GetEncoding("GBK")).GetBytes("facedata\\");
                                long   sourcePosition = br.BaseStream.Position; // Получаем позицию чтения листа
                                int    listLength     = -72 - pattern.Length;
                                bool   run            = true;
                                while (run)
                                {
                                    run = false;
                                    for (int i = 0; i < pattern.Length; i++)
                                    {
                                        listLength++;
                                        if (br.ReadByte() != pattern[i])
                                        {
                                            run = true;
                                            break;
                                        }
                                    }
                                }
                                br.BaseStream.Position = sourcePosition;
                                Li[l].elementTypes[0]  = "byte:" + listLength;

                                Li[l].elementValues       = new object[1][];
                                Li[l].elementValues[0]    = new object[Li[l].elementTypes.Length];
                                Li[l].elementValues[0][0] = readValue(br, Li[l].elementTypes[0]);
                            }

                            if (SW == 1)
                            {
                                long MainPosition = br.BaseStream.Position;
                                int  Talks        = br.ReadInt32();

                                for (int e = 0; e < Talks; e++)
                                {
                                    uint   ID          = (uint)readValue(br, "uint32");
                                    byte[] Name        = (byte[])readValue(br, "wstring:128");
                                    int    NUM_WINDOWS = (int)readValue(br, "int32");

                                    for (int j = 0; j < NUM_WINDOWS; j++)
                                    {
                                        uint   ID_WINDOW        = (uint)readValue(br, "uint32");
                                        int    ID_WINDOW_PARENT = (int)readValue(br, "int32");
                                        uint   TALK_TEXT_LEN    = (uint)readValue(br, "uint32");
                                        byte[] TALK_TEXT        = (byte[])readValue(br, ("wstring:" + TALK_TEXT_LEN * 2));
                                        int    NUM_OPTION       = (int)readValue(br, "int32");

                                        for (int k = 0; k < NUM_OPTION; k++)
                                        {
                                            int    ID_OPTION    = (int)readValue(br, "int32");
                                            byte[] TEXT_OPTION  = (byte[])readValue(br, "wstring:128");
                                            uint   PARAM_OPTION = (uint)readValue(br, "uint32");
                                        }
                                    }
                                    int  TALK_PROC_TYPE = (int)readValue(br, "int32");
                                    uint ID_PATH        = (uint)readValue(br, "uint32");
                                }

                                int    AfterTalkLen = br.ReadInt32();
                                byte[] AfterTalk    = br.ReadBytes(AfterTalkLen);

                                if (AfterTalkLen != AfterTalk.Length)
                                {
                                    MessageBox.Show("В данном Элике проблема с окончанием диалогов, \nпосле сохранения может быть не рабочим!");
                                }

                                long listLength = fs.Position - MainPosition;

                                br.BaseStream.Position = MainPosition;
                                Li[l].elementTypes[0]  = "byte:" + listLength;

                                Li[l].elementValues       = new object[1][];
                                Li[l].elementValues[0]    = new object[Li[l].elementTypes.Length];
                                Li[l].elementValues[0][0] = readValue(br, Li[l].elementTypes[0]);
                            }
                        }
                    }
                    // read lists
                    else
                    {
                        try
                        {
                            Li[l].elementValues = new object[br.ReadInt32()][];
                        }
                        catch
                        {
                            return(Li);
                        }

                        ushort[] FullSize = new ushort[Li[l].elementValues.Length];
                        uint[]   id       = new uint[Li[l].elementValues.Length];

                        uint sum_str_len;
                        long el_size = 0;

                        MemoryStream fsList = new MemoryStream();
                        BinaryWriter bwList = new BinaryWriter(fsList);

                        if (SW == 1 && l != ConversationListIndex)
                        {
                            ushort nameSize;

                            for (int f = 0; f < Li[l].elementValues.Length; f++)
                            {
                                id[f]       = br.ReadUInt32();
                                nameSize    = br.ReadUInt16();
                                FullSize[f] = nameSize;
                            }

                            if (Li[l].elementValues.Length > 0)
                            {
                                sum_str_len = br.ReadUInt32();

                                for (int i = 0; i < Li[l].elementValues.Length; i++)
                                {
                                    bwList.Write(UnpackMPPC(br.ReadBytes(FullSize[i])));
                                    if (i == 0)
                                    {
                                        el_size = fsList.Position;
                                    }
                                }
                            }
                        }

                        fsList.Position = 0;
                        BinaryReader brSW = new BinaryReader(fsList);

                        // go through all elements of a list
                        // sdfsdf asdl;zcmv,bl
                        for (int e = 0; e < Li[l].elementValues.Length; e++)
                        {
                            Li[l].elementValues[e] = new object[Li[l].elementTypes.Length];

                            // go through all fields of an element
                            for (int f = 0; f < Li[l].elementValues[e].Length; f++)
                            {
                                if (SW == 1)
                                {
                                    Li[l].elementValues[e][f] = readValue(brSW, Li[l].elementTypes[f]);
                                    if (e == 0 && f == Li[l].elementValues[e].Length - 1 && fsList.Position != el_size)
                                    {
                                        MessageBox.Show($"Лист {l}({Li[l].listName})\nТекущий размер: {fsList.Position} байт\nИсходный размер: {el_size} байт\nКол-во предметов: {Li[l].elementValues.Length}");
                                    }
                                }
                                if (SW != 1)
                                {
                                    Li[l].elementValues[e][f] = readValue(br, Li[l].elementTypes[f]);
                                }
                            }
                        }

                        brSW.Close();
                        bwList.Close();
                        fsList.Flush();
                        fsList.Close();
                    }
                }
            }
            else
            {
                MessageBox.Show("No corressponding configuration file found!\nVersion: " + Version + "\nPattern: " + "configs\\PW_*_v" + Version + ".cfg");
            }

            br.Close();
            fs.Close();

            return(Li);
        }
Exemplo n.º 2
0
        // add all new elements into the elementValues
        public ArrayList JoinElements(eList newList, int listID, bool addNew, bool backupNew, bool replaceChanged, bool backupChanged, bool removeMissing, bool backupMissing, string dirBackupNew, string dirBackupChanged, string dirBackupMissing)
        {
            object[][] newElementValues = newList.elementValues;
            string[]   newElementTypes  = newList.elementTypes;

            ArrayList report = new ArrayList();
            bool      exists;

            // check which elements are missing (removed)
            for (int n = 0; n < elementValues.Length; n++)
            {
                //Application.DoEvents();
                exists = false;
                for (int e = 0; e < newElementValues.Length; e++)
                {
                    if (GetValue(n, 0) == newList.GetValue(e, 0))
                    {
                        exists = true;
                    }
                }
                if (!exists)
                {
                    if (dirBackupMissing != null && Directory.Exists(dirBackupMissing))
                    {
                        ExportItem(dirBackupMissing + "\\List_" + listID.ToString() + "_Item_" + GetValue(n, 0) + ".txt", n);
                    }
                    if (removeMissing)
                    {
                        report.Add("- MISSING ITEM (*removed): " + ((int)elementValues[n][0]).ToString());
                        RemoveItem(n);
                        n--;
                    }
                    else
                    {
                        report.Add("- MISSING ITEM (*not removed): " + ((int)elementValues[n][0]).ToString());
                    }
                }
            }

            for (int e = 0; e < newElementValues.Length; e++)
            {
                //Application.DoEvents();
                // check if the element with this id already exists
                exists = false;
                for (int n = 0; n < elementValues.Length; n++)
                {
                    if (GetValue(n, 0) == newList.GetValue(e, 0))
                    {
                        exists = true;
                        // check if this item is different
                        if (elementValues[n].Length != newList.elementValues[e].Length)
                        {
                            // invalid amount of values !!!
                            report.Add("<> DIFFERENT ITEM (*not replaced, invalid amount of values): " + GetValue(n, 0));
                        }
                        else
                        {
                            // compare all values of current element
                            for (int i = 0; i < elementValues[n].Length; i++)
                            {
                                if (GetValue(n, i) != newList.GetValue(e, i))
                                {
                                    if (backupChanged && Directory.Exists(dirBackupChanged))
                                    {
                                        ExportItem(dirBackupChanged + "\\List_" + listID.ToString() + "_Item_" + GetValue(n, 0) + ".txt", n);
                                    }
                                    if (replaceChanged)
                                    {
                                        report.Add("<> DIFFERENT ITEM (*replaced): " + GetValue(n, 0));
                                        elementValues[n] = newList.elementValues[e];
                                    }
                                    else
                                    {
                                        report.Add("<> DIFFERENT ITEM (*not replaced): " + GetValue(n, 0));
                                    }
                                    break;
                                }
                            }
                        }
                        break;
                    }
                }
                if (!exists)
                {
                    if (backupNew && Directory.Exists(dirBackupNew))
                    {
                        newList.ExportItem(dirBackupNew + "\\List_" + listID.ToString() + "_Item_" + newList.GetValue(e, 0) + ".txt", e);
                    }
                    if (addNew)
                    {
                        AddItem(newElementValues[e]);
                        report.Add("+ NEW ITEM (*added): " + GetValue(elementValues.Length - 1, 0));
                    }
                    else
                    {
                        report.Add("+ NEW ITEM (*not added): " + GetValue(elementValues.Length - 1, 0));
                    }
                }
            }

            return(report);
        }