TEST(TestGameFileLoader, CanOpen) { // Test CGameFileLoader::CanOpen() with useStrategies = false, because // strategies have already already been tested above GameClientConfig gc("gameclient.test"); GameClientConfig gc_nes; gc_nes.extensions.insert(".nes"); GameClientConfig gc_bin; gc_bin.extensions.insert(".bin"); CFileItem file; EXPECT_TRUE(CGameFileLoader::CanOpen(file, gc)); file.SetProperty("gameclient", "gameclient.badegg"); EXPECT_FALSE(CGameFileLoader::CanOpen(file, gc)); file.ClearProperty("gameclient"); gc.platforms.push_back(PLATFORM_NINTENDO_64); EXPECT_TRUE(CGameFileLoader::CanOpen(file, gc)); file.GetGameInfoTag()->SetPlatform("Playstation"); EXPECT_FALSE(CGameFileLoader::CanOpen(file, gc)); gc.platforms.clear(); EXPECT_TRUE(CGameFileLoader::CanOpen(file, gc)); file.SetPath(XBMC_REF_FILE_PATH("xbmc/games/test/LocalFile.nes")); EXPECT_TRUE(CGameFileLoader::CanOpen(file, gc)); EXPECT_TRUE(CGameFileLoader::CanOpen(file, gc_nes)); EXPECT_FALSE(CGameFileLoader::CanOpen(file, gc_bin)); // Test entering .zip files CFileItem localZipFile(XBMC_REF_FILE_PATH("xbmc/games/test/LocalFile.zip"), false); EXPECT_TRUE(CGameFileLoader::CanOpen(localZipFile, gc)); // No extensions specified, will try to load zip directly EXPECT_TRUE(CGameFileLoader::CanOpen(localZipFile, gc_nes)); EXPECT_FALSE(CGameFileLoader::CanOpen(localZipFile, gc_bin)); }
bool CRetroPlayerDialogs::GameLauchDialog(const CFileItem &file, GameClientPtr &result) { CFileItem fileCopy = file; // If an explicit game client was specified, try to download that if (fileCopy.HasProperty("gameclient")) { if (InstallGameClient(fileCopy.GetProperty("gameclient").asString(), fileCopy, result)) return true; fileCopy.ClearProperty("gameclient"); // don't want this to interfere later on } // First, ask the user if they would like to install a game client or go to // the add-on manager CContextButtons choices; choices.Add(0, 24026); // Install emulator choices.Add(1, 24058); // Add-on manager int btnid = CGUIDialogContextMenu::ShowAndGetChoice(choices); if (btnid == 0) // Install emulator { return InstallGameClientDialog(fileCopy, result); } else if (btnid == 1) // Add-on manager { // Queue the file so that if a compatible game client is installed, the // user will be asked to launch the file. CGameManager::Get().SetAutoLaunch(fileCopy); CLog::Log(LOGDEBUG, "RetroPlayer: User chose to go to the add-on manager"); CStdStringArray params; params.push_back("addons://all/xbmc.gameclient"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); } else { CLog::Log(LOGDEBUG, "RetroPlayer: User canceled game client selection"); } return false; }
void CSaveFileState::DoWork(CFileItem& item, CBookmark& bookmark, bool updatePlayCount) { std::string progressTrackingFile = item.GetPath(); if (item.HasVideoInfoTag() && StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://")) progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified else if (item.HasProperty("original_listitem_url")) { // only use original_listitem_url for Python, UPnP and Bluray sources std::string original = item.GetProperty("original_listitem_url").asString(); if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(item.GetPath())) progressTrackingFile = original; } if (!progressTrackingFile.empty()) { #ifdef HAS_UPNP // checks if UPnP server of this file is available and supports updating if (URIUtils::IsUPnP(progressTrackingFile) && UPNP::CUPnP::SaveFileState(item, bookmark, updatePlayCount)) { return; } #endif if (item.IsVideo()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for video item %s", __FUNCTION__, redactPath.c_str()); CVideoDatabase videodatabase; if (!videodatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open video database. Can not save file state!", __FUNCTION__); } else { if (URIUtils::IsPlugin(progressTrackingFile) && !(item.HasVideoInfoTag() && item.GetVideoInfoTag()->m_iDbId >= 0)) { // FileItem from plugin can lack information, make sure all needed fields are set CVideoInfoTag *tag = item.GetVideoInfoTag(); CStreamDetails streams = tag->m_streamDetails; if (videodatabase.LoadVideoInfo(progressTrackingFile, *tag)) { item.SetPath(progressTrackingFile); item.ClearProperty("original_listitem_url"); tag->m_streamDetails = streams; } } bool updateListing = false; // No resume & watched status for livetv if (!item.IsLiveTV()) { if (updatePlayCount) { // no watched for not yet finished pvr recordings if (!item.IsInProgressPVRRecording()) { CLog::Log(LOGDEBUG, "%s - Marking video item %s as watched", __FUNCTION__, redactPath.c_str()); // consider this item as played videodatabase.IncrementPlayCount(item); item.GetVideoInfoTag()->IncrementPlayCount(); item.SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, true); updateListing = true; if (item.HasVideoInfoTag()) { CVariant data; data["id"] = item.GetVideoInfoTag()->m_iDbId; data["type"] = item.GetVideoInfoTag()->m_type; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data); } } } else videodatabase.UpdateLastPlayed(item); if (!item.HasVideoInfoTag() || item.GetVideoInfoTag()->GetResumePoint().timeInSeconds != bookmark.timeInSeconds) { if (bookmark.timeInSeconds <= 0.0f) videodatabase.ClearBookMarksOfFile(progressTrackingFile, CBookmark::RESUME); else videodatabase.AddBookMarkToFile(progressTrackingFile, bookmark, CBookmark::RESUME); if (item.HasVideoInfoTag()) item.GetVideoInfoTag()->SetResumePoint(bookmark); // UPnP announce resume point changes to clients // however not if playcount is modified as that already announces if (item.HasVideoInfoTag() && !updatePlayCount) { CVariant data; data["id"] = item.GetVideoInfoTag()->m_iDbId; data["type"] = item.GetVideoInfoTag()->m_type; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data); } updateListing = true; } } if (item.HasVideoInfoTag() && item.GetVideoInfoTag()->HasStreamDetails()) { CFileItem dbItem(item); // Check whether the item's db streamdetails need updating if (!videodatabase.GetStreamDetails(dbItem) || dbItem.GetVideoInfoTag()->m_streamDetails != item.GetVideoInfoTag()->m_streamDetails) { videodatabase.SetStreamDetailsForFile(item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile); updateListing = true; } } // Could be part of an ISO stack. In this case the bookmark is saved onto the part. // In order to properly update the list, we need to refresh the stack's resume point CApplicationStackHelper& stackHelper = g_application.GetAppStackHelper(); if (stackHelper.HasRegisteredStack(item) && stackHelper.GetRegisteredStackTotalTimeMs(item) == 0) videodatabase.GetResumePoint(*(stackHelper.GetRegisteredStack(item)->GetVideoInfoTag())); videodatabase.Close(); if (updateListing) { CUtil::DeleteVideoDatabaseDirectoryCache(); CFileItemPtr msgItem(new CFileItem(item)); if (item.HasProperty("original_listitem_url")) msgItem->SetPath(item.GetProperty("original_listitem_url").asString()); CGUIMessage message(GUI_MSG_NOTIFY_ALL, CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow(), 0, GUI_MSG_UPDATE_ITEM, 0, msgItem); CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(message); } } } if (item.IsAudio()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for audio item %s", __FUNCTION__, redactPath.c_str()); CMusicDatabase musicdatabase; if (updatePlayCount) { if (!musicdatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open music database. Can not save file state!", __FUNCTION__); } else { // consider this item as played CLog::Log(LOGDEBUG, "%s - Marking audio item %s as listened", __FUNCTION__, redactPath.c_str()); musicdatabase.IncrementPlayCount(item); musicdatabase.Close(); // UPnP announce resume point changes to clients // however not if playcount is modified as that already announces if (item.IsMusicDb()) { CVariant data; data["id"] = item.GetMusicInfoTag()->GetDatabaseId(); data["type"] = item.GetMusicInfoTag()->GetType(); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::AudioLibrary, "xbmc", "OnUpdate", data); } } } if (item.IsAudioBook()) { musicdatabase.Open(); musicdatabase.SetResumeBookmarkForAudioBook(item, item.m_lStartOffset + CUtil::ConvertSecsToMilliSecs(bookmark.timeInSeconds)); musicdatabase.Close(); } } } }