Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2014
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.05 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Data.SqlClient;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10.  
  11. namespace rdbStructure
  12. {
  13. /// <summary>
  14. /// To use a structure.dll with rEDIT follow these very simple rules:
  15. /// All structure fields must be defined as the proper type (e.g. Int32, Double, Single)
  16. /// All structure fields must be in the correct order (as they are written in the .rdb)
  17. /// The db_string rdb dynamically sets Length Handles, but other rdbs have set lengths, for those set primaryLengthOverride below
  18. /// </summary>
  19.  
  20. public class structure
  21. {
  22. /// <summary>
  23. /// The structure defines the column list of the rdb
  24. /// </summary>
  25. /// specialField = field to read but not store for viewing in the datatable
  26. /// specialField: Length = field used to read a string (db_string) || make sure length fields contain the word "Length"
  27. /// specialField: Blank = field used to advance the reader by a given number of bytes (e.g. blank_LENGTHINBYTES)
  28. /// WARNING!!!! the fields must be arranged as the rdb or the read will fail!
  29. //////////////////////////////////////////
  30. //////////////////////////////////////////
  31. ///////////// Structure /////////////////
  32. //////////////////////////////////////////
  33. public Int32 job_id { get; set; }
  34. public Int32 skill_id { get; set; }
  35. public Int32 min_skill_lv { get; set; }
  36. public Int32 max_skill_lv { get; set; }
  37. public Int32 lv { get; set; }
  38. public Int32 job_lv { get; set; }
  39. public Single jp_ratio { get; set; }
  40. public Int32 need_skill_id_1 { get; set; }
  41. public Int32 need_skill_id_2 { get; set; }
  42. public Int32 need_skill_id_3 { get; set; }
  43. public Int32 need_skill_lv_1 { get; set; }
  44. public Int32 need_skill_lv_2 { get; set; }
  45. public Int32 need_skill_lv_3 { get; set; }
  46. //////////////////////////////////////////
  47. //////////////////////////////////////////
  48.  
  49. ///////////////////////////////////////////////////
  50. /// <summary>
  51. /// primaryLengthOverride is used for db_tenacity,
  52. /// db_item and other rdb with static length strings
  53. /// WARNING!!!
  54. /// This value must be 0 if loading db_string!
  55. /// </summary>
  56. ///////////////////////////////////////////////////
  57. static int primaryLengthOverride = 0;
  58. static int secondaryLengthOverride = 0;
  59. ///////////////////////////////////////////////////
  60.  
  61. ///////////////////////////////////////////
  62. /// <summary>
  63. /// In order to use "fromDB you will need to provide
  64. /// some information
  65. /// </summary>
  66. /// <param name="tableName">table to be selected @ database (MANDATORY)</param> Example: db_item.rdb <> dbo.ItemResource
  67. /// <param name="sortOn">the column the results will be sorted by (OPTIONAL)</param>
  68. /// <param name="sortDirection">ASC = Ascending, DESC = Descending</param>
  69. public static string tableName = "dbo.SkillTreeResource";
  70. public static string sortOn = null;
  71. public static string sortDirection = null;
  72. //////////////////////////////////////////
  73.  
  74. //Columns to not add to the DataTable
  75. //Seperate words by , e.g. "your,face"
  76. ///////////////////////////////////////
  77. public static string specialFields = "";
  78. ///////////////////////////////////////
  79. ///////////////////////////////////////
  80.  
  81. /////////////////////////////////////////////////////////////
  82. //Setting this to true will cause the reader to
  83. //read the first field of a loop as jobTreeCount
  84. //then read normal structure until currentTree = jobTreeCount
  85. /////////////////////////////////////////////////////////////
  86. public static bool isSkillTree = true;
  87.  
  88. #region Structure Handles [DO NOT EDIT]
  89.  
  90. #region Length Handles
  91.  
  92. /// <summary>Lengths for relevant strings</summary>
  93. /// <param name="length1" >Used in reading strings</param>
  94. /// <param name="length2">Only used by db_string</param>
  95. static int primaryLength = 0;
  96. static int secondaryLength = 0;
  97.  
  98. static int lengthCount = 0;
  99. static int stringCount = 0;
  100.  
  101. #endregion
  102.  
  103. #region Binary Reader/Write
  104. static BinaryReader reader = null;
  105. static BinaryWriter writer = null;
  106. #endregion
  107.  
  108. #region File Header Info
  109.  
  110. /// <summary>
  111. /// The fields below store data read from the header
  112. /// </summary>
  113. static string fileDate = null;
  114. static int fileRows = 0;
  115.  
  116. #endregion
  117.  
  118. #region DLL Handles
  119. static Type type = typeof(structure);
  120. static PropertyInfo[] properties = typeof(structure).GetProperties();
  121. #endregion
  122.  
  123. #endregion
  124.  
  125. #region rdb Processing (load/save) [DO NOT EDIT]
  126. /// <summary>
  127. /// Filters out specialFields (fields that are to be read, but not viewed)
  128. /// </summary>
  129. /// <param name="columnName">Column to be checked for (isSpecial)</param>
  130. /// <returns>True if a special field is detected / False elsewise</returns>
  131. /// WARNING!!!
  132. /// Do not edit below unless you are absolutely sure you know what you're doing!
  133. ////////////////////////////////////////////////////////////////////////////////
  134. public static bool isSpecial(string columnName)
  135. {
  136. string[] fieldCollection = specialFields.Split(',');
  137.  
  138. bool blockDetected = false;
  139.  
  140. for (int currentColumn = 0; currentColumn < fieldCollection.Length; currentColumn++)
  141. {
  142. if (!blockDetected)
  143. blockDetected = fieldCollection.Contains(columnName);
  144. }
  145.  
  146. return blockDetected;
  147. }
  148.  
  149. /// <summary>
  150. /// Checks for blankSpace fields (e.g. blank_16 will move the reader forward 16 bytes
  151. /// </summary>
  152. /// <param name="columnName">Column to be checked for blankSpace</param>
  153. /// <returns>True if column is a blank / False if columns is not a blank</returns>
  154. /// WARNING!!!
  155. /// Do not edit below unless you are absolutely sure you know what you're doing!
  156. ////////////////////////////////////////////////////////////////////////////////
  157. public static bool isBlank(string columnName)
  158. {
  159. if (columnName.ToLower().Contains("blank"))
  160. {
  161. return true;
  162. }
  163. else
  164. {
  165. return false;
  166. }
  167. }
  168.  
  169. /// <summary>
  170. /// Parses the above structure into DataTable columns, that are then added to the outbound DataTable before
  171. /// data is read.
  172. /// INFO:
  173. /// To disallow special fields such as string lengths that need to be read but not viewed add them to specialFields
  174. /// with a , delimiter e.g. "your,face"
  175. /// </summary>
  176. /// <returns>A DataTable populated with columns</returns>
  177. /// WARNING!!!
  178. /// Do not edit below unless you are absolutely sure you know what you're doing!
  179. ////////////////////////////////////////////////////////////////////////////////
  180. public static DataTable prepareTable()
  181. {
  182. //Create an outbound DataTable to hold the rdb contents
  183. DataTable outTable = new DataTable();
  184.  
  185. //create the columns for each property setting the name & type (generic)
  186. foreach (PropertyInfo property in properties)
  187. {
  188. bool special = isSpecial(property.Name);
  189.  
  190. if (!special)
  191. {
  192. outTable.Columns.Add(property.Name, property.PropertyType);
  193. }
  194. }
  195.  
  196. return outTable;
  197. }
  198.  
  199. /// <summary>
  200. /// readFile reads a .rdb file into a DataTable
  201. /// </summary>
  202. /// <param name="rdbPath">Path of the rdb to read</param>
  203. /// <returns>Either populated datatable or null (error)</returns>
  204. /// WARNING!!!
  205. /// Do not edit below unless you are absolutely sure you know what you're doing!
  206. ////////////////////////////////////////////////////////////////////////////////
  207. public static DataTable readFile(string rdbPath)
  208. {
  209. //Create an outbound DataTable to store rdb data
  210. DataTable outTable = prepareTable();
  211.  
  212. //Instantiate the BinaryReader
  213. reader = new BinaryReader(File.Open(rdbPath, FileMode.Open, FileAccess.Read));
  214.  
  215. //If the reader is valid
  216. if (reader != null)
  217. {
  218. #region Read the RDB Header
  219. fileDate = Encoding.Default.GetString(reader.ReadBytes(8));
  220. reader.ReadBytes(120);
  221. fileRows = reader.ReadInt32();
  222. #endregion
  223.  
  224. #region Read the RDB Contents
  225. DataRow newRow = null;
  226.  
  227. /// <summary>
  228. /// Special rules below
  229. /// </summary>
  230. ////////////////////////////////////////////////////////////////////////////
  231. ////////////////////////////////////////////////////////////////////////////
  232.  
  233. //Foreach each row in the rdb
  234. for (int curRow = 0; curRow < fileRows; curRow++) //Standard Loop
  235. {
  236. //If this is a skilltree rdb (a secondary loop must be used)
  237. if (isSkillTree)
  238. {
  239. //Read this rows jobTreeCount
  240. int jobTreeCount = reader.ReadInt32();
  241.  
  242. //Foreach sub-row in the row
  243. for (int currentTree = 0; currentTree < jobTreeCount; currentTree++)
  244. {
  245. //Copy the columns from the outbound Table
  246. newRow = outTable.NewRow();
  247. //Populate the new row with Data from the RDB
  248. newRow = populateRow(newRow);
  249.  
  250. //If the newRow is actually populated with data
  251. if (newRow != null)
  252. //Add the row to the outbound DataTable
  253. outTable.Rows.Add(newRow);
  254. }
  255. }
  256. else //This is not a skilltree rdb (no secondary loop needed)
  257. {
  258. //Copy the columns from the outbound Table
  259. newRow = outTable.NewRow();
  260. //Populate the new row with Data from the RDB
  261. newRow = populateRow(newRow);
  262.  
  263. //If the newRow is actually populated with data
  264. if (newRow != null)
  265. //Add the row to the outbound DataTable
  266. outTable.Rows.Add(newRow);
  267. }
  268. }
  269. ////////////////////////////////////////////////////////////////////////////
  270. ////////////////////////////////////////////////////////////////////////////
  271.  
  272. #endregion
  273.  
  274. //Dispose the used reader
  275. reader.Dispose();
  276.  
  277. //Return the prepared and populated DataTable
  278. return outTable;
  279. }
  280. else
  281. {
  282. return null;
  283. }
  284. }
  285.  
  286. /// <summary>
  287. /// Populates a DataRow with relevant information
  288. /// </summary>
  289. /// <param name="newRow">DataRow formatted with columns</param>
  290. /// <returns>Formated DataRow populated with rdb data</returns>
  291. /// WARNING!!!
  292. /// Do not edit below unless you are absolutely sure you know what you're doing!
  293. ////////////////////////////////////////////////////////////////////////////////
  294. public static DataRow populateRow(DataRow newRow)
  295. {
  296. //Reset the length and string counts
  297. lengthCount = 0;
  298. stringCount = 0;
  299.  
  300. /// <summary>Foreach Property in this structure
  301. /// read rdb based on Property.PropertyType</summary>
  302. /////////////////////////////////////////////////////
  303. /////////////////////////////////////////////////////
  304. foreach (PropertyInfo property in properties)
  305. {
  306. //If property isSpecial Length field
  307. if (property.Name.ToLower().Contains("length"))
  308. {
  309. //If the property is Int32 (almost all length fields are Int32)
  310. if (property.PropertyType == typeof(Int32))
  311. {
  312. //If this is the first Length being read
  313. if (lengthCount == 0)
  314. {
  315. primaryLength = reader.ReadInt32();
  316. }
  317. //If this is the second Length being read
  318. if (lengthCount == 1)
  319. {
  320. secondaryLength = reader.ReadInt32();
  321. }
  322. }
  323.  
  324. //Increase amount of times Length has been counted
  325. lengthCount++;
  326. }
  327. else //This is not a length field
  328. {
  329. //Check if field has been marked isSpecial
  330. bool special = isSpecial(property.Name);
  331.  
  332. //Check if field is marked as a Blank
  333. bool blank = isBlank(property.Name);
  334.  
  335. //If field is blank space
  336. if (blank)
  337. {
  338. //split the blank and retrieve the bytes to advance
  339. string[] bytesToMove = property.Name.Split('_');
  340. //Advance the reader by bytesToMove
  341. reader.ReadBytes(Convert.ToInt32(bytesToMove[1]));
  342. }
  343. else
  344. {
  345. if (special)
  346. {
  347. if (property.PropertyType == typeof(Int16))
  348. {
  349. reader.ReadInt16();
  350. }
  351. if (property.PropertyType == typeof(Int32))
  352. {
  353. reader.ReadInt32();
  354. }
  355. }
  356. else
  357. {
  358. if (property.PropertyType == typeof(byte))
  359. {
  360. newRow[property.Name] = reader.ReadByte();
  361. }
  362. if (property.PropertyType == typeof(Int16))
  363. {
  364. newRow[property.Name] = reader.ReadInt16();
  365. }
  366. if (property.PropertyType == typeof(Int32))
  367. {
  368. newRow[property.Name] = reader.ReadInt32();
  369. }
  370. if (property.PropertyType == typeof(Int64))
  371. {
  372. newRow[property.Name] = reader.ReadInt64();
  373. }
  374. if (property.PropertyType == typeof(Single))
  375. {
  376. newRow[property.Name] = reader.ReadSingle();
  377. }
  378. if (property.PropertyType == typeof(Double))
  379. {
  380. newRow[property.Name] = reader.ReadDouble();
  381. }
  382. if (property.PropertyType == typeof(string))
  383. {
  384. //If string sized is static
  385. if (primaryLengthOverride != 0)
  386. {
  387. newRow[property.Name] = byteConverter.BytesToString(reader.ReadBytes(primaryLengthOverride));
  388. }
  389. else
  390. {
  391. if (stringCount == 0)
  392. {
  393. newRow[property.Name] = byteConverter.BytesToString(reader.ReadBytes(primaryLength));
  394. }
  395. if (stringCount == 1)
  396. {
  397. newRow[property.Name] = byteConverter.BytesToString(reader.ReadBytes(secondaryLength));
  398. }
  399.  
  400. stringCount++;
  401. }
  402. }
  403. }
  404. }
  405. }
  406. }
  407. /////////////////////////////////////////////////////
  408. /////////////////////////////////////////////////////
  409.  
  410. return newRow;
  411. }
  412.  
  413. /// <summary>
  414. /// Creates a .rdb file from a designated DataTable
  415. /// </summary>
  416. /// <param name="rdbPath">Path of file to be created</param>
  417. /// <param name="inTable">DataTable to save the contents of</param>
  418. /// WARNING!!!
  419. /// Do not edit below unless you are absolutely sure you know what you're doing!
  420. ////////////////////////////////////////////////////////////////////////////////
  421. public static void saveFile(string rdbPath, DataTable inTable)
  422. {
  423. //Fetch table to save
  424. DataTable saveTable = inTable;
  425.  
  426. //Create a BinaryWriter to read the file
  427. writer = new BinaryWriter(File.Create(rdbPath));
  428.  
  429. //Define some length parameters
  430. //To be used for strings
  431. lengthCount = 0;
  432. primaryLength = 0;
  433. secondaryLength = 0;
  434.  
  435. //If the table provided is valid
  436. if (saveTable != null)
  437. {
  438. //Fetch the amount of rows held within the table
  439. int rowCount = saveTable.Rows.Count;
  440.  
  441. //Using our previously defined BinaryWriter
  442. using (writer)
  443. {
  444. //Write header
  445. writer.Write(byteConverter.GetFileHeader());
  446.  
  447. //If this isn't a skilltree
  448. if (!isSkillTree)
  449. {
  450. //Write Row count
  451. writer.Write(rowCount);
  452.  
  453. //Foreach row in the table
  454. foreach (DataRow row in saveTable.Rows)
  455. {
  456. //Write the row to file
  457. writeRow(row);
  458. }
  459. }
  460. else
  461. {
  462. int jobId = 0; //num3
  463. int previousJobId = 0; //num1
  464. int jobCount = 0; //num2
  465.  
  466. List<int> wasRead = new List<int>();
  467.  
  468. //Collect the jobSet count
  469. for (int i = 0; i < saveTable.Rows.Count; i++)
  470. {
  471. //Fetch current job_id
  472. jobId = (int)saveTable.Rows[i].Field<Int32>("job_id");
  473.  
  474. //If jobId isn't equal to previousJobId
  475. if (previousJobId != jobId)
  476. {
  477. //Set previousJobId
  478. previousJobId = jobId;
  479. jobCount++; //jobTreeCount
  480. }
  481. }
  482.  
  483. //Write the jobSet count
  484. writer.Write(jobCount);
  485.  
  486. //Foreach row in saveTable
  487. for (int i = 0; i < saveTable.Rows.Count; i++)
  488. {
  489. //Get job_id for current row
  490. jobId = (int)saveTable.Rows[i].Field<Int32>("job_id");
  491.  
  492. //Check if jobSet has already been read
  493. bool alreadyRead = wasRead.Contains(jobId);
  494.  
  495. //If the current jobSet has not been read
  496. if (!alreadyRead)
  497. {
  498. //Collect the jobSet for this jobId
  499. DataRow[] jobTreeCollection = saveTable.Select(string.Format("job_id = {0}", jobId));
  500.  
  501. //Count amount of jobTrees in the jobSet
  502. int jobTreeCount = jobTreeCollection.Count();
  503.  
  504. //Write the jobTreeCount for this jobSet
  505. writer.Write(jobTreeCount);
  506.  
  507. //Foreach jobTree inside the jobSet
  508. for (int currentJobTree = 0; currentJobTree < jobTreeCount; currentJobTree++)
  509. {
  510. //Write the row
  511. writeRow(jobTreeCollection[currentJobTree]);
  512. }
  513.  
  514. //Mark the jobSet as read
  515. wasRead.Add(jobId);
  516. }
  517. }
  518. }
  519. }
  520. }
  521. }
  522.  
  523. /// <summary>
  524. /// Writes a prepared DataRow to the .rdb
  525. /// </summary>
  526. /// <param name="currentRow">DataRow to be written</param>
  527. /// WARNING!!!
  528. /// Do not edit below unless you are absolutely sure you know what you're doing!
  529. ////////////////////////////////////////////////////////////////////////////////
  530. public static void writeRow(DataRow currentRow)
  531. {
  532. lengthCount = 0;
  533.  
  534. //For each property in the structure
  535. foreach (PropertyInfo property in properties)
  536. {
  537. if (property.Name.ToLower().Contains("length"))
  538. {
  539. if (lengthCount == 0)
  540. {
  541. primaryLength = currentRow.Field<string>("name").Length + 1;
  542. writer.Write(primaryLength);
  543. }
  544. if (lengthCount == 1)
  545. {
  546. secondaryLength = currentRow.Field<string>("value").Length + 1;
  547. writer.Write(secondaryLength);
  548. }
  549.  
  550. lengthCount++;
  551. }
  552. else
  553. {
  554. bool special = isSpecial(property.Name);
  555.  
  556. bool blank = isBlank(property.Name);
  557.  
  558. if (blank)
  559. {
  560. //split the blank and retrieve the bytes to advance
  561. string[] bytesToMove = property.Name.Split('_');
  562. //Advance the reader by bytesToMove
  563. writer.Write(new Byte[Convert.ToInt32(bytesToMove[1])]);
  564. }
  565. else
  566. {
  567. if (special)
  568. {
  569. if (property.PropertyType == typeof(Int16))
  570. {
  571. Int16 columnValue = currentRow.Field<Int16>(property.Name);
  572. writer.Write(columnValue);
  573. }
  574. if (property.PropertyType == typeof(Int32))
  575. {
  576. Int32 columnValue = currentRow.Field<Int32>(property.Name);
  577. writer.Write(columnValue);
  578. }
  579. }
  580. else
  581. {
  582. if (property.PropertyType == typeof(byte))
  583. {
  584. byte columnValue = currentRow.Field<byte>(property.Name);
  585. writer.Write(columnValue);
  586. }
  587. if (property.PropertyType == typeof(Int16))
  588. {
  589. Int16 columnValue = currentRow.Field<Int16>(property.Name);
  590. writer.Write(columnValue);
  591. }
  592. if (property.PropertyType == typeof(Int32))
  593. {
  594. Int32 columnValue = currentRow.Field<Int32>(property.Name);
  595. writer.Write(columnValue);
  596. }
  597. if (property.PropertyType == typeof(Int64))
  598. {
  599. Int64 columnValue = currentRow.Field<Int64>(property.Name);
  600. writer.Write(columnValue);
  601. }
  602. if (property.PropertyType == typeof(Single))
  603. {
  604. Single columnValue = currentRow.Field<Single>(property.Name);
  605. writer.Write(columnValue);
  606. }
  607. if (property.PropertyType == typeof(Double))
  608. {
  609. Double columnValue = currentRow.Field<Double>(property.Name);
  610. writer.Write(columnValue);
  611. }
  612. if (property.PropertyType == typeof(string))
  613. {
  614. string columnValue = currentRow.Field<string>(property.Name);
  615. writer.Write(byteConverter.StringToBytes(columnValue));
  616.  
  617. if (primaryLengthOverride != 0)
  618. {
  619. writer.Write(new Byte[primaryLengthOverride - columnValue.Length]);
  620. }
  621. else
  622. {
  623. writer.Write(new Byte[1]);
  624. }
  625. }
  626. }
  627. }
  628. }
  629. }
  630. }
  631. #endregion
  632.  
  633. #region db Processing (load) [DO NOT EDIT]
  634.  
  635. /// <summary>
  636. /// Reads a relevant database table into a DataTable
  637. /// </summary>
  638. /// <param name="connectionString">Sql Connection string used to connect to the Database</param>
  639. /// <returns>A populated datatable</returns>
  640. /// WARNING!!!
  641. /// Do not edit below unless you are absolutely sure you know what you're doing!
  642. public static DataTable readDB(string connectionString)
  643. {
  644. DataTable outTable = new DataTable();
  645.  
  646. string connString = connectionString;
  647. string query = generateSelect();
  648.  
  649. SqlConnection conn = new SqlConnection(connString);
  650. SqlCommand cmd = new SqlCommand(query, conn);
  651. conn.Open();
  652.  
  653. // create data adapter
  654. SqlDataAdapter da = new SqlDataAdapter(cmd);
  655. // this will query your database and return the result to your datatable
  656. da.Fill(outTable);
  657. conn.Close();
  658. da.Dispose();
  659.  
  660. return outTable;
  661. }
  662.  
  663. /// <summary>
  664. /// Generates a select statement based on this structures properties
  665. /// for use by readDB above
  666. /// </summary>
  667. /// <returns>A populated select statement</returns>
  668. /// WARNING!!!
  669. /// Do not edit below unless you are absolutely sure you know what you're doing!
  670. public static String generateSelect()
  671. {
  672. String selectStatement = "SELECT ";
  673.  
  674. int propertyCount = 0;
  675.  
  676. bool isLastProperty = false;
  677.  
  678. int currentProperty = 0;
  679.  
  680. foreach (PropertyInfo property in properties)
  681. {
  682. bool special = isSpecial(property.Name);
  683.  
  684. if (!special)
  685. {
  686. propertyCount++;
  687. }
  688. }
  689.  
  690. foreach (PropertyInfo property in properties)
  691. {
  692. string columnName = null;
  693. bool special = isSpecial(property.Name);
  694.  
  695. if (!special)
  696. {
  697. currentProperty++;
  698.  
  699. isLastProperty = currentProperty == propertyCount;
  700.  
  701. if (!isLastProperty)
  702. {
  703. columnName = string.Concat(property.Name, ",");
  704. }
  705. else
  706. {
  707. columnName = property.Name;
  708. }
  709.  
  710. selectStatement += string.Format("{0} ", columnName);
  711. }
  712.  
  713. }
  714.  
  715. string returnString = null;
  716.  
  717. if (sortOn != null)
  718. {
  719. returnString = string.Format("{0} FROM {1} ORDER BY {2} {3}", selectStatement, tableName, sortOn, sortDirection);
  720. }
  721. else
  722. {
  723. returnString = string.Format("{0} FROM {1}", selectStatement, tableName);
  724. }
  725.  
  726. return returnString;
  727. }
  728.  
  729. #endregion
  730. }
  731. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement