Advertisement
cirion5

Shadowrun Hong Kong Music Replacer: C# for Windows

Dec 7th, 2017
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 19.00 KB | None | 0 0
  1. using System;
  2. using System.Windows.Forms;
  3.  
  4. namespace SuperShadowrunWindows
  5. {
  6.     public partial class Form1 : Form
  7.     {
  8.  
  9.         const long ORIGINAL_MUSIC_FILE_SIZE = 107277169;
  10.  
  11.         const String MESSAGE_BOX_TITLE = "Shadowrun Music Replacer";
  12.  
  13.         const String CURRENT_MUSIC_FILE_PATH = "SRHK_Data\\resources.assets.resS";
  14.         const String BACKUP_MUSIC_FILE_PATH = "SRHK_Data\\resources.assets.resS.original";
  15.         const String ASSETS_FILE_PATH = "SRHK_Data\\resources.assets";
  16.  
  17.         int[] SIZE_OFFSETS = {
  18.             2004907468, //  Hub-TeaHouse
  19.             2004907524, //  Hub-Exterior
  20.             2004907584, //  Combat-Generic-Int2
  21.             2004907640, //  Legwork-SLinterior
  22.             2004907692, //  TitleTheme-UI
  23.             2004907748, //  Combat-Matrix2
  24.             2004907808, //  Combat-Kowloon-Int2
  25.             2004907864, //  Combat-Gobbet-Int1
  26.             2004907924, //  Combat-Kowloon-WrapUp
  27.             2004907980, //  Hub-SafeHouse
  28.             2004908040, //  Combat-Is0bel-Int2
  29.             2004908092, //  Legwork-Generic
  30.             2004908152, //  Combat-Kowloon-Int1
  31.             2004908212, //  Combat-Gobbet-WrapUp
  32.             2004908268, //  Legwork-Is0bel
  33.             2004908324, //  Legwork-Erhu
  34.             2004908380, //  Legwork-Grendel
  35.             2004908444, //  Legwork-ExitStageLeft
  36.             2004908488, //  TESTSTINGER
  37.             2004908548, //  Hub-Club88-ThroughWalls
  38.             2004908604, //  Legwork-News
  39.             2004908656, //  Combat-Boss
  40.             2004908704, //  loudmusic
  41.             2004908764, //  Legwork-Whistleblower
  42.             2004908824, //  Combat-Is0bel-Int1
  43.             2004908884, //  Combat-Generic-WrapUp
  44.             2004908944, //  Combat-Generic-Int1
  45.             2004909000, //  Hub-Club88-InStreet
  46.             2004909052, //  Legwork-Kowloon
  47.             2004909112, //  Combat-stinger-end
  48.             2004909180, //  Combat-VictoriaHarbor-WrapUp
  49.             2004909240, //  Combat-Grendel-Int1
  50.             2004909292, //  Legwork-Museum
  51.             2004909340, //  Sewer
  52.             2004909396, //  Stealth-Matrix1
  53.             2004909452, //  Legwork-Gobbet
  54.             2004909508, //  Legwork-Hacking
  55.             2004909572, //  Combat-Grendel-WrapUp
  56.             2004909632, //  KnightKingsElevator
  57.             2004909692, //  Legwork-VictoriaHarbor
  58.             2004909752, //  Combat-Grendel-Int2
  59.             2004909812, //  Combat-Is0bel-WrapUp
  60.             2004909880, //  Combat-VictoriaHarbor-Int1
  61.             2004909940, //  Combat-stinger-start
  62.             2004910000, //  Combat-Gobbet-Int2
  63.             2004910056, //  Club88-MainRoom
  64.             2004910120  //  Combat-VictoriaHarbor-Int2
  65.         };
  66.  
  67.         int[] ORIGINAL_SIZE_VALUES =
  68.         {
  69.             3124134, // Hub-TeaHouse
  70.             5637312, // Hub-Exterior
  71.             2455567, // Combat-Generic-Int2
  72.             2188996, // Legwork-SLinterior
  73.             3114613, // TitleTheme-UI
  74.             3634330, // Combat-Matrix2
  75.             2041347, // Combat-Kowloon-Int2
  76.             1584808, // Combat-Gobbet-Int1
  77.             2041312, // Combat-Kowloon-WrapUp
  78.             4940168, // Hub-SafeHouse
  79.             1561468, // Combat-Is0bel-Int2
  80.             3314907, // Legwork-Generic
  81.             2041503, // Combat-Kowloon-Int1
  82.             1587765, // Combat-Gobbet-WrapUp
  83.             2769352, // Legwork-Is0bel
  84.             2335317, // Legwork-Erhu
  85.             4081444, // Legwork-Grendel
  86.             2137219, // Legwork-ExitStageLeft
  87.             23524,   // TESTSTINGER
  88.             1945118, // Hub-Club88-ThroughWalls
  89.             814336,  // Legwork-News
  90.             2379468, // Combat-Boss
  91.             1461548, // loudmusic
  92.             2076444, // Legwork-Whistleblower
  93.             1561717, // Combat-Is0bel-Int1
  94.             2453971, // Combat-Generic-WrapUp
  95.             2456839, // Combat-Generic-Int1
  96.             1946454, // Hub-Club88-InStreet
  97.             4769042, // Legwork-Kowloon
  98.             174738,  // Combat-stinger-end
  99.             1555961, // Combat-VictoriaHarbor-WrapUp
  100.             2201641, // Combat-Grendel-Int1
  101.             3824160, // Legwork-Museum
  102.             1248268, // Sewer
  103.             3632887, // Stealth-Matrix1
  104.             3386416, // Legwork-Gobbet
  105.             1558692, // Legwork-Hacking
  106.             2204970, // Combat-Grendel-WrapUp
  107.             1722735, // KnightKingsElevator
  108.             2772601, // Legwork-VictoriaHarbor
  109.             2203038, // Combat-Grendel-Int2
  110.             1561330, // Combat-Is0bel-WrapUp
  111.             1556423, // Combat-VictoriaHarbor-Int1
  112.             98449,   // Combat-stinger-start
  113.             1587496, // Combat-Gobbet-Int2
  114.             1951388, // Club88-MainRoom
  115.             1555953  // Combat-VictoriaHarbor-Int2
  116.         };
  117.  
  118.         int[] ORIGINAL_POSITION_VALUES =
  119.         {
  120.             0,         //    Hub-TeaHouse
  121.             3124134,   //    Hub-Exterior
  122.             8761446,   //    Combat-Generic-Int2
  123.             11217013,  //    Legwork-SLinterior
  124.             13406009,  //    TitleTheme-UI
  125.             16520622,  //    Combat-Matrix2
  126.             20154952,  //    Combat-Kowloon-Int2
  127.             22196299,  //    Combat-Gobbet-Int1
  128.             23781107,  //    Combat-Kowloon-WrapUp
  129.             25822419,  //    Hub-SafeHouse
  130.             30762587,  //    Combat-Is0bel-Int2
  131.             32324055,  //    Legwork-Generic
  132.             35638962,  //    Combat-Kowloon-Int1
  133.             37680465,  //    Combat-Gobbet-WrapUp
  134.             39268230,  //    Legwork-Is0bel
  135.             42037582,  //    Legwork-Erhu
  136.             44372899,  //    Legwork-Grendel
  137.             48454343,  //    Legwork-ExitStageLeft
  138.             50591562,  //    TESTSTINGER
  139.             50615086,  //    Hub-Club88-ThroughWalls
  140.             52560204,  //    Legwork-News
  141.             53374540,  //    Combat-Boss
  142.             55754008,  //    loudmusic
  143.             57215556,  //    Legwork-Whistleblower
  144.             59292000,  //    Combat-Is0bel-Int1
  145.             60853717,  //    Combat-Generic-WrapUp
  146.             63307688,  //    Combat-Generic-Int1
  147.             65764527,  //    Hub-Club88-InStreet
  148.             67710981,  //    Legwork-Kowloon
  149.             72480023,  //    Combat-stinger-end
  150.             72654761,  //    Combat-VictoriaHarbor-WrapUp
  151.             74210722,  //    Combat-Grendel-Int1
  152.             76412363,  //    Legwork-Museum
  153.             80236523,  //    Sewer
  154.             81484791,  //    Stealth-Matrix1
  155.             85117678,  //    Legwork-Gobbet
  156.             88504094,  //    Legwork-Hacking
  157.             90062786,  //    Combat-Grendel-WrapUp
  158.             92267756,  //    KnightKingsElevator
  159.             93990491,  //    Legwork-VictoriaHarbor
  160.             96763092,  //    Combat-Grendel-Int2
  161.             98966130,  //    Combat-Is0bel-WrapUp
  162.             100527460, //    Combat-VictoriaHarbor-Int1
  163.             102083883, //    Combat-stinger-start
  164.             102182332, //    Combat-Gobbet-Int2
  165.             103769828, //    Club88-MainRoom
  166.             105721216  //    Combat-VictoriaHarbor-Int2
  167.         };
  168.  
  169.         // The index into the new resources.assets.resS at which each track can be located. If using concat.py,
  170.         // these values can be taken from indices.txt. Pad out the array to 47 elements, you can safely reuse the
  171.         // same track multiple times. These do not necessarily need to be in ascending order.
  172.         int[] NEW_POSITION_VALUES =
  173.         {
  174.             0,
  175.             1393879,
  176.             3014944,
  177.             4520349,
  178.             6075686,
  179.             13224667,
  180.             16859277,
  181.             23705366,
  182.             27333628,
  183.             30392989,
  184.             31785729,
  185.             36227626,
  186.             37558729,
  187.             39215240,
  188.             42753645,
  189.             48193852,
  190.             50059652,
  191.             52826294,
  192.             58756297,
  193.             60484053,
  194.             61866854,
  195.             64926321,
  196.             67814125,
  197.             69554962,
  198.             70868771,
  199.             74036566,
  200.             77274731,
  201.             78780769,
  202.             80649419,
  203.             82085067,
  204.             83502179,
  205.             85835133,
  206.             89345991,
  207.             90902926,
  208.             92457982,
  209.             96090766,
  210.             99115787,
  211.             100674517,
  212.             102037008,
  213.             104243280,
  214.             107256232,
  215.             111057445,
  216.             113768371,
  217.             115841178,
  218.             117621935,
  219.             118888656,
  220.             126481541
  221.         };
  222.  
  223.         int[] NEW_SIZE_VALUES =
  224.         {
  225.             1393879,
  226.             1621065,
  227.             1505405,
  228.             1555337,
  229.             7148981,
  230.             3634610,
  231.             6846089,
  232.             3628262,
  233.             3059361,
  234.             1392740,
  235.             4441897,
  236.             1331103,
  237.             1656511,
  238.             3538405,
  239.             5440207,
  240.             1865800,
  241.             2766642,
  242.             5930003,
  243.             1727756,
  244.             1382801,
  245.             3059467,
  246.             2887804,
  247.             1740837,
  248.             1313809,
  249.             3167795,
  250.             3238165,
  251.             1506038,
  252.             1868650,
  253.             1435648,
  254.             1417112,
  255.             2332954,
  256.             3510858,
  257.             1556935,
  258.             1555056,
  259.             3632784,
  260.             3025021,
  261.             1558730,
  262.             1362491,
  263.             2206272,
  264.             3012952,
  265.             3801213,
  266.             2710926,
  267.             2072807,
  268.             1780757,
  269.             1266721,
  270.             7592885,
  271.             7064409
  272.         };
  273.  
  274.         // Mapping info
  275.         /*
  276.         Hub-TeaHouse              -> ../music/vlc_converted/track0.ogg
  277.         Hub-Exterior              -> ../music/vlc_converted/track1.ogg
  278.         Combat-Generic-Int2       -> ../music/vlc_converted/track3.ogg
  279.         Legwork-SLinterior        -> ../music/vlc_converted/track5.ogg
  280.         TitleTheme-UI             -> invocationarray_acff/04siren.ogg
  281.         Combat-Matrix2            -> ../music/combat_matrix2.ogg
  282.         Combat-Kowloon-Int2       -> invocationarray_op/06catalyst.ogg
  283.         Combat-Gobbet-Int1        -> ../music/vlc_converted/track6.ogg
  284.         Combat-Kowloon-WrapUp     -> ../music/vlc_converted/track7.ogg
  285.         Hub-SafeHouse             -> ../music/vlc_converted/track9.ogg
  286.         Combat-Is0bel-Int2        -> ../music/vlc_converted/track12.ogg
  287.         Legwork-Generic           -> ../music/vlc_converted/track14.ogg
  288.         Combat-Kowloon-Int1       -> ../music/vlc_converted/track16.ogg
  289.         Combat-Gobbet-WrapUp      -> ../music/vlc_converted/track17.ogg
  290.         Legwork-Is0bel            -> ../music/vlc_converted/track18.ogg
  291.         Legwork-Erhu              -> ../music/vlc_converted/track22.ogg
  292.         Legwork-Grendel           -> ../music/vlc_converted/track24.ogg
  293.         Legwork-ExitStageLeft     -> ../music/vlc_converted/track26.ogg
  294.         TESTSTINGER               -> ../music/vlc_converted/track27.ogg
  295.         Hub-Club88-ThroughWalls   -> ../music/vlc_converted/track30.ogg
  296.         Legwork-News              -> ../music/vlc_converted/track32.ogg
  297.         Combat-Boss               -> ../music/vlc_converted/track33.ogg
  298.         loudmusic                 -> ../music/vlc_converted/track34.ogg
  299.         Legwork-Whistleblower     -> ../music/vlc_converted/track35.ogg
  300.         Combat-Is0bel-Int1        -> ../music/vlc_converted/track36.ogg
  301.         Combat-Generic-WrapUp     -> ../music/vlc_converted/track37.ogg
  302.         Combat-Generic-Int1       -> ../music/vlc_converted/track38.ogg
  303.         Hub-Club88-InStreet       -> ../music/vlc_converted/track39.ogg
  304.         Legwork-Kowloon           -> ../music/vlc_converted/track41.ogg
  305.         Combat-stinger-end        -> ../music/vlc_converted/track43.ogg
  306.         Combat-VictoriaHarbor-WrapUp -> ../music/vlc_converted/track49.ogg
  307.         Combat-Grendel-Int1       -> ../music/vlc_converted/track46.ogg
  308.         Legwork-Museum            -> ../music/vlc_converted/track47.ogg
  309.         Sewer                     -> ../music/vlc_converted/track48.ogg
  310.         Stealth-Matrix1           -> ../music/stealth_matrix1.ogg
  311.         Legwork-Gobbet            -> ../music/vlc_converted/track50.ogg
  312.         Legwork-Hacking           -> ../music/legwork_hacking.ogg
  313.         Combat-Grendel-WrapUp     -> ../music/vlc_converted/track53.ogg
  314.         KnightKingsElevator       -> ../music/vlc_converted/track51.ogg
  315.         Legwork-VictoriaHarbor    -> ../music/vlc_converted/track54.ogg
  316.         Combat-Grendel-Int2       -> ../music/vlc_converted/track55.ogg
  317.         Combat-Is0bel-WrapUp      -> ../music/vlc_converted/track57.ogg
  318.         Combat-VictoriaHarbor-Int1 -> ../music/vlc_converted/track58.ogg
  319.         Combat-stinger-start      -> ../music/vlc_converted/track59.ogg
  320.         Combat-Gobbet-Int2        -> ../music/vlc_converted/track60.ogg
  321.         Club88-MainRoom           -> invocationarray_acff/08withme.ogg
  322.         Combat-VictoriaHarbor-Int2 -> invocationarray_op/16catalyst.ogg
  323.     */
  324.  
  325.         String path;
  326.  
  327.         public Form1()
  328.         {
  329.             InitializeComponent();
  330.             replaceButton.Enabled = false;
  331.             restoreButton.Enabled = false;
  332.         }
  333.  
  334.         // Browse...
  335.         private void button1_Click(object sender, EventArgs e)
  336.         {
  337.             if(openFileDialog1.ShowDialog() == DialogResult.OK)
  338.             {
  339.                 String fullPath = openFileDialog1.FileName;
  340.                 int endOfPath = fullPath.LastIndexOf("SRHK.exe");
  341.                 path = openFileDialog1.FileName.Substring(0, endOfPath);
  342.                 updateButtons();
  343.             }
  344.         }
  345.  
  346.         private void replaceButton_Click(object sender, EventArgs e)
  347.         {
  348.             String currentMusicFilePath = path + CURRENT_MUSIC_FILE_PATH;
  349.             String backupMusicFilePath = path + BACKUP_MUSIC_FILE_PATH;
  350.             String assetsFilePath = path + ASSETS_FILE_PATH;
  351.  
  352.             bool canSkipBackup = false;
  353.  
  354.             System.IO.FileInfo backupInfo = new System.IO.FileInfo(backupMusicFilePath);
  355.             if (backupInfo.Exists && backupInfo.Length == ORIGINAL_MUSIC_FILE_SIZE)
  356.             {
  357.                 canSkipBackup = true;
  358.             }
  359.  
  360.             System.IO.FileInfo currentInfo = new System.IO.FileInfo(currentMusicFilePath);
  361.             if (!canSkipBackup)
  362.             {
  363.                 if (currentInfo.Length != ORIGINAL_MUSIC_FILE_SIZE)
  364.                 {
  365.                     MessageBox.Show("WARNING: The current music file size appears incorrect. Please correct by verifying the integrity of Shadowrun Hong Kong within Steam. Aborting.", MESSAGE_BOX_TITLE, MessageBoxButtons.OK);
  366.                     return;
  367.                 }
  368.                 System.IO.File.Copy(currentMusicFilePath, backupMusicFilePath);
  369.             }
  370.  
  371.             System.IO.File.Delete(currentMusicFilePath);
  372.             CopyResource("SuperShadowrunWindows.Resources.resources.assets.resS", currentMusicFilePath);
  373.  
  374.             writeArrays(assetsFilePath, NEW_SIZE_VALUES, NEW_POSITION_VALUES);
  375.  
  376.             updateButtons();
  377.             MessageBox.Show("Conversion successful! The new music will now play for all campaigns, including the original.", MESSAGE_BOX_TITLE, MessageBoxButtons.OK);
  378.         }
  379.  
  380.         private void CopyResource(string resourceName, string file)
  381.         {
  382.             using (System.IO.Stream resource = GetType().Assembly
  383.                                               .GetManifestResourceStream(resourceName))
  384.             {
  385.                 if (resource == null)
  386.                 {
  387.                     throw new ArgumentException("No such resource", "resourceName");
  388.                 }
  389.                 using (System.IO.Stream output = System.IO.File.OpenWrite(file))
  390.                 {
  391.                     resource.CopyTo(output);
  392.                 }
  393.             }
  394.         }
  395.  
  396.         private void writeArrays(String filePath, int[] sizes, int[] positions)
  397.         {
  398.             // Should probably check errors here.
  399.             System.IO.Stream stream = System.IO.File.Open(filePath, System.IO.FileMode.Open);
  400.             for (int i = 0; i < SIZE_OFFSETS.Length; ++i)
  401.             {
  402.                 int offset = SIZE_OFFSETS[i];
  403.                 int size = sizes[i];
  404.                 int position = positions[i];
  405.                 stream.Seek(offset, System.IO.SeekOrigin.Begin);
  406.                 byte[] sizeBytes = BitConverter.GetBytes(size);
  407.                 stream.Write(sizeBytes, 0, 4);
  408.                 byte[] positionBytes = BitConverter.GetBytes(position);
  409.                 stream.Write(positionBytes, 0, 4);
  410.             }
  411.             stream.Close();
  412.         }
  413.  
  414.         private void updateButtons()
  415.         {
  416.             string currentMusicFilePath = path + CURRENT_MUSIC_FILE_PATH;
  417.             string backupMusicFilePath = path + BACKUP_MUSIC_FILE_PATH;
  418.             System.IO.FileInfo currentInfo = new System.IO.FileInfo(currentMusicFilePath);
  419.             System.IO.FileInfo backupInfo = new System.IO.FileInfo(backupMusicFilePath);
  420.             replaceButton.Enabled = currentInfo.Exists && currentInfo.Length == ORIGINAL_MUSIC_FILE_SIZE;
  421.             restoreButton.Enabled = backupInfo.Exists && currentInfo.Length != backupInfo.Length;
  422.         }
  423.  
  424.         private void restoreButton_Click(object sender, EventArgs e)
  425.         {
  426.             String currentMusicFilePath = path + CURRENT_MUSIC_FILE_PATH;
  427.             String backupMusicFilePath = path + BACKUP_MUSIC_FILE_PATH;
  428.             String assetsFilePath = path + ASSETS_FILE_PATH;
  429.  
  430.             bool canSkipBackup = false;
  431.  
  432.             System.IO.FileInfo backupInfo = new System.IO.FileInfo(backupMusicFilePath);
  433.             if (backupInfo.Exists && backupInfo.Length == ORIGINAL_MUSIC_FILE_SIZE)
  434.             {
  435.                 canSkipBackup = true;
  436.             }
  437.  
  438.             System.IO.FileInfo currentInfo = new System.IO.FileInfo(currentMusicFilePath);
  439.             if (!canSkipBackup)
  440.             {
  441.                 if (currentInfo.Length != ORIGINAL_MUSIC_FILE_SIZE)
  442.                 {
  443.                     MessageBox.Show("WARNING: The current music file size appears incorrect. Please correct by verifying the integrity of Shadowrun Hong Kong within Steam. Aborting.", MESSAGE_BOX_TITLE, MessageBoxButtons.OK);
  444.                     return;
  445.                 }
  446.                 System.IO.File.Copy(currentMusicFilePath, backupMusicFilePath);
  447.             }
  448.  
  449.             try {
  450.                 System.IO.File.Delete(currentMusicFilePath);
  451.             } catch (System.IO.IOException ioe) {
  452.                 MessageBox.Show("ERROR: Could not replace music file. Please exit Shadowrun Hong Kong if it is running and try again. If this problem persists, try rebooting your computer.", MESSAGE_BOX_TITLE, MessageBoxButtons.OK);
  453.                 return;
  454.             }
  455.  
  456.             System.IO.File.Copy(backupMusicFilePath, currentMusicFilePath);
  457.             writeArrays(assetsFilePath, ORIGINAL_SIZE_VALUES, ORIGINAL_POSITION_VALUES);
  458.  
  459.             updateButtons();
  460.             MessageBox.Show("Restore successful! The original Hong Kong music will now play for all campaigns.", MESSAGE_BOX_TITLE, MessageBoxButtons.OK);
  461.  
  462.         }
  463.  
  464.     }
  465. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement