INICODE.CPP 10 KB

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