std::string CGUIDialogSelectGameClient::ShowAndGetGameClient(const GameClientVector& candidates, const GameClientVector& installable)
{
  std::string gameClient;

  CLog::Log(LOGDEBUG, "Select game client dialog: Found %lu candidates", candidates.size());
  for (const auto& gameClient : candidates)
    CLog::Log(LOGDEBUG, "Adding %s as a candidate", gameClient->ID().c_str());

  if (!installable.empty())
  {
    CLog::Log(LOGDEBUG, "Select game client dialog: Found %lu installable clients", installable.size());
    for (const auto& gameClient : installable)
      CLog::Log(LOGDEBUG, "Adding %s as an installable client", gameClient->ID().c_str());
  }

  CContextButtons choiceButtons;

  // Add emulators
  int i = 0;
  for (const GameClientPtr& gameClient : candidates)
    choiceButtons.Add(i++, gameClient->Name());

  // Add button to install emulators
  const int iInstallEmulator = i++;
  if (!installable.empty())
    choiceButtons.Add(iInstallEmulator, 35253); // "Install emulator"

  // Add button to manage emulators
  const int iAddonMgr = i++;
  choiceButtons.Add(iAddonMgr, 35254); // "Manage emulators"

  // Do modal
  int result = CGUIDialogContextMenu::ShowAndGetChoice(choiceButtons);

  if (0 <= result && result < static_cast<int>(candidates.size()))
  {
    // Handle emulator
    gameClient = candidates[result]->ID();
  }
  else if (result == iInstallEmulator)
  {
    // Install emulator
    gameClient = InstallGameClient(installable);
  }
  else if (result == iAddonMgr)
  {
    // Go to add-on manager to manage emulators
    ActivateAddonMgr();
  }
  else
  {
    CLog::Log(LOGDEBUG, "Select game client dialog: User cancelled game client selection");
  }

  return gameClient;
}
Example #2
0
void CGameUtils::GetGameClients(const ADDON::VECADDONS& addons, const CURL& translatedUrl, GameClientVector& candidates, bool& bHasVfsGameClient)
{
  bHasVfsGameClient = false;

  const std::string extension = URIUtils::GetExtension(translatedUrl.Get());

  const bool bIsLocalFile = (translatedUrl.GetProtocol() == "file" ||
                             translatedUrl.GetProtocol().empty());

  for (auto& addon : addons)
  {
    GameClientPtr gameClient = std::static_pointer_cast<CGameClient>(addon);

    // Filter by extension
    if (!gameClient->IsExtensionValid(extension))
      continue;

    // Filter by VFS
    if (!bIsLocalFile && !gameClient->SupportsVFS())
    {
      bHasVfsGameClient = true;
      continue;
    }

    candidates.push_back(gameClient);
  }
}
Example #3
0
void CGameUtils::GetGameClients(const CFileItem& file, GameClientVector& candidates, GameClientVector& installable, bool& bHasVfsGameClient)
{
  using namespace ADDON;

  bHasVfsGameClient = false;

  // Try to resolve path to a local file, as not all game clients support VFS
  CURL translatedUrl(CSpecialProtocol::TranslatePath(file.GetPath()));

  // Get local candidates
  VECADDONS localAddons;
  CBinaryAddonCache& addonCache = CServiceBroker::GetBinaryAddonCache();
  addonCache.GetAddons(localAddons, ADDON_GAMEDLL);

  bool bVfs = false;
  GetGameClients(localAddons, translatedUrl, candidates, bVfs);
  bHasVfsGameClient |= bVfs;

  // Get remote candidates
  VECADDONS remoteAddons;
  if (CServiceBroker::GetAddonMgr().GetInstallableAddons(remoteAddons, ADDON_GAMEDLL))
  {
    GetGameClients(remoteAddons, translatedUrl, installable, bVfs);
    bHasVfsGameClient |= bVfs;
  }

  // Sort by name
  //! @todo Move to presentation code
  auto SortByName = [](const GameClientPtr& lhs, const GameClientPtr& rhs)
  {
    std::string lhsName = lhs->Name();
    std::string rhsName = rhs->Name();

    StringUtils::ToLower(lhsName);
    StringUtils::ToLower(rhsName);

    return lhsName < rhsName;
  };

  std::sort(candidates.begin(), candidates.end(), SortByName);
  std::sort(installable.begin(), installable.end(), SortByName);
}
void CGUIDialogSelectGameClient::LogGameClients(const GameClientVector& candidates, const GameClientVector& installable)
{
  CLog::Log(LOGDEBUG, "Select game client dialog: Found %u candidates", static_cast<unsigned int>(candidates.size()));
  for (const auto& gameClient : candidates)
    CLog::Log(LOGDEBUG, "Adding %s as a candidate", gameClient->ID().c_str());

  if (!installable.empty())
  {
    CLog::Log(LOGDEBUG, "Select game client dialog: Found %u installable clients", static_cast<unsigned int>(installable.size()));
    for (const auto& gameClient : installable)
      CLog::Log(LOGDEBUG, "Adding %s as an installable client", gameClient->ID().c_str());
  }
}
Example #5
0
bool CGameUtils::FillInGameClient(CFileItem &item, bool bPrompt)
{
  using namespace ADDON;

  if (item.GetGameInfoTag()->GetGameClient().empty())
  {
    // If the fileitem is an add-on, fall back to that
    if (item.HasAddonInfo() && item.GetAddonInfo()->Type() == ADDON::ADDON_GAMEDLL)
    {
      item.GetGameInfoTag()->SetGameClient(item.GetAddonInfo()->ID());
    }
    else if (bPrompt)
    {
      // No game client specified, need to ask the user
      GameClientVector candidates;
      GameClientVector installable;
      bool bHasVfsGameClient;
      GetGameClients(item, candidates, installable, bHasVfsGameClient);

      if (candidates.empty() && installable.empty())
      {
        int errorTextId = bHasVfsGameClient ?
            35214 : // "This game can only be played directly from a hard drive or partition. Compressed files must be extracted."
            35212;  // "This game isn't compatible with any available emulators."

        // "Failed to play game"
        KODI::MESSAGING::HELPERS::ShowOKDialogText(CVariant{ 35210 }, CVariant{ errorTextId });
      }
      else if (candidates.size() == 1 && installable.empty())
      {
        // Only 1 option, avoid prompting the user
        item.GetGameInfoTag()->SetGameClient(candidates[0]->ID());
      }
      else
      {
        std::string gameClient = CGUIDialogSelectGameClient::ShowAndGetGameClient(item.GetPath(), candidates, installable);
        if (!gameClient.empty())
          item.GetGameInfoTag()->SetGameClient(gameClient);
      }
    }
  }

  return !item.GetGameInfoTag()->GetGameClient().empty();
}
std::string CGUIDialogSelectGameClient::InstallGameClient(const GameClientVector& installable)
{
  using namespace ADDON;

  std::string gameClient;

  //! @todo Switch to add-on browser when more emulators have icons
  /*
  std::string chosenClientId;
  if (CGUIWindowAddonBrowser::SelectAddonID(ADDON_GAMEDLL, chosenClientId, false, true, false, true, false) >= 0 && !chosenClientId.empty())
  {
    CLog::Log(LOGDEBUG, "Select game client dialog: User installed %s", chosenClientId.c_str());
    AddonPtr addon;
    if (CAddonMgr::GetInstance().GetAddon(chosenClientId, addon, ADDON_GAMEDLL))
      gameClient = addon->ID();

    if (gameClient.empty())
      CLog::Log(LOGERROR, "Select game client dialog: Failed to get addon %s", chosenClientId.c_str());
  }
  */

  CContextButtons choiceButtons;

  // Add emulators
  int i = 0;
  for (const GameClientPtr& gameClient : installable)
    choiceButtons.Add(i++, gameClient->Name());

  // Add button to browser all emulators
  const int iAddonBrowser = i++;
  choiceButtons.Add(iAddonBrowser, 35255); // "Browse all emulators"

  // Do modal
  int result = CGUIDialogContextMenu::ShowAndGetChoice(choiceButtons);

  if (0 <= result && result < static_cast<int>(installable.size()))
  {
    std::string gameClientId = installable[result]->ID();
    CLog::Log(LOGDEBUG, "Select game client dialog: Installing %s", gameClientId.c_str());
    AddonPtr installedAddon;
    if (CAddonInstaller::GetInstance().InstallModal(gameClientId, installedAddon, false))
    {
      CLog::Log(LOGDEBUG, "Select game client dialog: Successfully installed %s", installedAddon->ID().c_str());

      // if the addon is disabled we need to enable it
      if (CAddonMgr::GetInstance().IsAddonDisabled(installedAddon->ID()))
        CAddonMgr::GetInstance().EnableAddon(installedAddon->ID());

      gameClient = installedAddon->ID();
    }
    else
    {
      CLog::Log(LOGERROR, "Select game client dialog: Failed to install %s", gameClientId.c_str());
      // "Error"
      // "Failed to install add-on."
      HELPERS::ShowOKDialogText(257, 35256);
    }
  }
  else if (result == iAddonBrowser)
  {
    ActivateAddonBrowser();
  }
  else
  {
    CLog::Log(LOGDEBUG, "Select game client dialog: User cancelled game client installation");
  }

  return gameClient;
}