CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

INICODE.CPP (10561B)


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