From 2cc7ee95e96d61988d72c0ed709dd73cbf1219b3 Mon Sep 17 00:00:00 2001 From: Oymate Date: Sat, 2 May 2020 15:07:01 +0000 Subject: [PATCH 01/11] Added translation using Weblate (Bengali (Bangladesh)) --- po/LINGUAS | 1 + po/bn_BD.po | 1797 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1798 insertions(+) create mode 100644 po/bn_BD.po diff --git a/po/LINGUAS b/po/LINGUAS index 41bc1cd4..f8fd6bd2 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -22,3 +22,4 @@ zh_CN zh_HK zh_TW mr +bn_BD diff --git a/po/bn_BD.po b/po/bn_BD.po new file mode 100644 index 00000000..63dff782 --- /dev/null +++ b/po/bn_BD.po @@ -0,0 +1,1797 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Oymate , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: bn_BD\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" From b5d66dccbc21ba9726ca0a43e29164f6d628317a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sat, 2 May 2020 21:02:16 +0000 Subject: [PATCH 02/11] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.4% (363 of 365 strings) Translation: GameHub/Translations Translate-URL: https://hosted.weblate.org/projects/gamehub/translations/nb_NO/ --- po/nb_NO.po | 75 ++++++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/po/nb_NO.po b/po/nb_NO.po index c099b7b1..36fe5f37 100644 --- a/po/nb_NO.po +++ b/po/nb_NO.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-01-26 06:40+0300\n" -"PO-Revision-Date: 2020-02-01 07:50+0000\n" +"PO-Revision-Date: 2020-05-04 12:11+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.11-dev\n" +"X-Generator: Weblate 4.1-dev\n" #: src/app.vala:91 msgid "Show help" @@ -255,9 +255,9 @@ msgstr "" "Logg inn på din konto i Steamklienten og kom tilbake til GameHub" #: src/data/sources/gog/GOGGame.vala:983 -#, c-format, fuzzy +#, c-format msgid "DLC: %s" -msgstr "DLC: %s" +msgstr "Nedlastbart innhold: %s" #: src/data/sources/humble/HumbleGame.vala:343 #, c-format @@ -612,14 +612,12 @@ msgid "Icon style" msgstr "Ikonstil" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 -#, fuzzy msgid "Game card" -msgstr "Spillnavn" +msgstr "Spillkort" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 -#, fuzzy msgid "Show platform icons" -msgstr "Vis plattformsikoner i rutenettvisning" +msgstr "Vis plattformsikoner" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 msgctxt "grid_size" @@ -632,14 +630,12 @@ msgid "Presets" msgstr "Forhåndsinnstillinger" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 -#, fuzzy msgid "Games list: installed" -msgstr "Spilliste: Installert" +msgstr "Spill-liste: Installert" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 -#, fuzzy msgid "Games list: not installed" -msgstr "Spilliste: Ikke installert" +msgstr "Spill-liste: Ikke installert" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 @@ -665,14 +661,13 @@ msgid "Dim" msgstr "Demp" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 -#, fuzzy msgid "Grid options" -msgstr "Spillegenskaper:" +msgstr "Rutenettsegenskaper" #: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 #, fuzzy msgid "List options" -msgstr "Loggføringsvalg:" +msgstr "Listevalg" #: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 msgid "Behavior" @@ -794,7 +789,6 @@ msgid "Tweak launch options and apply them to games automatically" msgstr "Tilpass oppstartsvalg og utfør dem for spill automatisk" #: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 -#, fuzzy msgid "" "Tweaks are loaded from following directories in order\n" "Last tweak overrides previous tweaks with same identifiers" @@ -1146,14 +1140,12 @@ msgid "Icon URL" msgstr "Ikonnettadresse" #: src/ui/dialogs/GamePropertiesDialog.vala:173 -#, fuzzy msgid "Select working directory" -msgstr "Velg mappe" +msgstr "Velg arbeidsmappe" #: src/ui/dialogs/GamePropertiesDialog.vala:173 -#, fuzzy msgid "Working directory" -msgstr "Åpne mappe" +msgstr "Arbeidsmappe" #: src/ui/dialogs/GamePropertiesDialog.vala:214 msgid "Compatibility" @@ -1279,9 +1271,9 @@ msgid "Select directory to import" msgstr "Velg mappe å importere" #: src/ui/dialogs/GameTweaksDialog.vala:40 -#, fuzzy, c-format +#, c-format msgid "%s: Tweaks" -msgstr "%s: Overlag" +msgstr "%s: Tilpasninger" #: src/ui/views/WelcomeView.vala:52 msgid "No enabled game sources" @@ -1308,7 +1300,6 @@ msgid "Authentication required" msgstr "Identitetsbekreftelse kreves" #: src/ui/views/WelcomeView.vala:152 -#, fuzzy msgid "Authenticating…" msgstr "Identitetsbekrefter…" @@ -1375,16 +1366,16 @@ msgstr[0] "%u spill" msgstr[1] "%u spill" #: src/ui/views/GamesView/GamesView.vala:553 -#, fuzzy, c-format +#, c-format msgctxt "games_view_subtitle_filtered_games" msgid "%1$u / %2$s" -msgstr "(%1$s / %2$s)" +msgstr "%1$u / %2$s" #: src/ui/views/GamesView/GamesView.vala:557 -#, fuzzy, c-format +#, c-format msgctxt "games_view_subtitle" msgid "%1$s: %2$s" -msgstr "(%1$s / %2$s)" +msgstr "%1$s: %2$s" #: src/ui/views/GamesView/GamesView.vala:568 msgid "No user-added games" @@ -1620,9 +1611,9 @@ msgid "Languages" msgstr "Språk" #: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 -#, fuzzy, c-format +#, c-format msgid "%u DLCs cannot be installed" -msgstr "%s: Skadet installasjonskandidat" +msgstr "%u: Nedlastbart innhold kan ikke installeres" #: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 msgid "Category" @@ -1737,14 +1728,12 @@ msgid "Add tag" msgstr "Legg til etikett" #: src/ui/widgets/TweaksList.vala:86 -#, fuzzy msgid "No description" -msgstr "Beskrivelse" +msgstr "Ingen beskrivelse" #: src/ui/widgets/TweaksList.vala:124 -#, fuzzy msgid "Edit file" -msgstr "Velg fil" +msgstr "Rediger fil" #: src/utils/Utils.vala:456 src/utils/Utils.vala:464 #, c-format @@ -1759,10 +1748,10 @@ msgid "%dm" msgstr "%dm" #: src/utils/Utils.vala:464 -#, fuzzy, c-format +#, c-format msgctxt "time" msgid "%ds" -msgstr "%dt" +msgstr "%ds" #: src/settings/UI.vala:153 msgctxt "grid_size_preset" @@ -1820,28 +1809,26 @@ msgid "Download failed" msgstr "Nedlasting mislyktes" #: src/utils/downloader/Downloader.vala:208 -#, fuzzy, c-format +#, c-format msgctxt "dl_status" msgid "Downloading: %s" -msgstr "Laster ned" +msgstr "Laster ned: %s" #: src/utils/downloader/Downloader.vala:210 -#, fuzzy msgctxt "dl_status" msgid "Downloading" msgstr "Laster ned" #: src/utils/downloader/Downloader.vala:214 -#, fuzzy, c-format +#, c-format msgctxt "dl_status" msgid "Paused: %s" -msgstr "Pauset: %d%% (%s / %s)" +msgstr "Pauset: %s" #: src/utils/downloader/Downloader.vala:216 -#, fuzzy msgctxt "dl_status" msgid "Paused" -msgstr "Pause nedlasting" +msgstr "Pauset" #: src/utils/downloader/Downloader.vala:218 msgctxt "dl_status" @@ -1850,10 +1837,10 @@ msgstr "Nedlasting avbrutt" #. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed #: src/utils/downloader/Downloader.vala:262 -#, fuzzy, c-format +#, c-format msgctxt "dl_status" msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" -msgstr "Laster ned: %d%% (%s / %s) [%s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" #~ msgid "Disable esync" #~ msgstr "Skru av esync" From a5cc00cc57750f7063d004b92ef39d2bb5f5ddec Mon Sep 17 00:00:00 2001 From: Oymate Date: Sun, 3 May 2020 11:55:20 +0000 Subject: [PATCH 03/11] Translated using Weblate (Bengali (Bangladesh)) Currently translated at 3.2% (12 of 365 strings) Translation: GameHub/Translations Translate-URL: https://hosted.weblate.org/projects/gamehub/translations/bn_BD/ --- po/bn_BD.po | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/po/bn_BD.po b/po/bn_BD.po index 63dff782..dea14314 100644 --- a/po/bn_BD.po +++ b/po/bn_BD.po @@ -7,62 +7,65 @@ msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-01-26 06:40+0300\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2020-05-04 12:11+0000\n" +"Last-Translator: Oymate \n" +"Language-Team: Bengali (Bangladesh) \n" "Language: bn_BD\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.1-dev\n" #: src/app.vala:91 msgid "Show help" -msgstr "" +msgstr "সহায়তা দেখান" #: src/app.vala:92 msgid "Show application version and exit" -msgstr "" +msgstr "অ্যাপ্লিকেশন সংস্করণ দেখান এবং বের হন" #: src/app.vala:93 msgid "Restart with GDB debugger attached" -msgstr "" +msgstr "সংযুক্ত জিডিবি ডিবাগার যুক্ত করে পুনরায় চালু করুন" #: src/app.vala:94 msgid "Show full GDB backtrace" -msgstr "" +msgstr "সম্পূর্ণ জিডিবি ব্যাকট্রেস দেখান" #: src/app.vala:95 msgid "Treat fatal errors as criticals and crash application" msgstr "" +"ভয়ঙ্কর ত্রুটিগুলোকে মারাত্বক বলে বিবেচনা করুন এবং অ্যাপ্লিকেশন ক্র্যাশ করুন" #: src/app.vala:99 msgid "Show main window" -msgstr "" +msgstr "প্রধান উইন্ডোটি দেখান" #: src/app.vala:100 msgid "Show application settings dialog" -msgstr "" +msgstr "অ্যাপ্লিকেশন সেটিংস ডায়ালগ দেখান" #: src/app.vala:101 msgid "Show about dialog" -msgstr "" +msgstr "অ্যাপ্লিকেশন সম্পর্কে ডায়লগ দেখান" #: src/app.vala:102 msgid "Maximum number of background worker threads" -msgstr "" +msgstr "সর্বোচ্চ সংখ্যক ব্যাকগ্রাউন্ড কার্যকর থ্রেড" #: src/app.vala:106 msgid "Run game" -msgstr "" +msgstr "গেম চালান" #: src/app.vala:107 msgid "Show compatibility options dialog" -msgstr "" +msgstr "উপযুক্ততার অপশন ডায়ালগ দেখান" #: src/app.vala:108 msgid "Open game details" -msgstr "" +msgstr "গেমের বিস্তারিত খুলুন" #: src/app.vala:109 msgid "Open game properties" From b1f51fb10a68b124012a18b9fd6f2fc83bd87abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=D0=B8=D0=B9=20=D0=A1=D1=83?= =?UTF-8?q?=D0=B4=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Sun, 7 Jun 2020 14:09:54 +0000 Subject: [PATCH 04/11] Translated using Weblate (Russian) Currently translated at 100.0% (365 of 365 strings) Translation: GameHub/Translations Translate-URL: https://hosted.weblate.org/projects/gamehub/translations/ru/ --- po/ru.po | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/po/ru.po b/po/ru.po index ad18fe6b..5f9d4793 100644 --- a/po/ru.po +++ b/po/ru.po @@ -4,22 +4,23 @@ # Automatically generated, 2018. # Anatoliy Kashkin , 2018, 2019. # Artem , 2020. +# Артемий Судаков , 2020. msgid "" msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-01-26 06:40+0300\n" -"PO-Revision-Date: 2020-04-25 13:11+0000\n" -"Last-Translator: Artem \n" +"PO-Revision-Date: 2020-06-08 14:41+0000\n" +"Last-Translator: Артемий Судаков \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=" -"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.0.2-dev\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.1-dev\n" #: src/app.vala:91 msgid "Show help" @@ -258,7 +259,7 @@ msgstr "" #: src/data/sources/gog/GOGGame.vala:983 #, c-format msgid "DLC: %s" -msgstr "" +msgstr "DLC: %s" #: src/data/sources/humble/HumbleGame.vala:343 #, c-format From aac7b8fb70f51a3e6eb132ea9cf02f462243ad56 Mon Sep 17 00:00:00 2001 From: Alireza Jabbari Date: Thu, 11 Jun 2020 19:24:20 +0000 Subject: [PATCH 05/11] Translated using Weblate (Persian) Currently translated at 13.1% (48 of 365 strings) Translation: GameHub/Translations Translate-URL: https://hosted.weblate.org/projects/gamehub/translations/fa/ --- po/fa.po | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/po/fa.po b/po/fa.po index efe1f987..cab1bd79 100644 --- a/po/fa.po +++ b/po/fa.po @@ -2,13 +2,14 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the com.github.tkashkin.gamehub package. # Goudarz Jafari , 2019. +# Alireza Jabbari , 2020. msgid "" msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-01-26 06:40+0300\n" -"PO-Revision-Date: 2019-08-03 20:23+0000\n" -"Last-Translator: Goudarz Jafari \n" +"PO-Revision-Date: 2020-06-12 19:41+0000\n" +"Last-Translator: Alireza Jabbari \n" "Language-Team: Persian \n" "Language: fa\n" @@ -16,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 3.8-dev\n" +"X-Generator: Weblate 4.1-dev\n" #: src/app.vala:91 msgid "Show help" @@ -28,7 +29,7 @@ msgstr "نمایش نسخه برنامه و خروج" #: src/app.vala:93 msgid "Restart with GDB debugger attached" -msgstr "" +msgstr "ری‌استارت همراه با عیب یاب GDB" #: src/app.vala:94 msgid "Show full GDB backtrace" @@ -48,7 +49,7 @@ msgstr "" #: src/app.vala:101 msgid "Show about dialog" -msgstr "" +msgstr "نمایش درباره گفت‌وگو" #: src/app.vala:102 msgid "Maximum number of background worker threads" From 4446b93e32e291fa15a7f6c6775ec17e4148f4ad Mon Sep 17 00:00:00 2001 From: Adam Jordanek Date: Wed, 29 Apr 2020 19:47:10 +0200 Subject: [PATCH 06/11] Epic games support --- data/icons/icons.gresource.xml | 1 + data/icons/symbolic/sources/epicgames.svg | 30 +++ src/app.vala | 3 +- src/data/GameSource.vala | 1 + src/data/db/tables/Games.vala | 9 + src/data/db/tables/IGDBData.vala | 1 + src/data/db/tables/Tags.vala | 1 + src/data/sources/epicgames/EpicGames.vala | 157 ++++++++++++++++ src/data/sources/epicgames/EpicGamesGame.vala | 172 ++++++++++++++++++ .../sources/epicgames/LegendaryWrapper.vala | 119 ++++++++++++ src/meson.build | 5 + .../SettingsDialog/SettingsDialog.vala | 1 + .../pages/sources/EpicGames.vala | 52 ++++++ src/ui/views/WelcomeView.vala | 4 +- 14 files changed, 553 insertions(+), 3 deletions(-) create mode 100644 data/icons/symbolic/sources/epicgames.svg create mode 100644 src/data/sources/epicgames/EpicGames.vala create mode 100644 src/data/sources/epicgames/EpicGamesGame.vala create mode 100644 src/data/sources/epicgames/LegendaryWrapper.vala create mode 100644 src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala diff --git a/data/icons/icons.gresource.xml b/data/icons/icons.gresource.xml index bf13ca6a..334ba166 100644 --- a/data/icons/icons.gresource.xml +++ b/data/icons/icons.gresource.xml @@ -3,6 +3,7 @@ symbolic/sources/sources-all.svg symbolic/sources/steam.svg + symbolic/sources/epicgames.svg symbolic/sources/gog.svg symbolic/sources/humble.svg symbolic/sources/humble-trove.svg diff --git a/data/icons/symbolic/sources/epicgames.svg b/data/icons/symbolic/sources/epicgames.svg new file mode 100644 index 00000000..f618e2a2 --- /dev/null +++ b/data/icons/symbolic/sources/epicgames.svg @@ -0,0 +1,30 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/app.vala b/src/app.vala index 9bb6a90d..f9b67a06 100644 --- a/src/app.vala +++ b/src/app.vala @@ -23,6 +23,7 @@ using Gee; using GameHub.Data; using GameHub.Data.DB; using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.EpicGames; using GameHub.Data.Sources.GOG; using GameHub.Data.Sources.Humble; using GameHub.Data.Sources.Itch; @@ -141,7 +142,7 @@ namespace GameHub ImageCache.init(); Database.create(); - GameSources = { new Steam(), new GOG(), new Humble(), new Trove(), new Itch(), new User() }; + GameSources = { new Steam(), new EpicGames(), new GOG(), new Humble(), new Trove(), new Itch(), new User() }; Providers.ImageProviders = { new Providers.Images.Steam(), new Providers.Images.SteamGridDB(), new Providers.Images.JinxSGVI() }; Providers.DataProviders = { new Providers.Data.IGDB() }; diff --git a/src/data/GameSource.vala b/src/data/GameSource.vala index 25b51e4e..c50abf81 100644 --- a/src/data/GameSource.vala +++ b/src/data/GameSource.vala @@ -21,6 +21,7 @@ using Gee; using GameHub.Utils; using GameHub.Data.Sources.Steam; using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.EpicGames; namespace GameHub.Data { diff --git a/src/data/db/tables/Games.vala b/src/data/db/tables/Games.vala index c7fcbda5..9423f20d 100644 --- a/src/data/db/tables/Games.vala +++ b/src/data/db/tables/Games.vala @@ -22,6 +22,7 @@ using Sqlite; using GameHub.Utils; using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.EpicGames; using GameHub.Data.Sources.GOG; using GameHub.Data.Sources.Humble; using GameHub.Data.Sources.Itch; @@ -311,6 +312,10 @@ namespace GameHub.Data.DB.Tables { g = new SteamGame.from_db((Steam) s, st); } + else if(s is EpicGames) + { + g = new EpicGamesGame.from_db((EpicGames) s, st); + } else if(s is GOG) { g = new GOGGame.from_db((GOG) s, st); @@ -396,6 +401,10 @@ namespace GameHub.Data.DB.Tables { g = new SteamGame.from_db((Steam) s, st); } + else if(s is EpicGames) + { + g = new EpicGamesGame.from_db((EpicGames) s, st); + } else if(s is GOG) { g = new GOGGame.from_db((GOG) s, st); diff --git a/src/data/db/tables/IGDBData.vala b/src/data/db/tables/IGDBData.vala index 6c151437..bc53146e 100644 --- a/src/data/db/tables/IGDBData.vala +++ b/src/data/db/tables/IGDBData.vala @@ -24,6 +24,7 @@ using GameHub.Utils; using GameHub.Data.Sources.Steam; using GameHub.Data.Sources.GOG; using GameHub.Data.Sources.Humble; +using GameHub.Data.Sources.EpicGames; namespace GameHub.Data.DB.Tables { diff --git a/src/data/db/tables/Tags.vala b/src/data/db/tables/Tags.vala index dfcad4a0..5803e420 100644 --- a/src/data/db/tables/Tags.vala +++ b/src/data/db/tables/Tags.vala @@ -22,6 +22,7 @@ using Sqlite; using GameHub.Utils; using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.EpicGames; using GameHub.Data.Sources.GOG; using GameHub.Data.Sources.Humble; diff --git a/src/data/sources/epicgames/EpicGames.vala b/src/data/sources/epicgames/EpicGames.vala new file mode 100644 index 00000000..622b3fc8 --- /dev/null +++ b/src/data/sources/epicgames/EpicGames.vala @@ -0,0 +1,157 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin +Copyright (C) 2020 Adam Jordanek + +GameHub 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. + +GameHub is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Sources.EpicGames +{ + public class EpicGames: GameSource + { + public static EpicGames instance; + + public override string id { get { return "epicgames"; } } + public override string name { get { return "EpicGames"; } } + public override string icon { get { return "source-epicgames-symbolic"; } } + + private Regex regex = /\*\s*([^(]*)\s\(App\sname:\s([a-zA-Z0-9]+),\sversion:\s([^)]*)\)/; + + private bool enable = true; + public override bool enabled + { + get { return enable; } + set { enable = value; } + } + + + public LegendaryWrapper? legendary_wrapper { get; private set; } + + public string? user_id { get; protected set; } + public string? user_name { get; protected set; } + + public EpicGames() + { + instance = this; + legendary_wrapper = new LegendaryWrapper(); + } + + public override bool is_installed(bool refresh) + { + debug("[EpicGames] is_installed: NOT IMPLEMENTED"); + return true; + } + + public override async bool install() + { + debug("[EpicGames] install: NOT IMPLEMENTED"); + return true; + } + + public override async bool authenticate() + { + debug("[EpicGames] authenticate: NOT IMPLEMENTED"); + return true; + } + + public override bool is_authenticated() + { + debug("[EpicGames] is_authenticated: NOT IMPLEMENTED"); + return true; + } + + public override bool can_authenticate_automatically() + { + debug("[EpicGames] can_authenticate_automatically: NOT IMPLEMENTED"); + return true; + } + + public async bool refresh_token() + { + debug("[EpicGames] refresh_token: NOT IMPLEMENTED"); + return true; + } + + private ArrayList _games = new ArrayList(Game.is_equal); + + public override ArrayList games { get { return _games; } } + + public override async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null) + { + if(_games.size > 0) + { + return _games; + } + + debug("[EpicGames] Load games"); + + Utils.thread("EpicGamesLoading", () => { + _games.clear(); + + games_count = 0; + + var cached = Tables.Games.get_all(this); + if(cached.size > 0) + { + foreach(var g in cached) + { + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g)) + { + _games.add(g); + if(game_loaded != null) + { + game_loaded(g, true); + } + } + games_count++; + } + } + + if(cache_loaded != null) + { + cache_loaded(); + } + + var games = legendary_wrapper.getGames(); + foreach(var game in games) + { + var g = new EpicGamesGame(this, game.name, game.id); + bool is_new_game = !_games.contains(g); + if(is_new_game) { + g.save(); + if(game_loaded != null) + { + game_loaded(g, true); + } + _games.add(g); + games_count++; + } else { + var index = _games.index_of(g); + _games.get(index).update_status(); + } + } + Idle.add(load_games.callback); + }); + yield; + return _games; + } + + + } +} diff --git a/src/data/sources/epicgames/EpicGamesGame.vala b/src/data/sources/epicgames/EpicGamesGame.vala new file mode 100644 index 00000000..b204128b --- /dev/null +++ b/src/data/sources/epicgames/EpicGamesGame.vala @@ -0,0 +1,172 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin +Copyright (C) 2020 Adam Jordanek + +GameHub 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. + +GameHub is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +using GameHub.Utils.Downloader; + +namespace GameHub.Data.Sources.EpicGames +{ + public class EpicGamesGame: Game + { + public ArrayList? installers { get; protected set; default = new ArrayList(); } + + public EpicGamesGame(EpicGames src, string nameP, string idP) + { + source = src; + name = nameP; + id = idP; + icon = ""; + image = src.legendary_wrapper.get_image(id); + platforms.add(Platform.LINUX); + + install_dir = null; + executable_path = "$game_dir/start.sh"; + work_dir_path = "$game_dir"; + info_detailed = @"{}"; + + mount_overlays.begin(); + update_status(); + } + + public override void update_status() + { + var state = Game.State.UNINSTALLED; + if (((EpicGames)source).legendary_wrapper.is_installed(id)) { + state = Game.State.INSTALLED; + debug ("New installed game: \tname = %s\t", name); + } else { + + debug ("New not installed game: \tname = %s\t", name); + } + + if(state == Game.State.INSTALLED) + { + remove_tag(Tables.Tags.BUILTIN_UNINSTALLED); + add_tag(Tables.Tags.BUILTIN_INSTALLED); + } + else + { + add_tag(Tables.Tags.BUILTIN_UNINSTALLED); + remove_tag(Tables.Tags.BUILTIN_INSTALLED); + } + status = new Game.Status(state, this); + } + + public EpicGamesGame.from_db(EpicGames src, Sqlite.Statement s) + { + source = src; + id = Tables.Games.ID.get(s); + name = Tables.Games.NAME.get(s); + info = Tables.Games.INFO.get(s); + info_detailed = Tables.Games.INFO_DETAILED.get(s); + icon = Tables.Games.ICON.get(s); + image = src.legendary_wrapper.get_image(id);//Tables.Games.IMAGE.get(s); + install_dir = Tables.Games.INSTALL_PATH.get(s) != null ? FSUtils.file(Tables.Games.INSTALL_PATH.get(s)) : null; + executable_path = Tables.Games.EXECUTABLE.get(s); + work_dir_path = Tables.Games.WORK_DIR.get(s); + compat_tool = Tables.Games.COMPAT_TOOL.get(s); + compat_tool_settings = Tables.Games.COMPAT_TOOL_SETTINGS.get(s); + arguments = Tables.Games.ARGUMENTS.get(s); + last_launch = Tables.Games.LAST_LAUNCH.get_int64(s); + playtime_source = Tables.Games.PLAYTIME_SOURCE.get_int64(s); + playtime_tracked = Tables.Games.PLAYTIME_TRACKED.get_int64(s); + image_vertical = Tables.Games.IMAGE_VERTICAL.get(s); + + platforms.clear(); + var pls = Tables.Games.PLATFORMS.get(s).split(","); + foreach(var pl in pls) + { + foreach(var p in Platform.PLATFORMS) + { + if(pl == p.id()) + { + platforms.add(p); + break; + } + } + } + installers.add(new EpicGamesGame.EpicGamesInstaller(this, id)); + update_status(); + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + new GameHub.UI.Dialogs.InstallDialog(this, installers, install_mode, install.callback); + yield; + update_status(); + } + public override async void uninstall() + { + ((EpicGames)source).legendary_wrapper.uninstall(id); + update_status(); + } + + public override async void run() + { + ((EpicGames)source).legendary_wrapper.run(id); + + } + + public class EpicGamesInstaller: Runnable.Installer + { + public EpicGamesGame game; + public override string name { owned get { return "TEST"; } } + + public EpicGamesInstaller(EpicGamesGame game, string id) + { + this.game = game; + id = id; + platform = Platform.CURRENT; + } + + public override async void install(Runnable runnable, CompatTool? tool=null) + { + EpicGamesGame? game = null; + if(runnable is EpicGamesGame) + { + game = runnable as EpicGamesGame; + } + + EpicGames epic = (EpicGames)(game.source); + + Utils.thread("EpicGamesGame.Installer", () => { + game.status = new Game.Status(Game.State.DOWNLOADING, game, null); + + + epic.legendary_wrapper.install(game.id); + Idle.add(install.callback); + }); + yield; + + if(game != null) game.status = new Game.Status(Game.State.INSTALLED, game, null); + + runnable.update_status(); + + debug("install"); + } + } + } + + + + +} diff --git a/src/data/sources/epicgames/LegendaryWrapper.vala b/src/data/sources/epicgames/LegendaryWrapper.vala new file mode 100644 index 00000000..82db64c2 --- /dev/null +++ b/src/data/sources/epicgames/LegendaryWrapper.vala @@ -0,0 +1,119 @@ +using Gee; + +namespace GameHub.Data.Sources.EpicGames +{ + public struct LegendaryGame { + string name; + string id; + string version; + } + + public class LegendaryWrapper + { + private Regex regex = /\*\s*([^(]*)\s\(App\sname:\s([a-zA-Z0-9]+),\sversion:\s([^)]*)\)/; + + public LegendaryWrapper() + { + } + + public ArrayList getGames() { + var result = new ArrayList(); + + string? line = null; + MatchInfo info; + var output = new DataInputStream(new Subprocess.newv ({"legendary", "list-games"}, STDOUT_PIPE).get_stdout_pipe ()); + + while ((line = output.read_line()) != null) { + if (regex.match (line, 0, out info)) { + LegendaryGame? g = {info.fetch (1), info.fetch (2), info.fetch (3)}; + result.add(g); + } + } + return result; + } + + public string get_image(string id) + { + string res = ""; + var file = File.new_for_path(Environment.get_home_dir () + "/.config/legendary/metadata/"+id+".json"); + + if (file.query_exists ()) { + var dis = new DataInputStream (file.read ()); + string line; + + while ((line = dis.read_line (null)) != null) { + res += line; + } + var parser = new Json.Parser (); + parser.load_from_data (res); + var root_object = parser.get_root().get_object(); + + var metadata = root_object.get_object_member ("metadata"); + var keyImages = metadata.get_array_member ("keyImages"); + var img = keyImages.get_object_element (0).get_string_member ("url"); + return img; + } + return ""; + } + + public void install(string id) + { + // FIXME: It can be done much better + var process = new Subprocess.newv ({"legendary", "download", id}, STDOUT_PIPE | STDIN_PIPE); + var input = new DataOutputStream(process.get_stdin_pipe ()); + var output = new DataInputStream(process.get_stdout_pipe ()); + string? line = null; + input.put_string("y\n"); + while ((line = output.read_line()) != null) { + debug("[EpicGames] %s", line); + } + refresh_installed = true; + } + + public void uninstall(string id) + { + // FIXME: It can be done much better + var process = new Subprocess.newv ({"legendary", "uninstall", id}, STDOUT_PIPE | STDIN_PIPE); + var input = new DataOutputStream(process.get_stdin_pipe ()); + var output = new DataInputStream(process.get_stdout_pipe ()); + string? line = null; + input.put_string("y\n"); + while ((line = output.read_line()) != null) { + debug("[EpicGames] %s", line); + } + refresh_installed = true; + } + + public void run(string id) { + // FIXME: not good idea + new Subprocess.newv ({"legendary", "launch", id}, STDOUT_PIPE); + } + + private bool refresh_installed = true; + private ArrayList _installed = new ArrayList(); + + public bool is_installed(string id) + { + if(refresh_installed) { + build_installed_list(); + refresh_installed = false; + } + return _installed.contains(id); + } + + + private void build_installed_list() + { + var installed_output = new DataInputStream(new Subprocess.newv ({"legendary", "list-installed"}, STDOUT_PIPE).get_stdout_pipe ()); + _installed.clear(); + string? line = null; + MatchInfo info; + while ((line = installed_output.read_line()) != null) { + if (regex.match (line, 0, out info)) { + _installed.add(info.fetch(2)); + } + } + } + + } +} \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 2acdeac9..23bc6db2 100644 --- a/src/meson.build +++ b/src/meson.build @@ -45,6 +45,10 @@ sources = [ 'data/sources/steam/Steam.vala', 'data/sources/steam/SteamGame.vala', + 'data/sources/epicgames/EpicGames.vala', + 'data/sources/epicgames/EpicGamesGame.vala', + 'data/sources/epicgames/LegendaryWrapper.vala', + 'data/sources/gog/GOG.vala', 'data/sources/gog/GOGGame.vala', @@ -104,6 +108,7 @@ sources = [ 'ui/dialogs/SettingsDialog/pages/general/Collection.vala', 'ui/dialogs/SettingsDialog/pages/general/Tweaks.vala', 'ui/dialogs/SettingsDialog/pages/sources/Steam.vala', + 'ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala', 'ui/dialogs/SettingsDialog/pages/sources/GOG.vala', 'ui/dialogs/SettingsDialog/pages/sources/Humble.vala', 'ui/dialogs/SettingsDialog/pages/sources/Itch.vala', diff --git a/src/ui/dialogs/SettingsDialog/SettingsDialog.vala b/src/ui/dialogs/SettingsDialog/SettingsDialog.vala index 2c15973f..b71cf692 100644 --- a/src/ui/dialogs/SettingsDialog/SettingsDialog.vala +++ b/src/ui/dialogs/SettingsDialog/SettingsDialog.vala @@ -89,6 +89,7 @@ namespace GameHub.UI.Dialogs.SettingsDialog #endif add_page("sources/steam", new Pages.Sources.Steam(this)); + add_page("sources/epicgames", new Pages.Sources.EpicGames(this)); add_page("sources/gog", new Pages.Sources.GOG(this)); add_page("sources/humble", new Pages.Sources.Humble(this)); add_page("sources/itch", new Pages.Sources.Itch(this)); diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala new file mode 100644 index 00000000..d7539d66 --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala @@ -0,0 +1,52 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources +{ + public class EpicGames: SettingsDialogPage + { + public EpicGames(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: "EpicGames", + description: _("Disabled"), + icon_name: "source-epicgames-symbolic", + activatable: true + ); + status = description; + } + + construct + { + var paths = FSUtils.Paths.Settings.instance; + + update(); + } + + private void update() + { + } + + } +} diff --git a/src/ui/views/WelcomeView.vala b/src/ui/views/WelcomeView.vala index 1029a4ab..e1271bb6 100644 --- a/src/ui/views/WelcomeView.vala +++ b/src/ui/views/WelcomeView.vala @@ -96,6 +96,7 @@ namespace GameHub.UI.Views foreach(var src in GameSources) { + debug("[GS] %s", src.icon); welcome.append(src.icon, src.name, ""); } @@ -126,12 +127,11 @@ namespace GameHub.UI.Views var src = GameSources[index]; var btn = welcome.get_button_from_index(index); - welcome.set_item_visible(index, !(src is Sources.Humble.Trove) && !(src is Sources.User.User) && src.enabled); if(src is Sources.Humble.Trove || !src.enabled) continue; enabled_sources++; - + debug("[GS] %s %s", src.name, src.is_installed(true).to_string()); if(src.is_installed(true)) { btn.title = src.name; From 2812574ff6985527cc10fcea7e6ca78e7b4b5982 Mon Sep 17 00:00:00 2001 From: Marco Cimolai Date: Fri, 23 Oct 2020 15:41:30 +0200 Subject: [PATCH 07/11] Added EpicGames authentication and settings --- ...com.github.tkashkin.gamehub.gschema.xml.in | 19 ++++ src/data/sources/epicgames/EpicGames.vala | 30 +++--- .../sources/epicgames/LegendaryWrapper.vala | 97 +++++++++++++++++-- src/settings/Auth.vala | 25 +++++ .../pages/sources/EpicGames.vala | 45 +++++++++ src/ui/windows/WebAuthWindow.vala | 17 +++- src/utils/FSUtils.vala | 1 + 7 files changed, 215 insertions(+), 19 deletions(-) diff --git a/data/com.github.tkashkin.gamehub.gschema.xml.in b/data/com.github.tkashkin.gamehub.gschema.xml.in index 134b2287..b2bd9380 100644 --- a/data/com.github.tkashkin.gamehub.gschema.xml.in +++ b/data/com.github.tkashkin.gamehub.gschema.xml.in @@ -146,6 +146,21 @@ + + + true + Is EpicGames enabled + + + false + Is user authenticated + + + '' + EpicGames access sid + + + true @@ -221,6 +236,10 @@ '~/Games/itch' itch.io games directory + + 'legendary' + Legendary client command + diff --git a/src/data/sources/epicgames/EpicGames.vala b/src/data/sources/epicgames/EpicGames.vala index 622b3fc8..4fa2e8e3 100644 --- a/src/data/sources/epicgames/EpicGames.vala +++ b/src/data/sources/epicgames/EpicGames.vala @@ -31,7 +31,7 @@ namespace GameHub.Data.Sources.EpicGames public override string name { get { return "EpicGames"; } } public override string icon { get { return "source-epicgames-symbolic"; } } - private Regex regex = /\*\s*([^(]*)\s\(App\sname:\s([a-zA-Z0-9]+),\sversion:\s([^)]*)\)/; + private Settings.Auth.EpicGames settings; private bool enable = true; public override bool enabled @@ -50,6 +50,7 @@ namespace GameHub.Data.Sources.EpicGames { instance = this; legendary_wrapper = new LegendaryWrapper(); + settings = Settings.Auth.EpicGames.instance; } public override bool is_installed(bool refresh) @@ -66,26 +67,31 @@ namespace GameHub.Data.Sources.EpicGames public override async bool authenticate() { - debug("[EpicGames] authenticate: NOT IMPLEMENTED"); - return true; + debug("[EpicGames] Performing auth"); + var username = yield legendary_wrapper.auth(); + settings.authenticated = username != null; + if(username != null) { + user_name = username; + return true; + }else return false; } public override bool is_authenticated() { - debug("[EpicGames] is_authenticated: NOT IMPLEMENTED"); - return true; + var result = legendary_wrapper.is_authenticated(); + settings.authenticated = result; + + if (result) { + user_name = legendary_wrapper.get_username(); + } + + return result; } public override bool can_authenticate_automatically() { debug("[EpicGames] can_authenticate_automatically: NOT IMPLEMENTED"); - return true; - } - - public async bool refresh_token() - { - debug("[EpicGames] refresh_token: NOT IMPLEMENTED"); - return true; + return false; } private ArrayList _games = new ArrayList(Game.is_equal); diff --git a/src/data/sources/epicgames/LegendaryWrapper.vala b/src/data/sources/epicgames/LegendaryWrapper.vala index 82db64c2..51c32ff9 100644 --- a/src/data/sources/epicgames/LegendaryWrapper.vala +++ b/src/data/sources/epicgames/LegendaryWrapper.vala @@ -1,4 +1,5 @@ using Gee; +using GameHub.Utils; namespace GameHub.Data.Sources.EpicGames { @@ -10,7 +11,14 @@ namespace GameHub.Data.Sources.EpicGames public class LegendaryWrapper { - private Regex regex = /\*\s*([^(]*)\s\(App\sname:\s([a-zA-Z0-9]+),\sversion:\s([^)]*)\)/; + private Regex regex = /\s?\*\s?(.+)\(App\sname:\s([a-zA-Z0-9]+)\s.\s[Vv]ersion:\s([^)]*)\)/; + private Regex authValidationRegex = /credentials are still valid/; + private Regex authSuccessRegex = /Successfully logged in as "([^"]+)/; + private Regex sidExtractionRegex = /sid":"([^"]+)/; + private Regex fileUserRegex = /displayName":\s"([^"]+)/; + + private FSUtils.Paths.Settings paths = FSUtils.Paths.Settings.instance; + private Settings.Auth.EpicGames settings = Settings.Auth.EpicGames.instance; public LegendaryWrapper() { @@ -21,7 +29,7 @@ namespace GameHub.Data.Sources.EpicGames string? line = null; MatchInfo info; - var output = new DataInputStream(new Subprocess.newv ({"legendary", "list-games"}, STDOUT_PIPE).get_stdout_pipe ()); + var output = new DataInputStream(new Subprocess.newv ({paths.legendary_command, "list-games"}, STDOUT_PIPE).get_stdout_pipe ()); while ((line = output.read_line()) != null) { if (regex.match (line, 0, out info)) { @@ -59,7 +67,7 @@ namespace GameHub.Data.Sources.EpicGames public void install(string id) { // FIXME: It can be done much better - var process = new Subprocess.newv ({"legendary", "download", id}, STDOUT_PIPE | STDIN_PIPE); + var process = new Subprocess.newv ({paths.legendary_command, "download", id}, STDOUT_PIPE | STDIN_PIPE); var input = new DataOutputStream(process.get_stdin_pipe ()); var output = new DataInputStream(process.get_stdout_pipe ()); string? line = null; @@ -70,10 +78,87 @@ namespace GameHub.Data.Sources.EpicGames refresh_installed = true; } + public bool is_authenticated() { + var savedSid = settings.sid; + if (savedSid == "") savedSid = "test"; + debug("[LegendaryWrapper] Saved sid: %s", savedSid); + + string? output = null; + string? error = null; + new Subprocess.newv ({paths.legendary_command, "auth", "--sid", savedSid}, STDOUT_PIPE | STDERR_PIPE).communicate_utf8(null, null, out output, out error); + + if (output.contains("ERROR")) return false; + else if(output.contains("Stored credentials are still valid")) return true; + else if (error.contains("ERROR")) return false; + else if(error.contains("Stored credentials are still valid")) return true; + + return false; + } + + public string? get_username() { + File userfile = File.new_for_path(GLib.Environment.get_home_dir () + "/.config/legendary/user.json"); + if (userfile.query_exists ()) { + debug("[LegendaryWrapper] File user.json exists"); + var dis = new DataInputStream (userfile.read ()); + string line; + + MatchInfo match; + while ((line = dis.read_line (null)) != null) + if(fileUserRegex.match (line, 0, out match)) return match.fetch (1); + + return null; + }else return null; + } + + public async string? auth() + { + + if(is_authenticated()) { + var username = get_username(); + if (username != null) return username; + + } + + //Do auth process + string url = "https://www.epicgames.com/id/login?redirectUrl=https://www.epicgames.com/id/api/redirect"; + var wnd = new GameHub.UI.Windows.WebAuthWindow(EpicGames.instance.name, url, "https://www.epicgames.com/id/api/redirect"); + + + string? username = null; + wnd.pageLoaded.connect(page => { + MatchInfo info; + sidExtractionRegex.match(page, 0, out info); + var sid = info.fetch(1); + + //Legendary auth with sid + var output = new DataInputStream(new Subprocess.newv ({paths.legendary_command, "auth", "--sid", sid}, STDOUT_PIPE).get_stdout_pipe ()); + string? line = null; + while ((line = output.read_line()) != null) { + if(authSuccessRegex.match(line, 0, out info)) { + username = info.fetch(1); + settings.sid = sid; + debug("[EpicGames] Successfully logged in as %s", username); + + Idle.add(auth.callback); + break; + } + } + }); + + wnd.canceled.connect(() => Idle.add(auth.callback)); + + wnd.set_size_request(550, 680); + wnd.show_all(); + wnd.present(); + + yield; + return username; + } + public void uninstall(string id) { // FIXME: It can be done much better - var process = new Subprocess.newv ({"legendary", "uninstall", id}, STDOUT_PIPE | STDIN_PIPE); + var process = new Subprocess.newv ({paths.legendary_command, "uninstall", id}, STDOUT_PIPE | STDIN_PIPE); var input = new DataOutputStream(process.get_stdin_pipe ()); var output = new DataInputStream(process.get_stdout_pipe ()); string? line = null; @@ -86,7 +171,7 @@ namespace GameHub.Data.Sources.EpicGames public void run(string id) { // FIXME: not good idea - new Subprocess.newv ({"legendary", "launch", id}, STDOUT_PIPE); + new Subprocess.newv ({paths.legendary_command, "launch", id}, STDOUT_PIPE); } private bool refresh_installed = true; @@ -104,7 +189,7 @@ namespace GameHub.Data.Sources.EpicGames private void build_installed_list() { - var installed_output = new DataInputStream(new Subprocess.newv ({"legendary", "list-installed"}, STDOUT_PIPE).get_stdout_pipe ()); + var installed_output = new DataInputStream(new Subprocess.newv ({paths.legendary_command, "list-installed"}, STDOUT_PIPE).get_stdout_pipe ()); _installed.clear(); string? line = null; MatchInfo info; diff --git a/src/settings/Auth.vala b/src/settings/Auth.vala index fa0b91cf..3d2c7b76 100644 --- a/src/settings/Auth.vala +++ b/src/settings/Auth.vala @@ -56,6 +56,31 @@ namespace GameHub.Settings.Auth } } + public class EpicGames: SettingsSchema + { + public bool enabled { get; set; } + public bool authenticated { get; set; } + public string sid { get; set; } + + public EpicGames() + { + base(ProjectConfig.PROJECT_NAME + ".auth.epicgames"); + } + + private static EpicGames? _instance; + public static unowned EpicGames instance + { + get + { + if(_instance == null) + { + _instance = new EpicGames(); + } + return _instance; + } + } + } + public class GOG: SettingsSchema { public bool enabled { get; set; } diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala index d7539d66..0618faac 100644 --- a/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala +++ b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala @@ -20,11 +20,18 @@ using Gtk; using GameHub.Utils; using GameHub.UI.Widgets; +using GameHub.Data.Sources.EpicGames; namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources { public class EpicGames: SettingsDialogPage { + + private LegendaryWrapper? legendary_wrapper { get; private set; } + private Settings.Auth.EpicGames epicgames_auth; + + private Button logout_btn; + public EpicGames(SettingsDialog dlg) { Object( @@ -40,12 +47,50 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources construct { var paths = FSUtils.Paths.Settings.instance; + epicgames_auth = Settings.Auth.EpicGames.instance; + + status_switch.active = epicgames_auth.enabled; + status_switch.notify["active"].connect(() => { + epicgames_auth.enabled = status_switch.active; + request_restart(); + update(); + }); + + logout_btn = new Button.with_label(_("Logout")); + action_area.add(logout_btn); + + logout_btn.clicked.connect(() => { + epicgames_auth.authenticated = false; + epicgames_auth.sid = ""; + request_restart(); + update(); + }); + + add_entry("Legendary client command", paths.legendary_command, (command) => { + paths.legendary_command = command; + }); update(); } private void update() { + content_area.sensitive = epicgames_auth.enabled; + logout_btn.sensitive = epicgames_auth.authenticated; + + if(!epicgames_auth.enabled) + { + status = description = _("Disabled"); + } + else if(!epicgames_auth.authenticated) + { + status = description = _("Not authenticated"); + } + else + { + var user_name = GameHub.Data.Sources.EpicGames.EpicGames.instance.user_name; + status = description = user_name != null ? _("Authenticated as %s").printf(user_name) : _("Authenticated"); + } } } diff --git a/src/ui/windows/WebAuthWindow.vala b/src/ui/windows/WebAuthWindow.vala index 9eec4673..1d024ee5 100644 --- a/src/ui/windows/WebAuthWindow.vala +++ b/src/ui/windows/WebAuthWindow.vala @@ -36,6 +36,7 @@ namespace GameHub.UI.Windows private bool is_finished = false; public signal void finished(string url); + public signal void pageLoaded(string page); public signal void canceled(); private const string GOG_CSS = "body { background-color: #d2d2d2 !important; } ._modal__box { box-shadow: none !important; vertical-align: top !important; margin-top: 0 !important; } ._modal__control, .form__buttons-container, .form__separator { display: none !important; }"; @@ -129,16 +130,30 @@ namespace GameHub.UI.Windows debug("[WebAuth/%s] Finished with result `%s`", source, token); } finished(token); - destroy(); + + //Execute javascript to extract page source + runJavascript.begin ("document.body.childNodes[0].textContent", (obj, res) => { + pageLoaded(runJavascript.end (res).get_js_value().to_string()); + destroy(); + }); } + + }); webview.load_uri(url); add(webview); + #endif destroy.connect(() => { if(!is_finished) canceled(); }); } + + private async WebKit.JavascriptResult runJavascript(string script) { + return yield webview.run_javascript(script); + } + + } } diff --git a/src/utils/FSUtils.vala b/src/utils/FSUtils.vala index c90b72da..250049df 100644 --- a/src/utils/FSUtils.vala +++ b/src/utils/FSUtils.vala @@ -41,6 +41,7 @@ namespace GameHub.Utils public string humble_games { get; set; } public string itch_home { get; set; } public string itch_games { get; set; } + public string legendary_command { get; set; } public Settings() { From cd8dffb8befc54da47810e1fa2a13e1719283409 Mon Sep 17 00:00:00 2001 From: Marco Cimolai Date: Fri, 23 Oct 2020 23:35:59 +0200 Subject: [PATCH 08/11] Support for epic games install --- src/data/Runnable.vala | 8 +-- src/data/sources/epicgames/EpicGames.vala | 19 ++++-- src/data/sources/epicgames/EpicGamesGame.vala | 44 +++++++++---- .../sources/epicgames/LegendaryWrapper.vala | 64 +++++++++++++++---- src/meson.build | 5 +- src/ui/dialogs/InstallDialog.vala | 12 +++- src/utils/downloader/EpicDownloader.vala | 49 ++++++++++++++ 7 files changed, 163 insertions(+), 38 deletions(-) create mode 100644 src/utils/downloader/EpicDownloader.vala diff --git a/src/data/Runnable.vala b/src/data/Runnable.vala index 20e3e694..cbaaa295 100644 --- a/src/data/Runnable.vala +++ b/src/data/Runnable.vala @@ -341,10 +341,10 @@ namespace GameHub.Data public abstract class Installer { - public string id { get; protected set; } - public Platform platform { get; protected set; default = Platform.CURRENT; } - public int64 full_size { get; protected set; default = 0; } - public string? version { get; protected set; } + public string id { get; protected set; } + public Platform platform { get; protected set; default = Platform.CURRENT; } + public virtual int64 full_size { get; protected set; default = 0; } + public string? version { get; protected set; } public virtual string name { owned get { return id; } } diff --git a/src/data/sources/epicgames/EpicGames.vala b/src/data/sources/epicgames/EpicGames.vala index 4fa2e8e3..3ac27a2e 100644 --- a/src/data/sources/epicgames/EpicGames.vala +++ b/src/data/sources/epicgames/EpicGames.vala @@ -33,11 +33,10 @@ namespace GameHub.Data.Sources.EpicGames private Settings.Auth.EpicGames settings; - private bool enable = true; public override bool enabled { - get { return enable; } - set { enable = value; } + get { return settings.enabled; } + set { settings.enabled = value; } } @@ -61,7 +60,6 @@ namespace GameHub.Data.Sources.EpicGames public override async bool install() { - debug("[EpicGames] install: NOT IMPLEMENTED"); return true; } @@ -82,7 +80,9 @@ namespace GameHub.Data.Sources.EpicGames settings.authenticated = result; if (result) { - user_name = legendary_wrapper.get_username(); + legendary_wrapper.get_username.begin ((obj, res) => { + user_name = legendary_wrapper.get_username.end (res); + }); } return result; @@ -139,6 +139,15 @@ namespace GameHub.Data.Sources.EpicGames { var g = new EpicGamesGame(this, game.name, game.id); bool is_new_game = !_games.contains(g); + if(is_new_game && (!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g))) + { + _games.add(g); + if(game_loaded != null) + { + game_loaded(g, false); + } + } + if(is_new_game) { g.save(); if(game_loaded != null) diff --git a/src/data/sources/epicgames/EpicGamesGame.vala b/src/data/sources/epicgames/EpicGamesGame.vala index b204128b..cfcff3f6 100644 --- a/src/data/sources/epicgames/EpicGamesGame.vala +++ b/src/data/sources/epicgames/EpicGamesGame.vala @@ -52,10 +52,9 @@ namespace GameHub.Data.Sources.EpicGames var state = Game.State.UNINSTALLED; if (((EpicGames)source).legendary_wrapper.is_installed(id)) { state = Game.State.INSTALLED; - debug ("New installed game: \tname = %s\t", name); + //debug ("New installed game: \tname = %s\t", name); } else { - - debug ("New not installed game: \tname = %s\t", name); + //debug ("New not installed game: \tname = %s\t", name); } if(state == Game.State.INSTALLED) @@ -129,39 +128,60 @@ namespace GameHub.Data.Sources.EpicGames public class EpicGamesInstaller: Runnable.Installer { public EpicGamesGame game; - public override string name { owned get { return "TEST"; } } + private EpicGames epic; + public override string name { owned get { return game.name; } } + + private int64 _full_size = 0; + public override int64 full_size { + get { + if(_full_size != 0) return _full_size; + else { + var size = epic.legendary_wrapper.get_install_size (game.id); + _full_size = size; + return _full_size; + } + + } + set {} + } public EpicGamesInstaller(EpicGamesGame game, string id) { this.game = game; id = id; platform = Platform.CURRENT; + epic = (EpicGames)(game.source); } public override async void install(Runnable runnable, CompatTool? tool=null) { + EpicGamesGame? game = null; if(runnable is EpicGamesGame) { game = runnable as EpicGamesGame; } - EpicGames epic = (EpicGames)(game.source); - Utils.thread("EpicGamesGame.Installer", () => { - game.status = new Game.Status(Game.State.DOWNLOADING, game, null); + EpicDownload ed = new EpicDownload(game.id); + game.status = new Game.Status(Game.State.DOWNLOADING, game, ed); + + ed.cancelled.connect(() => { + epic.legendary_wrapper.cancel_installation(); + }); + + epic.legendary_wrapper.install(game.id, null, progress => { + ed.status = new EpicDownload.EpicStatus(progress / 100); + game.status = new Game.Status(Game.State.DOWNLOADING, game, ed); + }); - epic.legendary_wrapper.install(game.id); Idle.add(install.callback); }); yield; if(game != null) game.status = new Game.Status(Game.State.INSTALLED, game, null); - - runnable.update_status(); - - debug("install"); + game.update_status(); } } } diff --git a/src/data/sources/epicgames/LegendaryWrapper.vala b/src/data/sources/epicgames/LegendaryWrapper.vala index 51c32ff9..b774055d 100644 --- a/src/data/sources/epicgames/LegendaryWrapper.vala +++ b/src/data/sources/epicgames/LegendaryWrapper.vala @@ -16,10 +16,14 @@ namespace GameHub.Data.Sources.EpicGames private Regex authSuccessRegex = /Successfully logged in as "([^"]+)/; private Regex sidExtractionRegex = /sid":"([^"]+)/; private Regex fileUserRegex = /displayName":\s"([^"]+)/; + private Regex progressRegex = /Progress:\s([0-9\.]+)/; + private Regex installSizeRegex = /Install size:\s([0-9\.]+)/; private FSUtils.Paths.Settings paths = FSUtils.Paths.Settings.instance; private Settings.Auth.EpicGames settings = Settings.Auth.EpicGames.instance; + private Subprocess? downloadProcess = null; + public LegendaryWrapper() { } @@ -64,24 +68,62 @@ namespace GameHub.Data.Sources.EpicGames return ""; } - public void install(string id) + public void cancel_installation() { + if(downloadProcess != null) { + downloadProcess.send_signal (2); + } + } + + public int64 get_install_size(string id) { + var process = new Subprocess.newv ( + {paths.legendary_command, "download", id}, STDOUT_PIPE | STDERR_PIPE); + var output = new DataInputStream(process.get_stdout_pipe ()); + var errOutput = new DataInputStream(process.get_stderr_pipe ()); + + string line; + MatchInfo info; + while ((line = errOutput.read_line ()) != null) { + if(installSizeRegex.match (line, 0, out info)) { + int64 size = ((int64) double.parse (info.fetch (1))) * 1000000; + process.send_signal (2); + return size; + } + } + + process.send_signal (2); + return 0; + } + + public void install(string id, string? game_folder = null, Utils.FutureResult? progress=null) { // FIXME: It can be done much better - var process = new Subprocess.newv ({paths.legendary_command, "download", id}, STDOUT_PIPE | STDIN_PIPE); - var input = new DataOutputStream(process.get_stdin_pipe ()); - var output = new DataInputStream(process.get_stdout_pipe ()); + string[] command = {paths.legendary_command, "install", id}; + if (game_folder != null) { + command = {paths.legendary_command, "install", id, "--game-folder", "game_folder"}; + } + + downloadProcess = new Subprocess.newv (command, STDOUT_PIPE | STDIN_PIPE | STDERR_PIPE); + + var input = new DataOutputStream(downloadProcess.get_stdin_pipe ()); + var output = new DataInputStream(downloadProcess.get_stdout_pipe ()); + var outputError = new DataInputStream(downloadProcess.get_stderr_pipe ()); + string? line = null; input.put_string("y\n"); - while ((line = output.read_line()) != null) { - debug("[EpicGames] %s", line); + + MatchInfo info; + while ((line = outputError.read_line()) != null) { + if(progressRegex.match (line, 0, out info)) { + progress(double.parse (info.fetch(1))); + } } + refresh_installed = true; } public bool is_authenticated() { var savedSid = settings.sid; if (savedSid == "") savedSid = "test"; - debug("[LegendaryWrapper] Saved sid: %s", savedSid); string? output = null; string? error = null; @@ -95,10 +137,9 @@ namespace GameHub.Data.Sources.EpicGames return false; } - public string? get_username() { + public async string? get_username() { File userfile = File.new_for_path(GLib.Environment.get_home_dir () + "/.config/legendary/user.json"); if (userfile.query_exists ()) { - debug("[LegendaryWrapper] File user.json exists"); var dis = new DataInputStream (userfile.read ()); string line; @@ -112,17 +153,14 @@ namespace GameHub.Data.Sources.EpicGames public async string? auth() { - if(is_authenticated()) { - var username = get_username(); + var username = yield get_username(); if (username != null) return username; - } //Do auth process string url = "https://www.epicgames.com/id/login?redirectUrl=https://www.epicgames.com/id/api/redirect"; var wnd = new GameHub.UI.Windows.WebAuthWindow(EpicGames.instance.name, url, "https://www.epicgames.com/id/api/redirect"); - string? username = null; wnd.pageLoaded.connect(page => { diff --git a/src/meson.build b/src/meson.build index 23bc6db2..e53e0f8b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -108,7 +108,7 @@ sources = [ 'ui/dialogs/SettingsDialog/pages/general/Collection.vala', 'ui/dialogs/SettingsDialog/pages/general/Tweaks.vala', 'ui/dialogs/SettingsDialog/pages/sources/Steam.vala', - 'ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala', + 'ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala', 'ui/dialogs/SettingsDialog/pages/sources/GOG.vala', 'ui/dialogs/SettingsDialog/pages/sources/Humble.vala', 'ui/dialogs/SettingsDialog/pages/sources/Itch.vala', @@ -191,7 +191,8 @@ sources = [ 'settings/Tweaks.vala', 'utils/downloader/Downloader.vala', - 'utils/downloader/SoupDownloader.vala' + 'utils/downloader/SoupDownloader.vala', + 'utils/downloader/EpicDownloader.vala' ] if get_option('os') == 'linux' diff --git a/src/ui/dialogs/InstallDialog.vala b/src/ui/dialogs/InstallDialog.vala index 03cc0f7a..f2835417 100644 --- a/src/ui/dialogs/InstallDialog.vala +++ b/src/ui/dialogs/InstallDialog.vala @@ -213,7 +213,11 @@ namespace GameHub.UI.Dialogs } else { - subtitle_label.label = _("Installer size: %s").printf(fsize(installers[0].full_size)); + subtitle_label.label = _("Installer size: calculating..."); + Utils.thread("CalculatingFileSize", () => { + subtitle_label.label = _("Installer size: %s").printf(fsize(installers[0].full_size)); + }); + } Revealer? compat_tool_revealer = new Revealer(); @@ -374,7 +378,11 @@ namespace GameHub.UI.Dialogs name.hexpand = true; name.halign = Align.START; - var size = new Label(fsize(installer.full_size)); + var size = new Label("calculating..."); + Utils.thread("CalculatingFileSize", () => { + size.label = fsize(installer.full_size); + }); + size.halign = Align.END; box.add(icon); diff --git a/src/utils/downloader/EpicDownloader.vala b/src/utils/downloader/EpicDownloader.vala new file mode 100644 index 00000000..a23a380b --- /dev/null +++ b/src/utils/downloader/EpicDownloader.vala @@ -0,0 +1,49 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin +Copyright (C) 2020 Adam Jordanek + +GameHub 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. + +GameHub is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GameHub. If not, see . +*/ + +using GLib; +using Gee; + +namespace GameHub.Utils.Downloader +{ + + public class EpicDownload : Download { + + public EpicDownload(string id) + { + base(id); + } + + public signal void cancelled(); + public override void cancel() { + cancelled(); + } + + public class EpicStatus : Download.Status { + private double _progress = -1; + public override double progress { get { return _progress; } } + + public EpicStatus(double progress) { + this._progress = progress; + } + + } + } + +} \ No newline at end of file From d8950ed44b5757a381026680cff4fff052a84677 Mon Sep 17 00:00:00 2001 From: Marco Cimolai Date: Sun, 25 Oct 2020 10:39:51 +0100 Subject: [PATCH 09/11] Fixes and new "game import" feature --- src/data/sources/epicgames/LegendaryWrapper.vala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/data/sources/epicgames/LegendaryWrapper.vala b/src/data/sources/epicgames/LegendaryWrapper.vala index b774055d..418f24be 100644 --- a/src/data/sources/epicgames/LegendaryWrapper.vala +++ b/src/data/sources/epicgames/LegendaryWrapper.vala @@ -96,10 +96,9 @@ namespace GameHub.Data.Sources.EpicGames public void install(string id, string? game_folder = null, Utils.FutureResult? progress=null) { - // FIXME: It can be done much better string[] command = {paths.legendary_command, "install", id}; if (game_folder != null) { - command = {paths.legendary_command, "install", id, "--game-folder", "game_folder"}; + command = {paths.legendary_command, "install", id, "--base-path", game_folder}; } downloadProcess = new Subprocess.newv (command, STDOUT_PIPE | STDIN_PIPE | STDERR_PIPE); @@ -207,6 +206,10 @@ namespace GameHub.Data.Sources.EpicGames refresh_installed = true; } + public void import_game(string id, string path) { + var process = new Subprocess.newv ({paths.legendary_command, "import-game", id, path}, STDOUT_PIPE); + } + public void run(string id) { // FIXME: not good idea new Subprocess.newv ({paths.legendary_command, "launch", id}, STDOUT_PIPE); From b0d9a82dc784cd6e9ef04ca3eeed02ddafa8da00 Mon Sep 17 00:00:00 2001 From: Marco Cimolai Date: Sun, 25 Oct 2020 10:40:51 +0100 Subject: [PATCH 10/11] New EpicGames default installation dir in settings --- ...com.github.tkashkin.gamehub.gschema.xml.in | 4 ++ src/data/sources/epicgames/EpicGamesGame.vala | 41 +++++++++++++++---- .../pages/sources/EpicGames.vala | 2 + src/utils/FSUtils.vala | 1 + 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/data/com.github.tkashkin.gamehub.gschema.xml.in b/data/com.github.tkashkin.gamehub.gschema.xml.in index b2bd9380..0a4b3ce2 100644 --- a/data/com.github.tkashkin.gamehub.gschema.xml.in +++ b/data/com.github.tkashkin.gamehub.gschema.xml.in @@ -240,6 +240,10 @@ 'legendary' Legendary client command + + '~/legendary' + EpicGames games directory + diff --git a/src/data/sources/epicgames/EpicGamesGame.vala b/src/data/sources/epicgames/EpicGamesGame.vala index cfcff3f6..7aaac468 100644 --- a/src/data/sources/epicgames/EpicGamesGame.vala +++ b/src/data/sources/epicgames/EpicGamesGame.vala @@ -16,6 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GameHub. If not, see . */ +using Gtk; using Gee; using GameHub.Data.DB; @@ -50,11 +51,11 @@ namespace GameHub.Data.Sources.EpicGames public override void update_status() { var state = Game.State.UNINSTALLED; - if (((EpicGames)source).legendary_wrapper.is_installed(id)) { + if (((EpicGames) source).legendary_wrapper.is_installed(id)) { state = Game.State.INSTALLED; - //debug ("New installed game: \tname = %s\t", name); + debug ("New installed game: \tname = %s\t", name); } else { - //debug ("New not installed game: \tname = %s\t", name); + debug ("New not installed game: \tname = %s\t", name); } if(state == Game.State.INSTALLED) @@ -115,18 +116,43 @@ namespace GameHub.Data.Sources.EpicGames } public override async void uninstall() { - ((EpicGames)source).legendary_wrapper.uninstall(id); + ((EpicGames) source).legendary_wrapper.uninstall(id); update_status(); } public override async void run() { - ((EpicGames)source).legendary_wrapper.run(id); + ((EpicGames) source).legendary_wrapper.run(id); } + public override void import(bool update=true) + { + var chooser = new FileChooserDialog(_("Select directory"), GameHub.UI.Windows.MainWindow.instance, FileChooserAction.SELECT_FOLDER); + + chooser.add_button(_("Cancel"), ResponseType.CANCEL); + var select_btn = chooser.add_button(_("Select"), ResponseType.ACCEPT); + + select_btn.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION); + select_btn.grab_default(); + + if(chooser.run() == ResponseType.ACCEPT) + { + install_dir = chooser.get_file(); + ((EpicGames) source).legendary_wrapper.import_game(id, install_dir.get_path()); + + if(update) { + update_status(); + save(); + } + } + + chooser.destroy(); + } + public class EpicGamesInstaller: Runnable.Installer { + private FSUtils.Paths.Settings paths = FSUtils.Paths.Settings.instance; public EpicGamesGame game; private EpicGames epic; public override string name { owned get { return game.name; } } @@ -170,8 +196,9 @@ namespace GameHub.Data.Sources.EpicGames ed.cancelled.connect(() => { epic.legendary_wrapper.cancel_installation(); }); - - epic.legendary_wrapper.install(game.id, null, progress => { + + var game_folder = (paths.epic_games == null || paths.epic_games == "") ? null : paths.epic_games; + epic.legendary_wrapper.install(game.id, game_folder, progress => { ed.status = new EpicDownload.EpicStatus(progress / 100); game.status = new Game.Status(Game.State.DOWNLOADING, game, ed); }); diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala index 0618faac..fe1a642d 100644 --- a/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala +++ b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala @@ -70,6 +70,8 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources paths.legendary_command = command; }); + var game_default_folder = (paths.epic_games == null || paths.epic_games == "") ? _("Default") : paths.epic_games; + add_file_chooser(_("Games directory"), FileChooserAction.SELECT_FOLDER, game_default_folder, v => { paths.epic_games = v; request_restart(); }, false); update(); } diff --git a/src/utils/FSUtils.vala b/src/utils/FSUtils.vala index 250049df..86057b6f 100644 --- a/src/utils/FSUtils.vala +++ b/src/utils/FSUtils.vala @@ -42,6 +42,7 @@ namespace GameHub.Utils public string itch_home { get; set; } public string itch_games { get; set; } public string legendary_command { get; set; } + public string epic_games { get; set; } public Settings() { From eb81ef4e6007be6afb40879ea408659ad85cc1dc Mon Sep 17 00:00:00 2001 From: Marco Cimolai Date: Sun, 25 Oct 2020 10:58:38 +0100 Subject: [PATCH 11/11] Running legendary check (implemented from jcnils/GameHub commit db87e36) --- src/data/sources/epicgames/EpicGames.vala | 31 +++++++++++++++++-- .../pages/sources/EpicGames.vala | 5 +++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/data/sources/epicgames/EpicGames.vala b/src/data/sources/epicgames/EpicGames.vala index 3ac27a2e..a011b1a1 100644 --- a/src/data/sources/epicgames/EpicGames.vala +++ b/src/data/sources/epicgames/EpicGames.vala @@ -26,12 +26,16 @@ namespace GameHub.Data.Sources.EpicGames public class EpicGames: GameSource { public static EpicGames instance; + + private bool? installed = null; + public File? legendary_executable = null; public override string id { get { return "epicgames"; } } public override string name { get { return "EpicGames"; } } public override string icon { get { return "source-epicgames-symbolic"; } } private Settings.Auth.EpicGames settings; + private FSUtils.Paths.Settings paths = FSUtils.Paths.Settings.instance; public override bool enabled { @@ -54,8 +58,31 @@ namespace GameHub.Data.Sources.EpicGames public override bool is_installed(bool refresh) { - debug("[EpicGames] is_installed: NOT IMPLEMENTED"); - return true; + /* + Epic games depends on + */ + if(installed != null && !refresh) + { + return (!) installed; + } + + //check if legendary exists + var legendary = Utils.find_executable(paths.legendary_command); + + if(legendary == null || !legendary.query_exists()) + { + debug("[EpicGames] is_installed: Legendary not found"); + + } + else + { + debug("[EpicGames] is_installed: LegendaryYES"); + } + + legendary_executable = legendary; + installed = legendary_executable != null && legendary_executable.query_exists(); + + return (!) installed; } public override async bool install() diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala index fe1a642d..980baf5f 100644 --- a/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala +++ b/src/ui/dialogs/SettingsDialog/pages/sources/EpicGames.vala @@ -29,6 +29,7 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources private LegendaryWrapper? legendary_wrapper { get; private set; } private Settings.Auth.EpicGames epicgames_auth; + private GameHub.Data.Sources.EpicGames.EpicGames epic = GameHub.Data.Sources.EpicGames.EpicGames.instance; private Button logout_btn; @@ -84,6 +85,10 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources { status = description = _("Disabled"); } + else if(!epic.is_installed()) + { + status = description = _("Missing Legendary"); + } else if(!epicgames_auth.authenticated) { status = description = _("Not authenticated");