// only works for PW !!! public eList[] Load(string elFile, ref ColorProgressBar.ColorProgressBar cpb2) { eList[] Li = new eList[0]; addonIndex = new Dictionary <int, int>(); Listcnts = null; ListOsets = null; Listver = -1; SStat = new int[5] { 0, 0, 0, 0, 0 }; string fileStream = Path.GetDirectoryName(elFile) + "\\elements.list.count"; if (File.Exists(fileStream)) { Listcnts = new SortedList(); ListOsets = new SortedList(); using (StreamReader reader = new StreamReader(fileStream)) { string line; while ((line = reader.ReadLine()) != null) { string[] val = line.Split('='); if (val[0] == "ver") { Listver = Convert.ToInt16(val[1]); } else if (val[0] == "offset") { ListOsets.Add(val[1], val[2]); } else { Listcnts.Add(val[0], val[1]); } } } } // open the element file FileStream fs = File.OpenRead(elFile); BinaryReader br = new BinaryReader(fs); Version = br.ReadInt16(); if (Listver > -1) { Version = Listver; } Signature = br.ReadInt16(); // check if a corresponding configuration file exists string[] configFiles = Directory.GetFiles(Application.StartupPath + "\\configs", "PW_*_v" + Version + ".cfg"); if (configFiles.Length > 0) { // configure an eList array with the configuration file ConfigFile = configFiles[0]; Li = loadConfiguration(ConfigFile); cpb2.Maximum = Li.Length; cpb2.Value = 0; // read the element file for (int l = 0; l < Li.Length; l++) { SStat[0] = l; Application.DoEvents(); // read offset if (Li[l].listOffset != null) { // 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 == 0) { byte[] t = br.ReadBytes(4); byte[] len = br.ReadBytes(4); byte[] buffer = br.ReadBytes(BitConverter.ToInt32(len, 0)); Li[l].listOffset = new byte[t.Length + len.Length + buffer.Length]; Array.Copy(t, 0, Li[l].listOffset, 0, t.Length); Array.Copy(len, 0, Li[l].listOffset, 4, len.Length); Array.Copy(buffer, 0, Li[l].listOffset, 8, buffer.Length); } if (l == 20) { byte[] tag = br.ReadBytes(4); byte[] len = br.ReadBytes(4); byte[] buffer = br.ReadBytes(BitConverter.ToInt32(len, 0)); byte[] t = br.ReadBytes(4); Li[l].listOffset = new byte[tag.Length + len.Length + buffer.Length + t.Length]; Array.Copy(tag, 0, Li[l].listOffset, 0, tag.Length); Array.Copy(len, 0, Li[l].listOffset, 4, len.Length); Array.Copy(buffer, 0, Li[l].listOffset, 8, buffer.Length); Array.Copy(t, 0, Li[l].listOffset, 8 + buffer.Length, t.Length); } int NPC_WAR_TOWERBUILD_SERVICE_index = 100; if (Version >= 191) { NPC_WAR_TOWERBUILD_SERVICE_index = 99; } if (l == NPC_WAR_TOWERBUILD_SERVICE_index) { byte[] tag = br.ReadBytes(4); byte[] len = br.ReadBytes(4); byte[] buffer = br.ReadBytes(BitConverter.ToInt32(len, 0)); Li[l].listOffset = new byte[tag.Length + len.Length + buffer.Length]; Array.Copy(tag, 0, Li[l].listOffset, 0, tag.Length); Array.Copy(len, 0, Li[l].listOffset, 4, len.Length); Array.Copy(buffer, 0, Li[l].listOffset, 8, buffer.Length); } } // read conversation list if (l == ConversationListIndex) { if (Version >= 191) { long sourcePosition = br.BaseStream.Position; int listLength = 0; bool run = true; while (run) { run = false; try { br.ReadByte(); listLength++; run = true; } catch { } } br.BaseStream.Position = sourcePosition; Li[l].elementTypes[0] = "byte:" + listLength; } else { // Auto detect only works for Perfect World elements.data !!! if (Li[l].elementTypes[0].Contains("AUTO")) { 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]); } // read lists else { if (Version >= 191) { Li[l].listType = br.ReadInt32(); } if (Listver > -1 && Listcnts[l.ToString()] != null) { int num = Convert.ToInt32(Listcnts[l.ToString()]); Li[l].elementValues = new object[num][]; br.ReadBytes(4); } else { Li[l].elementValues = new object[br.ReadInt32()][]; } SStat[1] = Li[l].elementValues.Length; if (Version >= 191) { Li[l].elementSize = br.ReadInt32(); } // go through all elements of a list 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 int idtest = -1; for (int f = 0; f < Li[l].elementValues[e].Length; f++) { Li[l].elementValues[e][f] = readValue(br, Li[l].elementTypes[f]); if (Li[l].elementFields[f] == "ID") { idtest = Int32.Parse(Li[l].GetValue(e, f)); SStat[2] = idtest; if (l == 0) { if (!addonIndex.ContainsKey(idtest)) { addonIndex.Add(idtest, e); } else { MessageBox.Show("Error: Found duplicate Addon id:" + idtest); addonIndex[idtest] = e; } } } } } } cpb2.Value++; } } else { MessageBox.Show("No corressponding configuration file found!\nVersion: " + Version + "\nPattern: " + "configs\\PW_*_v" + Version + ".cfg"); } br.Close(); fs.Close(); return(Li); }
// 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 (this.GetValue(n, 0) == newList.GetValue(e, 0)) { exists = true; } } if (!exists) { if (dirBackupMissing != null && System.IO.Directory.Exists(dirBackupMissing)) { ExportItem(dirBackupMissing + "\\List_" + listID.ToString() + "_Item_" + this.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 (this.GetValue(n, 0) == newList.GetValue(e, 0)) { exists = true; // check if this item is different if (this.elementValues[n].Length != newList.elementValues[e].Length) { // invalid amount of values !!! report.Add("<> DIFFERENT ITEM (*not replaced, invalid amount of values): " + this.GetValue(n, 0)); } else { // compare all values of current element for (int i = 0; i < this.elementValues[n].Length; i++) { if (this.GetValue(n, i) != newList.GetValue(e, i)) { if (backupChanged && System.IO.Directory.Exists(dirBackupChanged)) { ExportItem(dirBackupChanged + "\\List_" + listID.ToString() + "_Item_" + this.GetValue(n, 0) + ".txt", n); } if (replaceChanged) { report.Add("<> DIFFERENT ITEM (*replaced): " + this.GetValue(n, 0)); elementValues[n] = newList.elementValues[e]; } else { report.Add("<> DIFFERENT ITEM (*not replaced): " + this.GetValue(n, 0)); } break; } } } break; } } if (!exists) { if (backupNew && System.IO.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): " + this.GetValue(elementValues.Length - 1, 0)); } else { report.Add("+ NEW ITEM (*not added): " + this.GetValue(elementValues.Length - 1, 0)); } } } return(report); }