INICODE.CPP 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: F:\projects\c&c0\vcs\code\inicode.cpv 4.38 03 Jul 1996 05:14:04 JOE_BOSTIC $ */
  15. /***************************************************************************
  16. ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
  17. ***************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : INICODE.CPP *
  22. * *
  23. * Programmer : David R Dettmer *
  24. * *
  25. * Start Date : November 7, 1995 *
  26. * *
  27. * Last Update : February 20, 1996 [JLB] *
  28. * *
  29. *-------------------------------------------------------------------------*
  30. * Functions: *
  31. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  32. #include "function.h"
  33. #ifdef TOFIX
  34. void Get_Scenario_Digest(char * digest, char * buffer)
  35. {
  36. char buf[128]; // Working string staging buffer.
  37. char stage[sizeof(BigInt)*2];
  38. char * stage_ptr = &stage[0];
  39. int len = strlen(buffer) + 2;
  40. char * tbuffer = buffer + len;
  41. WWGetPrivateProfileString("DIGEST", NULL, NULL, tbuffer, sizeof(_staging_buffer)-len, buffer);
  42. stage[0] = '\0';
  43. while (*tbuffer != '\0') {
  44. WWGetPrivateProfileString("DIGEST", tbuffer, NULL, buf, sizeof(buf)-1, buffer);
  45. strcat(stage, buf);
  46. tbuffer += strlen(tbuffer)+1;
  47. }
  48. len = strlen(stage);
  49. char * dbuffer = &stage[0];
  50. tbuffer = &stage[0];
  51. for (int index = 0; index < len/2; index++) {
  52. int c;
  53. if (isdigit(*tbuffer)) {
  54. c = (*tbuffer) - '0';
  55. } else {
  56. c = 10 + (toupper(*tbuffer) - 'A');
  57. }
  58. tbuffer++;
  59. c <<= 4;
  60. if (isdigit(*tbuffer)) {
  61. c |= (*tbuffer) - '0';
  62. } else {
  63. c |= 10 + (toupper(*tbuffer) - 'A');
  64. }
  65. tbuffer++;
  66. *dbuffer++ = c;
  67. }
  68. /*
  69. ** Decode and decrypt the number.
  70. */
  71. BigInt hash = 0;
  72. hash.DERDecode((unsigned char*)stage);
  73. BigInt d;
  74. d = d.Decode_ASCII(KEY_D);
  75. BigInt n;
  76. n = n.Decode_ASCII(KEY_N);
  77. hash = hash.exp_b_mod_c(d, n);
  78. memcpy(digest, &hash, 20);
  79. buffer = strstr(buffer, "[DIGEST]");
  80. if (buffer) {
  81. *buffer = '\0';
  82. }
  83. }
  84. bool Read_Scenario_INI_Write_INB( char *root, bool fresh)
  85. {
  86. char *buffer; // Scenario.ini staging buffer pointer.
  87. char *binbuf; // Scenario.inb staging buffer pointer.
  88. char fname[_MAX_FNAME+_MAX_EXT]; // full INI filename
  89. char buf[256]; // Working string staging buffer.
  90. char scenarioname[40];
  91. int len;
  92. unsigned char val;
  93. /*
  94. ** Fetch working pointer to the INI staging buffer. Make sure that the buffer
  95. ** is cleared out before proceeding. (Don't use the HidPage for this, since
  96. ** the HidPage may be needed for various uncompressions during the INI
  97. ** parsing.)
  98. */
  99. buffer = (char *)_staging_buffer;
  100. memset(buffer, '\0', sizeof(_staging_buffer));
  101. /*
  102. ** Create scenario filename and read the file.
  103. ** The previous routine verifies that the file is available.
  104. */
  105. sprintf(fname,"%s.INI",root);
  106. CCFileClass file(fname);
  107. file.Read(buffer, sizeof(_staging_buffer)-1);
  108. /*
  109. ** Fetch and slice off any message digest attached.
  110. */
  111. char digest[20];
  112. Get_Scenario_Digest(digest, buffer);
  113. char real_digest[20];
  114. SHAEngine digest_engine;
  115. digest_engine.Hash(buffer, strlen(buffer));
  116. digest_engine.Result(real_digest);
  117. if (memcmp(digest, real_digest, sizeof(real_digest)) != 0) {
  118. WWMessageBox().Process(TXT_SCENARIO_ERROR, TXT_OK);
  119. }
  120. /*
  121. ** Init the Scenario CRC value
  122. */
  123. ScenarioCRC = 0;
  124. len = strlen(buffer);
  125. for (int i = 0; i < len; i++) {
  126. val = (unsigned char)buffer[i];
  127. Add_CRC(&ScenarioCRC, (unsigned long)val);
  128. }
  129. sprintf(fname,"%s.INB",root);
  130. file.Set_Name(fname);
  131. file.Cache(16384);
  132. file.Open(WRITE);
  133. unsigned long crc = Ini_Binary_Version();
  134. file.Write( (char *)&crc, sizeof(crc) );
  135. binbuf = (char *)Alloc( sizeof(_staging_buffer), MEM_NORMAL );
  136. if (binbuf) {
  137. Write_Bin_Init( binbuf, sizeof(_staging_buffer) );
  138. } else {
  139. Print_Error_End_Exit( "Unable to alloc space for writing INB" );
  140. }
  141. /*
  142. ** Fetch the appropriate movie names from the INI file.
  143. */
  144. WWGetPrivateProfileString("Basic", "Name", "", scenarioname, sizeof(scenarioname), buffer);
  145. WWGetPrivateProfileString("Basic", "Intro", "x", Scen.IntroMovie, sizeof(Scen.IntroMovie), buffer);
  146. WWGetPrivateProfileString("Basic", "Brief", "x", Scen.BriefMovie, sizeof(Scen.BriefMovie), buffer);
  147. WWGetPrivateProfileString("Basic", "Win", "x", Scen.WinMovie, sizeof(Scen.WinMovie), buffer);
  148. WWGetPrivateProfileString("Basic", "Lose", "x", Scen.LoseMovie, sizeof(Scen.LoseMovie), buffer);
  149. WWGetPrivateProfileString("Basic", "Action", "x", Scen.ActionMovie, sizeof(Scen.ActionMovie), buffer);
  150. Scen.IsToCarryOver = WWGetPrivateProfileInt("Basic", "ToCarryOver", 0, buffer);
  151. Scen.IsToInherit = WWGetPrivateProfileInt("Basic", "ToInherit", 0, buffer);
  152. Write_Bin_String( scenarioname, strlen(scenarioname), binbuf );
  153. Write_Bin_String( Scen.IntroMovie, strlen(Scen.IntroMovie), binbuf );
  154. Write_Bin_String( Scen.BriefMovie, strlen(Scen.BriefMovie), binbuf );
  155. Write_Bin_String( Scen.WinMovie, strlen(Scen.WinMovie), binbuf );
  156. Write_Bin_String( Scen.LoseMovie, strlen(Scen.LoseMovie), binbuf );
  157. Write_Bin_String( Scen.ActionMovie, strlen(Scen.ActionMovie), binbuf );
  158. /*
  159. ** Fetch the transition theme for this scenario.
  160. */
  161. Scen.TransitTheme = THEME_NONE;
  162. WWGetPrivateProfileString("Basic", "Theme", "No Theme", buf, sizeof(buf), buffer);
  163. Scen.TransitTheme = Theme.From_Name(buf);
  164. WWGetPrivateProfileString( "Basic", "Player", "Greece", buf, 127, buffer);
  165. Scen.PlayerHouse = HouseTypeClass::From_Name(buf);
  166. if (Scen.PlayerHouse >= HOUSE_MULTI1) {
  167. Scen.PlayerHouse = HOUSE_GREECE;
  168. }
  169. // TCTC To Fix?
  170. // Scen.CarryOverPercent = WWGetPrivateProfileInt( "Basic", "CarryOverMoney", 100, buffer);
  171. Scen.CarryOverCap = WWGetPrivateProfileInt( "Basic", "CarryOverCap", -1, buffer);
  172. Scen.Percent = WWGetPrivateProfileInt( "Basic", "Percent", 0, buffer);
  173. Write_Bin_Num( &Scen.TransitTheme, sizeof(Scen.TransitTheme), binbuf );
  174. Write_Bin_Num( &Scen.PlayerHouse, sizeof(Scen.PlayerHouse), binbuf );
  175. Write_Bin_Num( &Scen.CarryOverPercent, 1, binbuf );
  176. Write_Bin_Num( &Scen.CarryOverCap, 2, binbuf );
  177. Write_Bin_Num( &Scen.Percent, 1, binbuf );
  178. /*
  179. ** Read in the specific information for each of the house types. This creates
  180. ** the houses of different types.
  181. */
  182. HouseClass::Read_INI(buffer);
  183. Call_Back();
  184. /*
  185. ** Read in the team-type data. The team types must be created before any
  186. ** triggers can be created.
  187. */
  188. TeamTypeClass::Read_INI(buffer);
  189. Call_Back();
  190. /*
  191. ** Assign PlayerPtr by reading the player's house from the INI;
  192. ** Must be done before any TechnoClass objects are created.
  193. */
  194. if (Session.Type == GAME_NORMAL) {
  195. Scen.CarryOverPercent = Cardinal_To_Fixed(100, Scen.CarryOverPercent);
  196. PlayerPtr = HouseClass::As_Pointer( Scen.PlayerHouse );
  197. assert(PlayerPtr != NULL);
  198. PlayerPtr->IsHuman = true;
  199. int carryover;
  200. if (Scen.CarryOverCap != -1) {
  201. carryover = MIN(Fixed_To_Cardinal(Scen.CarryOverMoney, Scen.CarryOverPercent), (Scen.CarryOverCap * 100) );
  202. } else {
  203. carryover = Fixed_To_Cardinal(Scen.CarryOverMoney, Scen.CarryOverPercent);
  204. }
  205. PlayerPtr->Credits += carryover;
  206. PlayerPtr->Control.InitialCredits += carryover;
  207. } else {
  208. Assign_Houses();
  209. }
  210. /*
  211. ** Read in the trigger data. The triggers must be created before any other
  212. ** objects can be initialized.
  213. */
  214. TriggerClass::Read_INI(buffer);
  215. Call_Back();
  216. /*
  217. ** Read in the map control values. This includes dimensions
  218. ** as well as theater information.
  219. */
  220. Map.Read_INI(buffer);
  221. Call_Back();
  222. /*
  223. ** Attempt to read the map's binary image file; if fails, read the
  224. ** template data from the INI, for backward compatibility
  225. */
  226. if (fresh) {
  227. if (!Map.Read_Binary(root, &ScenarioCRC)) {
  228. return( false );
  229. }
  230. }
  231. Call_Back();
  232. /*
  233. ** Read in and place the 3D terrain objects.
  234. */
  235. TerrainClass::Read_INI(buffer);
  236. Call_Back();
  237. /*
  238. ** Read in and place the units (all sides).
  239. */
  240. UnitClass::Read_INI(buffer);
  241. Call_Back();
  242. AircraftClass::Read_INI(buffer);
  243. Call_Back();
  244. VesselClass::Read_INI(buffer);
  245. Call_Back();
  246. /*
  247. ** Read in and place the infantry units (all sides).
  248. */
  249. InfantryClass::Read_INI(buffer);
  250. Call_Back();
  251. /*
  252. ** Read in and place all the buildings on the map.
  253. */
  254. BuildingClass::Read_INI(buffer);
  255. Call_Back();
  256. /*
  257. ** Read in the AI's base information.
  258. */
  259. Base.Read_INI(buffer);
  260. Call_Back();
  261. /*
  262. ** Read in any normal overlay objects.
  263. */
  264. OverlayClass::Read_INI(buffer);
  265. Call_Back();
  266. /*
  267. ** Read in any smudge overlays.
  268. */
  269. SmudgeClass::Read_INI(buffer);
  270. Call_Back();
  271. /*
  272. ** Read in any briefing text.
  273. */
  274. char * stage = &Scen.BriefingText[0];
  275. *stage = '\0';
  276. int index = 1;
  277. /*
  278. ** Build the full text of the mission objective.
  279. */
  280. for (;;) {
  281. char buff[16];
  282. sprintf(buff, "%d", index++);
  283. *stage = '\0';
  284. WWGetPrivateProfileString("Briefing", buff, "", stage, 255, buffer);
  285. if (strlen(stage) == 0) break;
  286. strcat(stage, " ");
  287. stage += strlen(stage);
  288. }
  289. len = Write_Bin_Length( binbuf );
  290. if (len != -1) {
  291. file.Write( binbuf, len );
  292. }
  293. Free( binbuf );
  294. file.Close();
  295. return(true);
  296. }
  297. #endif