Advertisement
userWeapon

GTA 5 CSC / XSC TOOL CONTAINER SOURCE CODE LEAKED

Jul 2nd, 2014
1,977
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 54.57 KB | None | 0 0
  1. Form1.cs:
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. using System.IO;
  12.  
  13. using System.Net;
  14.  
  15. using GTAV;
  16.  
  17. namespace CSC_Editor
  18. {
  19. public partial class Form1 : Form
  20. {
  21. public Form1()
  22. {
  23. InitializeComponent();
  24.  
  25. Task task = GetNativesInit();
  26. }
  27.  
  28. //native info..
  29. native[] natives;
  30. bool nativesLoaded = false;
  31.  
  32. public struct native
  33. {
  34. public uint hash;
  35. public string name;
  36. }
  37.  
  38.  
  39.  
  40. private void exitToolStripMenuItem_Click(object sender, EventArgs e)
  41. {
  42. Application.Exit();
  43. }
  44.  
  45. private void openCSCToolStripMenuItem_Click(object sender, EventArgs e)
  46. {
  47. OpenFileDialog op = new OpenFileDialog();
  48. op.Title = "Select a GTA V CSC File.";
  49. if (op.ShowDialog() == DialogResult.OK)
  50. {
  51. if (!nativesLoaded) //we need natives before we can open csc.
  52. return;
  53.  
  54. CSC ScriptFile = new CSC(op.FileName);
  55. ScriptFile.Read(); //read the file..
  56.  
  57. opcodeBox.Text = "";
  58. nativesList.Items.Clear();
  59. scriptStringsList.Items.Clear();
  60. this.Text = "CSCEditor - " + ScriptFile.scriptName;
  61.  
  62. for (int i = 0; i < ScriptFile.Natives.Length; i++)
  63. {
  64. nativesList.Items.Add(getNativeName(ScriptFile.Natives[i],natives));
  65. }
  66.  
  67. foreach(string scriptString in ScriptFile.scriptStrings)
  68. {
  69. scriptStringsList.Items.Add(scriptString);
  70. }
  71.  
  72. for (int i = 0; i < 500; i++)
  73. {
  74. string code = "\t" + ScriptFile.codePageData[i].ToString("X");
  75. switch (ScriptFile.codePageData[i])
  76. {
  77. case 0:
  78. code = "\tnop";
  79. break;
  80.  
  81. case 1:
  82. code = "\tiadd";
  83. break;
  84.  
  85. case 2:
  86. code = "\tisub";
  87. break;
  88.  
  89. case 3:
  90. code = "\timul";
  91. break;
  92.  
  93. case 4:
  94. code = "\tidiv";
  95. break;
  96.  
  97. case 5:
  98. code = "\timod";
  99. break;
  100.  
  101. case 6:
  102. code = "\tiszero";
  103. break;
  104.  
  105. case 7:
  106. code = "\tineg";
  107. break;
  108.  
  109. case 8:
  110. code = "\ticompeq";
  111. break;
  112.  
  113. case 45:
  114. code = "\tnativeCall";
  115. int argCount = ScriptFile.codePageData[i + 1];
  116. int retCount = ScriptFile.codePageData[i + 2];
  117.  
  118. byte[] hash = new byte[4];
  119. Buffer.BlockCopy(ScriptFile.codePageData, i + 3, hash, 0, 4);
  120. Array.Reverse(hash);
  121. uint n = BitConverter.ToUInt32(hash, 0);
  122. code += ": " + getNativeName(n, natives);
  123.  
  124. break;
  125.  
  126. case 46:
  127. code = "{";
  128. break;
  129.  
  130. case 47:
  131. code = "}";
  132. break;
  133. }
  134. opcodeBox.Text += code + "\n";
  135. }
  136.  
  137. }
  138. op.Dispose();
  139. }
  140.  
  141. #region natives
  142.  
  143. private Task GetNativesInit()
  144. {
  145. return Task.Run(() => GetNatives());
  146. }
  147.  
  148. async Task GetNatives()
  149. {
  150. natives = GetNativeNames().ToArray();
  151. nativesLoaded = true;
  152. nativeStatus.Text = "Natives Loaded";
  153. nativeStatus.Image = null;
  154. }
  155.  
  156. public string getNativeName(uint code, native[] natives)
  157. {
  158. for (int i = 0; i < natives.Length; i++)
  159. {
  160. if (natives[i].hash == code)
  161. return natives[i].name;
  162. }
  163. return code.ToString();
  164. }
  165.  
  166. public List<native> GetNativeNames()
  167. {
  168. List<native> natives = new List<native>();
  169.  
  170. byte[] result = GetFileViaHttp(@"http://gta5hasher.glokon.org/raw/confirmed");
  171. string str = Encoding.UTF8.GetString(result);
  172. str = str.Replace("<pre>", "");
  173. str = str.Replace("</pre>", "");
  174.  
  175. string[] strArr = str.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
  176.  
  177. for (int i = 0; i < strArr.Length; i++)
  178. {
  179. if (strArr[i].StartsWith("//"))
  180. continue;
  181.  
  182. int split_index = strArr[i].IndexOf(':');
  183.  
  184. native native;
  185.  
  186. native.hash = Convert.ToUInt32(strArr[i].Substring(0, split_index));
  187. native.name = strArr[i].Substring(split_index + 1);
  188.  
  189. natives.Add(native);
  190.  
  191. }
  192.  
  193. return natives;
  194. }
  195.  
  196. public byte[] GetFileViaHttp(string url)
  197. {
  198. using (WebClient client = new WebClient())
  199. {
  200. return client.DownloadData(url);
  201. }
  202. }
  203.  
  204. #endregion
  205. }
  206. }
  207.  
  208. Form1.Designer.cs:
  209. namespace CSC_Editor
  210. {
  211. partial class Form1
  212. {
  213. /// <summary>
  214. /// Required designer variable.
  215. /// </summary>
  216. private System.ComponentModel.IContainer components = null;
  217.  
  218. /// <summary>
  219. /// Clean up any resources being used.
  220. /// </summary>
  221. /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
  222. protected override void Dispose(bool disposing)
  223. {
  224. if (disposing && (components != null))
  225. {
  226. components.Dispose();
  227. }
  228. base.Dispose(disposing);
  229. }
  230.  
  231. #region Windows Form Designer generated code
  232.  
  233. /// <summary>
  234. /// Required method for Designer support - do not modify
  235. /// the contents of this method with the code editor.
  236. /// </summary>
  237. private void InitializeComponent()
  238. {
  239. this.menuStrip1 = new System.Windows.Forms.MenuStrip();
  240. this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
  241. this.openCSCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
  242. this.saveCSCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
  243. this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
  244. this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
  245. this.opcodeBox = new System.Windows.Forms.RichTextBox();
  246. this.nativesList = new System.Windows.Forms.ListBox();
  247. this.scriptStringsList = new System.Windows.Forms.ListBox();
  248. this.label1 = new System.Windows.Forms.Label();
  249. this.label2 = new System.Windows.Forms.Label();
  250. this.label3 = new System.Windows.Forms.Label();
  251. this.statusStrip1 = new System.Windows.Forms.StatusStrip();
  252. this.nativeStatus = new System.Windows.Forms.ToolStripStatusLabel();
  253. this.menuStrip1.SuspendLayout();
  254. this.statusStrip1.SuspendLayout();
  255. this.SuspendLayout();
  256. //
  257. // menuStrip1
  258. //
  259. this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
  260. this.fileToolStripMenuItem});
  261. this.menuStrip1.Location = new System.Drawing.Point(0, 0);
  262. this.menuStrip1.Name = "menuStrip1";
  263. this.menuStrip1.Size = new System.Drawing.Size(925, 24);
  264. this.menuStrip1.TabIndex = 0;
  265. this.menuStrip1.Text = "menuStrip1";
  266. //
  267. // fileToolStripMenuItem
  268. //
  269. this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
  270. this.openCSCToolStripMenuItem,
  271. this.saveCSCToolStripMenuItem,
  272. this.toolStripSeparator1,
  273. this.exitToolStripMenuItem});
  274. this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
  275. this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
  276. this.fileToolStripMenuItem.Text = "File";
  277. //
  278. // openCSCToolStripMenuItem
  279. //
  280. this.openCSCToolStripMenuItem.Name = "openCSCToolStripMenuItem";
  281. this.openCSCToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
  282. this.openCSCToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
  283. this.openCSCToolStripMenuItem.Text = "Open CSC";
  284. this.openCSCToolStripMenuItem.Click += new System.EventHandler(this.openCSCToolStripMenuItem_Click);
  285. //
  286. // saveCSCToolStripMenuItem
  287. //
  288. this.saveCSCToolStripMenuItem.Name = "saveCSCToolStripMenuItem";
  289. this.saveCSCToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
  290. this.saveCSCToolStripMenuItem.Text = "Save CSC";
  291. //
  292. // toolStripSeparator1
  293. //
  294. this.toolStripSeparator1.Name = "toolStripSeparator1";
  295. this.toolStripSeparator1.Size = new System.Drawing.Size(168, 6);
  296. //
  297. // exitToolStripMenuItem
  298. //
  299. this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
  300. this.exitToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
  301. this.exitToolStripMenuItem.Text = "Exit";
  302. this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
  303. //
  304. // opcodeBox
  305. //
  306. this.opcodeBox.Location = new System.Drawing.Point(12, 53);
  307. this.opcodeBox.Name = "opcodeBox";
  308. this.opcodeBox.Size = new System.Drawing.Size(557, 304);
  309. this.opcodeBox.TabIndex = 1;
  310. this.opcodeBox.Text = "";
  311. //
  312. // nativesList
  313. //
  314. this.nativesList.FormattingEnabled = true;
  315. this.nativesList.Location = new System.Drawing.Point(575, 53);
  316. this.nativesList.Name = "nativesList";
  317. this.nativesList.Size = new System.Drawing.Size(169, 303);
  318. this.nativesList.TabIndex = 2;
  319. //
  320. // scriptStringsList
  321. //
  322. this.scriptStringsList.FormattingEnabled = true;
  323. this.scriptStringsList.Location = new System.Drawing.Point(750, 53);
  324. this.scriptStringsList.Name = "scriptStringsList";
  325. this.scriptStringsList.Size = new System.Drawing.Size(169, 303);
  326. this.scriptStringsList.TabIndex = 3;
  327. //
  328. // label1
  329. //
  330. this.label1.AutoSize = true;
  331. this.label1.Location = new System.Drawing.Point(12, 37);
  332. this.label1.Name = "label1";
  333. this.label1.Size = new System.Drawing.Size(55, 13);
  334. this.label1.TabIndex = 4;
  335. this.label1.Text = "OP Codes";
  336. //
  337. // label2
  338. //
  339. this.label2.AutoSize = true;
  340. this.label2.Location = new System.Drawing.Point(572, 37);
  341. this.label2.Name = "label2";
  342. this.label2.Size = new System.Drawing.Size(43, 13);
  343. this.label2.TabIndex = 5;
  344. this.label2.Text = "Natives";
  345. //
  346. // label3
  347. //
  348. this.label3.AutoSize = true;
  349. this.label3.Location = new System.Drawing.Point(750, 37);
  350. this.label3.Name = "label3";
  351. this.label3.Size = new System.Drawing.Size(69, 13);
  352. this.label3.TabIndex = 6;
  353. this.label3.Text = "Script Strings";
  354. //
  355. // statusStrip1
  356. //
  357. this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
  358. this.nativeStatus});
  359. this.statusStrip1.Location = new System.Drawing.Point(0, 363);
  360. this.statusStrip1.Name = "statusStrip1";
  361. this.statusStrip1.Size = new System.Drawing.Size(925, 22);
  362. this.statusStrip1.TabIndex = 7;
  363. this.statusStrip1.Text = "statusStrip1";
  364. //
  365. // nativeStatus
  366. //
  367. this.nativeStatus.Image = global::CSC_Editor.Properties.Resources.loader;
  368. this.nativeStatus.Margin = new System.Windows.Forms.Padding(3, 3, 0, 2);
  369. this.nativeStatus.Name = "nativeStatus";
  370. this.nativeStatus.Size = new System.Drawing.Size(165, 17);
  371. this.nativeStatus.Text = "Please wait, getting natives";
  372. //
  373. // Form1
  374. //
  375. this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  376. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  377. this.ClientSize = new System.Drawing.Size(925, 385);
  378. this.Controls.Add(this.statusStrip1);
  379. this.Controls.Add(this.label3);
  380. this.Controls.Add(this.label2);
  381. this.Controls.Add(this.label1);
  382. this.Controls.Add(this.scriptStringsList);
  383. this.Controls.Add(this.nativesList);
  384. this.Controls.Add(this.opcodeBox);
  385. this.Controls.Add(this.menuStrip1);
  386. this.MainMenuStrip = this.menuStrip1;
  387. this.Name = "Form1";
  388. this.Text = "CSCEditor";
  389. this.menuStrip1.ResumeLayout(false);
  390. this.menuStrip1.PerformLayout();
  391. this.statusStrip1.ResumeLayout(false);
  392. this.statusStrip1.PerformLayout();
  393. this.ResumeLayout(false);
  394. this.PerformLayout();
  395.  
  396. }
  397.  
  398. #endregion
  399.  
  400. private System.Windows.Forms.MenuStrip menuStrip1;
  401. private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
  402. private System.Windows.Forms.ToolStripMenuItem openCSCToolStripMenuItem;
  403. private System.Windows.Forms.ToolStripMenuItem saveCSCToolStripMenuItem;
  404. private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
  405. private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
  406. private System.Windows.Forms.RichTextBox opcodeBox;
  407. private System.Windows.Forms.ListBox nativesList;
  408. private System.Windows.Forms.ListBox scriptStringsList;
  409. private System.Windows.Forms.Label label1;
  410. private System.Windows.Forms.Label label2;
  411. private System.Windows.Forms.Label label3;
  412. private System.Windows.Forms.StatusStrip statusStrip1;
  413. private System.Windows.Forms.ToolStripStatusLabel nativeStatus;
  414. }
  415. }
  416.  
  417. EndianIO.cs:
  418. using System;
  419. using System.Drawing;
  420. using System.Text;
  421.  
  422. namespace System.IO
  423. {
  424. #region EndianType
  425.  
  426. /// <summary>
  427. /// The two Endian Types that determine the way data is read and written.
  428. /// </summary>
  429. public enum EndianType
  430. {
  431. /// <summary>
  432. /// Reversed byte order.
  433. /// </summary>
  434. BigEndian,
  435.  
  436. /// <summary>
  437. /// Normal byte order.
  438. /// </summary>
  439. LittleEndian
  440. }
  441.  
  442. #endregion
  443.  
  444. #region EndianIO
  445.  
  446. /// <summary>
  447. /// A powerful multi-endian reading and writing class.
  448. /// </summary>
  449. public class EndianIO : IDisposable
  450. {
  451. internal FileMode FileMode;
  452. internal FileAccess FileAccess;
  453. internal FileShare FileShare;
  454. private EndianType _endianType;
  455.  
  456. /// <summary>
  457. /// Gets or sets the Endian Type.
  458. /// </summary>
  459. ///
  460. public EndianType EndianType
  461. {
  462. get
  463. {
  464. return _endianType;
  465. }
  466. set
  467. {
  468. _endianType = value;
  469. if (In != null)
  470. In.EndianType = value;
  471. if (Out != null)
  472. Out.EndianType = value;
  473. }
  474. }
  475.  
  476. /// <summary>
  477. /// Gets the Endian Reader instance.
  478. /// </summary>
  479. public EndianReader In { get; internal protected set; }
  480.  
  481. /// <summary>
  482. /// Gets the Endian Writer instance.
  483. /// </summary>
  484. public EndianWriter Out { get; internal protected set; }
  485.  
  486. /// <summary>
  487. /// Gets the file name of the currently open file.
  488. /// </summary>
  489. public virtual string FileName { get; internal protected set; }
  490.  
  491. /// <summary>
  492. /// Gets the stream initialized on the file or bytes.
  493. /// </summary>
  494. public virtual Stream Stream { get; internal protected set; }
  495.  
  496. /// <summary>
  497. /// Determines whether there are any open streams.
  498. /// </summary>
  499. public bool Opened { get; internal protected set; }
  500.  
  501. public virtual long Length { get { return this.Stream.Length; } }
  502. /// <summary>
  503. /// Initializes a new instance of the EndianIO class.
  504. /// </summary>
  505. public EndianIO() { }
  506.  
  507. /// <summary>
  508. /// Initializes a new instance of the EndianIO class on the specified file.
  509. /// </summary>
  510. /// <param name="FileName">The location of the file to load.</param>
  511. /// <param name="EndianType">The Endian Type used to read/write.</param>
  512. /// <param name="FileMode">System.IO.FileMode</param>
  513. /// <param name="FileAccess">System.IO.FileAccess</param>
  514. /// <param name="FileShare">System.IO.FileShare</param>
  515. public EndianIO(string FileName, EndianType EndianType, FileMode FileMode, FileAccess FileAccess, FileShare FileShare)
  516. {
  517. this.FileMode = FileMode;
  518. this.FileAccess = FileAccess;
  519. this.FileShare = FileShare;
  520. this.EndianType = EndianType;
  521. this.FileName = FileName;
  522. }
  523. public EndianIO(string FileName, EndianType EndianType)
  524. : this(FileName, EndianType, false)
  525. {
  526. }
  527. public EndianIO(string FileName, EndianType EndianType, bool Open)
  528. {
  529. this.FileMode = FileMode.OpenOrCreate;
  530. this.FileAccess = FileAccess.ReadWrite;
  531. this.FileShare = FileShare.Read;
  532. this.EndianType = EndianType;
  533. this.FileName = FileName;
  534. if (Open)
  535. this.Open();
  536. }
  537. /// <summary>
  538. /// Initializes a new instance of the EndianIO class on the specified stream.
  539. /// </summary>
  540. /// <param name="Stream">The Stream to load.</param>
  541. /// <param name="EndianType">The Endian Type used to read/write.</param>
  542. public EndianIO(Stream Stream, EndianType EndianType)
  543. : this(Stream, EndianType, false)
  544. {
  545. }
  546. public EndianIO(Stream Stream, EndianType EndianType, bool Open)
  547. {
  548. this.EndianType = EndianType;
  549. this.Stream = Stream;
  550.  
  551. if (Open) this.Open();
  552. }
  553. /// <summary>
  554. /// Initializes a new instance of the EndianIO class on the specified byte array.
  555. /// </summary>
  556. /// <param name="ByteArray">The byte array to load.</param>
  557. /// <param name="EndianType">The Endian Type used to read/write.</param>
  558. public EndianIO(byte[] ByteArray, EndianType EndianType)
  559. : this(ByteArray, EndianType, false)
  560. {
  561. }
  562.  
  563. public EndianIO(byte[] ByteArray, EndianType EndianType, bool Open)
  564. {
  565. this.EndianType = EndianType;
  566. Stream = new MemoryStream(ByteArray);
  567. if (Open) this.Open();
  568. }
  569.  
  570. /// <summary>
  571. /// The destructor for the class.
  572. /// </summary>
  573. ~EndianIO()
  574. {
  575. try
  576. {
  577. // If the file doesn't exist anymore (disconnected device perhaps), this will throw an error on shutdown.
  578. this.Close();
  579. }
  580. catch
  581. {
  582.  
  583. }
  584. }
  585.  
  586. /// <summary>
  587. /// Opens the IO and initializes the necessary streams. If the IO is already open, this will re-open it.
  588. /// </summary>
  589. public virtual void Open()
  590. {
  591. if (Opened)
  592. Close();
  593. if (Stream != null)
  594. {
  595. if (Stream.CanRead)
  596. {
  597. this.In = new EndianReader(Stream, EndianType);
  598. }
  599. if (Stream.CanWrite)
  600. {
  601. this.Out = new EndianWriter(Stream, EndianType);
  602. }
  603. Opened = true;
  604. }
  605. if (FileName != null)
  606. {
  607. Stream = new FileStream(FileName, FileMode, FileAccess, FileShare);
  608. if (FileAccess == FileAccess.Read || FileAccess == FileAccess.ReadWrite)
  609. {
  610. this.In = new EndianReader(Stream, EndianType);
  611. }
  612. if (FileAccess == FileAccess.Write || FileAccess == FileAccess.ReadWrite)
  613. {
  614. this.Out = new EndianWriter(Stream, EndianType);
  615. }
  616. Opened = true;
  617. }
  618. }
  619.  
  620. /// <summary>
  621. /// Closes the IO and any open streams.
  622. /// </summary>
  623. public virtual void Close()
  624. {
  625. if (Opened)
  626. {
  627. if (Stream != null) Stream.Dispose();
  628. if (In != null) In.Close();
  629. if (Out != null) Out.Close();
  630. Opened = false;
  631. }
  632. }
  633.  
  634. /// <summary>
  635. /// Sets the positions of the reader and writer using the specified Seek Origin.
  636. /// </summary>
  637. /// <param name="Position">Position to set.</param>
  638. /// <param name="Origin">System.IO.SeekOrigin</param>
  639. public virtual void SeekTo(long Position, SeekOrigin Origin) { Stream.Seek(Position, Origin); }
  640.  
  641. /// <summary>
  642. /// Sets the positions of the reader and writer.
  643. /// </summary>
  644. /// <param name="Position">Position value.</param>
  645. public virtual void SeekTo(object Position) { SeekTo(Convert.ToInt64(Position), SeekOrigin.Begin); }
  646.  
  647. /// <summary>
  648. /// Returns the stream as an array.
  649. /// </summary>
  650. public byte[] ToArray()
  651. {
  652. if (Stream.GetType() == typeof(FileStream))
  653. {
  654. Stream.Position = 0;
  655. byte[] buffer = new byte[Stream.Length];
  656. Stream.Read(buffer, 0, buffer.Length);
  657. return buffer;
  658. }
  659. return ((MemoryStream)Stream).ToArray();
  660. }
  661.  
  662. /// <summary>
  663. /// Gets or sets the current position of the IO.
  664. /// </summary>
  665. public virtual long Position
  666. {
  667. get { return Stream.Position; }
  668. set { Stream.Position = value; }
  669. }
  670.  
  671. /// <summary>
  672. /// Closes the streams and release any resources that may be in use.
  673. /// </summary>
  674. public void Dispose() { Close(); }
  675.  
  676. public override string ToString() { return Path.GetFileName(FileName); }
  677. }
  678.  
  679. #endregion
  680.  
  681. #region EndianReader
  682.  
  683. /// <summary>
  684. /// The Endian Reader class that can read data in Big Endian and Little Endian.
  685. /// </summary>
  686. public class EndianReader : BinaryReader
  687. {
  688. public EndianType EndianType;
  689.  
  690. /// <summary>
  691. /// Initializes a new instance of the EndianReader class on the specified stream in the specified Endian Type.
  692. /// </summary>
  693. /// <param name="Input">The input stream to load for reading.</param>
  694. /// <param name="EndianType">The Endian Type used to read.</param>
  695. public EndianReader(Stream Input, EndianType EndianType) : base(Input) { this.EndianType = EndianType; }
  696. public EndianReader(byte[] Data, EndianType EndianType) : this(new MemoryStream(Data), EndianType) { }
  697. public void SeekTo(object Position)
  698. {
  699. SeekTo(Position, SeekOrigin.Begin);
  700. }
  701. public virtual void SeekTo(object offset, SeekOrigin SeekOrigin)
  702. {
  703. this.BaseStream.Seek(Convert.ToInt64(offset), SeekOrigin);
  704. }
  705.  
  706. public byte[] ReadBytes(object count)
  707. {
  708. byte[] buffer = new byte[Convert.ToInt32(count)];
  709. Read(buffer, 0, buffer.Length);
  710. return buffer;
  711. }
  712.  
  713. public override byte[] ReadBytes(int count)
  714. {
  715. byte[] buffer = new byte[count];
  716. Read(buffer, 0, count);
  717. return buffer;
  718. }
  719.  
  720. public override int Read(byte[] buffer, int index, int count)
  721. {
  722. return this.BaseStream.Read(buffer, index, count);
  723. }
  724.  
  725. /// <summary>
  726. /// Reads the specified number of bytes from the current stream into a byte array and advances the current position by that number of bytes.
  727. /// </summary>
  728. /// <param name="Count">The number of bytes to read.</param>
  729. /// <param name="EndianType">Endian Type to read with.</param>
  730. public byte[] ReadBytes(object Count, EndianType EndianType)
  731. {
  732. var array = base.ReadBytes(Convert.ToInt32(Count));
  733. if (EndianType == EndianType.BigEndian) Array.Reverse(array);
  734. return array;
  735. }
  736.  
  737. /// <summary>
  738. /// Reads a 2-byte signed integer from the current stream and advances the current position of the stream by two bytes.
  739. /// </summary>
  740. public override short ReadInt16() { return ReadInt16(EndianType); }
  741.  
  742. /// <summary>
  743. /// Reads a 2-byte signed integer from the current stream and advances the current position of the stream by two bytes.
  744. /// </summary>
  745. /// <param name="EndianType">Endian Type to read with.</param>
  746. public short ReadInt16(EndianType EndianType) { return BitConverter.ToInt16(ReadBytes(2, EndianType), 0); }
  747.  
  748. /// <summary>
  749. /// Reads a 2-byte unsigned integer from the current stream and advances the position of the stream by two bytes.
  750. /// </summary>
  751. public override ushort ReadUInt16() { return ReadUInt16(EndianType); }
  752.  
  753. /// <summary>
  754. /// Reads a 2-byte unsigned integer from the current stream and advances the position of the stream by two bytes.
  755. /// </summary>
  756. /// <param name="EndianType">Endian Type to read with.</param>
  757. public ushort ReadUInt16(EndianType EndianType) { return BitConverter.ToUInt16(ReadBytes(2, EndianType), 0); }
  758.  
  759. /// <summary>
  760. /// Reads a 3-byte signed integer from the current stream and advances the current position of the stream by three bytes.
  761. /// </summary>
  762. public int ReadInt24() { return ReadInt24(EndianType); }
  763.  
  764. /// <summary>
  765. /// Reads a 3-byte signed integer from the current stream and advances the current position of the stream by three bytes.
  766. /// </summary>
  767. /// <param name="EndianType">Endian Type to read with.</param>
  768. public int ReadInt24(EndianType EndianType)
  769. {
  770. var buffer = base.ReadBytes(3);
  771. if (EndianType == EndianType.BigEndian) return (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
  772. return (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
  773. }
  774.  
  775. /// <summary>
  776. /// Reads a 3-byte unsigned integer from the current stream and advances the position of the stream by two bytes.
  777. /// </summary>
  778. public uint ReadUInt24() { return ReadUInt24(EndianType); }
  779.  
  780. /// <summary>
  781. /// Reads a 3-byte unsigned integer from the current stream and advances the position of the stream by two bytes.
  782. /// </summary>
  783. /// <param name="EndianType">Endian Type to read with.</param>
  784. public uint ReadUInt24(EndianType EndianType) { return (uint)ReadInt24(EndianType); }
  785.  
  786. /// <summary>
  787. /// Reads a 4-byte signed integer from the current stream and advances the current position of the stream by four bytes.
  788. /// </summary>
  789. public override int ReadInt32() { return ReadInt32(EndianType); }
  790.  
  791. /// <summary>
  792. /// Reads a 4-byte signed integer from the current stream and advances the current position of the stream by four bytes.
  793. /// </summary>
  794. /// <param name="EndianType">Endian Type to read with.</param>
  795. public int ReadInt32(EndianType EndianType) { return BitConverter.ToInt32(ReadBytes(4, EndianType), 0); }
  796.  
  797. /// <summary>
  798. /// Reads a 4-byte unsigned integer from the current stream and advances the position of the stream by four bytes.
  799. /// </summary>
  800. public override uint ReadUInt32() { return ReadUInt32(EndianType); }
  801.  
  802. /// <summary>
  803. /// Reads a 4-byte unsigned integer from the current stream and advances the position of the stream by four bytes.
  804. /// </summary>
  805. /// <param name="EndianType">Endian Type to read with.</param>
  806. public uint ReadUInt32(EndianType EndianType) { return BitConverter.ToUInt32(ReadBytes(4, EndianType), 0); }
  807.  
  808. /// <summary>
  809. /// Reads an 8-byte signed integer from the current stream and advances the current position of the stream by eight bytes.
  810. /// </summary>
  811. public override long ReadInt64() { return ReadInt64(EndianType); }
  812.  
  813. /// <summary>
  814. /// Reads an 8-byte signed integer from the current stream and advances the current position of the stream by eight bytes.
  815. /// </summary>
  816. /// <param name="EndianType">Endian Type to read with.</param>
  817. public long ReadInt64(EndianType EndianType) { return BitConverter.ToInt64(ReadBytes(8, EndianType), 0); }
  818.  
  819. /// <summary>
  820. /// Reads an 8-byte unsigned integer from the current stream and advances the position of the stream by eight bytes.
  821. /// </summary>
  822. public override ulong ReadUInt64() { return ReadUInt64(EndianType); }
  823.  
  824. /// <summary>
  825. /// Reads an 8-byte unsigned integer from the current stream and advances the position of the stream by eight bytes.
  826. /// </summary>
  827. /// <param name="EndianType">Endian Type to read with.</param>
  828. public ulong ReadUInt64(EndianType EndianType) { return BitConverter.ToUInt64(ReadBytes(8, EndianType), 0); }
  829.  
  830. /// <summary>
  831. /// Reads an 8-byte floating point value from the current stream and advances the current position of the stream by eight bytes.
  832. /// </summary>
  833. public override double ReadDouble() { return ReadDouble(EndianType); }
  834.  
  835. /// <summary>
  836. /// Reads an 8-byte floating point value from the current stream and advances the current position of the stream by eight bytes.
  837. /// </summary>
  838. /// <param name="EndianType">Endian Type to read with.</param>
  839. public double ReadDouble(EndianType EndianType) { return BitConverter.ToDouble(ReadBytes(8, EndianType), 0); }
  840.  
  841. /// <summary>
  842. /// Reads a 4-byte floating point value from the current stream and advances the current position of the stream by four bytes.
  843. /// </summary>
  844. public override float ReadSingle() { return ReadSingle(EndianType); }
  845.  
  846. /// <summary>
  847. /// Reads a 4-byte floating point value from the current stream and advances the current position of the stream by four bytes.
  848. /// </summary>
  849. /// <param name="EndianType">Endian Type to read with.</param>
  850. public float ReadSingle(EndianType EndianType) { return BitConverter.ToSingle(ReadBytes(4, EndianType), 0); }
  851.  
  852. /// <summary>
  853. /// Reads a string from the current stream. The string is prefixed with the length, encoded as an integer seven bits at a time.
  854. /// </summary>
  855. /// <param name="Length">Length of the string.</param>
  856. public string ReadString(int Length) { return Encoding.ASCII.GetString(base.ReadBytes(Length)).Replace("\0", string.Empty); }
  857.  
  858. /// <summary>
  859. /// Reads a unicode string from the current stream. The string is prefixed with the length, encoded as an integer seven bits at a time.
  860. /// </summary>
  861. /// <param name="Length">Length of the string.</param>
  862. public string ReadUnicodeString(int Length) { return Encoding.BigEndianUnicode.GetString(base.ReadBytes(Length * 2)).Replace("\0", string.Empty); }
  863.  
  864. public string ReadAsciiString(int Length)
  865. {
  866. string str = String.Empty;
  867. int num = 0;
  868. for (int i = 0; i < Length; i++)
  869. {
  870. char ch = (char)this.ReadByte();
  871. num++;
  872. if (ch == '\0')
  873. break;
  874. str += ch;
  875. }
  876. this.BaseStream.Seek((long)(Length - num), SeekOrigin.Current);
  877. return str;
  878. }
  879. public string ReadCString()
  880. {
  881. char ch;
  882. string str = String.Empty;
  883. while ((ch = base.ReadChar()) != '\0')
  884. {
  885. if (ch == '\0')
  886. return str;
  887. str += ch;
  888. }
  889. return str;
  890. }
  891. public string ReadStringNullTerminated()
  892. {
  893. string str = String.Empty;
  894. while (true)
  895. {
  896. byte num = this.ReadByte();
  897. if (num == 0x0)
  898. return str;
  899. str = str + ((char)num);
  900. }
  901. }
  902. public string ReadUnicodeNullTermString()
  903. {
  904. string str = String.Empty;
  905. while (true)
  906. {
  907. ushort num = this.ReadUInt16(EndianType.BigEndian);
  908. if (num == 0x0)
  909. return str;
  910. str += (char)num;
  911. }
  912. }
  913.  
  914. public ushort SeekNReadUInt16(long Address)
  915. {
  916. base.BaseStream.Position = Address;
  917. return ReadUInt16();
  918. }
  919. public uint SeekNReadUInt32(long Address)
  920. {
  921. base.BaseStream.Position = Address;
  922. return ReadUInt32();
  923. }
  924.  
  925. /// <summary>
  926. /// Reads an image from the current stream and advances the current position of the stream by the size of the image.
  927. /// </summary>
  928. /// <param name="Size">Size of the image.</param>
  929. public Image ParseImage(int Size) { using (var stream = new MemoryStream(base.ReadBytes(Size))) return Image.FromStream(stream); }
  930. }
  931.  
  932. #endregion
  933.  
  934. #region EndianWriter
  935.  
  936. /// <summary>
  937. /// The Endian Writer class that can write data in Big Endian and Little Endian.
  938. /// </summary>
  939. public class EndianWriter : BinaryWriter
  940. {
  941. public EndianType EndianType;
  942.  
  943. /// <summary>
  944. /// Initializes a new instance of the EndianWriter class on the specified stream in the specified Endian Type.
  945. /// </summary>
  946. /// <param name="Input">The stream to load for reading.</param>
  947. /// <param name="EndianType">Endian Type to write with.</param>
  948. public EndianWriter(Stream Input, EndianType EndianType) : base(Input) { this.EndianType = EndianType; }
  949. public EndianWriter(byte[] Buffer, EndianType EndianType) : this(new MemoryStream(Buffer), EndianType) { }
  950.  
  951. public virtual void SeekTo(object Position)
  952. {
  953. base.BaseStream.Seek(Convert.ToInt64(Position), SeekOrigin.Begin);
  954. }
  955.  
  956. /// <summary>
  957. /// Writes a byte array to the underlying stream.
  958. /// </summary>
  959. /// <param name="Data">Byte array to write</param>
  960. /// <param name="EndianType">Endian Type to write with.</param>
  961. public virtual void Write(byte[] Data, EndianType EndianType)
  962. {
  963. if (EndianType == EndianType.BigEndian)
  964. Array.Reverse(Data);
  965. base.Write(Data);
  966. }
  967.  
  968. /// <summary>
  969. /// Writes a character array to the current stream and advances the current position of the stream in accordance with the Encoding used and the specific characters being written to the stream.
  970. /// </summary>
  971. /// <param name="Value">Chars to write.</param>
  972. public override void Write(char[] Value) { Write(Value, EndianType); }
  973.  
  974. /// <summary>
  975. /// Writes a character array to the current stream and advances the current position of the stream in accordance with the Encoding used and the specific characters being written to the stream.
  976. /// </summary>
  977. /// <param name="Value">Chars to write.</param>
  978. /// <param name="EndianType">Endian Type to write with.</param>
  979. public void Write(char[] Value, EndianType EndianType)
  980. {
  981. if (EndianType == EndianType.BigEndian) { Array.Reverse(Value); }
  982. base.Write(Value);
  983. }
  984.  
  985. /// <summary>
  986. /// Writes a two-byte signed integer to the current stream and advances the stream position by two bytes.
  987. /// </summary>
  988. /// <param name="Value">Short to write.</param>
  989. public override void Write(short Value) { Write(Value, EndianType); }
  990.  
  991. /// <summary>
  992. /// Writes a two-byte signed integer to the current stream and advances the stream position by two bytes.
  993. /// </summary>
  994. /// <param name="Value">Short to write.</param>
  995. /// <param name="EndianType">Endian Type to write with.</param>
  996. public void Write(short Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  997.  
  998. /// <summary>
  999. /// Writes a two-byte unsigned integer to the current stream and advances the stream position by two bytes.
  1000. /// </summary>
  1001. /// <param name="Value">Ushort to write.</param>
  1002. public override void Write(ushort Value) { Write(Value, EndianType); }
  1003.  
  1004. /// <summary>
  1005. /// Writes a two-byte unsigned integer to the current stream and advances the stream position by two bytes.
  1006. /// </summary>
  1007. /// <param name="Value">Ushort to write.</param>
  1008. /// <param name="EndianType">Endian Type to write with.</param>
  1009. public void Write(ushort Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  1010.  
  1011. /// <summary>
  1012. /// Writes a 3-byte signed integer from the current stream and advances the current position of the stream by three bytes.
  1013. /// </summary>
  1014. /// <param name="Value">Int24 to write.</param>
  1015. public void WriteInt24(int Value) { WriteInt24(Value, EndianType); }
  1016.  
  1017. /// <summary>
  1018. /// Writes a 3-byte signed integer from the current stream and advances the current position of the stream by three bytes.
  1019. /// </summary>
  1020. /// <param name="Value">Int24 to write.</param>
  1021. /// <param name="EndianType">Endian Type to write with.</param>
  1022. public void WriteInt24(int Value, EndianType EndianType)
  1023. {
  1024. var buffer = BitConverter.GetBytes(Value);
  1025. Array.Resize(ref buffer, 3);
  1026. Write(buffer, EndianType);
  1027. }
  1028.  
  1029. /// <summary>
  1030. /// Writes a four-byte signed integer to the current stream and advances the stream position by four bytes.
  1031. /// </summary>
  1032. /// <param name="Value">Int to write.</param>
  1033. public override void Write(int Value) { Write(Value, EndianType); }
  1034.  
  1035. /// <summary>
  1036. /// Writes a four-byte signed integer to the current stream and advances the stream position by four bytes.
  1037. /// </summary>
  1038. /// <param name="Value">Int to write.</param>
  1039. /// <param name="EndianType">Endian Type to write with.</param>
  1040. public void Write(int Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  1041.  
  1042. /// <summary>
  1043. /// Writes a four-byte unsigned integer to the current stream and advances the stream position by four bytes.
  1044. /// </summary>
  1045. /// <param name="Value">Uint to write.</param>
  1046. public override void Write(uint Value) { Write(Value, EndianType); }
  1047.  
  1048. /// <summary>
  1049. /// Writes a four-byte unsigned integer to the current stream and advances the stream position by four bytes.
  1050. /// </summary>
  1051. /// <param name="Value">Uint to write.</param>
  1052. /// <param name="EndianType">Endian Type to write with.</param>
  1053. public void Write(uint Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  1054.  
  1055. /// <summary>
  1056. /// Writes an eight-byte signed integer to the current stream and advances the stream position by eight bytes.
  1057. /// </summary>
  1058. /// <param name="Value">Long to write.</param>
  1059. public override void Write(long Value) { Write(Value, EndianType); }
  1060.  
  1061. /// <summary>
  1062. /// Writes an eight-byte signed integer to the current stream and advances the stream position by eight bytes.
  1063. /// </summary>
  1064. /// <param name="Value">Long to write.</param>
  1065. /// <param name="EndianType">Endian Type to write with.</param>
  1066. public void Write(long Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  1067.  
  1068. /// <summary>
  1069. /// Writes an eight-byte unsigned integer to the current stream and advances the stream position by eight bytes.
  1070. /// </summary>
  1071. /// <param name="Value">Ulong to write.</param>
  1072. public override void Write(ulong Value) { Write(Value, EndianType); }
  1073.  
  1074. /// <summary>
  1075. /// Writes an eight-byte unsigned integer to the current stream and advances the stream position by eight bytes.
  1076. /// </summary>
  1077. /// <param name="Value">Ulong to write</param>
  1078. /// <param name="EndianType">Endian Type to write with.</param>
  1079. public void Write(ulong Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  1080.  
  1081. /// <summary>
  1082. /// Writes an eight-byte floating-point value to the current stream and advances the stream position by eight bytes.
  1083. /// </summary>
  1084. /// <param name="Value">Double to write.</param>
  1085. public override void Write(double Value) { Write(Value, EndianType); }
  1086.  
  1087. /// <summary>
  1088. /// Writes an eight-byte floating-point value to the current stream and advances the stream position by eight bytes.
  1089. /// </summary>
  1090. /// <param name="Value">Double to write.</param>
  1091. /// <param name="EndianType">Endian Type to write with.</param>
  1092. public void Write(double Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  1093.  
  1094. /// <summary>
  1095. /// Writes a four-byte floating-point value to the current stream and advances the stream position by four bytes.
  1096. /// </summary>
  1097. /// <param name="Value">Float to write.</param>
  1098. public override void Write(float Value) { Write(Value, EndianType); }
  1099.  
  1100. /// <summary>
  1101. /// Writes a four-byte floating-point value to the current stream and advances the stream position by four bytes.
  1102. /// </summary>
  1103. /// <param name="Value">Float to write.</param>
  1104. /// <param name="EndianType">Endian Type to write with.</param>
  1105. public void Write(float Value, EndianType EndianType) { Write(BitConverter.GetBytes(Value), EndianType); }
  1106.  
  1107. /// <summary>
  1108. /// Writes a length-prefixed string to this stream in the current encoding of the BinaryWriter, and advances the current position of the stream in accordance with the encoding used and the specific characters being written to the stream.
  1109. /// </summary>
  1110. /// <param name="Value">String to write.</param>
  1111. public override void Write(string Value) { base.Write(Encoding.ASCII.GetBytes(Value)); }
  1112.  
  1113. /// <summary>
  1114. /// Writes a length-prefixed unicode string to this stream in the current encoding of the BinaryWriter, and advances the current position of the stream in accordance with the encoding used and the specific characters being written to the stream.
  1115. /// </summary>
  1116. /// <param name="Value">Unicode string to write.</param>
  1117. public void WriteUnicodeString(string Value) { WriteUnicodeString(Value, Value.Length); }
  1118.  
  1119. /// <summary>
  1120. /// Writes a length-prefixed unicode string to this stream in the current encoding of the BinaryWriter, and advances the current position of the stream in accordance with the encoding used and the specific characters being written to the stream.
  1121. /// </summary>
  1122. /// <param name="Value">Unicode string to write.</param>
  1123. /// <param name="Length">Length of the string. (If it exceed the actual length, null bytes will be written.)</param>
  1124. public void WriteUnicodeString(string Value, int Length)
  1125. {
  1126. int length = Value.Length;
  1127. for (int i = 0; i < length; i++)
  1128. {
  1129. if (i > Length)
  1130. break;
  1131. ushort num3 = Value[i];
  1132. this.Write(num3, this.EndianType);
  1133. }
  1134. int num4 = (Length - length) * 2;
  1135. if (num4 > 0)
  1136. this.Write(new byte[num4]);
  1137. }
  1138. /// <summary>
  1139. /// Writes an image from the current stream and advances the current position of the stream by the size of the image.
  1140. /// </summary>
  1141. /// <param name="Image">Image to write.</param>
  1142. public void Write(Image Image)
  1143. {
  1144. using (var ms = new MemoryStream())
  1145. {
  1146. Image.Save(ms, Image.RawFormat);
  1147. base.Write(ms.ToArray());
  1148. }
  1149. }
  1150.  
  1151. public void WriteUnicodeNullTermString(string String)
  1152. {
  1153. int length = String.Length;
  1154. for (int i = 0; i < length; i++)
  1155. {
  1156. ushort num = String[i];
  1157. this.Write(num, this.EndianType);
  1158. }
  1159. this.Write(new byte[2]);
  1160. }
  1161.  
  1162. public void WriteUInt24(uint value)
  1163. {
  1164. WriteUInt24(value, this.EndianType);
  1165. }
  1166.  
  1167. public void WriteUInt24(uint value, EndianType endianType)
  1168. {
  1169. byte[] buffer = BitConverter.GetBytes(value);
  1170.  
  1171. Array.Resize(ref buffer, 3);
  1172.  
  1173. if (endianType == EndianType.BigEndian)
  1174. Array.Reverse(buffer);
  1175.  
  1176. base.Write(buffer);
  1177. }
  1178.  
  1179. public void WriteAsciiString(string String, int Length)
  1180. {
  1181. this.WriteAsciiString(String, Length, this.EndianType);
  1182. }
  1183.  
  1184. public void WriteAsciiString(string String, int Length, EndianType EndianType)
  1185. {
  1186. if (String.Length > Length)
  1187. String = String.Substring(0, Length);
  1188. this.Write(System.Text.Encoding.ASCII.GetBytes(String));
  1189. if (String.Length < Length)
  1190. this.Write(new byte[Length - String.Length]);
  1191. }
  1192. public virtual void Write(byte[] Buffer, object offset, object BufferLength)
  1193. {
  1194. base.Write(Buffer, Convert.ToInt32(offset), Convert.ToInt32(BufferLength));
  1195. }
  1196. public virtual void Write(byte[] Buffer, object BufferLength)
  1197. {
  1198. base.Write(Buffer, 0, Convert.ToInt32(BufferLength));
  1199. }
  1200. public virtual void SeekTo(object offset, SeekOrigin SeekOrigin)
  1201. {
  1202. Seek(Convert.ToInt32(offset), SeekOrigin);
  1203. }
  1204. public void SeekNWrite(long position, int Value)
  1205. {
  1206. base.BaseStream.Position = position;
  1207. this.Write(Value);
  1208. }
  1209. public void SeekNWrite(long position, short Value)
  1210. {
  1211. base.BaseStream.Position = position;
  1212. this.Write(Value);
  1213. }
  1214. public void WriteByte(object value)
  1215. {
  1216. long val = Convert.ToInt64(value);
  1217. base.Write((byte)(val & 0xFF));
  1218. }
  1219. }
  1220.  
  1221. #endregion
  1222. }
  1223.  
  1224. CSC.cs:
  1225. using System;
  1226. using System.Collections.Generic;
  1227. using System.Linq;
  1228. using System.Text;
  1229. using System.Threading.Tasks;
  1230. using System.IO;
  1231.  
  1232. namespace GTAV
  1233. {
  1234. class CSC
  1235. {
  1236. private EndianIO io;
  1237. private byte[] buffer;
  1238.  
  1239. public header_t header;
  1240. public dataInfo_t dataInfo;
  1241.  
  1242. public string scriptName;
  1243. public uint[] Natives;
  1244.  
  1245. public byte[] codePageData;
  1246. public string[] scriptStrings;
  1247.  
  1248. public int[] StringPages;
  1249. public int[] CodePages;
  1250.  
  1251. public CSC(string path)
  1252. {
  1253. buffer = File.ReadAllBytes(path);
  1254. }
  1255.  
  1256. public CSC(byte[] _buffer)
  1257. {
  1258. buffer = _buffer;
  1259. }
  1260.  
  1261. public CSC(CSC csc)
  1262. {
  1263. //idk yet...
  1264. }
  1265.  
  1266. private bool checkVersion()
  1267. {
  1268. if (io.In.ReadUInt32() == 0x52534337) //RSC7
  1269. return true;
  1270. return false;
  1271. }
  1272.  
  1273. public void Read()
  1274. {
  1275. io = new EndianIO(buffer, EndianType.BigEndian, true);
  1276.  
  1277. if (!checkVersion())
  1278. return;
  1279.  
  1280. io.Position = 0;
  1281.  
  1282. //read header
  1283. header.magic = io.In.ReadUInt32();
  1284. header.version = io.In.ReadInt32();
  1285.  
  1286. io.Position += 8; //skip to data start.
  1287.  
  1288. //read start of data info..
  1289. io.Position += 8; //skip past unk0 and hash...
  1290. dataInfo.codeBlockOffset = getOffset(io.In.ReadInt32());
  1291. dataInfo.globalsVersion = io.In.ReadInt32();
  1292.  
  1293. //counts
  1294. dataInfo.codeLength = io.In.ReadInt32();
  1295. dataInfo.paramsCount = io.In.ReadInt32();
  1296. dataInfo.staticsCount = io.In.ReadInt32();
  1297. dataInfo.globalsCount = io.In.ReadInt32();
  1298. dataInfo.nativesCount = io.In.ReadInt32();
  1299.  
  1300. //offsets
  1301. dataInfo.staticsOffset = getOffset(io.In.ReadInt32());
  1302. dataInfo.globalsOffset = getOffset(io.In.ReadInt32());
  1303. dataInfo.nativesOffset = getOffset(io.In.ReadInt32());
  1304.  
  1305. io.Position += 16;
  1306.  
  1307. dataInfo.scriptNameOffset = getOffset(io.In.ReadInt32());
  1308. dataInfo.stringBlockOffset = getOffset(io.In.ReadInt32());
  1309. dataInfo.stringSize = io.In.ReadInt32();
  1310.  
  1311. //Getting the code pages
  1312. io.Position = dataInfo.codeBlockOffset;
  1313. int pageCount = getPageCount(dataInfo.codeLength);
  1314. CodePages = new int[pageCount];
  1315. for (int i = 0; i < pageCount; i++)
  1316. CodePages[i] = getOffset(io.In.ReadInt32());
  1317.  
  1318. //Getting the string pages
  1319. io.Position = dataInfo.stringBlockOffset;
  1320. pageCount = getPageCount(dataInfo.stringSize);
  1321. StringPages = new int[pageCount];
  1322. for (int i = 0; i < pageCount; i++)
  1323. StringPages[i] = getOffset(io.In.ReadInt32());
  1324.  
  1325. //Getting the natives
  1326. io.Position = dataInfo.nativesOffset;
  1327. Natives = new uint[dataInfo.nativesCount];
  1328. for (int i = 0; i < dataInfo.nativesCount; i++)
  1329. Natives[i] = io.In.ReadUInt32();
  1330.  
  1331. //Getting the script name
  1332. io.Position = dataInfo.scriptNameOffset;
  1333. scriptName = io.In.ReadCString();
  1334.  
  1335. //get string pages strings..
  1336. scriptStrings = ExtractStringPage(0);
  1337.  
  1338. //get first code page
  1339. codePageData = ExtractCodePage(0);
  1340.  
  1341. interpretCSC();
  1342.  
  1343. }
  1344.  
  1345. private void interpretCSC()
  1346. {
  1347. //to do: interpret.
  1348. }
  1349.  
  1350. private int getOffset(int n)
  1351. {
  1352. return (n & 0xFFFFFF) + 0x10;
  1353. }
  1354.  
  1355. private int getPageCount(int n)
  1356. {
  1357. return ( n + 0x3FFF) >> 0xE;
  1358. }
  1359.  
  1360. private int getPageLen(int numPages, int pagesLen, int pg)
  1361. {
  1362. return (pg == numPages) ? (pagesLen % 0x4000) : 0x4000;
  1363. }
  1364.  
  1365. private string[] ExtractStringPage(int page)
  1366. {
  1367. int pageLen = getPageLen((StringPages.Length - 1), dataInfo.stringSize, page);
  1368. io.Position = StringPages[page];
  1369.  
  1370. int len = 0;
  1371. List<string> stringsFound = new List<string>();
  1372. while (len < pageLen)
  1373. {
  1374. string str = io.In.ReadCString();
  1375.  
  1376. if (str != "")
  1377. stringsFound.Add(str);
  1378.  
  1379. len += str.Length + 1;
  1380. }
  1381. return stringsFound.ToArray();
  1382. }
  1383.  
  1384. public byte[] ExtractCodePage(int page)
  1385. {
  1386. int pageLen = getPageLen(CodePages.Length - 1, dataInfo.codeLength, page);
  1387. io.Position = CodePages[page];
  1388. return io.In.ReadBytes(pageLen);
  1389. }
  1390.  
  1391. public struct header_t
  1392. {
  1393. public uint magic; //RSC7
  1394. public int version; //rage version
  1395. }
  1396.  
  1397. public struct dataInfo_t
  1398. {
  1399. public int hash;
  1400. public int unk0;
  1401. public int codeBlockOffset;
  1402. public int globalsVersion;
  1403. public int codeLength;
  1404. public int paramsCount;
  1405. public int staticsCount;
  1406. public int globalsCount;
  1407. public int nativesCount;
  1408. public int staticsOffset;
  1409. public int globalsOffset;
  1410. public int nativesOffset;
  1411. public int unk1;
  1412. public int unk2;
  1413. public int unk3;
  1414. public int unk4;
  1415. public int scriptNameOffset;
  1416. public int stringBlockOffset;
  1417. public int stringSize;
  1418. public int unk5;
  1419. }
  1420. }
  1421. }
  1422. _________________________________________________________________________-
  1423. Ready: https://anonfiles.com/file/d64688e39b483c235bf08845946336bd
  1424.  
  1425. . u$erWeapon .
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement