bool CSaveLoadMgr::CanContinueGame( ) { // Is the .ini file actually there... if( !CWinUtil::FileExist( GetSaveINIFile( ) )) return false; char szSaveKey[SLMGR_MAX_INIKEY_LEN]; char szSaveFile[MAX_PATH]; if( !ReadContinueINI( szSaveKey, ARRAY_LEN( szSaveKey ), NULL, 0, szSaveFile, ARRAY_LEN( szSaveFile ))) return false; if( !SaveExists( szSaveKey, szSaveFile )) return false; return true; }
// called from ---GUI--- thread bool NetPlayServer::SyncSaveData() { m_save_data_synced_players = 0; u8 save_count = 0; constexpr size_t exi_device_count = 2; for (size_t i = 0; i < exi_device_count; i++) { if (m_settings.m_EXIDevice[i] == ExpansionInterface::EXIDEVICE_MEMORYCARD || SConfig::GetInstance().m_EXIDevice[i] == ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER) { save_count++; } } const auto game = m_dialog->FindGameFile(m_selected_game); if (game == nullptr) { PanicAlertT("Selected game doesn't exist in game list!"); return false; } bool wii_save = false; if (m_settings.m_CopyWiiSave && (game->GetPlatform() == DiscIO::Platform::WiiDisc || game->GetPlatform() == DiscIO::Platform::WiiWAD)) { wii_save = true; save_count++; } { sf::Packet pac; pac << static_cast<MessageId>(NP_MSG_SYNC_SAVE_DATA); pac << static_cast<MessageId>(SYNC_SAVE_DATA_NOTIFY); pac << save_count; SendAsyncToClients(std::move(pac)); } if (save_count == 0) return true; const std::string region = SConfig::GetDirectoryForRegion(SConfig::ToGameCubeRegion(game->GetRegion())); for (size_t i = 0; i < exi_device_count; i++) { const bool is_slot_a = i == 0; if (m_settings.m_EXIDevice[i] == ExpansionInterface::EXIDEVICE_MEMORYCARD) { std::string path = is_slot_a ? Config::Get(Config::MAIN_MEMCARD_A_PATH) : Config::Get(Config::MAIN_MEMCARD_B_PATH); MemoryCard::CheckPath(path, region, is_slot_a); bool mc251; IniFile gameIni = SConfig::LoadGameIni(game->GetGameID(), game->GetRevision()); gameIni.GetOrCreateSection("Core")->Get("MemoryCard251", &mc251, false); if (mc251) path.insert(path.find_last_of('.'), ".251"); sf::Packet pac; pac << static_cast<MessageId>(NP_MSG_SYNC_SAVE_DATA); pac << static_cast<MessageId>(SYNC_SAVE_DATA_RAW); pac << is_slot_a << region << mc251; if (File::Exists(path)) { if (!CompressFileIntoPacket(path, pac)) return false; } else { // No file, so we'll say the size is 0 pac << sf::Uint64{0}; } SendAsyncToClients(std::move(pac)); } else if (SConfig::GetInstance().m_EXIDevice[i] == ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER) { const std::string path = File::GetUserPath(D_GCUSER_IDX) + region + DIR_SEP + StringFromFormat("Card %c", is_slot_a ? 'A' : 'B'); sf::Packet pac; pac << static_cast<MessageId>(NP_MSG_SYNC_SAVE_DATA); pac << static_cast<MessageId>(SYNC_SAVE_DATA_GCI); pac << is_slot_a; if (File::IsDirectory(path)) { std::vector<std::string> files = GCMemcardDirectory::GetFileNamesForGameID(path + DIR_SEP, game->GetGameID()); pac << static_cast<u8>(files.size()); for (const std::string& file : files) { pac << file.substr(file.find_last_of('/') + 1); if (!CompressFileIntoPacket(file, pac)) return false; } } else { pac << static_cast<u8>(0); } SendAsyncToClients(std::move(pac)); } } if (wii_save) { const auto configured_fs = IOS::HLE::FS::MakeFileSystem(IOS::HLE::FS::Location::Configured); const auto save = WiiSave::MakeNandStorage(configured_fs.get(), game->GetTitleID()); sf::Packet pac; pac << static_cast<MessageId>(NP_MSG_SYNC_SAVE_DATA); pac << static_cast<MessageId>(SYNC_SAVE_DATA_WII); if (save->SaveExists()) { const std::optional<WiiSave::Header> header = save->ReadHeader(); const std::optional<WiiSave::BkHeader> bk_header = save->ReadBkHeader(); const std::optional<std::vector<WiiSave::Storage::SaveFile>> files = save->ReadFiles(); if (!header || !bk_header || !files) return false; pac << true; // save exists // Header pac << sf::Uint64{header->tid}; pac << header->banner_size << header->permissions << header->unk1; for (size_t i = 0; i < header->md5.size(); i++) pac << header->md5[i]; pac << header->unk2; for (size_t i = 0; i < header->banner_size; i++) pac << header->banner[i]; // BkHeader pac << bk_header->size << bk_header->magic << bk_header->ngid << bk_header->number_of_files << bk_header->size_of_files << bk_header->unk1 << bk_header->unk2 << bk_header->total_size; for (size_t i = 0; i < bk_header->unk3.size(); i++) pac << bk_header->unk3[i]; pac << sf::Uint64{bk_header->tid}; for (size_t i = 0; i < bk_header->mac_address.size(); i++) pac << bk_header->mac_address[i]; // Files for (const WiiSave::Storage::SaveFile& file : *files) { pac << file.mode << file.attributes << static_cast<u8>(file.type) << file.path; if (file.type == WiiSave::Storage::SaveFile::Type::File) { const std::optional<std::vector<u8>>& data = *file.data; if (!data || !CompressBufferIntoPacket(*data, pac)) return false; } } } else { pac << false; // save does not exist } SendAsyncToClients(std::move(pac)); } return true; }
bool CSaveLoadMgr::ReloadSaveExists( ) { return SaveExists( RELOADLEVEL_INIKEY, GetReloadLevelFile( )); }
bool CSaveLoadMgr::SlotSaveExists( uint32 nSlot ) { return SaveExists( GetSlotSaveKey( nSlot ), GetSlotSaveFile( nSlot )); }
bool CSaveLoadMgr::QuickSaveExists( ) { return SaveExists( QUICKSAVE_INIKEY, GetQuickSaveFile( )); }