/// <summary> /// Try to get the Silkroad version from Pk2 /// </summary> /// <returns>Return success</returns> public static bool TryGetVersion(this Pk2Reader Pk2Reader, out uint Version) { try { // Localize the file and prepare to read it Stream data = Pk2Reader.GetFileStream("SV.T"); BinaryReader buffer = new BinaryReader(data, Encoding.ASCII); // Reading the encrypted file int versionLength = buffer.ReadInt32(); byte[] versionBuffer = buffer.ReadBytes(versionLength); // Initialize the blowfish to decrypt the file Blowfish bf = new Blowfish(); bf.Initialize(Encoding.ASCII.GetBytes("SILKROADVERSION"), 0, 8); // Decrypting versionBuffer = bf.Decode(versionBuffer); // Only four starting bytes contains the numbers Version = uint.Parse(Encoding.ASCII.GetString(versionBuffer, 0, 4)); // Success return(true); } catch { Version = uint.MinValue; return(false); } }
/// <summary> /// Read the Pk2 structure recursively. /// </summary> private void Read(long Position, string RootPath) { BinaryReader reader = new BinaryReader(m_FileStream); reader.BaseStream.Position = Position; List <Pk2Folder> folders = new List <Pk2Folder>(); sPk2EntryBlock entryBlock = (sPk2EntryBlock)BufferToStruct(m_Blowfish.Decode(reader.ReadBytes(Marshal.SizeOf(typeof(sPk2EntryBlock)))), typeof(sPk2EntryBlock)); for (int i = 0; i < 20; i++) { sPk2Entry entry = entryBlock.Entries[i]; //..... switch (entry.Type) { case 0: //Null Entry break; case 1: //Folder if (entry.Name != "." && entry.Name != "..") { Pk2Folder folder = new Pk2Folder(); folder.Name = entry.Name; folder.Position = BitConverter.ToInt64(entry.g_Position, 0); folders.Add(folder); m_Folders[(RootPath + entry.Name).ToUpper()] = folder; m_CurrentFolder.SubFolders.Add(folder); } break; case 2: //File Pk2File file = new Pk2File(); file.Position = entry.Position; file.Name = entry.Name; file.Size = entry.Size; file.ParentFolder = m_CurrentFolder; m_Files[(RootPath + entry.Name).ToUpper()] = file; m_CurrentFolder.Files.Add(file); break; } } if (entryBlock.Entries[19].NextChain != 0) { Read(entryBlock.Entries[19].NextChain, RootPath); } foreach (Pk2Folder folder in folders) { m_CurrentFolder = folder; if (folder.Files == null) { folder.Files = new List <Pk2File>(); } if (folder.SubFolders == null) { folder.SubFolders = new List <Pk2Folder>(); } Read(folder.Position, RootPath + folder.Name + "\\"); } }
static int GetVersionFromSvt(byte[] svtContents) { byte[] bfKey = ASCIIEncoding.ASCII.GetBytes("SILKROAD"); Blowfish bf = new Blowfish(); bf.Initialize(bfKey); byte[] toDecode = new byte[8]; Buffer.BlockCopy(svtContents, 4, toDecode, 0, 8); byte[] decoded = bf.Decode(toDecode); string verStr = ASCIIEncoding.ASCII.GetString(decoded); int firstZeroTermAt = verStr.IndexOf('\0'); verStr = verStr.Remove(firstZeroTermAt, verStr.Length - firstZeroTermAt); byte[] verStrBytes = ASCIIEncoding.ASCII.GetBytes(verStr); return(int.Parse(verStr)); }
/// <summary> /// Try to generate the database. /// </summary> public void ThreadGenerateData() { Log("Opening Pk2 file using " + (tbxBlowfishKey.Text != "" ? "blowfish key: " + tbxBlowfishKey.Text : "default blowfish key")); LogState("Opening Pk2 file..."); try { pk2 = new Pk2Reader(MediaPk2Path, tbxBlowfishKey.Text); } catch { Log("Error opening Pk2 file. Possibly wrong blowfish key"); LogState("Error"); btnStart.InvokeIfRequired(() => { btnStart.Enabled = true; }); return; } Log("Pk2 file opened!"); LogState(); // Fill info to Main GUI Window w = Window.Get; try { Log("Extracting Silkroad Version"); LogState("Extracting..."); // Reading Packet p = new Packet(0, false, false, pk2.GetFileBytes("SV.T")); p.Lock(); int dataLength = p.ReadInt(); byte[] dataBuffer = p.ReadByteArray(dataLength); // Decoding Blowfish bf = new Blowfish(); bf.Initialize(Encoding.ASCII.GetBytes("SILKROADVERSION"), 0, dataLength); byte[] dataDecoded = bf.Decode(dataBuffer); this.Version = uint.Parse(Encoding.ASCII.GetString(dataDecoded, 0, 4)); } catch (Exception ex) { Log("Extracting error, the version cannot be readed. " + ex.Message); LogState("Error"); btnStart.InvokeIfRequired(() => { btnStart.Enabled = true; }); return; } try { Log("Extracting Locale & Gateway"); LogState("Extracting..."); // Reading Packet p = new Packet(0, false, false, pk2.GetFileBytes("DIVISIONINFO.TXT")); p.Lock(); this.Locale = p.ReadByte(); byte divisionCount = p.ReadByte(); for (int i = 0; i < divisionCount; i++) { string DivisionName = p.ReadString(p.ReadInt()); p.ReadByte(); // 0 byte gatewayCount = p.ReadByte(); Gateways = new System.Collections.Generic.List <string>(gatewayCount); for (int j = 0; j < gatewayCount; j++) { string gatewayHost = p.ReadString(p.ReadInt()); p.ReadByte(); // 0 Gateways.Add(gatewayHost); } } } catch (Exception ex) { Log("Extracting error, gateways cannot be readed. " + ex.Message); LogState("Error"); btnStart.InvokeIfRequired(() => { btnStart.Enabled = true; }); return; } try { Log("Extracting Gateport"); LogState("Extracting..."); // Reading Packet p = new Packet(0, false, false, pk2.GetFileBytes("GATEPORT.TXT")); p.Lock(); string test = p.ReadString(p.RemainingRead()); this.Gateport = ushort.Parse(test); } catch (Exception ex) { Log("Extracting error, the gateport cannot be readed. " + ex.Message); LogState("Error"); btnStart.InvokeIfRequired(() => { btnStart.Enabled = true; }); return; } // Updating database Log("Creating Database..."); string dbPath = GetDatabasePath(SilkroadName); if (File.Exists(dbPath)) { LogState("Deleting old database"); if (!WinAPI.FileTryDelete(dbPath)) { // Deleting issues Log("The database from \"" + SilkroadName + "\" is being used by another program. Please, close all the bots and try again!"); LogState("Error"); btnStart.InvokeIfRequired(() => { btnStart.Font = new Font(btnStart.Font, FontStyle.Regular); }); return; } } // Creating the database LogState("Creating database"); db = new SQLDatabase(dbPath); if (!db.Create()) { Log("Error creating the database. Please, close all the bots and try again!"); LogState("Error"); btnStart.InvokeIfRequired(() => { btnStart.Font = new Font(btnStart.Font, FontStyle.Regular); }); return; } Log("Database has been created!"); // Create connection LogState("Connecting to database"); if (!db.Connect()) { Log("Database connection error!"); Log("Error"); return; } LogState("Connected"); // Generating database Log("Generating database (this may take a while)"); SetLanguageIndex(); Log("Loading name references..."); LoadNameReferences(); Log("Loading & Adding text references..."); LoadTextReferences(); AddTextReferences(); Log("Adding Items..."); AddItems(); Log("Adding Magic options..."); AddMagicOptions(); Log("Adding Characters & Mobs..."); AddModels(); Log("Adding Masteries & Skills..."); AddMasteries(); AddSkills(); Log("Adding Exp. & Levels..."); AddLevelExperience(); Log("Adding Shops..."); AddShops(); Log("Loading Teleport references"); LoadTeleportData(); Log("Adding Teleports & Structures..."); AddTeleportBuildings(); AddTeleportLinks(); Log("Adding Regions..."); AddRegions(); Log("Database has been generated correctly!"); Log("Creating Item icons..."); AddItemIcons(); Log("Creating Skill icons..."); AddSkillIcons(); if (this.cbxMinimap.Checked) { Log("Creating minimap images to the bot folder..."); AddMinimap(); } Log("All has been generated succesfully, Enjoy! :)"); db.Close(); pk2.Close(); pk2.Dispose(); LogState("Closing Pk2 file..."); Thread.Sleep(1000); WinAPI.InvokeIfRequired(this, () => { this.DialogResult = DialogResult.OK; this.Activate(); this.Close(); }); }