public int ImportFromFile(string filename) { int fileoffset = 0; import_valid = false; descentversion = -1; Encoding encBinary = Encoding.GetEncoding(28591); byte[] filedata = File.ReadAllBytes(filename); string filenameonly = Path.GetFileNameWithoutExtension(filename); SetName(filenameonly); SetSignature(BitConverter.ToInt32(filedata, fileoffset)); //0 fileoffset += 4; if (signature != FILE_SIGNATURE) { Console.WriteLine("ERROR: Can't load PLR file. PLR file signature invalid. file signature {0} does not match {1}", signature, FILE_SIGNATURE); import_valid = false; return(-1); } SetSavegame_version(BitConverter.ToUInt16(filedata, fileoffset)); fileoffset += 2; // now at 8 if ((savegame_version >= 0) && (savegame_version <= 8)) { descentversion = 1; } else { descentversion = 2; } const int PLR_COMATIBLE_SAVEGAME_VERSION = 4; const int PLR_COMPATIBLE_STRUCT_VERSION = 16; if (descentversion == 1) { SetStruct_version(BitConverter.ToUInt16(filedata, fileoffset)); fileoffset += 2; if (savegame_version < PLR_COMATIBLE_SAVEGAME_VERSION || struct_version < PLR_COMPATIBLE_STRUCT_VERSION) { Console.WriteLine("ERROR: savegame version {0} < {1} or PLR struct version {2} < {3}. Can't load PLR file.", savegame_version, PLR_COMATIBLE_SAVEGAME_VERSION, struct_version, PLR_COMPATIBLE_STRUCT_VERSION); return(-1); } SetNum_mission_protocol_entries(BitConverter.ToInt32(filedata, fileoffset)); fileoffset += 4; SetDefault_difficulty(BitConverter.ToInt32(filedata, fileoffset)); fileoffset += 4; SetAuto_leveling(BitConverter.ToInt32(filedata, fileoffset)); fileoffset += 4; if (savegame_version <= 5) { Console.WriteLine("ERROR: savegame_version <=5. Old style highest level info not supported."); return(-1); } } int filesize_without_highlevels = filedata.Length - (PLR_MISSION_MAXLEVEL_ENTRY_LENGTH * num_mission_protocol_entries); if (savegame_version >= 0 && savegame_version <= 7) { Console.WriteLine("ERROR: Descent 1 PLR file version {0} not supported at PLR save version 7 and older.", savegame_version); return(-1); } else if (savegame_version == 8) { if (filesize_without_highlevels == 2212) { Console.WriteLine("ERROR: Shareware version not supported"); return(-1); } else if (filesize_without_highlevels == 2252) { // valid full version PLR file but need to skip the next 2 Int32 data } else if (filesize_without_highlevels == (2212 + 2 * sizeof(Int32))) { Console.WriteLine("ERROR: Shareware version not supported (v0.31 to v0.42 d1x)."); return(-1); } else if (filesize_without_highlevels == (2252 + 2 * sizeof(Int32))) { // valid full version PLR file but need to skip the next 2 Int32 data } else { Console.WriteLine("ERROR: file size {0} ({1} without high level data)not known to be a valid PLR file for Descent 1", filedata.Length, filesize_without_highlevels); } descentversion = 1; //Console.WriteLine ("ERROR: Descent 1 PLR files not implemented yet."); //return (-1); } else if (savegame_version == 24) { descentversion = 2; } else if (savegame_version > 255) { isbigendianfile = true; descentversion = 2; savegame_version = (UInt16)System.Net.IPAddress.NetworkToHostOrder((int)savegame_version); Console.WriteLine("ERROR: PLR file looks like it is bigendian. That architecture is not supported."); return(-1); } //byte[] fileunknown1 = { 0, 0, 0 }; //Array.Copy(filedata, 8, fileunknown1, 0, 3); //SetUnknown1( fileunknown1 ); if (descentversion == 2) { SetGame_window_h(BitConverter.ToUInt16(filedata, fileoffset)); fileoffset += 2; SetGame_window_w(BitConverter.ToUInt16(filedata, fileoffset)); fileoffset += 2; SetDefault_difficulty(filedata[fileoffset++]); SetAuto_leveling(filedata [fileoffset++]); SetShow_reticle(filedata [fileoffset++]); SetCockpit_mode(filedata [fileoffset++]); SetVideo_resolution(filedata [fileoffset++]); SetMissile_view(filedata [fileoffset++]); SetHeadlight_on_when_picked_up(filedata [fileoffset++]); // 16 here d2 SetShow_guided_missile_in_main_display(filedata [fileoffset++]); SetAutomap_always_hires(filedata [fileoffset++]); // 18 here d2 SetNum_mission_protocol_entries(BitConverter.ToInt16(filedata, fileoffset)); // an extra byte so assuming this is a 16 bit number fileoffset += 2; //19 here d2... 21 next line } //const int MISSION_PROTOCOL_ENTRIES_OFFSET_START = 21; mission_arr = new PlrMission[num_mission_protocol_entries]; int loop = 0; while (loop < num_mission_protocol_entries) { PlrMission thisMiss = new PlrMission(); //int startoffset = loop * MISSION_PROTOCOL_ENTRY_LENGTH + fileoffset; thisMiss.mission_name = encBinary.GetString(filedata, fileoffset, PLR_MISSION_MAXLEVEL_NAME_LENGTH); fileoffset += PLR_MISSION_MAXLEVEL_NAME_LENGTH; thisMiss.maximum_level = filedata [fileoffset++]; mission_arr [loop] = thisMiss; ++loop; } if (descentversion == 1) { if (savegame_version != 7) { Array.Copy(filedata, fileoffset, saved_game_data_shareware, 0, PLR_SAVED_GAMED_SW_SIZE); fileoffset += PLR_SAVED_GAMED_SW_SIZE; } } //const int PLR_MISSION_PROTOCOL_ENTRIES_OFFSET = 21; const int MULTIPLAYER_MACRO_BUFFER_SIZE = 35; //int offset = PLR_MISSION_PROTOCOL_ENTRIES_OFFSET + (num_mission_protocol_entries * 10); multiplayer_macro_f9 = encBinary.GetString(filedata, fileoffset, MULTIPLAYER_MACRO_BUFFER_SIZE); fileoffset += MULTIPLAYER_MACRO_BUFFER_SIZE; multiplayer_macro_f10 = encBinary.GetString(filedata, fileoffset, MULTIPLAYER_MACRO_BUFFER_SIZE); fileoffset += MULTIPLAYER_MACRO_BUFFER_SIZE; multiplayer_macro_f11 = encBinary.GetString(filedata, fileoffset, MULTIPLAYER_MACRO_BUFFER_SIZE); fileoffset += MULTIPLAYER_MACRO_BUFFER_SIZE; multiplayer_macro_f12 = encBinary.GetString(filedata, fileoffset, MULTIPLAYER_MACRO_BUFFER_SIZE); fileoffset += MULTIPLAYER_MACRO_BUFFER_SIZE; const int PLR_CONTROL_MAX_TYPES_D1 = 7; const int PLR_CONTROL_MAX_TYPES_D2 = 8; const int PLR_MAX_CONTROLS_D1 = 50; const int PLR_MAX_CONTROLS_D2 = 60; if (descentversion == 1) { int configurationlength = PLR_MAX_CONTROLS_D1 * PLR_CONTROL_MAX_TYPES_D1; configuration = new byte[configurationlength]; Array.Copy(filedata, fileoffset, configuration, 0, configurationlength); fileoffset += configurationlength; } if (descentversion == 2) { int configurationlength = (savegame_version < 20 ? PLR_MAX_CONTROLS_D1 : PLR_MAX_CONTROLS_D2) * PLR_CONTROL_MAX_TYPES_D2; configuration = new byte[configurationlength]; Array.Copy(filedata, fileoffset, configuration, 0, configurationlength); fileoffset += configurationlength; } if (descentversion == 1) { SetController_type(filedata [fileoffset++]); } if (descentversion == 2) { if (savegame_version <= 20) { SetObsolete_winjoy_map(filedata [fileoffset++]); } SetControl_type_dos(filedata [fileoffset++]); SetControl_type_win(filedata [fileoffset++]); } SetObsolete_joy_sens(filedata [fileoffset++]); if (descentversion == 2) { weapons_order_arr = new PlrWeaponOrder[PLR_MAX_WEAPON_ORDER_ENTRIES]; loop = 0; while (loop < PLR_MAX_WEAPON_ORDER_ENTRIES) { PlrWeaponOrder tmpWeaponOrder = new PlrWeaponOrder(filedata [fileoffset++], filedata [fileoffset++]); //tmpWeaponOrder.primaryOrder = filedata [fileoffset++]; //tmpWeaponOrder.secondaryOrder = filedata [fileoffset++]; weapons_order_arr [loop] = tmpWeaponOrder; loop++; } if (savegame_version >= 16) { cockpit_3dview1 = BitConverter.ToUInt32(filedata, fileoffset); fileoffset += 4; cockpit_3dview2 = BitConverter.ToUInt32(filedata, fileoffset); fileoffset += 4; } lifetimerankings_num_kills = BitConverter.ToUInt32(filedata, fileoffset); fileoffset += 4; lifetimerankings_num_deaths = BitConverter.ToUInt32(filedata, fileoffset); fileoffset += 4; lifetimerankings_checksum = BitConverter.ToUInt32(filedata, fileoffset); fileoffset += 4; const int PLR_GUIDEBOT_MAX_LEN = 10; if (savegame_version >= 18) { guidebot_callsign = encBinary.GetString(filedata, fileoffset, PLR_GUIDEBOT_MAX_LEN); fileoffset += PLR_GUIDEBOT_MAX_LEN; } if (savegame_version >= 24) { joystick_name = encBinary.GetString(filedata, fileoffset, PLR_MAX_JOYSTICK_NAME_BUFFER); fileoffset += PLR_MAX_JOYSTICK_NAME_BUFFER; } } if (fileoffset != filedata.Length) { Console.WriteLine("ERROR: problem reading file. Parsed offset ended at {0} while file length is {1}", fileoffset, filedata.Length); return(-1); } imported_filesize = filedata.Length; import_valid = true; return(0); }
public int CleanupMissions() { if (import_valid) { int missionsRemoved = 0; if (mission_arr != null) { // Need a count of missions with max level greater than 1 to set the array to the new size int newMissionCount = 0; foreach (PlrMission tmp2Mission in mission_arr) { if (tmp2Mission.maximum_level > 1) { //Console.WriteLine ("'{0}':{1} {2}", tmpMission.mission_name, tmpMission.mission_name.Length, tmpMission.maximum_level); newMissionCount++; } } if (newMissionCount < num_mission_protocol_entries) { PlrMission[] cleanedUpMissions = new PlrMission[newMissionCount]; int msnLoop = 0; foreach (PlrMission tmp3Mission in mission_arr) { if (tmp3Mission.maximum_level > 1) { PlrMission tmpMission = new PlrMission(); tmpMission.maximum_level = tmp3Mission.maximum_level; tmpMission.mission_name = tmp3Mission.mission_name; cleanedUpMissions [msnLoop] = tmpMission; msnLoop++; } else { if (debugEnabled) { Console.WriteLine("CleanupMissions: Removing mission status entry '{0}' with max level at '{1}'", tmp3Mission.mission_name, tmp3Mission.maximum_level); } } } missionsRemoved = num_mission_protocol_entries - msnLoop; imported_filesize -= PLR_MISSION_MAXLEVEL_ENTRY_LENGTH * missionsRemoved; if (displayInfoMessages) { Console.WriteLine("Removed {0} mission status entries with maximum level at 1", missionsRemoved); } num_mission_protocol_entries = msnLoop; mission_arr = cleanedUpMissions; } else { if (debugEnabled) { Console.WriteLine("CleanupMissions: Missions do not need cleaned up. No mission status entries have a maximum level equal to 1"); } } } else { Console.WriteLine("ERROR: CleanupMissions mission_arr is null."); return(-1); } return(missionsRemoved); } else { Console.WriteLine("ERROR: CleanupMissions requires an imported PLR file"); return(-1); } }