| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
- // software: you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation,
- // either version 3 of the License, or (at your option) any later version.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /* $Header: F:\projects\c&c0\vcs\code\inicode.cpv 4.38 03 Jul 1996 05:14:04 JOE_BOSTIC $ */
- /***************************************************************************
- ** 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 **
- ***************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : INICODE.CPP *
- * *
- * Programmer : David R Dettmer *
- * *
- * Start Date : November 7, 1995 *
- * *
- * Last Update : February 20, 1996 [JLB] *
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- #ifdef TOFIX
- void Get_Scenario_Digest(char * digest, char * buffer)
- {
- char buf[128]; // Working string staging buffer.
- char stage[sizeof(BigInt)*2];
- char * stage_ptr = &stage[0];
- int len = strlen(buffer) + 2;
- char * tbuffer = buffer + len;
- WWGetPrivateProfileString("DIGEST", NULL, NULL, tbuffer, sizeof(_staging_buffer)-len, buffer);
- stage[0] = '\0';
- while (*tbuffer != '\0') {
- WWGetPrivateProfileString("DIGEST", tbuffer, NULL, buf, sizeof(buf)-1, buffer);
- strcat(stage, buf);
- tbuffer += strlen(tbuffer)+1;
- }
- len = strlen(stage);
- char * dbuffer = &stage[0];
- tbuffer = &stage[0];
- for (int index = 0; index < len/2; index++) {
- int c;
- if (isdigit(*tbuffer)) {
- c = (*tbuffer) - '0';
- } else {
- c = 10 + (toupper(*tbuffer) - 'A');
- }
- tbuffer++;
- c <<= 4;
- if (isdigit(*tbuffer)) {
- c |= (*tbuffer) - '0';
- } else {
- c |= 10 + (toupper(*tbuffer) - 'A');
- }
- tbuffer++;
- *dbuffer++ = c;
- }
- /*
- ** Decode and decrypt the number.
- */
- BigInt hash = 0;
- hash.DERDecode((unsigned char*)stage);
- BigInt d;
- d = d.Decode_ASCII(KEY_D);
- BigInt n;
- n = n.Decode_ASCII(KEY_N);
- hash = hash.exp_b_mod_c(d, n);
- memcpy(digest, &hash, 20);
- buffer = strstr(buffer, "[DIGEST]");
- if (buffer) {
- *buffer = '\0';
- }
- }
- bool Read_Scenario_INI_Write_INB( char *root, bool fresh)
- {
- char *buffer; // Scenario.ini staging buffer pointer.
- char *binbuf; // Scenario.inb staging buffer pointer.
- char fname[_MAX_FNAME+_MAX_EXT]; // full INI filename
- char buf[256]; // Working string staging buffer.
- char scenarioname[40];
- int len;
- unsigned char val;
- /*
- ** Fetch working pointer to the INI staging buffer. Make sure that the buffer
- ** is cleared out before proceeding. (Don't use the HidPage for this, since
- ** the HidPage may be needed for various uncompressions during the INI
- ** parsing.)
- */
- buffer = (char *)_staging_buffer;
- memset(buffer, '\0', sizeof(_staging_buffer));
- /*
- ** Create scenario filename and read the file.
- ** The previous routine verifies that the file is available.
- */
- sprintf(fname,"%s.INI",root);
- CCFileClass file(fname);
- file.Read(buffer, sizeof(_staging_buffer)-1);
- /*
- ** Fetch and slice off any message digest attached.
- */
- char digest[20];
- Get_Scenario_Digest(digest, buffer);
- char real_digest[20];
- SHAEngine digest_engine;
- digest_engine.Hash(buffer, strlen(buffer));
- digest_engine.Result(real_digest);
- if (memcmp(digest, real_digest, sizeof(real_digest)) != 0) {
- WWMessageBox().Process(TXT_SCENARIO_ERROR, TXT_OK);
- }
- /*
- ** Init the Scenario CRC value
- */
- ScenarioCRC = 0;
- len = strlen(buffer);
- for (int i = 0; i < len; i++) {
- val = (unsigned char)buffer[i];
- Add_CRC(&ScenarioCRC, (unsigned long)val);
- }
- sprintf(fname,"%s.INB",root);
- file.Set_Name(fname);
- file.Cache(16384);
- file.Open(WRITE);
- unsigned long crc = Ini_Binary_Version();
- file.Write( (char *)&crc, sizeof(crc) );
- binbuf = (char *)Alloc( sizeof(_staging_buffer), MEM_NORMAL );
- if (binbuf) {
- Write_Bin_Init( binbuf, sizeof(_staging_buffer) );
- } else {
- Print_Error_End_Exit( "Unable to alloc space for writing INB" );
- }
- /*
- ** Fetch the appropriate movie names from the INI file.
- */
- WWGetPrivateProfileString("Basic", "Name", "", scenarioname, sizeof(scenarioname), buffer);
- WWGetPrivateProfileString("Basic", "Intro", "x", Scen.IntroMovie, sizeof(Scen.IntroMovie), buffer);
- WWGetPrivateProfileString("Basic", "Brief", "x", Scen.BriefMovie, sizeof(Scen.BriefMovie), buffer);
- WWGetPrivateProfileString("Basic", "Win", "x", Scen.WinMovie, sizeof(Scen.WinMovie), buffer);
- WWGetPrivateProfileString("Basic", "Lose", "x", Scen.LoseMovie, sizeof(Scen.LoseMovie), buffer);
- WWGetPrivateProfileString("Basic", "Action", "x", Scen.ActionMovie, sizeof(Scen.ActionMovie), buffer);
- Scen.IsToCarryOver = WWGetPrivateProfileInt("Basic", "ToCarryOver", 0, buffer);
- Scen.IsToInherit = WWGetPrivateProfileInt("Basic", "ToInherit", 0, buffer);
- Write_Bin_String( scenarioname, strlen(scenarioname), binbuf );
- Write_Bin_String( Scen.IntroMovie, strlen(Scen.IntroMovie), binbuf );
- Write_Bin_String( Scen.BriefMovie, strlen(Scen.BriefMovie), binbuf );
- Write_Bin_String( Scen.WinMovie, strlen(Scen.WinMovie), binbuf );
- Write_Bin_String( Scen.LoseMovie, strlen(Scen.LoseMovie), binbuf );
- Write_Bin_String( Scen.ActionMovie, strlen(Scen.ActionMovie), binbuf );
- /*
- ** Fetch the transition theme for this scenario.
- */
- Scen.TransitTheme = THEME_NONE;
- WWGetPrivateProfileString("Basic", "Theme", "No Theme", buf, sizeof(buf), buffer);
- Scen.TransitTheme = Theme.From_Name(buf);
- WWGetPrivateProfileString( "Basic", "Player", "Greece", buf, 127, buffer);
- Scen.PlayerHouse = HouseTypeClass::From_Name(buf);
- if (Scen.PlayerHouse >= HOUSE_MULTI1) {
- Scen.PlayerHouse = HOUSE_GREECE;
- }
- // TCTC To Fix?
- // Scen.CarryOverPercent = WWGetPrivateProfileInt( "Basic", "CarryOverMoney", 100, buffer);
- Scen.CarryOverCap = WWGetPrivateProfileInt( "Basic", "CarryOverCap", -1, buffer);
- Scen.Percent = WWGetPrivateProfileInt( "Basic", "Percent", 0, buffer);
- Write_Bin_Num( &Scen.TransitTheme, sizeof(Scen.TransitTheme), binbuf );
- Write_Bin_Num( &Scen.PlayerHouse, sizeof(Scen.PlayerHouse), binbuf );
- Write_Bin_Num( &Scen.CarryOverPercent, 1, binbuf );
- Write_Bin_Num( &Scen.CarryOverCap, 2, binbuf );
- Write_Bin_Num( &Scen.Percent, 1, binbuf );
- /*
- ** Read in the specific information for each of the house types. This creates
- ** the houses of different types.
- */
- HouseClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in the team-type data. The team types must be created before any
- ** triggers can be created.
- */
- TeamTypeClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Assign PlayerPtr by reading the player's house from the INI;
- ** Must be done before any TechnoClass objects are created.
- */
- if (Session.Type == GAME_NORMAL) {
- Scen.CarryOverPercent = Cardinal_To_Fixed(100, Scen.CarryOverPercent);
- PlayerPtr = HouseClass::As_Pointer( Scen.PlayerHouse );
- assert(PlayerPtr != NULL);
- PlayerPtr->IsHuman = true;
- int carryover;
- if (Scen.CarryOverCap != -1) {
- carryover = MIN(Fixed_To_Cardinal(Scen.CarryOverMoney, Scen.CarryOverPercent), (Scen.CarryOverCap * 100) );
- } else {
- carryover = Fixed_To_Cardinal(Scen.CarryOverMoney, Scen.CarryOverPercent);
- }
- PlayerPtr->Credits += carryover;
- PlayerPtr->Control.InitialCredits += carryover;
- } else {
- Assign_Houses();
- }
- /*
- ** Read in the trigger data. The triggers must be created before any other
- ** objects can be initialized.
- */
- TriggerClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in the map control values. This includes dimensions
- ** as well as theater information.
- */
- Map.Read_INI(buffer);
- Call_Back();
- /*
- ** Attempt to read the map's binary image file; if fails, read the
- ** template data from the INI, for backward compatibility
- */
- if (fresh) {
- if (!Map.Read_Binary(root, &ScenarioCRC)) {
- return( false );
- }
- }
- Call_Back();
- /*
- ** Read in and place the 3D terrain objects.
- */
- TerrainClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in and place the units (all sides).
- */
- UnitClass::Read_INI(buffer);
- Call_Back();
- AircraftClass::Read_INI(buffer);
- Call_Back();
- VesselClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in and place the infantry units (all sides).
- */
- InfantryClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in and place all the buildings on the map.
- */
- BuildingClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in the AI's base information.
- */
- Base.Read_INI(buffer);
- Call_Back();
- /*
- ** Read in any normal overlay objects.
- */
- OverlayClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in any smudge overlays.
- */
- SmudgeClass::Read_INI(buffer);
- Call_Back();
- /*
- ** Read in any briefing text.
- */
- char * stage = &Scen.BriefingText[0];
- *stage = '\0';
- int index = 1;
- /*
- ** Build the full text of the mission objective.
- */
- for (;;) {
- char buff[16];
- sprintf(buff, "%d", index++);
- *stage = '\0';
- WWGetPrivateProfileString("Briefing", buff, "", stage, 255, buffer);
- if (strlen(stage) == 0) break;
- strcat(stage, " ");
- stage += strlen(stage);
- }
- len = Write_Bin_Length( binbuf );
- if (len != -1) {
- file.Write( binbuf, len );
- }
- Free( binbuf );
- file.Close();
- return(true);
- }
- #endif
|