diff --git a/.github/workflows/gen_emu_config_old-build-linux.yml b/.github/workflows/gen_emu_config_old-build-linux.yml new file mode 100644 index 0000000..d30b3a6 --- /dev/null +++ b/.github/workflows/gen_emu_config_old-build-linux.yml @@ -0,0 +1,52 @@ +name: "Build gen_emu_config_old script (Linux)" + +on: + workflow_call: + # needed since it allows this to become a reusable workflow + workflow_dispatch: + # allows manual trigger + +permissions: + contents: "write" + +env: + ARTIFACT_NAME: "gen_emu_config_old-linux-${{ github.sha }}" + SCRIPT_BASE_DIR: "generate_emu_config_old" + PACKAGE_BASE_DIR: "generate_emu_config_old/bin/linux" + +jobs: + build: + runs-on: "ubuntu-20.04" + + steps: + - name: "Checkout branch" + uses: actions/checkout@v4 + + # env + - name: "Install env" + shell: "bash" + working-directory: "${{ env.SCRIPT_BASE_DIR }}" + run: sudo chmod 777 recreate_venv_linux.sh && sudo ./recreate_venv_linux.sh + + # fix folder permissions! not sure why this fails + # nested subdirs "build/linux/release" cause permission problems + - name: "Give all permissions to repo folder" + shell: "bash" + working-directory: "${{ github.workspace }}" + run: sudo chmod -R 777 "${{ github.workspace }}" + + # build + - name: "Rebuild" + shell: "bash" + working-directory: "${{ env.SCRIPT_BASE_DIR }}" + run: sudo chmod 777 rebuild_linux.sh && ./rebuild_linux.sh + + # upload artifact + - name: "Upload build package" + uses: actions/upload-artifact@v4 + with: + name: "${{ env.ARTIFACT_NAME }}" + path: "${{ env.PACKAGE_BASE_DIR }}/" + if-no-files-found: "error" + compression-level: 9 + retention-days: 1 diff --git a/.github/workflows/gen_emu_config_old-build-win.yml b/.github/workflows/gen_emu_config_old-build-win.yml new file mode 100644 index 0000000..81dc9b7 --- /dev/null +++ b/.github/workflows/gen_emu_config_old-build-win.yml @@ -0,0 +1,61 @@ +name: "Build gen_emu_config_old script (Windows)" + +on: + workflow_call: + # needed since it allows this to become a reusable workflow + workflow_dispatch: + # allows manual trigger + +permissions: + contents: "write" + +env: + ARTIFACT_NAME: "gen_emu_config_old-win-${{ github.sha }}" + SCRIPT_BASE_DIR: "generate_emu_config_old" + PACKAGE_BASE_DIR: "generate_emu_config_old/bin/win" + + THIRD_PARTY_BASE_DIR: "third-party" + +jobs: + build: + runs-on: "windows-2022" + + steps: + - name: "Set up Python" + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + ### on Windows Git will auto change line ending to CRLF, not preferable + - name: "Ensure LF line ending" + shell: "cmd" + working-directory: "${{ github.workspace }}" + run: | + git config --local core.autocrlf false + git config --system core.autocrlf false + git config --global core.autocrlf false + + - name: "Checkout branch" + uses: actions/checkout@v4 + + # env + - name: "Install env" + shell: "cmd" + working-directory: "${{ env.SCRIPT_BASE_DIR }}" + run: recreate_venv_win.bat + + # build + - name: "Rebuild" + shell: "cmd" + working-directory: "${{ env.SCRIPT_BASE_DIR }}" + run: rebuild_win.bat + + # upload artifact + - name: "Upload build package" + uses: actions/upload-artifact@v4 + with: + name: "${{ env.ARTIFACT_NAME }}" + path: "${{ env.PACKAGE_BASE_DIR }}/" + if-no-files-found: "error" + compression-level: 9 + retention-days: 1 diff --git a/.github/workflows/gen_emu_config_old-pull-request.yml b/.github/workflows/gen_emu_config_old-pull-request.yml new file mode 100644 index 0000000..3a78d20 --- /dev/null +++ b/.github/workflows/gen_emu_config_old-pull-request.yml @@ -0,0 +1,22 @@ +name: "Gen emu cfg old PR" + +on: + pull_request: + branches: ["dev"] + paths: + - "!**/*.md" + - "generate_emu_config_old/**" + +permissions: + contents: "write" + +jobs: + script-win: + name: "Gen emu config win" + if: ${{ !cancelled() }} + uses: "./.github/workflows/gen_emu_config_old-build-win.yml" + + script-linux: + name: "Gen emu config linux" + if: ${{ !cancelled() }} + uses: "./.github/workflows/gen_emu_config_old-build-linux.yml" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9e9820 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# IDE +**/.vs +**/.vscode + +# PYTHON +**/.venv +**/__pycache__ + +# PROTOBUF +/proto_gen + +# SPECIFIC +/build +/third-party + +# TOOLS + +# generate_emu_config +/tools/generate_emu_config/.py*/ +/tools/generate_emu_config/.env*/ +/tools/generate_emu_config/bin + +/tools/generate_emu_config/backup/ +/tools/generate_emu_config/login_temp/ +/tools/generate_emu_config/output/ +/tools/generate_emu_config/**/my_login.txt +/tools/generate_emu_config/top_owners_ids.txt + +# migrate_gse +/tools/migrate_gse/.py*/ +/tools/migrate_gse/.env*/ +/tools/migrate_gse/bin diff --git a/generate_emu_config_old/README.md b/generate_emu_config_old/README.md new file mode 100644 index 0000000..569d595 --- /dev/null +++ b/generate_emu_config_old/README.md @@ -0,0 +1,64 @@ +## What is this ? +This is a command line tool to generate the `steam_settings` folder for the emu, +you need a Steam account to grab most info, but you can use an anonymous account with limited access to Steam data. + +
+ +## Usage +```bash +generate_emu_config [options] [app id 2] [app id 3] ... +``` + +--- + +### Available **\[options\]** +To get all available options, run the tool without any arguments. + +--- + +### Login: +You'll be asked each time to enter your username and password, but you can automate this prompt. + +* You can create a file called `my_login.txt` beside this tool with the following data: + - Your **username** on the **first** line + - Your **password** on the **second** line + + **But beware though of accidentally distributing your login data when using this file**. + --- +* You can define these environment variables, note that these environment variables will override the file `my_login.txt`: + - `GSE_CFG_USERNAME` + - `GSE_CFG_PASSWORD` + + When defining these environment variables in a script, take care of special characters. + + Example for Windows: + ```shell + set GSE_CFG_USERNAME=my_username + set GSE_CFG_PASSWORD=123 abc + generate_emu_config.exe 480 + ``` + + Example for Linux: + ```shell + export GSE_CFG_USERNAME=my_username + export GSE_CFG_PASSWORD=123 abc + ./generate_emu_config 480 + ``` + +--- + +### Downloading data for new apps/games and defining extra account IDs: +The script uses public Steam IDs (in Steam64 format) of apps/games owners in order to query the required info, such as achievement data. +By default, it has a built-in list of public users IDs, and you can extend this list by creating a file called `top_owners_ids.txt` beside the script, then add each new ID in Steam64 format on a separate line. + +When you login with a non-anonymous account, its ID will be added to the top of the list. + +
+ +--- + +## Attributions and credits + +* Windows icon by: [FroyoShark](https://www.iconarchive.com/artist/froyoshark.html) + license: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/) + Source: [icon archive: Steam Icon](https://www.iconarchive.com/show/enkel-icons-by-froyoshark/Steam-icon.html) diff --git a/generate_emu_config_old/backup/1599600/UserGameStatsSchema_1599600.bin b/generate_emu_config_old/backup/1599600/UserGameStatsSchema_1599600.bin new file mode 100644 index 0000000..6302e1f Binary files /dev/null and b/generate_emu_config_old/backup/1599600/UserGameStatsSchema_1599600.bin differ diff --git a/generate_emu_config_old/backup/1599600/dlc_product_info.json b/generate_emu_config_old/backup/1599600/dlc_product_info.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/generate_emu_config_old/backup/1599600/dlc_product_info.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/generate_emu_config_old/backup/1599600/product_info.json b/generate_emu_config_old/backup/1599600/product_info.json new file mode 100644 index 0000000..dd7284b --- /dev/null +++ b/generate_emu_config_old/backup/1599600/product_info.json @@ -0,0 +1,443 @@ +{ + "appid": "1599600", + "common": { + "name": "PlateUp!", + "type": "Game", + "oslist": "windows", + "osarch": "", + "osextended": "", + "logo": "26f97a270c9e4716a7b253984ca8669bba2f863a", + "logo_small": "26f97a270c9e4716a7b253984ca8669bba2f863a_thumb", + "icon": "8ab51cc26c5b54c8858bf95538d71f728b460611", + "clienticon": "6cc2e797ba3f4f212c5987c99ecf4ba283930798", + "clienttga": "5a587903a883ae347d9bbfd9472ebd799ef4763e", + "releasestate": "released", + "name_localized": { + "schinese": "速速上菜!", + "tchinese": "速速上菜!", + "koreana": "플레이트업!", + "japanese": "プレートアップ!" + }, + "languages": { + "english": "1", + "german": "1", + "french": "1", + "koreana": "1", + "spanish": "1", + "schinese": "1", + "tchinese": "1", + "russian": "1", + "japanese": "1", + "polish": "1", + "turkish": "1", + "brazilian": "1" + }, + "steam_deck_compatibility": { + "category": "3", + "test_timestamp": "1662681600", + "tested_build_id": "9455410", + "tests": { + "0": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_DefaultControllerConfigFullyFunctional" + }, + "1": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_ControllerGlyphsMatchDeckDevice" + }, + "2": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_InterfaceTextIsLegible" + }, + "3": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_DefaultConfigurationIsPerformant" + } + }, + "configuration": { + "supported_input": "gamepad", + "requires_manual_keyboard_invoke": "0", + "requires_non_controller_launcher_nav": "0", + "primary_player_is_controller_slot_0": "0", + "non_deck_display_glyphs": "0", + "small_text": "0", + "requires_internet_for_setup": "0", + "requires_internet_for_singleplayer": "0", + "recommended_runtime": "proton-stable", + "requires_h264": "0", + "gamescope_frame_limiter_not_supported": "0" + } + }, + "controller_support": "full", + "small_capsule": { + "english": "capsule_231x87.jpg", + "schinese": "capsule_231x87_schinese.jpg", + "tchinese": "capsule_231x87_tchinese.jpg", + "koreana": "capsule_231x87_koreana.jpg" + }, + "header_image": { + "english": "header.jpg", + "schinese": "header_schinese.jpg", + "tchinese": "header_tchinese.jpg", + "koreana": "header_koreana.jpg" + }, + "library_assets": { + "library_capsule": "en,zh-cn,zh-tw,ko", + "library_hero": "en", + "library_logo": "en,ko,zh-cn,zh-tw", + "logo_position": { + "pinned_position": "BottomLeft", + "width_pct": "73.61634980389326", + "height_pct": "100" + } + }, + "library_assets_full": { + "library_capsule": { + "image": { + "english": "library_600x900.jpg", + "schinese": "library_600x900_schinese.jpg", + "tchinese": "library_600x900_tchinese.jpg", + "koreana": "library_600x900_koreana.jpg" + }, + "image2x": { + "english": "library_600x900_2x.jpg", + "schinese": "library_600x900_schinese_2x.jpg", + "tchinese": "library_600x900_tchinese_2x.jpg", + "koreana": "library_600x900_koreana_2x.jpg" + } + }, + "library_hero": { + "image": { + "english": "library_hero.jpg" + }, + "image2x": { + "english": "library_hero_2x.jpg" + } + }, + "library_logo": { + "image": { + "english": "logo.png", + "koreana": "logo_koreana.png", + "schinese": "logo_schinese.png", + "tchinese": "logo_tchinese.png" + }, + "logo_position": { + "pinned_position": "BottomLeft", + "width_pct": "73.61634980389326", + "height_pct": "100" + }, + "image2x": { + "english": "logo_2x.png", + "koreana": "logo_koreana_2x.png", + "schinese": "logo_schinese_2x.png", + "tchinese": "logo_tchinese_2x.png" + } + } + }, + "store_asset_mtime": "1723038856", + "associations": { + "0": { + "type": "developer", + "name": "It's happening" + }, + "1": { + "type": "publisher", + "name": "Yogscast Games" + }, + "2": { + "type": "franchise", + "name": "Yogscast Games" + } + }, + "primary_genre": "23", + "genres": { + "0": "1", + "1": "4", + "2": "23", + "3": "2" + }, + "category": { + "category_2": "1", + "category_1": "1", + "category_9": "1", + "category_38": "1", + "category_39": "1", + "category_24": "1", + "category_44": "1", + "category_28": "1", + "category_33": "1", + "category_23": "1", + "category_43": "1", + "category_22": "1", + "category_45": "1", + "category_46": "1", + "category_30": "1", + "category_62": "1" + }, + "supported_languages": { + "english": { + "supported": "true" + }, + "french": { + "supported": "true" + }, + "german": { + "supported": "true" + }, + "spanish": { + "supported": "true" + }, + "japanese": { + "supported": "true" + }, + "polish": { + "supported": "true" + }, + "brazilian": { + "supported": "true" + }, + "russian": { + "supported": "true" + }, + "schinese": { + "supported": "true" + }, + "tchinese": { + "supported": "true" + }, + "koreana": { + "supported": "true" + }, + "turkish": { + "supported": "true" + } + }, + "steam_release_date": "1659621689", + "community_visible_stats": "1", + "workshop_visible": "1", + "community_hub_visible": "1", + "gameid": "1599600", + "store_tags": { + "0": "1685", + "1": "12472", + "2": "3920", + "3": "3959", + "4": "1643", + "5": "3841", + "6": "1716", + "7": "4726", + "8": "5125", + "9": "4136", + "10": "7332", + "11": "597", + "12": "4840", + "13": "7481", + "14": "3843", + "15": "9", + "16": "42804", + "17": "4791", + "18": "4182", + "19": "19" + }, + "review_score": "9", + "review_percentage": "95" + }, + "extended": { + "developer": "It's happening", + "publisher": "Yogscast Games", + "homepage": "https://www.plateupgame.com" + }, + "config": { + "installdir": "PlateUp", + "launch": { + "1": { + "executable": "PlateUp/PlateUp.exe", + "arguments": "-appid 1599600", + "description_loc": { + "english": "Launch" + }, + "description": "Launch" + } + }, + "uselaunchcommandline": "1" + }, + "depots": { + "baselanguages": "english", + "workshopdepot": "1599600", + "1599601": { + "config": { + "oslist": "windows" + }, + "manifests": { + "public": { + "gid": "3511304844048280730", + "size": "1394090112", + "download": "401764176" + }, + "crash-fix-test": { + "gid": "3754009520993631004", + "size": "1394071616", + "download": "401544576" + }, + "crossplaybeta": { + "gid": "6594253868093343203", + "size": "1397661267", + "download": "401897600" + } + }, + "encryptedmanifests": { + "ch_pr": { + "gid": "36D567E3C6EDBF76DAE9537825B2FDE5", + "size": "F2BA04F6CF9DBBF0787861494F533A6A", + "download": "4A1B08395CE0C1C1C422D56D7363EE4C" + }, + "chef": { + "gid": "FE64F23927880259A04CE8DB878D918A", + "size": "90B55476BAA2E495B2E587AF276718C5", + "download": "6B2E75D19C1D8663F0762C1F090E3DC1" + }, + "development": { + "gid": "CE4A112CAC82A33E53AA298F2C529D37", + "size": "EAF100AEF364DC5AFD7937F6EBF0673E", + "download": "4D9C0240869BF08DAB124AC4731A2ECC" + }, + "discordbetaaccess": { + "gid": "C0842BFE32F9F5C8CADD479E3B21E49E", + "size": "C346FF77F32785FDFAE4A835647F217F", + "download": "79018ADC6D516835369BE55B33D4CC8E" + }, + "japan": { + "gid": "817B69EE9BD3090BEA5F225BC6E05ED5", + "size": "4EC9FEDE0FFE8596F4476172A0EF69E6", + "download": "7DEC42894D7187042A87C966E83FD73B" + }, + "secret": { + "gid": "BEFDC25DD1BAB568E31EE4E264832F61", + "size": "C52474E52F801694CDB3725A0219C8A1", + "download": "CEEF42E455759C9D8D98807745A51DF8" + }, + "creator": { + "gid": "1466323502A7DB72D4021991A4A9CFA8", + "size": "FE31C5D5087E9A314C5B0A8558E66D3B", + "download": "16E7D860E992B1D95C8CEF867797E93E" + }, + "crossplaystaging": { + "gid": "B78FB53D3CB814D531A90BAD0E9EC1E3", + "size": "57CA11ABADFB2AE9184FD395FA1D221D", + "download": "00C6ED64019A1A53576C8C05E3979F87" + }, + "playtest": { + "gid": "C6E4EB704BBF7ECDBA8F8552F51B9D12", + "size": "6482BB9F09AF187DD335DBC5C963BA79", + "download": "68B689343F81AF7401CB2CF8B1A4DF27" + }, + "playtest2": { + "gid": "4522E87851833CEE8625443478AABE00", + "size": "C864E0496731294B4E07D6F9AABF7120", + "download": "18F24E98C694F5986E8226B08188FA83" + } + } + }, + "1599602": { + "config": { + "oslist": "windows" + } + }, + "branches": { + "public": { + "buildid": "15591994", + "timeupdated": "1725468206" + }, + "ch_pr": { + "buildid": "10759092", + "pwdrequired": "1", + "timeupdated": "1678805610" + }, + "chef": { + "buildid": "9251549", + "pwdrequired": "1", + "timeupdated": "1659606643" + }, + "development": { + "buildid": "13189763", + "pwdrequired": "1", + "timeupdated": "1705444518" + }, + "discordbetaaccess": { + "buildid": "9355221", + "pwdrequired": "1", + "timeupdated": "1661039040" + }, + "japan": { + "buildid": "11468716", + "pwdrequired": "1", + "timeupdated": "1686754875" + }, + "secret": { + "buildid": "12841040", + "pwdrequired": "1", + "timeupdated": "1701361864" + }, + "crash-fix-test": { + "buildid": "15335463", + "description": "Test for Environment crash", + "timeupdated": "1723404695" + }, + "creator": { + "buildid": "15548843", + "pwdrequired": "1", + "timeupdated": "1725050086" + }, + "crossplaybeta": { + "buildid": "15776693", + "description": "branch dedicated for crossplay", + "timeupdated": "1727881044" + }, + "crossplaystaging": { + "buildid": "15776693", + "pwdrequired": "1", + "timeupdated": "1726871838" + }, + "playtest": { + "buildid": "15591994", + "pwdrequired": "1", + "timeupdated": "1725464710" + }, + "playtest2": { + "buildid": "15776695", + "pwdrequired": "1", + "timeupdated": "1726871859" + } + } + }, + "ufs": { + "quota": "100000000", + "maxnumfiles": "1000", + "savefiles": { + "0": { + "root": "WinAppDataLocalLow", + "path": "It's Happening/PlateUp", + "pattern": "*.plateupsave", + "recursive": "1" + } + }, + "rootoverrides": { + "0": { + "root": "WinAppDataLocalLow", + "os": "Linux", + "oscompare": "=", + "useinstead": "LinuxHome", + "pathtransforms": { + "0": { + "find": "It's Happening/PlateUp", + "replace": ".config/unity3d/It's Happening/PlateUp" + } + } + } + } + }, + "_missing_token": false, + "_change_number": 25512918, + "_sha": "cdfcc36ba29461619a05c8bc44aa9fa0bf94c8f1", + "_size": 10292 +} \ No newline at end of file diff --git a/generate_emu_config_old/backup/238370/controller_mobile_touch2069657566/2069657566_controller_config.vdf b/generate_emu_config_old/backup/238370/controller_mobile_touch2069657566/2069657566_controller_config.vdf new file mode 100644 index 0000000..657fc2e --- /dev/null +++ b/generate_emu_config_old/backup/238370/controller_mobile_touch2069657566/2069657566_controller_config.vdf @@ -0,0 +1,615 @@ +"controller_mappings" +{ + "version" "3" + "revision" "9" + "title" "#Library_ControllerSaveDefaultTitle" + "description" "#Library_ControllerSaveDefaultDescription" + "creator" "76561197978266558" + "controller_type" "controller_mobile_touch" + "major_revision" "0" + "minor_revision" "0" + "Timestamp" "1587503775" + "touch_layout" "0afa0210012218080010011d0000703d255555d53d2d0000803f350000803f2218080110011d6666fe3e255555d53d2d0000803f350000803f2204080210002204080310002204080410002204080510002218080610011d92b7ca3d259468ac3e2dbc2c523f35bc2c523f2218080710011d10685f3f2597b55a3f2d41038c3f3541038c3f2218080810011d10686f3f25d0433e3f2d41038c3f3541038c3f2218080910011d10684f3f25d0433e3f2d41038c3f3541038c3f2218080a10011d10685f3f2509d2213f2d41038c3f3541038c3f2218080b10011d6666ce3e255555d53d2d0000803f350000803f2218080c10011d3333173f255555d53d2d0000803f350000803f2218080d10011dcfd6473f25743a153f2d0000803f350000803f2218080e10011dcfd6473f2530de643f2d0000803f350000803f2218080f10011d0000703d25985d633f2da6199d3f35a6199d3f2218081010011d5d4a763f25743a153f2d0000803f350000803f2204081c10002204081d10002a00" + "localization" + { + "english" + { + "title" "Gamepad" + "description" "This template is for games that already have built-in gamepad support. Intended for dual stick games such as twin-stick shooters, side-scrollers, etc." + } + "czech" + { + "title" "Gamepad" + "description" "Tato šablona je pro většinu her podporujících gamepad a byla navržena pro použití ve hrách využívajících dvě páčky, jakými jsou například plošinovky nebo automatové hry." + } + "danish" + { + "title" "Gamepad" + "description" "Denne skabelon er til spil, der allerede har indbygget gamepad-understøttelse. Beregnet til spil med dobbelte styrepinde såsom twin-stick shooters, side-scrollers osv." + } + "dutch" + { + "title" "Gamepad" + "description" "Deze template is voor spellen die al ingebouwde gamepadondersteuning hebben. Bedoeld voor dual-stick spellen zoals twin-stick-shooters, side-scrollers, etc." + } + "finnish" + { + "title" "Ohjain" + "description" "Tämä malli on muita ohjaimia valmiiksi tukeville peleille. Se on tarkoitettu kahta sauvaa käyttäville peleille, kuten twin-stick shooterit, side-scrollerit, jne." + } + "french" + { + "title" "Manette" + "description" "Ce modèle fonctionne pour les jeux conçus pour manettes à deux sticks tels que les jeux de type twin-stick shooter, à défilement horizontal (side-scrollers), etc." + } + "german" + { + "title" "Gamepad" + "description" "Diese Vorlage ist für Spiele konzipiert, die bereits volle Unterstützung für Gamepads mit sich bringen. Gedacht für Zwei-Analogstick-Spiele wie Twin-Stick-Shooter, Side-Scrollers usw." + } + "hungarian" + { + "title" "Gamepad" + "description" "Ez a sablon olyan játékokhoz való, melyek már rendelkeznek beépített gamepad-támogatással. Olyan két karos játékokhoz szánva, mint a kétkaros vagy oldalnézetes lövöldözős játékok stb." + } + "italian" + { + "title" "Controller" + "description" "Questo modello funziona per la maggior parte dei giochi che supportano i controller in modalità nativa." + } + "japanese" + { + "title" "ゲームパッド" + "description" "このテンプレートは、標準でゲームパッドをサポートしているツインスティックシューターや横スクロール等といったデュアルスティックゲームを対象としたゲーム向けです。" + } + "koreana" + { + "title" "게임패드" + "description" "게임 패드를 지원하도록 설계된 게임들을 위한 설정입니다. 이중 스틱 슈팅 게임, 사이드 스크롤 게임 등 스틱을 두 개 쓰는 게임을 염두에 두고 만들어졌습니다." + } + "polish" + { + "title" "Kontroler" + "description" "Ten szablon jest odpowiedni dla gier, które już mają wbudowane wsparcie dla kontrolerów. Przeznaczony dla gier obsługujących dwie gałki, m.in. twin-stick shootery, side-scrollery itp." + } + "portuguese" + { + "title" "Comando" + "description" "Este modelo é indicado para jogos que já têm compatibilidade nativa com comando. Foi concebido para jogos de tiros que usam dois sticks, jogos de plataformas, de naves, etc." + } + "romanian" + { + "title" "Gamepad" + "description" "Șablonul acesta este pentru jocurile care au deja suport pentru gamepad implementat. Destinat pentru jocuri dual stick, precum shooter-e twin-stick, side-scroller, etc." + } + "russian" + { + "title" "Геймпад" + "description" "Этот шаблон подходит для большинства игр с поддержкой геймпада — например, для шутеров с видом сверху или сбоку." + } + "spanish" + { + "title" "Mando" + "description" "Esta plantilla es para juegos que ya incluyen de serie compatibilidad con mando. Está destinada a juegos de doble stick como twin-stick shooters, side-scrollers, etc." + } + "swedish" + { + "title" "Gamepad" + "description" "Denna mall är för spel som redan har inbyggt stöd för spelkontroller. Avsett för spel som använder två styrspakar, som twin-stick shooters och side-scrollers, etc." + } + "schinese" + { + "title" "手柄" + "description" "该模板适用于已内置手柄支持的游戏。针对双摇杆游戏,如双摇杆射击游戏、横版过关游戏等设计。" + } + "thai" + { + "title" "เกมแพด" + } + "brazilian" + { + "title" "Controle padrão" + "description" "Este modelo é para jogos já compatíveis com controle que usam ambas as alavancas, como jogos de nave, etc." + } + "bulgarian" + { + "title" "Геймпад" + "description" "Този шаблон е за игри, които вече имат вградена поддръжка на геймпад. Предназначен e за игри ползващи двата стика. Като например, екшъни за два аналогови стика, странични скролери и т.н." + } + "greek" + { + "title" "Χειριστήριο" + "description" "Αυτό το πρότυπο ορίζεται για παιχνίδια τα οποία έχουν ήδη υποστήριξη χειριστηρίου. Προορίζεται για παιχνίδια dual-stick όπως twin-stick shooters, side-scrollers, κλπ." + } + "turkish" + { + "title" "Oyun Kumandası" + "description" "Bu şablon hali hazırda oyun içi oyun kumandası desteği ve birincil veya üçüncü kişi kontrollü kameraya sahip oyunlar içindir. Çift çubuk kullanılan oyunlar olan ikiz çubuk nişancılık, side-scroller oyunlar vb. içindir." + } + "ukrainian" + { + "title" "Ґеймпад" + "description" "Цей шаблон для більшості ігор, в яких вже вбудовано підтримку ґеймпада. Призначено для ігор з керуванням двома стіками." + } + } + "group" + { + "id" "0" + "mode" "four_buttons" + "inputs" + { + "button_a" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button A" + } + } + } + } + "button_b" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button B" + } + } + } + } + "button_x" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button X" + } + } + } + } + "button_y" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button Y" + } + } + } + } + } + } + "group" + { + "id" "1" + "mode" "dpad" + "inputs" + { + "dpad_north" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button dpad_up" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + "dpad_south" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button dpad_down" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + "dpad_east" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button dpad_right" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + "dpad_west" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button dpad_left" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + } + } + "group" + { + "id" "2" + "mode" "joystick_move" + "inputs" + { + "click" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button JOYSTICK_RIGHT" + } + "settings" + { + "haptic_intensity" "2" + } + } + } + } + } + } + "group" + { + "id" "3" + "mode" "joystick_move" + "inputs" + { + "click" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button JOYSTICK_LEFT" + } + "settings" + { + "haptic_intensity" "2" + } + } + } + } + } + } + "group" + { + "id" "4" + "mode" "trigger" + "inputs" + { + "click" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button TRIGGER_LEFT" + } + "settings" + { + "haptic_intensity" "2" + } + } + } + } + } + "settings" + { + "output_trigger" "1" + } + } + "group" + { + "id" "5" + "mode" "trigger" + "inputs" + { + "click" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button TRIGGER_RIGHT" + } + "settings" + { + "haptic_intensity" "2" + } + } + } + } + } + "settings" + { + "output_trigger" "2" + } + } + "group" + { + "id" "6" + "mode" "joystick_move" + "inputs" + { + "click" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button JOYSTICK_RIGHT" + } + "settings" + { + "haptic_intensity" "2" + } + } + } + } + } + } + "group" + { + "id" "8" + "mode" "joystick_move" + "inputs" + { + "click" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button JOYSTICK_RIGHT" + } + } + } + } + } + } + "group" + { + "id" "9" + "mode" "dpad" + "inputs" + { + "dpad_north" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button DPAD_UP" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + "dpad_south" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button DPAD_DOWN" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + "dpad_east" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button DPAD_RIGHT" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + "dpad_west" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button DPAD_LEFT" + } + "settings" + { + "haptic_intensity" "1" + } + } + } + } + } + "settings" + { + "requires_click" "0" + "haptic_intensity_override" "0" + } + } + "group" + { + "id" "7" + "mode" "switches" + "inputs" + { + "button_escape" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button start" + } + } + } + } + "button_menu" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button select" + } + } + } + } + "left_bumper" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button shoulder_left" + } + } + } + } + "right_bumper" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button shoulder_right" + } + } + } + } + "button_back_left" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button a" + } + } + } + } + "button_back_right" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "xinput_button x" + } + } + } + } + } + } + "preset" + { + "id" "0" + "name" "Default" + "group_source_bindings" + { + "7" "switch active" + "0" "button_diamond active" + "1" "left_trackpad inactive" + "2" "right_trackpad inactive" + "6" "right_trackpad inactive" + "3" "joystick active" + "4" "left_trigger active" + "5" "right_trigger active" + "8" "right_joystick active" + "9" "dpad active" + } + } + "settings" + { + "left_trackpad_mode" "0" + "right_trackpad_mode" "0" + } +} diff --git a/generate_emu_config_old/backup/238370/controller_mobile_touch2069657566/info.txt b/generate_emu_config_old/backup/238370/controller_mobile_touch2069657566/info.txt new file mode 100644 index 0000000..2506e30 --- /dev/null +++ b/generate_emu_config_old/backup/238370/controller_mobile_touch2069657566/info.txt @@ -0,0 +1,66 @@ +publishedfiledetails { + result: 1 + publishedfileid: 2069657566 + creator: 76561197978266558 + creator_appid: 241100 + consumer_appid: 241100 + consumer_shortcutid: 0 + filename: "2069657566_controller_config.vdf" + file_size: 13051 + preview_file_size: 0 + file_url: "https://steamusercontent-a.akamaihd.net/ugc/1013816293494657051/0CCBDCD4DFE1344CC76812A8A95B70F40BC4497D/" + preview_url: "" + url: "" + hcontent_file: 1013816293494657051 + hcontent_preview: 18446744073709551615 + title: "#Library_ControllerSaveDefaultTitle" + short_description: "#Library_ControllerSaveDefaultDescription" + time_created: 1587503775 + time_updated: 1587503775 + visibility: 0 + flags: 1536 + workshop_file: false + workshop_accepted: false + show_subscribe_all: false + num_comments_public: 0 + banned: false + ban_reason: "" + banner: 76561197960265728 + can_be_deleted: true + app_name: "Steam Input Configs" + file_type: 12 + can_subscribe: true + subscriptions: 41978 + favorited: 0 + followers: 0 + lifetime_subscriptions: 41978 + lifetime_favorited: 0 + lifetime_followers: 0 + views: 1 + num_children: 0 + num_reports: 0 + tags { + tag: "hasactivators" + display_name: "hasactivators" + } + tags { + tag: "splitconfig" + display_name: "splitconfig" + } + tags { + tag: "feature_gamepad" + display_name: "feature_gamepad" + } + tags { + tag: "controller_mobile_touch" + display_name: "controller_mobile_touch" + } + language: 0 + lifetime_playtime: 10836716 + lifetime_playtime_sessions: 4767 + maybe_inappropriate_sex: false + maybe_inappropriate_violence: false + revision_change_number: 1 + revision: k_EPublishedFileRevision_Latest + ban_text_check_result: k_EBanContentCheckResult_NotScanned +} diff --git a/generate_emu_config_old/backup/238370/controller_steamcontroller_gordon-551563382/controller_config_238370_#library_controllersavedefaulttitle.vdf b/generate_emu_config_old/backup/238370/controller_steamcontroller_gordon-551563382/controller_config_238370_#library_controllersavedefaulttitle.vdf new file mode 100644 index 0000000..19ba9f6 --- /dev/null +++ b/generate_emu_config_old/backup/238370/controller_steamcontroller_gordon-551563382/controller_config_238370_#library_controllersavedefaulttitle.vdf @@ -0,0 +1,561 @@ +"controller_mappings" +{ + "version" "2" + "title" "#Library_ControllerSaveDefaultTitle" + "description" "#Library_ControllerSaveDefaultDescription" + "creator" "76561197995653544" + "actions" + { + "Menu" + { + "title" "#Set_Menu" + "StickPadGyro" + { + "Move" + { + "title" "#Menu_Move" + "input_mode" "joystick_move" + } + } + "Button" + { + "confirm" "#Menu_Confirm" + "Back" "#Menu_Back" + "sign_out" "#Menu_SignOut" + "skip" "#Menu_Skip" + "edit" "#Menu_Edit" + "nav_prev" "#Menu_NavPrev" + "nav_next" "#Menu_NavNext" + "nav_prev_inner" "#Menu_NavPrevInner" + "nav_next_inner" "#Menu_NavNextInner" + "nav_left" "#Menu_NavLeft" + "nav_right" "#Menu_NavRight" + "nav_up" "#Menu_NavUp" + "nav_down" "#Menu_NavDown" + "refresh" "#Menu_Refresh" + "toggle_private_session" "#Menu_TogglePrivateSession" + "invite_player" "#Menu_InvitePlayer" + "select_player_slots" "#Menu_SelectPlayerSlots" + } + } + "In-Game" + { + "title" "#Set_InGame" + "StickPadGyro" + { + "Move" + { + "title" "#Game_Move" + "input_mode" "joystick_move" + } + "direction" + { + "title" "#Game_Direction" + "input_mode" "joystick_move" + } + } + "Button" + { + "fire" "#Game_Fire" + "cold" "#Game_Cold" + "arcane" "#Game_Arcane" + "life" "#Game_Life" + "earth" "#Game_Earth" + "lightning" "#Game_Lightning" + "shield" "#Game_Shield" + "water" "#Game_Water" + "element_switch" "#Game_ElementSwitch" + "open_magick_menu1" "#Game_OpenQuickslotMenu1" + "open_magick_menu2" "#Game_OpenQuickslotMenu2" + "open_magick_menu3" "#Game_OpenQuickslotMenu3" + "open_magick_menu4" "#Game_OpenQuickslotMenu4" + "melee_attack" "#Game_MeleeAttack" + "imbue_weapon" "#Game_ImbueWeapon" + "twist_free" "#Game_TwistFree" + "spell_self" "#Game_CastSpellSelf" + "spell_aoe" "#Game_CastSpellAoE" + "Activate" "#Game_Activate" + "use_magick1" "#Game_UseQuickslot1" + "use_magick2" "#Game_UseQuickslot2" + "use_magick3" "#Game_UseQuickslot3" + "use_magick4" "#Game_UseQuickslot4" + "request_revive" "#Game_RequestRevive" + "confirm" "#Game_Confirm" + "Back" "#Game_Back" + "select_magick_template" "#Game_SelectMagickTemplate" + "deselect_magick_template" "#Game_DeselectMagickTemplate" + "pause" "#Game_Pause" + "skip" "#Menu_Skip" + } + } + } + "localization" + { + "english" + { + "Set_General" "General Controls" + "Game_Move" "Movement" + "Game_Direction" "Direction/Forward Cast" + "Game_AoECast" "Area Cast" + "Game_SelfCast" "Self Cast" + "Game_MeleeAttack" "Melee Attack/Cast Magick" + "Game_Fire" "Fire" + "Game_Cold" "Cold" + "Game_Arcane" "Arcane" + "Game_Life" "Life" + "Game_Earth" "Earth" + "Game_Lightning" "Lightning" + "Game_Shield" "Shield" + "Game_Water" "Water" + "Set_Menu" "Menu Controls" + "Set_InGame" "In-Game Controls" + "Menu_Move" "Navigate" + "Menu_Confirm" "Confirm" + "Menu_Back" "Back" + "Menu_SignOut" "Sign Out" + "Menu_Skip" "Skip" + "Menu_Edit" "Edit" + "Menu_NavPrev" "Navigation Previous" + "Menu_NavNext" "Navigation Next" + "Menu_NavPrevInner" "Navigation Previous (Inner)" + "Menu_NavNextInner" "Navigation Next (Inner)" + "Menu_NavLeft" "Navigation Left" + "Menu_NavRight" "Navigation Right" + "Menu_NavUp" "Navigation Up" + "Menu_NavDown" "Navigation Down" + "Menu_Refresh" "Refresh" + "Menu_TogglePrivateSession" "Toggle Private Session" + "Menu_InvitePlayer" "Invite Player" + "Menu_SelectPlayerSlots" "Select Player Slots" + "#Game_ElementSwitch" "Element Wheel Switch" + "#Game_OpenQuickslotMenu1" "Open Quickslot Menu 1" + "#Game_OpenQuickslotMenu2" "Open Quickslot Menu 2" + "#Game_OpenQuickslotMenu3" "Open Quickslot Menu 3" + "#Game_OpenQuickslotMenu4" "Open Quickslot Menu 4" + "#Game_CastMagick" "Cast Magick" + "#Game_MeleeAttack" "Melee Attack" + "#Game_ImbueWeapon" "Imbue Weapon" + "#Game_TwistFree" "Twist Free" + "#Game_CastSpellSelf" "Cast Self" + "#Game_CastSpellAoE" "Cast Area of Effect" + "#Game_Activate" "Use" + "#Game_UseQuickslot1" "Quickslot 1" + "#Game_UseQuickslot2" "Quickslot 2" + "#Game_UseQuickslot3" "Quickslot 3" + "#Game_UseQuickslot4" "Quickslot 4" + "#Game_RequestRevive" "Request Revive" + "#Game_Confirm" "Confirm" + "#Game_Back" "Back" + "#Game_SelectMagickTemplate" "Select as Magick Template" + "#Game_DeselectMagickTemplate" "Deselect Magick Template" + "#Game_Pause" "Pause/Menu" + "Game_ElementSwitch" "Element Wheel Switch" + "Game_OpenQuickslotMenu1" "Open Quickslot Menu 1" + "Game_OpenQuickslotMenu2" "Open Quickslot Menu 2" + "Game_OpenQuickslotMenu3" "Open Quickslot Menu 3" + "Game_OpenQuickslotMenu4" "Open Quickslot Menu 4" + "Game_CastMagick" "Cast Magick" + "Game_ImbueWeapon" "Imbue Weapon" + "Game_TwistFree" "Twist Free" + "Game_CastSpellSelf" "Cast Self" + "Game_CastSpellAoE" "Cast Area of Effect" + "Game_Activate" "Interact" + "Game_UseQuickslot1" "Quickslot 1" + "Game_UseQuickslot2" "Quickslot 2" + "Game_UseQuickslot3" "Quickslot 3" + "Game_UseQuickslot4" "Quickslot 4" + "Game_RequestRevive" "Request Revive" + "Game_Confirm" "Confirm" + "Game_Back" "Back" + "Game_SelectMagickTemplate" "Select as Magick Template" + "Game_DeselectMagickTemplate" "Deselect Magick Template" + "Game_Pause" "Pause/Menu" + } + } + "group" + { + "id" "0" + "mode" "four_buttons" + "bindings" + { + "button_A" "xinput_button A" + "button_B" "xinput_button B" + "button_X" "xinput_button X" + "button_Y" "xinput_button Y" + } + } + "group" + { + "id" "1" + "mode" "dpad" + "bindings" + { + "dpad_north" "key_press W" + "dpad_south" "key_press S" + "dpad_east" "key_press D" + "dpad_west" "key_press A" + } + "settings" + { + "requires_click" "0" + } + } + "group" + { + "id" "2" + "mode" "dpad" + "bindings" + { + "dpad_north" "xinput_button DPAD_UP" + "dpad_south" "xinput_button DPAD_DOWN" + "dpad_east" "xinput_button DPAD_RIGHT" + "dpad_west" "xinput_button DPAD_LEFT" + } + } + "group" + { + "id" "3" + "mode" "absolute_mouse" + } + "group" + { + "id" "4" + "mode" "trigger" + "settings" + { + "output_trigger" "1" + } + } + "group" + { + "id" "5" + "mode" "trigger" + "settings" + { + "output_trigger" "2" + } + } + "group" + { + "id" "6" + "mode" "joystick_move" + } + "group" + { + "id" "7" + "mode" "joystick_move" + "settings" + { + "output_joystick" "1" + } + } + "group" + { + "id" "8" + "mode" "four_buttons" + "bindings" + { + "button_A" "xinput_button A" + "button_B" "xinput_button B" + "button_X" "xinput_button X" + "button_Y" "xinput_button Y" + } + } + "group" + { + "id" "9" + "mode" "joystick_move" + } + "group" + { + "id" "10" + "mode" "four_buttons" + } + "group" + { + "id" "11" + "mode" "four_buttons" + } + "group" + { + "id" "12" + "mode" "trigger" + } + "group" + { + "id" "13" + "mode" "trigger" + } + "group" + { + "id" "14" + "mode" "four_buttons" + "bindings" + { + "button_A" "game_action Menu confirm" + "button_B" "game_action Menu Back" + "button_X" "game_action Menu edit" + "button_X" "game_action Menu invite_player" + "button_X" "game_action Menu skip" + "button_Y" "game_action Menu select_player_slots" + } + } + "group" + { + "id" "15" + "mode" "trigger" + "bindings" + { + "click" "game_action Menu nav_prev_inner" + } + } + "group" + { + "id" "16" + "mode" "trigger" + "bindings" + { + "edge" "game_action Menu nav_next_inner" + "edge" "game_action Menu refresh" + "edge" "game_action Menu toggle_private_session" + } + } + "group" + { + "id" "17" + "mode" "four_buttons" + "bindings" + { + "button_A" "game_action In-Game skip" + "button_A" "game_action In-Game confirm" + "button_A" "game_action In-Game request_revive" + "button_A" "game_action In-Game fire" + "button_B" "game_action In-Game earth" + "button_B" "game_action In-Game Back" + "button_X" "game_action In-Game lightning" + "button_X" "game_action In-Game select_magick_template" + "button_Y" "game_action In-Game arcane" + "button_Y" "game_action In-Game deselect_magick_template" + } + } + "group" + { + "id" "18" + "mode" "trigger" + "bindings" + { + "edge" "game_action In-Game spell_aoe" + } + } + "group" + { + "id" "19" + "mode" "trigger" + "bindings" + { + "edge" "game_action In-Game melee_attack" + "edge" "game_action In-Game imbue_weapon" + "edge" "game_action In-Game twist_free" + } + } + "group" + { + "id" "20" + "mode" "joystick_move" + "settings" + { + "virtual_mode" "1" + } + "gameactions" + { + "In-Game" "Move" + } + } + "group" + { + "id" "21" + "mode" "joystick_move" + "settings" + { + "virtual_mode" "1" + } + "gameactions" + { + "In-Game" "direction" + } + } + "group" + { + "id" "22" + "mode" "joystick_move" + "settings" + { + "virtual_mode" "1" + } + "gameactions" + { + "Menu" "Move" + } + } + "group" + { + "id" "23" + "mode" "dpad" + } + "group" + { + "id" "24" + "mode" "dpad" + "bindings" + { + "dpad_north" "game_action Menu nav_up" + "dpad_south" "game_action Menu nav_down" + "dpad_east" "game_action Menu nav_right" + "dpad_west" "game_action Menu nav_left" + } + } + "group" + { + "id" "25" + "mode" "dpad" + "bindings" + { + "dpad_north" "game_action In-Game use_magick2" + "dpad_south" "game_action In-Game use_magick4" + "dpad_east" "game_action In-Game use_magick3" + "dpad_west" "game_action In-Game use_magick1" + } + } + "group" + { + "id" "26" + "mode" "dpad" + } + "group" + { + "id" "27" + "mode" "four_buttons" + "bindings" + { + "button_A" "game_action In-Game cold" + "button_B" "game_action In-Game shield" + "button_X" "game_action In-Game water" + "button_Y" "game_action In-Game life" + } + } + "group" + { + "id" "28" + "mode" "dpad" + "bindings" + { + "dpad_north" "game_action In-Game open_magick_menu2" + "dpad_south" "game_action In-Game open_magick_menu4" + "dpad_east" "game_action In-Game open_magick_menu3" + "dpad_west" "game_action In-Game open_magick_menu1" + } + } + "group" + { + "id" "29" + "mode" "touch_menu" + "settings" + { + "touch_menu_button_count" "2" + } + } + "group" + { + "id" "30" + "mode" "joystick_move" + "settings" + { + "virtual_mode" "1" + } + "gameactions" + { + "In-Game" "direction" + } + } + "preset" + { + "id" "0" + "name" "General" + "group_source_bindings" + { + "11" "button_diamond active" + "12" "left_trigger active" + "13" "right_trigger active" + } + "switch_bindings" + { + "bindings" + { + } + } + "settings" + { + } + } + "preset" + { + "id" "1" + "name" "Menu" + "group_source_bindings" + { + "14" "button_diamond active" + "15" "left_trigger active" + "16" "right_trigger active" + "24" "left_trackpad active" + "22" "joystick active" + "23" "joystick inactive" + } + "switch_bindings" + { + "bindings" + { + "button_menu" "game_action Menu sign_out" + "right_bumper" "game_action Menu nav_next" + "left_bumper" "game_action Menu nav_prev" + "left_bumper" "game_action Menu nav_prev" + } + } + "settings" + { + } + } + "preset" + { + "id" "2" + "name" "In-Game" + "group_source_bindings" + { + "17" "button_diamond active" + "26" "button_diamond inactive modeshift" + "27" "button_diamond active modeshift" + "18" "left_trigger active" + "19" "right_trigger active" + "25" "left_trackpad active" + "28" "left_trackpad active modeshift" + "20" "joystick active" + "21" "right_trackpad active" + "29" "right_trackpad inactive" + "30" "gyro inactive" + } + "switch_bindings" + { + "bindings" + { + "right_bumper" "game_action In-Game spell_self" + "button_escape" "game_action In-Game pause" + "left_bumper" "game_action In-Game Activate" + "button_back_left" "game_action In-Game element_switch" + "button_back_left" "mode_shift button_diamond 27" + "button_back_left" "mode_shift left_trackpad 28" + } + } + "settings" + { + } + } +} diff --git a/generate_emu_config_old/backup/238370/controller_steamcontroller_gordon-551563382/info.txt b/generate_emu_config_old/backup/238370/controller_steamcontroller_gordon-551563382/info.txt new file mode 100644 index 0000000..fc76f0c --- /dev/null +++ b/generate_emu_config_old/backup/238370/controller_steamcontroller_gordon-551563382/info.txt @@ -0,0 +1,50 @@ +publishedfiledetails { + result: 1 + publishedfileid: 551563382 + creator: 76561197995653544 + creator_appid: 241100 + consumer_appid: 241100 + consumer_shortcutid: 0 + filename: "controller_config/238370/#library_controllersavedefaulttitle.vdf" + file_size: 11920 + preview_file_size: 0 + file_url: "https://steamusercontent-a.akamaihd.net/ugc/397801945102408096/7B4190B98B637F5619E111CAE3773B8266F79E39/" + preview_url: "" + url: "" + hcontent_file: 397801945102408096 + hcontent_preview: 18446744073709551615 + title: "#Library_ControllerSaveDefaultTitle" + short_description: "#Library_ControllerSaveDefaultDescription" + time_created: 1447149277 + time_updated: 1448006225 + visibility: 0 + flags: 1536 + workshop_file: false + workshop_accepted: false + show_subscribe_all: false + num_comments_public: 0 + banned: false + ban_reason: "" + banner: 76561197960265728 + can_be_deleted: true + app_name: "Steam Input Configs" + file_type: 12 + can_subscribe: true + subscriptions: 863814 + favorited: 0 + followers: 0 + lifetime_subscriptions: 863815 + lifetime_favorited: 0 + lifetime_followers: 0 + views: 7 + num_children: 0 + num_reports: 0 + language: 0 + lifetime_playtime: 466443563 + lifetime_playtime_sessions: 288464 + maybe_inappropriate_sex: false + maybe_inappropriate_violence: false + revision_change_number: 0 + revision: k_EPublishedFileRevision_Latest + ban_text_check_result: k_EBanContentCheckResult_NotScanned +} diff --git a/generate_emu_config_old/backup/238370/dlc_product_info.json b/generate_emu_config_old/backup/238370/dlc_product_info.json new file mode 100644 index 0000000..efa59a2 --- /dev/null +++ b/generate_emu_config_old/backup/238370/dlc_product_info.json @@ -0,0 +1,681 @@ +{ + "353120": { + "appid": "353120", + "common": { + "name": "Magicka 2 - Midgård Interactive Map", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "353120", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "50879d4dbed29a65b730d0cf198abf6f71cdc4c1", + "_size": 373 + }, + "352870": { + "appid": "352870", + "common": { + "name": "Magicka 2 - Cultist Robe", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352870", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "fad662e20e67f79a9edabd78d1247aee559cc1fb", + "_size": 361 + }, + "352871": { + "appid": "352871", + "common": { + "name": "Magicka 2 - Cultist Staff of Aeons", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352871", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "61c2f7a06f8916871875dea23edaffc4217e7f82", + "_size": 371 + }, + "352872": { + "appid": "352872", + "common": { + "name": "Magicka 2 - Cultist Ritual Sword", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352872", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "bdcbe5eb510a88631cdd60469bbd983960334f96", + "_size": 369 + }, + "352873": { + "appid": "352873", + "common": { + "name": "Magicka 2 - Epic Warlord Dragon Armor", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "metacritic_name": "Epic Warlord Dragon Armor", + "associations": { + "0": { + "type": "developer", + "name": "Pieces Interactive" + } + }, + "primary_genre": "0", + "genres": { + "0": "1", + "1": "25" + }, + "category": { + "category_1": "1", + "category_2": "1", + "category_9": "1", + "category_24": "1" + }, + "supported_languages": { + "english": { + "supported": "true" + } + }, + "gameid": "352873", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370", + "developer": "Pieces Interactive", + "homepage": "http://www.magicka2.com" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "929f7839f5c81585fe36588305c6c554f36eb397", + "_size": 825 + }, + "352874": { + "appid": "352874", + "common": { + "name": "Magicka 2 - Epic Crystal Staff", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352874", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "eb0adf52209d340b586da69901a08eda806fa1f2", + "_size": 367 + }, + "352875": { + "appid": "352875", + "common": { + "name": "Magicka 2 - Epic Soul Screecher Sword", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352875", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "1560964ea3f6848d0c77ba28c49c32509c67722a", + "_size": 374 + }, + "343980": { + "appid": "343980", + "common": { + "name": "Magicka 2 - Ritual sickle", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "343980", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "8b2bf5ffba06701c26ac496f591ec3c3c4be05d8", + "_size": 362 + }, + "343981": { + "appid": "343981", + "common": { + "name": "Magicka 2 - Peace Treaty staff", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "343981", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "ac6c151d53eca02b3eeed5d14c2d2e28d13d5ee1", + "_size": 367 + }, + "343982": { + "appid": "343982", + "common": { + "name": "Magicka 2 - Warlock robe", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "343982", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "393e9d18a2d517195114c7a36502e762fd0577d6", + "_size": 361 + }, + "393830": { + "appid": "393830", + "common": { + "name": "Magicka 2: Gates of Midgård Challenge pack", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "metacritic_name": "Gates of Midgård Challenge pack", + "controller_support": "full", + "small_capsule": { + "english": "capsule_231x87.jpg" + }, + "header_image": { + "english": "header.jpg" + }, + "store_asset_mtime": "1441025201", + "associations": { + "0": { + "type": "developer", + "name": "Paradox Arctic" + }, + "1": { + "type": "publisher", + "name": "Paradox Interactive" + } + }, + "primary_genre": "1", + "genres": { + "0": "1", + "1": "25" + }, + "category": { + "category_1": "1", + "category_2": "1", + "category_9": "1", + "category_24": "1", + "category_22": "1", + "category_29": "1", + "category_28": "1", + "category_45": "1", + "category_46": "1", + "category_62": "1" + }, + "supported_languages": { + "english": { + "supported": "true", + "subtitles": "true" + }, + "french": { + "supported": "true", + "subtitles": "true" + }, + "italian": { + "supported": "true", + "subtitles": "true" + }, + "german": { + "supported": "true", + "subtitles": "true" + }, + "spanish": { + "supported": "true", + "subtitles": "true" + }, + "polish": { + "supported": "true", + "subtitles": "true" + }, + "brazilian": { + "supported": "true", + "subtitles": "true" + }, + "russian": { + "supported": "true", + "subtitles": "true" + } + }, + "steam_release_date": "1442329159", + "gameid": "393830", + "store_tags": { + "0": "19", + "1": "21" + }, + "review_score": "5", + "review_percentage": "57" + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370", + "developer": "Paradox Arctic", + "publisher": "Paradox Interactive", + "homepage": "http://www.magicka2.com", + "dlcavailableonstore": "1" + }, + "_missing_token": false, + "_change_number": 23591175, + "_sha": "9607afea54a0337c63a1e6380dfb9634dec9eca6", + "_size": 1890 + }, + "393831": { + "appid": "393831", + "common": { + "name": "Magicka 2: Three Cardinals Robe Pack", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "metacritic_name": "Three Cardinals Robe Pack", + "controller_support": "full", + "small_capsule": { + "english": "capsule_231x87.jpg" + }, + "header_image": { + "english": "header.jpg" + }, + "store_asset_mtime": "1442330622", + "associations": { + "0": { + "type": "developer", + "name": "Paradox Arctic" + }, + "1": { + "type": "publisher", + "name": "Paradox Interactive" + } + }, + "primary_genre": "1", + "genres": { + "0": "1", + "1": "25" + }, + "category": { + "category_1": "1", + "category_2": "1", + "category_9": "1", + "category_24": "1", + "category_22": "1", + "category_29": "1", + "category_28": "1", + "category_45": "1", + "category_46": "1", + "category_62": "1" + }, + "supported_languages": { + "english": { + "supported": "true", + "subtitles": "true" + }, + "french": { + "supported": "true", + "subtitles": "true" + }, + "italian": { + "supported": "true", + "subtitles": "true" + }, + "german": { + "supported": "true", + "subtitles": "true" + }, + "spanish": { + "supported": "true", + "subtitles": "true" + }, + "polish": { + "supported": "true", + "subtitles": "true" + }, + "brazilian": { + "supported": "true", + "subtitles": "true" + }, + "russian": { + "supported": "true", + "subtitles": "true" + } + }, + "steam_release_date": "1442329163", + "gameid": "393831", + "store_tags": { + "0": "19", + "1": "21" + }, + "review_score": "6", + "review_percentage": "78" + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370", + "developer": "Paradox Arctic", + "publisher": "Paradox Interactive", + "homepage": "http://www.magicka2.com", + "dlcavailableonstore": "1" + }, + "_missing_token": false, + "_change_number": 23591175, + "_sha": "95d39a23cc5f52d293dbf69bb44dbbaa80db281c", + "_size": 1876 + }, + "354390": { + "appid": "354390", + "common": { + "name": "Magicka 1 Orchestral soundtrack", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "354390", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "3586f1838f9737563075cf48b2b32f205299f82f", + "_size": 368 + }, + "414650": { + "appid": "414650", + "common": { + "name": "Magicka 2: Chirpy Staff", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "414650", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370" + }, + "_missing_token": false, + "_change_number": 11703200, + "_sha": "3f23c089684a923f3fc771cea75374e2e2be4319", + "_size": 360 + }, + "414651": { + "appid": "414651", + "common": { + "name": "Magicka 2: Ice, Death and Fury", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "metacritic_name": "Magicka 2: Ice, Death and Fury", + "controller_support": "full", + "small_capsule": { + "english": "capsule_231x87.jpg" + }, + "header_image": { + "english": "header.jpg" + }, + "store_asset_mtime": "1448902168", + "associations": { + "0": { + "type": "developer", + "name": "Paradox Arctic" + }, + "1": { + "type": "publisher", + "name": "Paradox Interactive" + } + }, + "primary_genre": "1", + "genres": { + "0": "1", + "1": "25" + }, + "category": { + "category_1": "1", + "category_2": "1", + "category_9": "1", + "category_24": "1", + "category_22": "1", + "category_29": "1", + "category_28": "1", + "category_33": "1", + "category_45": "1", + "category_46": "1", + "category_62": "1" + }, + "supported_languages": { + "english": { + "supported": "true", + "subtitles": "true" + }, + "french": { + "supported": "true", + "subtitles": "true" + }, + "italian": { + "supported": "true", + "subtitles": "true" + }, + "german": { + "supported": "true", + "subtitles": "true" + }, + "spanish": { + "supported": "true", + "subtitles": "true" + }, + "polish": { + "supported": "true", + "subtitles": "true" + }, + "brazilian": { + "supported": "true", + "subtitles": "true" + }, + "russian": { + "supported": "true", + "subtitles": "true" + } + }, + "steam_release_date": "1450188029", + "gameid": "414651", + "store_tags": { + "0": "19", + "1": "21" + }, + "review_score": "5", + "review_percentage": "64" + }, + "extended": { + "dlcforappid": "238370", + "mustownapptopurchase": "238370", + "developer": "Paradox Arctic", + "publisher": "Paradox Interactive", + "homepage": "http://www.magicka2.com", + "dlcavailableonstore": "1" + }, + "_missing_token": false, + "_change_number": 23591175, + "_sha": "8f4c921aed49c30c29947bc529ba5daad0186f5e", + "_size": 1897 + }, + "352860": { + "appid": "352860", + "public_only": "1", + "common": { + "name": "Magicka 2 - Headmaster Robe", + "section_type": "ownersonly", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352860", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "_missing_token": true, + "_change_number": 11703200, + "_sha": "6e5b16940c2e17acb0f07fe577a3babd03aab36b", + "_size": 336 + }, + "352861": { + "appid": "352861", + "public_only": "1", + "common": { + "name": "Magicka 2 - Headmaster Sword", + "section_type": "ownersonly", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352861", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "_missing_token": true, + "_change_number": 11703200, + "_sha": "2acb73b63bfcde936850e7f6bd4493c0316d9cc3", + "_size": 337 + }, + "352862": { + "appid": "352862", + "public_only": "1", + "common": { + "name": "Magicka 2 - Headmaster Staff", + "section_type": "ownersonly", + "type": "DLC", + "parent": "238370", + "releasestate": "released", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "352862", + "store_tags": { + "0": "19", + "1": "21" + } + }, + "_missing_token": true, + "_change_number": 11703200, + "_sha": "369f6dcad4fa98e40d7285546576bcc3fcd4a34c", + "_size": 337 + } +} \ No newline at end of file diff --git a/generate_emu_config_old/backup/238370/product_info.json b/generate_emu_config_old/backup/238370/product_info.json new file mode 100644 index 0000000..15319d6 --- /dev/null +++ b/generate_emu_config_old/backup/238370/product_info.json @@ -0,0 +1,1038 @@ +{ + "appid": "238370", + "common": { + "name": "Magicka 2", + "type": "Game", + "releasestate": "released", + "icon": "6c1ca2ff2c0f87c4d0a5378a9dbc7b7277bd239b", + "clienticon": "c9d0e3c1f94425b3b7b3b4fcae255bb797e90cd8", + "clienttga": "19af58740bc931ed31252b303854bb2796c3eb9c", + "clienticns": "db7fa19e0472abc26a778d8240ac1721ca1bbc2c", + "logo": "c541f56b343320cccfdab1f9b9a87230e6e0b341", + "logo_small": "c541f56b343320cccfdab1f9b9a87230e6e0b341_thumb", + "oslist": "windows,macos,linux", + "languages": { + "english": "1", + "german": "1", + "french": "1", + "italian": "1", + "spanish": "1", + "russian": "1", + "polish": "1", + "brazilian": "1" + }, + "linuxclienticon": "74e501a95d22b8fdf584d3e3a2b83ac7aefca5a4", + "eulas": { + "0": { + "id": "238370_eula_0", + "name": "Magicka 2 EULA", + "url": "https://store.steampowered.com//eula/238370_eula_0", + "version": "1" + } + }, + "steam_deck_compatibility": { + "category": "1", + "test_timestamp": "1645574400", + "tested_build_id": "3982521", + "tests": { + "0": { + "display": "2", + "token": "#SteamDeckVerified_TestResult_SteamOSDoesNotSupport" + } + }, + "configuration": { + "supported_input": "simultaneous_gamepad_mouse", + "requires_manual_keyboard_invoke": "0", + "requires_non_controller_launcher_nav": "0", + "primary_player_is_controller_slot_0": "0", + "non_deck_display_glyphs": "1", + "small_text": "0", + "requires_internet_for_setup": "0", + "requires_internet_for_singleplayer": "0", + "recommended_runtime": "proton-7.0-1", + "requires_h264": "0" + } + }, + "controller_support": "full", + "small_capsule": { + "english": "capsule_231x87.jpg" + }, + "header_image": { + "english": "header.jpg" + }, + "library_assets": { + "library_capsule": "en", + "library_hero": "en", + "library_logo": "en", + "logo_position": { + "pinned_position": "CenterCenter", + "width_pct": "100", + "height_pct": "100" + } + }, + "library_assets_full": { + "library_capsule": { + "image": { + "english": "library_600x900.jpg" + }, + "image2x": { + "english": "library_600x900_2x.jpg" + } + }, + "library_hero": { + "image": { + "english": "library_hero.jpg" + }, + "image2x": { + "english": "library_hero_2x.jpg" + } + }, + "library_logo": { + "image": { + "english": "logo.png" + }, + "image2x": { + "english": "logo_2x.png" + }, + "logo_position": { + "pinned_position": "CenterCenter", + "width_pct": "100", + "height_pct": "100" + } + } + }, + "store_asset_mtime": "1615973693", + "associations": { + "0": { + "type": "developer", + "name": "Pieces Interactive" + }, + "1": { + "type": "publisher", + "name": "Paradox Interactive" + }, + "2": { + "type": "franchise", + "name": "Magicka" + } + }, + "primary_genre": "1", + "genres": { + "0": "1", + "1": "25" + }, + "category": { + "category_1": "1", + "category_2": "1", + "category_9": "1", + "category_24": "1", + "category_22": "1", + "category_29": "1", + "category_28": "1", + "category_33": "1", + "category_44": "1", + "category_43": "1", + "category_41": "1", + "category_42": "1", + "category_45": "1", + "category_46": "1", + "category_62": "1" + }, + "supported_languages": { + "english": { + "supported": "true", + "subtitles": "true" + }, + "french": { + "supported": "true", + "subtitles": "true" + }, + "italian": { + "supported": "true", + "subtitles": "true" + }, + "german": { + "supported": "true", + "subtitles": "true" + }, + "spanish": { + "supported": "true", + "subtitles": "true" + }, + "polish": { + "supported": "true", + "subtitles": "true" + }, + "brazilian": { + "supported": "true", + "subtitles": "true" + }, + "russian": { + "supported": "true", + "subtitles": "true" + } + }, + "steam_release_date": "1432652400", + "community_visible_stats": "1", + "community_hub_visible": "1", + "gameid": "238370", + "store_tags": { + "0": "4057", + "1": "1685", + "2": "21", + "3": "3859", + "4": "1719", + "5": "19", + "6": "3843", + "7": "4136", + "8": "3841", + "9": "122", + "10": "4166", + "11": "5711", + "12": "1775", + "13": "1684", + "14": "1695", + "15": "7368", + "16": "4182", + "17": "4345", + "18": "10397", + "19": "5851" + }, + "review_score": "8", + "review_percentage": "82" + }, + "extended": { + "checkpkgstate": "1", + "developer": "Pieces Interactive", + "gamedir": "", + "homepage": "http://www.magicka2.com", + "icon": "", + "noservers": "0", + "sourcegame": "1", + "state": "eStateComingSoonNoPreload", + "visibleonlywhensubscribed": "1", + "publisher": "Paradox Interactive", + "listofdlc": "343980,343981,343982,352860,352861,352862,352870,352871,352872,352873,352874,352875,353120,354390,393830,393831,414650,414651", + "dlcavailableonstore": "1" + }, + "config": { + "contenttype": "3", + "installdir": "Magicka 2", + "launch": { + "0": { + "executable": "engine/Magicka2.exe", + "workingdir": "engine", + "description": "Play Magicka 2", + "type": "none", + "config": { + "oslist": "windows" + } + }, + "1": { + "executable": "engine/Magicka2", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "linux", + "osarch": "32" + } + }, + "2": { + "executable": "engine/Magicka2_x64", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "linux", + "osarch": "64" + } + }, + "3": { + "executable": "engine/Magicka2.app", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "macos" + } + } + }, + "steamcontrollertemplateindex": "1", + "steamcontrollertouchtemplateindex": "1", + "steamcontrollertouchconfigdetails": { + "2069657566": { + "controller_type": "controller_mobile_touch", + "enabled_branches": "default", + "use_action_block": "false" + } + }, + "steamcontrollerconfigdetails": { + "551563382": { + "controller_type": "controller_steamcontroller_gordon", + "enabled_branches": "default", + "use_action_block": "false" + } + } + }, + "depots": { + "overridescddb": "1", + "baselanguages": "english,german,french,italian,spanish,russian,polish,brazilian", + "228984": { + "config": { + "oslist": "windows" + }, + "depotfromapp": "228980", + "sharedinstall": "1" + }, + "228990": { + "config": { + "oslist": "windows" + }, + "depotfromapp": "228980", + "sharedinstall": "1" + }, + "238371": { + "systemdefined": "1", + "config": { + "oslist": "windows" + }, + "manifests": { + "public": { + "gid": "4722487876550547005", + "size": "3126586661", + "download": "3037827376" + } + }, + "encryptedmanifests": { + "1_0_1_3": { + "gid": "1F8ECBCF7B1816DC5077CE481229E541", + "size": "0E2ED2A291E2E60EFFDB2AF2A4DFD362", + "download": "AAFE100964BDC5BD28ED2AA1BAFBAFC5" + }, + "1_0_1_4": { + "gid": "5CDF3D12FA91812FB807C8025C1F516A", + "size": "FF863A1B5FA97ECBE0F7A0E92FDB2E29", + "download": "3C40D9DE30AB7F9A60810E82B91CCE6E" + }, + "1_0_1_5": { + "gid": "1F90EF256B1735929ED07F21404A7661", + "size": "C85D53E94140655CA6ECF5D2651A2904", + "download": "90D0682E7A2F1C3213F8AAF28C7BDF65" + }, + "1_1_0_0": { + "gid": "8BC67724703EF9102B288BC73F83C684", + "size": "91C29CA5DC777ED096836490D8B63B6D", + "download": "14307662AACA699407E326E6565D6AAB" + }, + "1_1_0_0_v3": { + "gid": "8EC6C5981DCACAEC4D3FF7EFAE16FA6C", + "size": "6A3317178621939B0615130EB0AEAD4D", + "download": "FE1FD9A00C931BE0A984A14F985E159E" + }, + "1_2_1_0": { + "gid": "D36A2C34BCF705A49D3C0066FB6032DD", + "size": "9BC3A2FE95E92D5BFB83E2B3A124AF1E", + "download": "C8F733519D83E6C2D55B447687649190" + }, + "dev": { + "gid": "C4A6D6837AE82BF7BE9BB4F9AC604F03", + "size": "96F16B3905F54BFD63854EFF3107B3E7", + "download": "32435FAA19311A6D64B0B2A9DFBA10D7" + }, + "development": { + "gid": "70C274AC71C68DDB3B69BC87C982D2BC", + "size": "2232CC9DA1E93F27F4873B855C33F96B", + "download": "986C4872D70994DC3B74B4B8BB4DA68A" + }, + "dlc_1": { + "gid": "F2209AEAB99909B124B90C850F7CC69A", + "size": "64D8F509797E15C2AE8BB7C48551A937", + "download": "6AE1F0D7F1E616D3474B87A47D02AF77" + }, + "dlc_2": { + "gid": "0DE3C846B1C48935B89FFEF992C2A31F", + "size": "A6371A0F2B5A91050A8584561A6C02D8", + "download": "C2627F876CEB25428A92E858C5B88410" + }, + "dlc_2_sh": { + "gid": "5F74D84BD426AF6A4019DBC5A0E6031C", + "size": "53BC67AD0959030797E048F84F04739C", + "download": "938A340EFADDED43943C821E9C5EC197" + }, + "early_access": { + "gid": "01050CE80F97DBB0FB73F9E4D3922124", + "size": "197D8174E5A6F207CF4DDC68702626F6", + "download": "7F6A11CB77598FAA21EC56EC01B054DA" + }, + "enzyme": { + "gid": "A13FD9FA9FE56A7EAF57659027AD2C09", + "size": "D52D27BDF078A3955B813A09FFB0238C", + "download": "7BC0DFD4A61CB6EED3518EA0CF5BE0D0" + }, + "gm_6": { + "gid": "9FE7008918604AD52D2ED45D88AF5C0C", + "size": "A2169859E9FC358D27F59FCB85A526C5", + "download": "824C1EF7225DC4B8495E8C6519286C57" + }, + "gm_6_1": { + "gid": "41B62FBFDD2C82DBD8C5E2951EBAF28E", + "size": "BD460B6A526094CCC576A0858CFF8CA1", + "download": "3C0755DF91FACC9D1758AA5AF5A3C584" + }, + "master": { + "gid": "BB6AD432DCFF4BD70DC4A9F66E63A10D", + "size": "00EA8937DA01D28E32E5A66F72CB300F", + "download": "C981388CB9418C3C691E821DF2FD286C" + } + } + }, + "353120": { + "manifests": { + "public": { + "gid": "8753634293660869213", + "size": "343535983", + "download": "104647760" + } + }, + "encryptedmanifests": { + "1_0_1_3": { + "gid": "4B42CF1311A3A53C3C321EA5CB6222CA", + "size": "F03542992CFD78DBABFF1AE6C20E7E04", + "download": "C3A570B7DC4BE256A900A52EEAA9CA64" + }, + "1_0_1_4": { + "gid": "3D1B151C9B42851252EC5A9482207D74", + "size": "20EF48A943F9263BB8C51EBA6DC93E02", + "download": "29E81977E001F24474D83E5EAD9429C4" + }, + "1_0_1_5": { + "gid": "6C7C7D225DC169FCE2DE71B044B09104", + "size": "41A2482852F88976E562EA2F50979962", + "download": "69F700E8E0BBC5179FEF88055DBA7D87" + }, + "1_1_0_0": { + "gid": "0A97C900ED8BFDB8DE342015C9625973", + "size": "C73B061D42BFB3E91C745EBAFAB54B32", + "download": "C0E08CD3B0C86D5F89ABBDE9728CEF9F" + }, + "1_1_0_0_v3": { + "gid": "3F852EC9B83A325E1FCBDBC4238DFF65", + "size": "F8DF3716EC101EE51994776EC2F0BF28", + "download": "6078A4F022F685964CE47F005533FA69" + }, + "1_2_1_0": { + "gid": "4B0743B1E62CFF5233B983D0870F3166", + "size": "43FCEB17DBEAD47D5B61AD7C625E47F5", + "download": "76DEF3A6F5D5C4734425CF461A691106" + }, + "dev": { + "gid": "F5D7C1A7CE9305BB0F9C9D2801E33448", + "size": "80ADB377413057CE8DA2FE8E545A7D4B", + "download": "3A11E5BD75E2D262CF1FB2D5C8B5728F" + }, + "development": { + "gid": "335C765A9B1587B4E1771F06C3B1D558", + "size": "5204F298000FE52A7E306EDEF6FA8457", + "download": "3B950BD094355D12BF00D77486139E45" + }, + "dlc_1": { + "gid": "0E3AD1CB42177332B995E4C69C40D356", + "size": "3611099E9CE1A04A693D1B45074817E2", + "download": "CA85B793983125901D7DA705BDC0FAC6" + }, + "dlc_2": { + "gid": "1FF05007553F07961E54A8A87AB39372", + "size": "3CAE24D953C1205890DD728E2E5DCC34", + "download": "EA1D91C00D841DA0599904C8AD517A5B" + }, + "dlc_2_sh": { + "gid": "DA1C90312A9B189F4071D8D8219BF3B9", + "size": "61F1D58CAA4C8BD200E182482CF99C11", + "download": "81F8D880B15F93B4D2472BD602B56182" + }, + "early_access": { + "gid": "59E507BD728A66E41723DD3D95AE9072", + "size": "F998E0418029DA522CC2018F316C6037", + "download": "A40DA4D63D8330ECACE40DE6E7678863" + }, + "enzyme": { + "gid": "5A9096D8041BE0556D0B6DDCBA2513A7", + "size": "FABAA3C1EF7C6CD8161132001DCC42AF", + "download": "3002F08544CF426C55741878530BFEE6" + }, + "gm_6": { + "gid": "7DC2DEC3F15B136B541ECC88B22129B4", + "size": "1033F3AD9903122602C9E6ADCDEC4569", + "download": "3AC0935072AF2CF06D05DE483D13638A" + }, + "gm_6_1": { + "gid": "6BA1E03EA3082A9E3BE622C64EB7F18C", + "size": "724B709EC4E1A81B2D95FD6BB180F622", + "download": "909F8CA933894F6CE8AAE4629F2FA4C8" + }, + "master": { + "gid": "330399036DC03850797F7491729011CB", + "size": "C4D90AA5FB586CA18558A37DA55BA58C", + "download": "9CA4541F45BA7D41F7F1281007AF37FF" + } + }, + "dlcappid": "353120" + }, + "354390": { + "manifests": { + "public": { + "gid": "4304180385385745678", + "size": "49364429", + "download": "48980992" + } + }, + "encryptedmanifests": { + "1_0_1_3": { + "gid": "0CE13CB28E0CA2578209DE3F16E990F2", + "size": "9CCE902BCF0156ED3F84EB8070157545", + "download": "471B122A62F3C8C68DBD83E17FB601BF" + }, + "1_0_1_4": { + "gid": "94652B27B8438C4D63F3F0685986DC86", + "size": "0C0C6D8B3F75375C7F4BF8D0B5337D5C", + "download": "6BF3358241D8F5F27BBD3B96EB6439FA" + }, + "1_0_1_5": { + "gid": "E2FCE8B43BB6429B8D28F50BA330E27A", + "size": "8CDCDB96627E354DC7505F881ED8CC39", + "download": "3FD7531AE6B99D0738799DE628AE15C5" + }, + "1_1_0_0": { + "gid": "EFB33F286DCFF2556750CE5E873C197C", + "size": "F3DE202383F8A9D13420FBDB07463CF3", + "download": "BA33624E511E9E105E25F559CD31A267" + }, + "1_1_0_0_v3": { + "gid": "25A1705FF60762EE53833CF38191028E", + "size": "671E4C35D54CB6B9A2A556BAB40BCF43", + "download": "1F806F8A1095A3804B82E0DDA48DC54C" + }, + "1_2_1_0": { + "gid": "EA9306335CF35113D9A753D1B7CD6534", + "size": "70490C3F7BD104F283BF0C190EDCBB8B", + "download": "055E1D74985E9B98D73DB6052DF66F5B" + }, + "dev": { + "gid": "6B08495D68998ED31CF5FD0EA23ED62C", + "size": "1B763E6F6F641AF188E33F73E515668B", + "download": "313C2715120F21EEE73BF0AAB9823661" + }, + "development": { + "gid": "D1DF7B0B66593A6B29691F65E5AF0C26", + "size": "FE31C89CD65E3B20DE576F01CA1D8D4E", + "download": "7BA72C7C413FB78A6035ACA659679AA9" + }, + "dlc_1": { + "gid": "03BA3F18DF260BB2FD771370D5E65004", + "size": "B519DCEC75D60220058B5ACB43A6915A", + "download": "4D5FCBD259171F844194FF1F018F01E6" + }, + "dlc_2": { + "gid": "56AB3A9446E1390C40C846AC82EDE12C", + "size": "F2EE53661ECCAB4001530652600C5E96", + "download": "098E1798A94763705089F8AF60B7777A" + }, + "dlc_2_sh": { + "gid": "E2A3A9FBDDFFAA5AA1CFA35E3D5A3CCD", + "size": "610BA408EA627DA4D4E95CC960A06A53", + "download": "A502E25265F586DF8FFAD40CC3DF6F44" + }, + "early_access": { + "gid": "6195C9CDF0F9724EFD4F016FECC8BD01", + "size": "4516F959E977EC032385C41A6551E102", + "download": "2A62BFFB87D52CF19E2816E99A1F8DBD" + }, + "enzyme": { + "gid": "633EB6224B62F9F42A3442FF4B58B414", + "size": "FC3F52763C67C63AFAFB30649E767626", + "download": "F6AF0CA872DC3853A00B0987B91D4B4D" + }, + "gm_6": { + "gid": "A13B78E26D9B61B6EBE6CDD9C54D5B68", + "size": "80A707E6317567C871C3E4DAF4C71517", + "download": "7803F94085031954C7B2310018122A1B" + }, + "gm_6_1": { + "gid": "B8331C22999B5B709F980D09C658493C", + "size": "032AC498B9CCE298EBC475908A43C14F", + "download": "ACB0B00E41E582AF9D15EACE6D262A1E" + }, + "master": { + "gid": "EB5643FEFB32F2A2379F88C62F887B60", + "size": "F95F6BCA8A33A949674A9B6984267E52", + "download": "BEE1415539B8D0B3C5742122F084322E" + } + }, + "dlcappid": "354390" + }, + "238372": { + "config": { + "oslist": "linux" + }, + "manifests": { + "public": { + "gid": "6830296416247391615", + "size": "3108736752", + "download": "3020588384" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "2D786A18762E5025628B30BC4555ED8D", + "size": "BAB9DB3FABE0294AA2A4ECEFD697248E", + "download": "888C2AEE7C51E58A88469F0D18F75F05" + }, + "1_1_0_0_v3": { + "gid": "AC1BB7AED4D6A9B2226DC5D0045E76F1", + "size": "D3740BF0F147F8CCA1C803DC24DFE1F5", + "download": "4CFA4E83687C0FB478DBF91B1CAB8391" + }, + "1_2_1_0": { + "gid": "27DB8ECCEBC662BCFE4AD94DAC80E0F7", + "size": "A19708D6CBBD0D954FE5949CE018B320", + "download": "9487F76B50EAFF4A4EAFE1B356ECCFD9" + }, + "development": { + "gid": "0DFA84610CDA6F1285CBAD451A828687", + "size": "324FBBB2DB0968373E0E1B7A736699B3", + "download": "C45530A384B3A5ECB8EED630321885DE" + }, + "dlc_1": { + "gid": "EAD1D6E4BDF5B0B030C680AADE04BC10", + "size": "9E8FC642208231F766C4040D0B5F063A", + "download": "38EF38875C8C5BF0A0C3AC034BB4B097" + }, + "dlc_2": { + "gid": "CC62D0AEB42CBE2AD9B3BB295F4FC366", + "size": "091BC4BC2D3F12028377F12AC44B61BB", + "download": "50C9AE908C065D6E2A3D5239F4F90E69" + }, + "dlc_2_sh": { + "gid": "DB415084AC035DA11C0DF807F185FE19", + "size": "FEB960BC634A2AC207767005DE413CB5", + "download": "D5DFE4C40B2AB0097A725FBD8FEAF5FD" + }, + "early_access": { + "gid": "B4CFB55E284CF1B3C88605B41002D239", + "size": "615692F762B716E599FBFA29B44BFCE8", + "download": "6BD02B25E244FFBA9BF9AB25BFA8AB50" + }, + "enzyme": { + "gid": "F8F6E5639C91BEDD8A2AEAC885F118B4", + "size": "541861DE7876A25A3C323BBB883E01B2", + "download": "396C5592BC83CA57FABAF32536DB7682" + }, + "master": { + "gid": "BF5F486702CB49BDB0A375C73DDA9446", + "size": "57BF546E55231D511A36B730D5C9954A", + "download": "B73E88F06A427471A65D06A934E7A4F9" + } + } + }, + "238373": { + "config": { + "oslist": "macos" + }, + "manifests": { + "public": { + "gid": "3339522036327649421", + "size": "3106330089", + "download": "3019218640" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "B51E782F34D56C1715B6A2445B3CF9DB", + "size": "CFE44459B1FDEF6BC487C0ADF09375B6", + "download": "59A3D57A0A1E652F0B6F67B0E48D4FC2" + }, + "1_1_0_0_v3": { + "gid": "C112DE50D08AF0FDE24B376D0169D3AF", + "size": "3506583E918F3651B0130582A839208C", + "download": "B89A2B90D1106FDFE8DAD1E1897B7ED6" + }, + "1_2_1_0": { + "gid": "1E1B410D417219F12A31A6BA11544F8F", + "size": "E79D8ADF6AD737FDF56BE2BC9C73F525", + "download": "DC4481B317C23D18B35972298C99F5B0" + }, + "development": { + "gid": "8D7F3C78F953C4F032427689335C0444", + "size": "CC3B2539200487D7E9B5C51FA0CD2211", + "download": "F979B970271E51E01684CFDD7F0EB3E2" + }, + "dlc_1": { + "gid": "E696C42AF67E9397B2AF14612BD29DD3", + "size": "7FF59D6BDE4EA86EFBDD266D28079623", + "download": "F653C181DCBD0A363A42A66D5F810F9A" + }, + "dlc_2": { + "gid": "626D010BC91FCAC728A9878866F39B99", + "size": "7BCAB250A15663C557DC2836EDC8765C", + "download": "AD3904BA9BA9CBE72959045C18B848A6" + }, + "dlc_2_sh": { + "gid": "F4252187ED5921EBAC7217BC41058130", + "size": "EE5F6F883A21E1BF1E783DD45C622EDE", + "download": "1F0C176C800B9ADFE58693212CCC5C35" + }, + "early_access": { + "gid": "31527A7229A1394E47E93462304C7ACC", + "size": "0DB5DE375C5EBA24C77732F40F7D4F91", + "download": "467A085A277B041881E137A90813A41C" + }, + "enzyme": { + "gid": "D4737F6155BE351AEB3BA15B96B49B26", + "size": "75B0496C65AAA3255C4A6EED5DEF8022", + "download": "34F17204D0FD2FE1B7C13DE871030FAE" + }, + "master": { + "gid": "70AECB37AE8BBACC24D7E801E9F4A662", + "size": "2B9B2A487BB4AB0426D5942811D3FD31", + "download": "24A1F6977C525511CB6A8119C157E5FD" + } + } + }, + "238374": { + "config": { + "oslist": "windows" + }, + "manifests": { + "public": { + "gid": "3116099421414652121", + "size": "24457579", + "download": "7325424" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "B533ABA939C20A1D082AA44CCCD98328", + "size": "E9D9EDB6CBD4650011980E15DCF33B19", + "download": "70E7EB73A9AF4482FCD03899618B2675" + }, + "1_1_0_0_v3": { + "gid": "D9CCDFD5F930448233874C6C93ECD0D4", + "size": "9319B3FDD90A461474143DB973DFE90B", + "download": "5D766318E786103839ACD3A7722AFE0F" + }, + "1_2_1_0": { + "gid": "E9B7BA02FCB883BC1644BDBABF1FA2C7", + "size": "40E124CAE6A93B45144BC10C535818BA", + "download": "46E1F434FD35A3133561E0451B1148EF" + }, + "development": { + "gid": "8096CCC84464F569BA6989359A41BECF", + "size": "5AC65736D43D8985740296A599D48C27", + "download": "1D12E74527911D1DCA205ACE5A4D97A3" + }, + "dlc_1": { + "gid": "22ED0D129105219A9DA55C85F87D9C4B", + "size": "6D84056FB92FC375CA0EDEE751A76638", + "download": "F6007515F2CAD768EF75258E5B88386B" + }, + "dlc_2": { + "gid": "E860FCD9416E2149F7C52D713B50FA3A", + "size": "F6084F68F14C0759BC3F8A4DEBA1F8E3", + "download": "81FCB6523D8378FEBFC6D8C4894B41B7" + }, + "dlc_2_sh": { + "gid": "89745964BEF579E6965F453AA5E5514B", + "size": "A6BF2DA12BB379FFA7E56C7332592031", + "download": "EFA957B28DE6645892A4F2EA0A81B3BF" + }, + "early_access": { + "gid": "532B0700AC37C93807E9F4A7CA021D91", + "size": "0B848AE77829DE7D706012A3A6094D52", + "download": "C27D567D5931AC6E279DE93F156D6C95" + }, + "enzyme": { + "gid": "ED726E71DC2899A4ED275C3885072D1F", + "size": "24863BE795D5C1CBA7EB48C98A3F0CD2", + "download": "E3A0C43FAB7912E4A981DD1BB68F52E5" + }, + "master": { + "gid": "051B96CBA7639DBEA505751318774416", + "size": "E6A9198EDB513FC5C7257DFF90BAE993", + "download": "D042CE1B0307F959F8755D5C1D5F909E" + } + } + }, + "238375": { + "config": { + "oslist": "linux", + "osarch": "32" + }, + "manifests": { + "public": { + "gid": "7961351643475508039", + "size": "14189908", + "download": "4272816" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "C4024A8196E47DB856596F9C2624184A", + "size": "9AD187517679E5233B4D59D3CD5A2FC6", + "download": "D4EEB29C9577501DB6080A6D6B5BB153" + }, + "1_1_0_0_v3": { + "gid": "9CA9996DB927303510763C407C68D64C", + "size": "C3687262C4402E88F03FFABDCBE79316", + "download": "CB0246CFCCA66A1C11B961C4D6D7FB96" + }, + "1_2_1_0": { + "gid": "E8AB95B5EDEC3A9BDE63DCB0B5124CF3", + "size": "596B0F1F2D026214D290C1642D9D95D0", + "download": "42C6161934E18E350B65041DB9B7CC85" + }, + "development": { + "gid": "ECB16A3546FD85A7B1E4A411979067D0", + "size": "70F0961CD3BC28D3EBE2E4A37BD97B99", + "download": "05B5EFDD883282EEA71443E4F3F921A6" + }, + "dlc_1": { + "gid": "DA5F1E2871CF71891C92817D05FC0695", + "size": "9964E77BD284153CC302EBF82B3635BC", + "download": "B89A37AC9ED643C73F76F781A7EC0CE9" + }, + "dlc_2": { + "gid": "C810D3A06902635DACC9D9FAC7E237D5", + "size": "67FFC37B0680BF3247D7A61DD41B3043", + "download": "9CD6B16A6FA37755D959D7CD5E217C30" + }, + "dlc_2_sh": { + "gid": "6A76773FAF38BB953CDA1FBF2826A76F", + "size": "25E05D386F5B2624C3A2ACBDCC2FB0F4", + "download": "5259BDE5B3EF0A5BD96A32EC16EC8F35" + }, + "early_access": { + "gid": "3630E5B65FB06ED044DC8651DF6074EE", + "size": "957E723A4759BC0A278F003B353AF047", + "download": "18D42EDD365DA916986A1054388FC11A" + }, + "enzyme": { + "gid": "7C788D22FFBF26EE748AA290FE264CEC", + "size": "54DEBD725016397E21A70D62DB0899ED", + "download": "2A4FF42E458B1F25D62B00ECEEC8A37E" + }, + "master": { + "gid": "0121DC9CEF2F5048DA6EF2B2D6868FCC", + "size": "12CFB44977C1CDE55B7F60E780F2263C", + "download": "CC3AA8FC9F9265FC5E8F27E5FD461607" + } + } + }, + "238377": { + "config": { + "oslist": "linux", + "osarch": "64" + }, + "manifests": { + "public": { + "gid": "3015461552370049559", + "size": "13748004", + "download": "4091856" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "14F06D265AC5F87165630CBCC615110D", + "size": "A449BD7030E5CEF19E9BE35F063D5B58", + "download": "F20B6837B52CE933D07E58F4C973B013" + }, + "1_1_0_0_v3": { + "gid": "47FDC1524F7DE0B1179322DD25AAF4F7", + "size": "91A4FF87D25552E9CA70A73706C355C3", + "download": "B8DA4A4CC44EE28787CD0BF31D28AD82" + }, + "1_2_1_0": { + "gid": "E3AE7EC3AE8118B632266502FCB38771", + "size": "E5EDF8E20DCAF041E8E415DC406DD972", + "download": "EC6DE8143C10CF15D0058E1DC28C114E" + }, + "development": { + "gid": "3F7FBEE42AF1D5F257E8768BAB223F87", + "size": "73C4FD016F4BB19502A85579F771DE96", + "download": "3C7D87D365920BE86A6390ADE85996ED" + }, + "dlc_1": { + "gid": "DB54E6D2EDDA7D50A1139C678C8E873E", + "size": "0C1F5B8F0F50D77249C14C6306804965", + "download": "D8CEE748356CF478D59D50009D2058C8" + }, + "dlc_2": { + "gid": "CAD6176B50F30867107BA83F8090B838", + "size": "AB0B9E160EE0F107EA5F461425C30A0A", + "download": "0AF771AFF1F1D23B4C2A1FFBB1D16CBC" + }, + "dlc_2_sh": { + "gid": "E86905E971425AC478DA0073EDBAB58F", + "size": "812EB7DDAACF3E862B02D149E359F61D", + "download": "5B02FA18096EB3D63070D3CDC5678919" + }, + "early_access": { + "gid": "B3727459DB929D260393A2804907AA2F", + "size": "8728149E3841D31A56BE8EF517BA811A", + "download": "7FA6A0425C484827702A3DCF73F5A82E" + }, + "enzyme": { + "gid": "8133E98AFDD50D43DFEA1C56A240FECF", + "size": "E795618ADCB6D6A0D09B01B9CDF0488D", + "download": "796F1A48E5943CC3E53F15C47FB24349" + }, + "master": { + "gid": "D327C96FD5D006E9E1B1BDD587B33CC1", + "size": "654E54D0F9B4B0901B589645EF8CD375", + "download": "75014A292FCB80703C2861DDDBD66D52" + } + } + }, + "238376": { + "config": { + "oslist": "macos" + }, + "manifests": { + "public": { + "gid": "8208414792312360470", + "size": "14179513", + "download": "3444960" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "A082F9368B96CA29D72E3DA14A1E7F5B", + "size": "0C3F716F8D4D97C2C67E9FB47E7A0E43", + "download": "C78635CA5A0934E41119088D12D49F2F" + }, + "1_1_0_0_v3": { + "gid": "21FB4C6D0EDFC6F041F8F41231A1CA0F", + "size": "1063D0BF54CFDCC0CCC60984569BCA1F", + "download": "909FAD3E913120B4E1920828182A29A5" + }, + "1_2_1_0": { + "gid": "2E23C0C7813CE4C1144F96173376E8F7", + "size": "412AB235E044692413569859373846A8", + "download": "E798F3228816F227009272DCE41BA62E" + }, + "development": { + "gid": "4AD6E926E73451CF1FC5B39F9F4C2687", + "size": "E6ACCF6F1DACACC4BB643BDA9708F208", + "download": "9001451E999C75219DFA7D3159BE287A" + }, + "dlc_1": { + "gid": "5FBDAB77F377350246FB98D55B48223C", + "size": "7855D0A5E60C36B0438F497F25E6E67B", + "download": "2096F2614A39AD0635E515FB79CC1051" + }, + "dlc_2": { + "gid": "92EE480EC2141FBC3D45350BAF55FA05", + "size": "2987796374E7EFEFEFCEE5D48B7AE4C2", + "download": "F8813DF90C42E14FF8C4A18A4EE323DC" + }, + "dlc_2_sh": { + "gid": "2C8E2D3E648A9E37AC349CC26E8B34A1", + "size": "37E251867C8D11D7DF61F0915676D076", + "download": "320CEFB48B0493276BF5D34C80BFC79D" + }, + "early_access": { + "gid": "82FE25EC4FAACC6C00425CEBF3F9CC89", + "size": "CBE6E07926EF444FA5B6554E648E1537", + "download": "63AB872A7A99D01EB2E915BC8ADB1B2E" + }, + "enzyme": { + "gid": "E45434266E3D034CFE47FF5EF6196477", + "size": "DFD76C1D655F06EDEAA815135215CF87", + "download": "AC4250D61C64DE175D486182F006094C" + }, + "master": { + "gid": "E2C175F6E18FA051419B67889B74AF0B", + "size": "8FB8708118742A913226BD0EE412B30F", + "download": "41A47B4E2CFDB6979BF32836B93FCAC0" + } + } + }, + "branches": { + "public": { + "buildid": "3982521", + "timeupdated": "1562252380" + }, + "1_0_1_3": { + "buildid": "661720", + "pwdrequired": "1" + }, + "1_0_1_4": { + "buildid": "668796", + "pwdrequired": "1" + }, + "1_0_1_5": { + "buildid": "728859", + "pwdrequired": "1" + }, + "1_1_0_0": { + "buildid": "773817", + "pwdrequired": "1" + }, + "1_1_0_0_v3": { + "buildid": "773817", + "pwdrequired": "1" + }, + "1_2_1_0": { + "buildid": "939506", + "pwdrequired": "1" + }, + "dev": { + "buildid": "740930", + "pwdrequired": "1" + }, + "development": { + "buildid": "3981993", + "pwdrequired": "1", + "timeupdated": "1562239021" + }, + "dlc_1": { + "buildid": "748516", + "pwdrequired": "1" + }, + "dlc_2": { + "buildid": "869382", + "pwdrequired": "1" + }, + "dlc_2_sh": { + "buildid": "869382", + "pwdrequired": "1" + }, + "early_access": { + "buildid": "773817", + "pwdrequired": "1" + }, + "enzyme": { + "buildid": "939506", + "pwdrequired": "1" + }, + "gm_6": { + "buildid": "626044", + "pwdrequired": "1" + }, + "gm_6_1": { + "buildid": "639965", + "pwdrequired": "1" + }, + "master": { + "buildid": "3982521", + "pwdrequired": "1", + "timeupdated": "1562249233" + } + } + }, + "ufs": { + "quota": "10000000", + "maxnumfiles": "10" + }, + "_missing_token": false, + "_change_number": 24981165, + "_sha": "0a036f41996b4919278619e9259eb13cf739ee4a", + "_size": 28621 +} \ No newline at end of file diff --git a/generate_emu_config_old/backup/480/controller_steamcontroller_gordon-1417465272/1417465272_controller_config.vdf b/generate_emu_config_old/backup/480/controller_steamcontroller_gordon-1417465272/1417465272_controller_config.vdf new file mode 100644 index 0000000..3dfb09e --- /dev/null +++ b/generate_emu_config_old/backup/480/controller_steamcontroller_gordon-1417465272/1417465272_controller_config.vdf @@ -0,0 +1,647 @@ +"controller_mappings" +{ + "version" "3" + "title" "#Library_ControllerSaveDefaultTitle" + "description" "#Library_ControllerSaveDefaultDescription" + "creator" "76561197969363440" + "controller_type" "controller_steamcontroller_gordon" + "Timestamp" "1529529957" + "actions" + { + "ship_controls" + { + "title" "Ship Controls" + "legacy_set" "0" + "StickPadGyro" + { + "analog_controls" + { + "title" "#AnalogControls" + "input_mode" "joystick_move" + } + } + "Button" + { + "turn_left" "#TurnLeft" + "turn_right" "#TurnRight" + "fire_lasers" "#FireLasers" + "pause_menu" "#PauseMenu" + "forward_thrust" "#ForwardThrust" + "backward_thrust" "#BackwardThrust" + } + "Layers" + { + "thrust_action_layer" "#ThrustLayer" + } + } + "menu_controls" + { + "title" "#MenuControls" + "legacy_set" "0" + "Button" + { + "menu_up" "#MenuUp" + "menu_down" "#MenuDown" + "menu_left" "#MenuLeft" + "menu_right" "#MenuRight" + "menu_select" "#MenuSelect" + "menu_cancel" "#MenuCancel" + } + } + } + "action_layers" + { + "thrust_action_layer" + { + "title" "#ThrustLayer" + "legacy_set" "1" + "set_layer" "1" + "parent_set_name" "ship_controls" + } + } + "localization" + { + "english" + { + "title" "Space War Action Set Config Sample" + "description" "This is an example configuration for using Steamworks Action Sets." + "AnalogControls" "Analog Controls" + "TurnLeft" "Turn Left" + "TurnRight" "Turn Right" + "FireLasers" "Fire Lasers" + "PauseMenu" "Pause Menu" + "BackwardThrust" "Backward Thrust" + "MenuControls" "Menu Controls" + "MenuUp" "Menu Up" + "MenuDown" "Menu Down" + "MenuLeft" "Menu Left" + "MenuRight" "Menu Right" + "MenuSelect" "Menu Select" + "ThrustLayer" "Thrust Layer" + } + } + "group" + { + "id" "0" + "mode" "four_buttons" + "inputs" + { + } + "settings" + { + "button_size" "17988" + "button_dist" "19988" + } + } + "group" + { + "id" "1" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "2" + "mode" "trigger" + "inputs" + { + "edge" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action ship_controls fire_lasers" + } + "settings" + { + "haptic_intensity" "2" + } + } + } + } + } + } + "group" + { + "id" "3" + "mode" "four_buttons" + "inputs" + { + "button_a" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_select" + } + } + } + } + "button_b" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_cancel" + } + } + } + } + } + "settings" + { + "button_size" "17992" + "button_dist" "19992" + } + } + "group" + { + "id" "4" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "5" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "6" + "mode" "dpad" + "inputs" + { + "dpad_north" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_up" + } + } + } + } + "dpad_south" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_down" + } + } + } + } + "dpad_east" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_right" + } + } + } + } + "dpad_west" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_left" + } + } + } + } + } + "settings" + { + "edge_binding_radius" "24995" + "analog_emulation_period" "29" + } + } + "group" + { + "id" "7" + "mode" "dpad" + "inputs" + { + } + "settings" + { + "edge_binding_radius" "24995" + "analog_emulation_period" "29" + } + } + "group" + { + "id" "8" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24997" + "sensitivity" "98" + } + } + "group" + { + "id" "9" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24997" + "sensitivity" "98" + } + } + "group" + { + "id" "10" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24996" + "sensitivity" "98" + } + } + "group" + { + "id" "11" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "12" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "13" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "14" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "15" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "16" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "17" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "18" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "19" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "20" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "21" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "22" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "23" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "24" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "25" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "26" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24999" + "sensitivity" "99" + } + "gameactions" + { + "ship_controls" "analog_controls" + } + } + "group" + { + "id" "35" + "mode" "four_buttons" + "inputs" + { + "button_a" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action ship_controls fire_lasers, Fire Lasers" + } + } + } + } + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "36" + "mode" "trigger" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "37" + "mode" "trigger" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "38" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "layer" "1" + } + "gameactions" + { + "ship_controls" "analog_controls" + } + } + "group" + { + "id" "39" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "27" + "mode" "switches" + "inputs" + { + "button_escape" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action ship_controls pause_menu" + } + } + } + } + } + } + "group" + { + "id" "28" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "29" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "30" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "31" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "32" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "33" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "34" + "mode" "switches" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "preset" + { + "id" "0" + "name" "ship_controls" + "group_source_bindings" + { + "27" "switch active" + "0" "button_diamond active" + "1" "left_trigger active" + "2" "right_trigger active" + "7" "joystick inactive" + "10" "joystick inactive" + "26" "joystick active" + "8" "left_trackpad inactive" + "9" "right_trackpad active" + } + } + "preset" + { + "id" "1" + "name" "menu_controls" + "group_source_bindings" + { + "28" "switch active" + "3" "button_diamond active" + "4" "left_trigger active" + "5" "right_trigger active" + "6" "joystick active" + } + } + "preset" + { + "id" "2" + "name" "thrust_action_layer" + "group_source_bindings" + { + "34" "switch active" + "35" "button_diamond active" + "36" "left_trigger active" + "37" "right_trigger active" + "38" "joystick active" + "39" "right_trackpad active" + } + } + "settings" + { + } +} diff --git a/generate_emu_config_old/backup/480/controller_steamcontroller_gordon-1417465272/info.txt b/generate_emu_config_old/backup/480/controller_steamcontroller_gordon-1417465272/info.txt new file mode 100644 index 0000000..525f26f --- /dev/null +++ b/generate_emu_config_old/backup/480/controller_steamcontroller_gordon-1417465272/info.txt @@ -0,0 +1,70 @@ +publishedfiledetails { + result: 1 + publishedfileid: 1417465272 + creator: 76561197969363440 + creator_appid: 241100 + consumer_appid: 241100 + consumer_shortcutid: 0 + filename: "1417465272_controller_config.vdf" + file_size: 8153 + preview_file_size: 0 + file_url: "https://steamusercontent-a.akamaihd.net/ugc/946201442187518041/BDBC0070B04FF09BF0C538C82DC8AAF60DE0E2AB/" + preview_url: "" + url: "" + hcontent_file: 946201442187518041 + hcontent_preview: 18446744073709551615 + title: "#Library_ControllerSaveDefaultTitle" + short_description: "#Library_ControllerSaveDefaultDescription" + time_created: 1529529959 + time_updated: 1529529959 + visibility: 0 + flags: 1536 + workshop_file: false + workshop_accepted: false + show_subscribe_all: false + num_comments_public: 0 + banned: false + ban_reason: "" + banner: 76561197960265728 + can_be_deleted: true + app_name: "Steam Input Configs" + file_type: 12 + can_subscribe: true + subscriptions: 5569673 + favorited: 0 + followers: 0 + lifetime_subscriptions: 5569674 + lifetime_favorited: 0 + lifetime_followers: 0 + views: 14 + num_children: 0 + num_reports: 0 + tags { + tag: "hasactivators" + display_name: "hasactivators" + } + tags { + tag: "controller_steamcontroller_gordon" + display_name: "controller_steamcontroller_gordon" + } + tags { + tag: "splitconfig" + display_name: "splitconfig" + } + tags { + tag: "controller_native" + display_name: "controller_native" + } + tags { + tag: "feature_actionset" + display_name: "feature_actionset" + } + language: 0 + lifetime_playtime: 35470580378 + lifetime_playtime_sessions: 7262101 + maybe_inappropriate_sex: false + maybe_inappropriate_violence: false + revision_change_number: 0 + revision: k_EPublishedFileRevision_Latest + ban_text_check_result: k_EBanContentCheckResult_NotScanned +} diff --git a/generate_emu_config_old/backup/480/controller_xboxone-1761888411/1761888411_controller_config.vdf b/generate_emu_config_old/backup/480/controller_xboxone-1761888411/1761888411_controller_config.vdf new file mode 100644 index 0000000..916ac4d --- /dev/null +++ b/generate_emu_config_old/backup/480/controller_xboxone-1761888411/1761888411_controller_config.vdf @@ -0,0 +1,717 @@ +"controller_mappings" +{ + "version" "3" + "revision" "8" + "title" "#Library_ControllerSaveDefaultTitle" + "description" "#Library_ControllerSaveDefaultDescription" + "creator" "76561198078024435" + "controller_type" "controller_xboxone" + "major_revision" "0" + "minor_revision" "0" + "Timestamp" "1559770832" + "actions" + { + "ship_controls" + { + "title" "Ship Controls" + "legacy_set" "0" + "StickPadGyro" + { + "analog_controls" + { + "title" "#AnalogControls" + "input_mode" "joystick_move" + } + } + "Button" + { + "turn_left" "#TurnLeft" + "turn_right" "#TurnRight" + "fire_lasers" "#FireLasers" + "pause_menu" "#PauseMenu" + "forward_thrust" "#ForwardThrust" + "backward_thrust" "#BackwardThrust" + } + "Layers" + { + "thrust_action_layer" "#ThrustLayer" + } + } + "menu_controls" + { + "title" "#MenuControls" + "legacy_set" "0" + "Button" + { + "menu_up" "#MenuUp" + "menu_down" "#MenuDown" + "menu_left" "#MenuLeft" + "menu_right" "#MenuRight" + "menu_select" "#MenuSelect" + "menu_cancel" "#MenuCancel" + } + } + } + "action_layers" + { + "thrust_action_layer" + { + "title" "#ThrustLayer" + "legacy_set" "1" + "set_layer" "1" + "parent_set_name" "ship_controls" + } + } + "localization" + { + "english" + { + "title" "Space War Action Set Config Sample" + "description" "This is an example configuration for using Steamworks Action Sets." + "AnalogControls" "Analog Controls" + "TurnLeft" "Turn Left" + "TurnRight" "Turn Right" + "FireLasers" "Fire Lasers" + "PauseMenu" "Pause Menu" + "BackwardThrust" "Backward Thrust" + "MenuControls" "Menu Controls" + "MenuUp" "Menu Up" + "MenuDown" "Menu Down" + "MenuLeft" "Menu Left" + "MenuRight" "Menu Right" + "MenuSelect" "Menu Select" + "ThrustLayer" "Thrust Layer" + } + } + "group" + { + "id" "0" + "mode" "four_buttons" + "inputs" + { + } + "settings" + { + "button_size" "17988" + "button_dist" "19988" + } + } + "group" + { + "id" "1" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "2" + "mode" "trigger" + "inputs" + { + "edge" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action ship_controls fire_lasers" + } + "settings" + { + "haptic_intensity" "2" + } + } + } + } + } + } + "group" + { + "id" "3" + "mode" "four_buttons" + "inputs" + { + "button_a" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_select" + } + } + } + } + "button_b" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_cancel" + } + } + } + } + } + "settings" + { + "button_size" "17992" + "button_dist" "19992" + } + } + "group" + { + "id" "4" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "5" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "6" + "mode" "dpad" + "inputs" + { + "dpad_north" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_up" + } + } + } + } + "dpad_south" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_down" + } + } + } + } + "dpad_east" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_right" + } + } + } + } + "dpad_west" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_left" + } + } + } + } + } + "settings" + { + "requires_click" "0" + "edge_binding_radius" "24995" + "analog_emulation_period" "29" + } + } + "group" + { + "id" "7" + "mode" "dpad" + "inputs" + { + } + "settings" + { + "requires_click" "0" + "edge_binding_radius" "24995" + "analog_emulation_period" "29" + } + } + "group" + { + "id" "8" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24997" + "sensitivity" "98" + } + } + "group" + { + "id" "9" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24997" + "sensitivity" "98" + } + } + "group" + { + "id" "10" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24996" + "sensitivity" "98" + } + } + "group" + { + "id" "11" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "12" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "13" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "14" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "15" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "16" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "17" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "18" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "19" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "20" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "21" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "22" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "23" + "mode" "four_buttons" + "inputs" + { + } + } + "group" + { + "id" "24" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "25" + "mode" "trigger" + "inputs" + { + } + } + "group" + { + "id" "26" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "virtual_mode" "1" + "edge_binding_radius" "24999" + "sensitivity" "99" + } + "gameactions" + { + "ship_controls" "analog_controls" + } + } + "group" + { + "id" "35" + "mode" "four_buttons" + "inputs" + { + "button_a" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action ship_controls fire_lasers, Fire Lasers" + } + } + } + } + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "36" + "mode" "trigger" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "37" + "mode" "trigger" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "38" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "layer" "1" + } + "gameactions" + { + "ship_controls" "analog_controls" + } + } + "group" + { + "id" "39" + "mode" "joystick_move" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "group" + { + "id" "40" + "mode" "dpad" + "inputs" + { + "dpad_north" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_up, Menu Up" + } + } + } + } + "dpad_south" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_down, Menu Down" + } + } + } + } + "dpad_east" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_right, Menu Right" + } + } + } + } + "dpad_west" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action menu_controls menu_left, Menu Left" + } + } + } + } + } + "settings" + { + "requires_click" "0" + } + } + "group" + { + "id" "27" + "mode" "switches" + "inputs" + { + "button_escape" + { + "activators" + { + "Full_Press" + { + "bindings" + { + "binding" "game_action ship_controls pause_menu" + } + } + } + } + } + } + "group" + { + "id" "28" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "29" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "30" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "31" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "32" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "33" + "mode" "switches" + "inputs" + { + } + } + "group" + { + "id" "34" + "mode" "switches" + "inputs" + { + } + "settings" + { + "layer" "1" + } + } + "preset" + { + "id" "0" + "name" "ship_controls" + "group_source_bindings" + { + "27" "switch active" + "0" "button_diamond active" + "1" "left_trigger active" + "2" "right_trigger active" + "7" "joystick inactive" + "10" "joystick inactive" + "26" "joystick active" + "8" "dpad inactive" + "9" "right_joystick active" + } + } + "preset" + { + "id" "1" + "name" "menu_controls" + "group_source_bindings" + { + "28" "switch active" + "3" "button_diamond active" + "4" "left_trigger active" + "5" "right_trigger active" + "6" "joystick active" + "40" "dpad active" + } + } + "preset" + { + "id" "2" + "name" "thrust_action_layer" + "group_source_bindings" + { + "34" "switch active" + "35" "button_diamond active" + "36" "left_trigger active" + "37" "right_trigger active" + "38" "joystick active" + "39" "right_joystick active" + } + } + "settings" + { + } +} diff --git a/generate_emu_config_old/backup/480/controller_xboxone-1761888411/info.txt b/generate_emu_config_old/backup/480/controller_xboxone-1761888411/info.txt new file mode 100644 index 0000000..909734f --- /dev/null +++ b/generate_emu_config_old/backup/480/controller_xboxone-1761888411/info.txt @@ -0,0 +1,74 @@ +publishedfiledetails { + result: 1 + publishedfileid: 1761888411 + creator: 76561198078024435 + creator_appid: 241100 + consumer_appid: 241100 + consumer_shortcutid: 0 + filename: "1761888411_controller_config.vdf" + file_size: 9119 + preview_file_size: 0 + file_url: "https://steamusercontent-a.akamaihd.net/ugc/797614364640018072/EE1DD64FD6CAC7FF698E3647668837F55DCA794A/" + preview_url: "" + url: "" + hcontent_file: 797614364640018072 + hcontent_preview: 18446744073709551615 + title: "#Library_ControllerSaveDefaultTitle" + short_description: "#Library_ControllerSaveDefaultDescription" + time_created: 1559770834 + time_updated: 1559770834 + visibility: 0 + flags: 1536 + workshop_file: false + workshop_accepted: false + show_subscribe_all: false + num_comments_public: 0 + banned: false + ban_reason: "" + banner: 76561197960265728 + can_be_deleted: true + app_name: "Steam Input Configs" + file_type: 12 + can_subscribe: true + subscriptions: 4780851 + favorited: 0 + followers: 0 + lifetime_subscriptions: 4780852 + lifetime_favorited: 0 + lifetime_followers: 0 + views: 13 + num_children: 0 + num_reports: 0 + tags { + tag: "hasactivators" + display_name: "hasactivators" + } + tags { + tag: "splitconfig" + display_name: "splitconfig" + } + tags { + tag: "controller_xboxone" + display_name: "controller_xboxone" + } + tags { + tag: "GenericXInput" + display_name: "GenericXInput" + } + tags { + tag: "controller_native" + display_name: "controller_native" + } + tags { + tag: "feature_actionset" + display_name: "feature_actionset" + } + language: 0 + lifetime_playtime: 67724208584 + lifetime_playtime_sessions: 17165097 + maybe_inappropriate_sex: false + maybe_inappropriate_violence: false + revision_change_number: 0 + revision: k_EPublishedFileRevision_Latest + ban_text_check_result: k_EBanContentCheckResult_NotScanned +} diff --git a/generate_emu_config_old/backup/480/dlc_product_info.json b/generate_emu_config_old/backup/480/dlc_product_info.json new file mode 100644 index 0000000..7a47371 --- /dev/null +++ b/generate_emu_config_old/backup/480/dlc_product_info.json @@ -0,0 +1,36 @@ +{ + "447130": { + "appid": "447130", + "public_only": "1", + "common": { + "name": "ticket test DLC", + "section_type": "ownersonly", + "type": "DLC", + "parent": "480", + "releasestate": "released", + "exfgls": "1", + "oslist": "windows,macos,linux", + "associations": {}, + "gameid": "447130" + }, + "_missing_token": true, + "_change_number": 11703200, + "_sha": "68212bfd479aa0ba7b731fc6c59f7d1e0ec3044a", + "_size": 288 + }, + "110902": { + "appid": "110902", + "public_only": "1", + "common": { + "name": "pieterw test DLC", + "section_type": "ownersonly", + "type": "DLC", + "parent": "480", + "gameid": "110902" + }, + "_missing_token": true, + "_change_number": 20193286, + "_sha": "bbb0d197df0654e1cb38be61c34b9038be876121", + "_size": 185 + } +} \ No newline at end of file diff --git a/generate_emu_config_old/backup/480/product_info.json b/generate_emu_config_old/backup/480/product_info.json new file mode 100644 index 0000000..0aac5fb --- /dev/null +++ b/generate_emu_config_old/backup/480/product_info.json @@ -0,0 +1,155 @@ +{ + "appid": "480", + "common": { + "name": "Spacewar", + "eulas": { + "0": { + "id": "480_eula_0", + "name": "Spacewar EULA", + "url": "http://store.steampowered.com/eula/480_eula_0" + }, + "1": { + "id": "480_eula_1", + "name": "Spacewar EULA 1", + "url": "http://store.steampowered.com/eula/480_eula_1", + "countries": "US" + } + }, + "requireskbmouse": "1", + "type": "Game", + "releasestate": "released", + "steamchinaapproved": "1", + "releasestatesteamchina": "released", + "oslist": "windows,macos,linux", + "osarch": "", + "osextended": "", + "controller_support": "full", + "associations": { + "0": { + "type": "publisher", + "name": "Telltale Games" + } + }, + "primary_genre": "0", + "category": { + "category_28": "1", + "category_33": "1", + "category_44": "1" + }, + "community_visible_stats": "1", + "workshop_visible": "1", + "gameid": "480" + }, + "extended": { + "developer": "Valve", + "gamedir": "spacewar", + "homepage": "", + "icon": "", + "noservers": "1", + "serverbrowsername": "Spacewar", + "state": "eStateAvailable", + "vacmacmodulecache": "160", + "vacmodulecache": "203", + "vacmodulefilename": "sourceinit.dat", + "visibleonlywheninstalled": "1", + "disableshaderreporting": "1", + "publisher": "Telltale Games", + "listofdlc": "110902,447130" + }, + "config": { + "usemms": "1", + "launch": { + "0": { + "executable": "SteamWorksExample.exe", + "type": "none" + } + }, + "contenttype": "3", + "installdir": "Spacewar", + "nativesteamcontroller": "1", + "checkforupdatesbeforelaunch": "1", + "testchange": "2", + "steamcontrollertemplateindex": "1", + "steamcontrollerconfigdetails": { + "1417465272": { + "controller_type": "controller_steamcontroller_gordon", + "enabled_branches": "default,previous,private", + "use_action_block": "true" + }, + "1761888411": { + "controller_type": "controller_xboxone", + "enabled_branches": "default,previous,private", + "use_action_block": "false" + } + }, + "steamconfigurator3rdpartynative": "65535", + "steam_china_only": { + "steam_china_enable_duration_control": "0" + } + }, + "depots": { + "229006": { + "config": { + "oslist": "windows" + }, + "depotfromapp": "228980", + "sharedinstall": "1" + }, + "481": { + "manifests": { + "public": { + "gid": "3183503801510301321", + "size": "1906055", + "download": "797632" + }, + "previous": { + "gid": "8382873932604653347", + "size": "1752776", + "download": "841424" + } + }, + "encryptedmanifests": { + "private": { + "gid": "89A09467D33499F8ED88480C22A2B962", + "size": "3F5CBBE518C2058886C5E37A62D1E6F1", + "download": "5A5D38347D011C6ACF52287D279FDBDA" + } + } + }, + "workshopdepot": "480", + "baselanguages": "", + "privatebranches": "1", + "branches": { + "public": { + "buildid": "3538192", + "timeupdated": "1549489971" + }, + "previous": { + "buildid": "316058", + "description": "SDK 1.30", + "timeupdated": "1503510482" + }, + "private": { + "buildid": "316281", + "pwdrequired": "1", + "timeupdated": "1506539230" + } + } + }, + "ufs": { + "sync_while_suspended": "1", + "quota": "4096", + "maxnumfiles": "10" + }, + "sysreqs": { + "windows": { + "supported": "1", + "cpu_min": "42", + "ram_min": "42" + } + }, + "_missing_token": false, + "_change_number": 25200962, + "_sha": "71055fab92d9008e56bcd86c66681062c8285bd1", + "_size": 3229 +} \ No newline at end of file diff --git a/generate_emu_config_old/controller_config_generator/parse_controller_vdf.py b/generate_emu_config_old/controller_config_generator/parse_controller_vdf.py new file mode 100644 index 0000000..2199f11 --- /dev/null +++ b/generate_emu_config_old/controller_config_generator/parse_controller_vdf.py @@ -0,0 +1,224 @@ +#controller vdf script by mr_goldberg +#generates controller config from a vdf +import vdf +import sys +import os +import traceback + +keymap_digital = { + "button_a": "A", + "button_b": "B", + "button_x": "X", + "button_y": "Y", + "dpad_north": "DUP", + "dpad_south": "DDOWN", + "dpad_east": "DRIGHT", + "dpad_west": "DLEFT", + "button_escape": "START", + "button_menu": "BACK", + "left_bumper": "LBUMPER", + "right_bumper": "RBUMPER", + "button_back_left": "A", + "button_back_right": "X", + "button_back_left_upper": "B", + "button_back_right_upper": "Y", + "": "", + "": "", + "": "", + "": "", +} + +def add_input_bindings(group, bindings, force_binding=None, keymap=keymap_digital): + if "inputs" not in group: + return bindings + for i, i_val in group["inputs"].iteritems(): + for act in i_val.itervalues(): + for fp in act.itervalues(): + for bd in fp.itervalues(): + for bbd, ss in bd.iteritems(): + if bbd.lower() == 'binding': + st = ss.split() + supported_binding = False + if st[0].lower() == 'game_action': + supported_binding = True + if st[2][-1] == ",": + action_name = st[2][:-1] + else: + action_name = st[2][:] + elif st[0].lower() == 'xinput_button': + supported_binding = True + if st[1][-1] == ",": + action_name = st[1][:-1] + else: + action_name = st[1][:] + + if supported_binding: + if force_binding is None: + binding = keymap.get(i.lower(), None) + else: + binding = force_binding + + if binding: + if action_name in bindings: + if binding not in bindings[action_name]: + bindings[action_name].append(binding) + else: + bindings[action_name] = [binding] + else: + print(f"[X] missing keymap for {i}") + return bindings + + +def generate_controller_config(controller_vdf, config_dir): + d = vdf.loads(controller_vdf, mapper=vdf.VDFDict, merge_duplicate_keys=False) + + controller_mappings = d["controller_mappings"] + + groups = controller_mappings.get_all_for("group") + groups_byid = {} + for g in groups: + groups_byid[g["id"]] = g + + actions = controller_mappings.get_all_for("actions") + action_list = [] + for a in actions: + for k in a: + action_list.append(k) + + presets = controller_mappings.get_all_for("preset") + all_bindings = {} + for p in presets: + name = p["name"] + if (name not in action_list) and name.lower() != 'default': + continue + group_bindings = p["group_source_bindings"] + bindings = {} + for number in group_bindings: + s = group_bindings[number].split() + if s[1].lower() != "active": + continue + + #print(s) + if s[0].lower() in ["switch", "button_diamond", "dpad"]: + group = groups_byid[number] + #print(group) + bindings = add_input_bindings(group, bindings) + + if s[0].lower() in ["left_trigger", "right_trigger"]: + group = groups_byid[number] + if group["mode"].lower() == "trigger": + for g in group: + if g.lower() == "gameactions": + #print(group) + action_name = group["gameactions"][name] + if s[0].lower() == "left_trigger": + binding = "LTRIGGER" + else: + binding = "RTRIGGER" + if action_name in bindings: + if binding not in bindings[action_name] and (binding + "=trigger") not in bindings[action_name]: + bindings[action_name].insert(0, binding) + else: + bindings[action_name] = [binding + "=trigger"] + if g.lower() == "inputs": + if s[0].lower() == "left_trigger": + binding = "DLTRIGGER" + else: + binding = "DRTRIGGER" + bindings = add_input_bindings(group, bindings, binding) + + else: + print("unhandled trigger mode", group["mode"]) + + if s[0].lower() in ["joystick", "right_joystick", "dpad"]: + group = groups_byid[number] + if group["mode"].lower() == "joystick_move": + for g in group: + if g.lower() == "gameactions": + #print(group) + action_name = group["gameactions"][name] + if s[0].lower() == "joystick": + binding = "LJOY" + elif s[0].lower() == "right_joystick": + binding = "RJOY" + elif s[0].lower() == "dpad": + binding = "DPAD" + else: + print("could not handle", s[0]) + if action_name in bindings: + if binding not in bindings[action_name] and (binding + "=joystick_move") not in bindings[action_name]: + bindings[action_name].insert(0, binding) + else: + bindings[action_name] = [binding + "=joystick_move"] + if g.lower() == "inputs": + if s[0].lower() == "joystick": + binding = "LSTICK" + else: + binding = "RSTICK" + bindings = add_input_bindings(group, bindings, binding) + + elif group["mode"].lower() == "dpad": + if s[0].lower() == "joystick": + binding_map = {"dpad_north":"DLJOYUP", "dpad_south": "DLJOYDOWN", "dpad_west": "DLJOYLEFT", "dpad_east": "DLJOYRIGHT", "click": "LSTICK"} + bindings = add_input_bindings(group, bindings, keymap=binding_map) + elif s[0].lower() == "right_joystick": + binding_map = {"dpad_north":"DRJOYUP", "dpad_south": "DRJOYDOWN", "dpad_west": "DRJOYLEFT", "dpad_east": "DRJOYRIGHT", "click": "RSTICK"} + bindings = add_input_bindings(group, bindings, keymap=binding_map) + else: + if s[0].lower() != "dpad": + print("no pad", s[0]) + else: + print("unhandled joy mode", group["mode"]) + + all_bindings[name] = bindings + + #print(controller_mappings["preset"][(0, "group_source_bindings")]) + + #print(all_bindings) + + if all_bindings: + if not os.path.exists(config_dir): + os.makedirs(config_dir) + + for k in all_bindings: + with open(os.path.join(config_dir, f'{k}.txt'), 'w', encoding='utf-8') as f: + for b in all_bindings[k]: + f.write(f"{b}=" + ','.join(all_bindings[k][b]) + "\n") + + +def help(): + exe_name = os.path.basename(sys.argv[0]) + print(f"\nUsage: {exe_name} xbox_controller_config.vdf [xbox360_controller_config.vdf] ... ") + print(f" Example: {exe_name} xbox_controller_config.vdf") + print(f" Example: {exe_name} xboxone_controller.vdf xbox360_controller.vdf") + print("\nAt least 1 .vdf file must be provided\n") + +if __name__ == '__main__': + if len(sys.argv) < 2: + help() + sys.exit(1) + + for vdf_file in sys.argv[1:]: + try: + print(f"parsing controller file '{vdf_file}'") + t = '' + with open(vdf_file, 'rb') as f: + t = f.read().decode('utf-8') + if t: + filename = os.path.basename(vdf_file) + outdir = os.path.join(f"{filename}_config", "steam_settings", "controller") + print(f"output dir: '{outdir}'") + generate_controller_config(t, outdir) + else: + print("[X] couldn't load file", file=sys.stderr) + + print('**********************************\n') + except Exception as e: + print("Unexpected error:") + print(e) + print("-----------------------") + for line in traceback.format_exception(e): + print(line) + print('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n') + + sys.exit(0) diff --git a/generate_emu_config_old/controller_config_generator/vdf/__init__.py b/generate_emu_config_old/controller_config_generator/vdf/__init__.py new file mode 100644 index 0000000..6b47213 --- /dev/null +++ b/generate_emu_config_old/controller_config_generator/vdf/__init__.py @@ -0,0 +1,521 @@ +""" +Module for deserializing/serializing to and from VDF +""" +__version__ = "3.4" +__author__ = "Rossen Georgiev" + +import re +import sys +import struct +from binascii import crc32 +from io import BytesIO +from io import StringIO as unicodeIO + +try: + from collections.abc import Mapping +except: + from collections import Mapping + +from vdf.vdict import VDFDict + +# Py2 & Py3 compatibility +if sys.version_info[0] >= 3: + string_type = str + int_type = int + BOMS = '\ufffe\ufeff' + + def strip_bom(line): + return line.lstrip(BOMS) +else: + from StringIO import StringIO as strIO + string_type = basestring + int_type = long + BOMS = '\xef\xbb\xbf\xff\xfe\xfe\xff' + BOMS_UNICODE = '\\ufffe\\ufeff'.decode('unicode-escape') + + def strip_bom(line): + return line.lstrip(BOMS if isinstance(line, str) else BOMS_UNICODE) + +# string escaping +_unescape_char_map = { + r"\n": "\n", + r"\t": "\t", + r"\v": "\v", + r"\b": "\b", + r"\r": "\r", + r"\f": "\f", + r"\a": "\a", + r"\\": "\\", + r"\?": "?", + r"\"": "\"", + r"\'": "\'", +} +_escape_char_map = {v: k for k, v in _unescape_char_map.items()} + +def _re_escape_match(m): + return _escape_char_map[m.group()] + +def _re_unescape_match(m): + return _unescape_char_map[m.group()] + +def _escape(text): + return re.sub(r"[\n\t\v\b\r\f\a\\\?\"']", _re_escape_match, text) + +def _unescape(text): + return re.sub(r"(\\n|\\t|\\v|\\b|\\r|\\f|\\a|\\\\|\\\?|\\\"|\\')", _re_unescape_match, text) + +# parsing and dumping for KV1 +def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): + """ + Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a VDF) + to a Python object. + + ``mapper`` specifies the Python object used after deserializetion. ``dict` is + used by default. Alternatively, ``collections.OrderedDict`` can be used if you + wish to preserve key order. Or any object that acts like a ``dict``. + + ``merge_duplicate_keys`` when ``True`` will merge multiple KeyValue lists with the + same key into one instead of overwriting. You can se this to ``False`` if you are + using ``VDFDict`` and need to preserve the duplicates. + """ + if not issubclass(mapper, Mapping): + raise TypeError("Expected mapper to be subclass of dict, got %s" % type(mapper)) + if not hasattr(fp, 'readline'): + raise TypeError("Expected fp to be a file-like object supporting line iteration") + + stack = [mapper()] + expect_bracket = False + + re_keyvalue = re.compile(r'^("(?P(?:\\.|[^\\"])*)"|(?P#?[a-z0-9\-\_\\\?$%<>]+))' + r'([ \t]*(' + r'"(?P(?:\\.|[^\\"])*)(?P")?' + r'|(?P(?:(? ])+)' + r'|(?P{[ \t]*)(?P})?' + r'))?', + flags=re.I) + + for lineno, line in enumerate(fp, 1): + if lineno == 1: + line = strip_bom(line) + + line = line.lstrip() + + # skip empty and comment lines + if line == "" or line[0] == '/': + continue + + # one level deeper + if line[0] == "{": + expect_bracket = False + continue + + if expect_bracket: + raise SyntaxError("vdf.parse: expected openning bracket", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 1, line)) + + # one level back + if line[0] == "}": + if len(stack) > 1: + stack.pop() + continue + + raise SyntaxError("vdf.parse: one too many closing parenthasis", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + # parse keyvalue pairs + while True: + match = re_keyvalue.match(line) + + if not match: + try: + line += next(fp) + continue + except StopIteration: + raise SyntaxError("vdf.parse: unexpected EOF (open key quote?)", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + key = match.group('key') if match.group('qkey') is None else match.group('qkey') + val = match.group('qval') + if val is None: + val = match.group('val') + if val is not None: + val = val.rstrip() + if val == "": + val = None + + if escaped: + key = _unescape(key) + + # we have a key with value in parenthesis, so we make a new dict obj (level deeper) + if val is None: + if merge_duplicate_keys and key in stack[-1]: + _m = stack[-1][key] + # we've descended a level deeper, if value is str, we have to overwrite it to mapper + if not isinstance(_m, mapper): + _m = stack[-1][key] = mapper() + else: + _m = mapper() + stack[-1][key] = _m + + if match.group('eblock') is None: + # only expect a bracket if it's not already closed or on the same line + stack.append(_m) + if match.group('sblock') is None: + expect_bracket = True + + # we've matched a simple keyvalue pair, map it to the last dict obj in the stack + else: + # if the value is line consume one more line and try to match again, + # until we get the KeyValue pair + if match.group('vq_end') is None and match.group('qval') is not None: + try: + line += next(fp) + continue + except StopIteration: + raise SyntaxError("vdf.parse: unexpected EOF (open quote for value?)", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + stack[-1][key] = _unescape(val) if escaped else val + + # exit the loop + break + + if len(stack) != 1: + raise SyntaxError("vdf.parse: unclosed parenthasis or quotes (EOF)", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + return stack.pop() + + +def loads(s, **kwargs): + """ + Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON + document) to a Python object. + """ + if not isinstance(s, string_type): + raise TypeError("Expected s to be a str, got %s" % type(s)) + + try: + fp = unicodeIO(s) + except TypeError: + fp = strIO(s) + + return parse(fp, **kwargs) + + +def load(fp, **kwargs): + """ + Deserialize ``fp`` (a ``.readline()``-supporting file-like object containing + a JSON document) to a Python object. + """ + return parse(fp, **kwargs) + + +def dumps(obj, pretty=False, escaped=True): + """ + Serialize ``obj`` to a VDF formatted ``str``. + """ + if not isinstance(obj, Mapping): + raise TypeError("Expected data to be an instance of``dict``") + if not isinstance(pretty, bool): + raise TypeError("Expected pretty to be of type bool") + if not isinstance(escaped, bool): + raise TypeError("Expected escaped to be of type bool") + + return ''.join(_dump_gen(obj, pretty, escaped)) + + +def dump(obj, fp, pretty=False, escaped=True): + """ + Serialize ``obj`` as a VDF formatted stream to ``fp`` (a + ``.write()``-supporting file-like object). + """ + if not isinstance(obj, Mapping): + raise TypeError("Expected data to be an instance of``dict``") + if not hasattr(fp, 'write'): + raise TypeError("Expected fp to have write() method") + if not isinstance(pretty, bool): + raise TypeError("Expected pretty to be of type bool") + if not isinstance(escaped, bool): + raise TypeError("Expected escaped to be of type bool") + + for chunk in _dump_gen(obj, pretty, escaped): + fp.write(chunk) + + +def _dump_gen(data, pretty=False, escaped=True, level=0): + indent = "\t" + line_indent = "" + + if pretty: + line_indent = indent * level + + for key, value in data.items(): + if escaped and isinstance(key, string_type): + key = _escape(key) + + if isinstance(value, Mapping): + yield '%s"%s"\n%s{\n' % (line_indent, key, line_indent) + for chunk in _dump_gen(value, pretty, escaped, level+1): + yield chunk + yield "%s}\n" % line_indent + else: + if escaped and isinstance(value, string_type): + value = _escape(value) + + yield '%s"%s" "%s"\n' % (line_indent, key, value) + + +# binary VDF +class BASE_INT(int_type): + def __repr__(self): + return "%s(%d)" % (self.__class__.__name__, self) + +class UINT_64(BASE_INT): + pass + +class INT_64(BASE_INT): + pass + +class POINTER(BASE_INT): + pass + +class COLOR(BASE_INT): + pass + +BIN_NONE = b'\x00' +BIN_STRING = b'\x01' +BIN_INT32 = b'\x02' +BIN_FLOAT32 = b'\x03' +BIN_POINTER = b'\x04' +BIN_WIDESTRING = b'\x05' +BIN_COLOR = b'\x06' +BIN_UINT64 = b'\x07' +BIN_END = b'\x08' +BIN_INT64 = b'\x0A' +BIN_END_ALT = b'\x0B' + +def binary_loads(b, mapper=dict, merge_duplicate_keys=True, alt_format=False, raise_on_remaining=True): + """ + Deserialize ``b`` (``bytes`` containing a VDF in "binary form") + to a Python object. + + ``mapper`` specifies the Python object used after deserializetion. ``dict` is + used by default. Alternatively, ``collections.OrderedDict`` can be used if you + wish to preserve key order. Or any object that acts like a ``dict``. + + ``merge_duplicate_keys`` when ``True`` will merge multiple KeyValue lists with the + same key into one instead of overwriting. You can se this to ``False`` if you are + using ``VDFDict`` and need to preserve the duplicates. + """ + if not isinstance(b, bytes): + raise TypeError("Expected s to be bytes, got %s" % type(b)) + + return binary_load(BytesIO(b), mapper, merge_duplicate_keys, alt_format, raise_on_remaining) + +def binary_load(fp, mapper=dict, merge_duplicate_keys=True, alt_format=False, raise_on_remaining=False): + """ + Deserialize ``fp`` (a ``.read()``-supporting file-like object containing + binary VDF) to a Python object. + + ``mapper`` specifies the Python object used after deserializetion. ``dict` is + used by default. Alternatively, ``collections.OrderedDict`` can be used if you + wish to preserve key order. Or any object that acts like a ``dict``. + + ``merge_duplicate_keys`` when ``True`` will merge multiple KeyValue lists with the + same key into one instead of overwriting. You can se this to ``False`` if you are + using ``VDFDict`` and need to preserve the duplicates. + """ + if not hasattr(fp, 'read') or not hasattr(fp, 'tell') or not hasattr(fp, 'seek'): + raise TypeError("Expected fp to be a file-like object with tell()/seek() and read() returning bytes") + if not issubclass(mapper, Mapping): + raise TypeError("Expected mapper to be subclass of dict, got %s" % type(mapper)) + + # helpers + int32 = struct.Struct(' 1: + stack.pop() + continue + break + + key = read_string(fp) + + if t == BIN_NONE: + if merge_duplicate_keys and key in stack[-1]: + _m = stack[-1][key] + else: + _m = mapper() + stack[-1][key] = _m + stack.append(_m) + elif t == BIN_STRING: + stack[-1][key] = read_string(fp) + elif t == BIN_WIDESTRING: + stack[-1][key] = read_string(fp, wide=True) + elif t in (BIN_INT32, BIN_POINTER, BIN_COLOR): + val = int32.unpack(fp.read(int32.size))[0] + + if t == BIN_POINTER: + val = POINTER(val) + elif t == BIN_COLOR: + val = COLOR(val) + + stack[-1][key] = val + elif t == BIN_UINT64: + stack[-1][key] = UINT_64(uint64.unpack(fp.read(int64.size))[0]) + elif t == BIN_INT64: + stack[-1][key] = INT_64(int64.unpack(fp.read(int64.size))[0]) + elif t == BIN_FLOAT32: + stack[-1][key] = float32.unpack(fp.read(float32.size))[0] + else: + raise SyntaxError("Unknown data type at offset %d: %s" % (fp.tell() - 1, repr(t))) + + if len(stack) != 1: + raise SyntaxError("Reached EOF, but Binary VDF is incomplete") + if raise_on_remaining and fp.read(1) != b'': + fp.seek(-1, 1) + raise SyntaxError("Binary VDF ended at offset %d, but there is more data remaining" % (fp.tell() - 1)) + + return stack.pop() + +def binary_dumps(obj, alt_format=False): + """ + Serialize ``obj`` to a binary VDF formatted ``bytes``. + """ + buf = BytesIO() + binary_dump(obj, buf, alt_format) + return buf.getvalue() + +def binary_dump(obj, fp, alt_format=False): + """ + Serialize ``obj`` to a binary VDF formatted ``bytes`` and write it to ``fp`` filelike object + """ + if not isinstance(obj, Mapping): + raise TypeError("Expected obj to be type of Mapping") + if not hasattr(fp, 'write'): + raise TypeError("Expected fp to have write() method") + + for chunk in _binary_dump_gen(obj, alt_format=alt_format): + fp.write(chunk) + +def _binary_dump_gen(obj, level=0, alt_format=False): + if level == 0 and len(obj) == 0: + return + + int32 = struct.Struct('= 3: + _iter_values = 'values' + _range = range + _string_type = str + import collections.abc as _c + class _kView(_c.KeysView): + def __iter__(self): + return self._mapping.iterkeys() + class _vView(_c.ValuesView): + def __iter__(self): + return self._mapping.itervalues() + class _iView(_c.ItemsView): + def __iter__(self): + return self._mapping.iteritems() +else: + _iter_values = 'itervalues' + _range = xrange + _string_type = basestring + _kView = lambda x: list(x.iterkeys()) + _vView = lambda x: list(x.itervalues()) + _iView = lambda x: list(x.iteritems()) + + +class VDFDict(dict): + def __init__(self, data=None): + """ + This is a dictionary that supports duplicate keys and preserves insert order + + ``data`` can be a ``dict``, or a sequence of key-value tuples. (e.g. ``[('key', 'value'),..]``) + The only supported type for key is str. + + Get/set duplicates is done by tuples ``(index, key)``, where index is the duplicate index + for the specified key. (e.g. ``(0, 'key')``, ``(1, 'key')``...) + + When the ``key`` is ``str``, instead of tuple, set will create a duplicate and get will look up ``(0, key)`` + """ + self.__omap = [] + self.__kcount = Counter() + + if data is not None: + if not isinstance(data, (list, dict)): + raise ValueError("Expected data to be list of pairs or dict, got %s" % type(data)) + self.update(data) + + def __repr__(self): + out = "%s(" % self.__class__.__name__ + out += "%s)" % repr(list(self.iteritems())) + return out + + def __len__(self): + return len(self.__omap) + + def _verify_key_tuple(self, key): + if len(key) != 2: + raise ValueError("Expected key tuple length to be 2, got %d" % len(key)) + if not isinstance(key[0], int): + raise TypeError("Key index should be an int") + if not isinstance(key[1], _string_type): + raise TypeError("Key value should be a str") + + def _normalize_key(self, key): + if isinstance(key, _string_type): + key = (0, key) + elif isinstance(key, tuple): + self._verify_key_tuple(key) + else: + raise TypeError("Expected key to be a str or tuple, got %s" % type(key)) + return key + + def __setitem__(self, key, value): + if isinstance(key, _string_type): + key = (self.__kcount[key], key) + self.__omap.append(key) + elif isinstance(key, tuple): + self._verify_key_tuple(key) + if key not in self: + raise KeyError("%s doesn't exist" % repr(key)) + else: + raise TypeError("Expected either a str or tuple for key") + super(VDFDict, self).__setitem__(key, value) + self.__kcount[key[1]] += 1 + + def __getitem__(self, key): + return super(VDFDict, self).__getitem__(self._normalize_key(key)) + + def __delitem__(self, key): + key = self._normalize_key(key) + result = super(VDFDict, self).__delitem__(key) + + start_idx = self.__omap.index(key) + del self.__omap[start_idx] + + dup_idx, skey = key + self.__kcount[skey] -= 1 + tail_count = self.__kcount[skey] - dup_idx + + if tail_count > 0: + for idx in _range(start_idx, len(self.__omap)): + if self.__omap[idx][1] == skey: + oldkey = self.__omap[idx] + newkey = (dup_idx, skey) + super(VDFDict, self).__setitem__(newkey, self[oldkey]) + super(VDFDict, self).__delitem__(oldkey) + self.__omap[idx] = newkey + + dup_idx += 1 + tail_count -= 1 + if tail_count == 0: + break + + if self.__kcount[skey] == 0: + del self.__kcount[skey] + + return result + + def __iter__(self): + return iter(self.iterkeys()) + + def __contains__(self, key): + return super(VDFDict, self).__contains__(self._normalize_key(key)) + + def __eq__(self, other): + if isinstance(other, VDFDict): + return list(self.items()) == list(other.items()) + else: + return False + + def __ne__(self, other): + return not self.__eq__(other) + + def clear(self): + super(VDFDict, self).clear() + self.__kcount.clear() + self.__omap = list() + + def get(self, key, *args): + return super(VDFDict, self).get(self._normalize_key(key), *args) + + def setdefault(self, key, default=None): + if key not in self: + self.__setitem__(key, default) + return self.__getitem__(key) + + def pop(self, key): + key = self._normalize_key(key) + value = self.__getitem__(key) + self.__delitem__(key) + return value + + def popitem(self): + if not self.__omap: + raise KeyError("VDFDict is empty") + key = self.__omap[-1] + return key[1], self.pop(key) + + def update(self, data=None, **kwargs): + if isinstance(data, dict): + data = data.items() + elif not isinstance(data, list): + raise TypeError("Expected data to be a list or dict, got %s" % type(data)) + + for key, value in data: + self.__setitem__(key, value) + + def iterkeys(self): + return (key[1] for key in self.__omap) + + def keys(self): + return _kView(self) + + def itervalues(self): + return (self[key] for key in self.__omap) + + def values(self): + return _vView(self) + + def iteritems(self): + return ((key[1], self[key]) for key in self.__omap) + + def items(self): + return _iView(self) + + def get_all_for(self, key): + """ Returns all values of the given key """ + if not isinstance(key, _string_type): + raise TypeError("Key needs to be a string.") + return [self[(idx, key)] for idx in _range(self.__kcount[key])] + + def remove_all_for(self, key): + """ Removes all items with the given key """ + if not isinstance(key, _string_type): + raise TypeError("Key need to be a string.") + + for idx in _range(self.__kcount[key]): + super(VDFDict, self).__delitem__((idx, key)) + + self.__omap = list(filter(lambda x: x[1] != key, self.__omap)) + + del self.__kcount[key] + + def has_duplicates(self): + """ + Returns ``True`` if the dict contains keys with duplicates. + Recurses through any all keys with value that is ``VDFDict``. + """ + for n in getattr(self.__kcount, _iter_values)(): + if n != 1: + return True + + def dict_recurse(obj): + for v in getattr(obj, _iter_values)(): + if isinstance(v, VDFDict) and v.has_duplicates(): + return True + elif isinstance(v, dict): + return dict_recurse(v) + return False + + return dict_recurse(self) diff --git a/generate_emu_config_old/external_components/ach_watcher_gen.py b/generate_emu_config_old/external_components/ach_watcher_gen.py new file mode 100644 index 0000000..7cea6ad --- /dev/null +++ b/generate_emu_config_old/external_components/ach_watcher_gen.py @@ -0,0 +1,173 @@ +import copy +import os +import time +import json + +def __ClosestDictKey(targetKey : str, srcDict : dict[str, object] | set[str]) -> str | None: + for k in srcDict: + if k.lower() == f"{targetKey}".lower(): + return k + + return None + +def __generate_ach_watcher_schema(lang: str, app_id: int, achs: list[dict]) -> list[dict]: + out_achs_list = [] + for idx in range(len(achs)): + ach = copy.deepcopy(achs[idx]) + out_ach_data = {} + + # adjust the displayName + displayName = "" + ach_displayName = ach.get("displayName", None) + if ach_displayName: + if type(ach_displayName) == dict: # this is a dictionary + displayName : str = ach_displayName.get(lang, "") + if not displayName and ach_displayName: # has some keys but language not found + #print(f'[?] Missing language "{lang}" in "displayName" of achievement {ach["name"]}') + nearestLang = __ClosestDictKey(lang, ach_displayName) + if nearestLang: + #print(f'[?] Best matching language "{nearestLang}"') + displayName = ach_displayName[nearestLang] + else: + print(f'[?] Missing language "{lang}", using displayName from the first language for achievement {ach["name"]}') + displayName : str = list(ach_displayName.values())[0] + else: # single string (or anything else) + displayName = ach_displayName + + del ach["displayName"] + else: + print(f'[?] Missing "displayName" in achievement {ach["name"]}') + + out_ach_data["displayName"] = displayName + + desc = "" + ach_desc = ach.get("description", None) + if ach_desc: + if type(ach_desc) == dict: # this is a dictionary + desc : str = ach_desc.get(lang, "") + if not desc and ach_desc: # has some keys but language not found + #print(f'[?] Missing language "{lang}" in "description" of achievement {ach["name"]}') + nearestLang = __ClosestDictKey(lang, ach_desc) + if nearestLang: + #print(f'[?] Best matching language "{nearestLang}"') + desc = ach_desc[nearestLang] + else: + print(f'[?] Missing language "{lang}", using description from the first language for achievement {ach["name"]}') + desc : str = list(ach_desc.values())[0] + else: # single string (or anything else) + desc = ach_desc + + del ach["description"] + else: + print(f'[?] Missing "description" in achievement {ach["name"]}') + + # adjust the description + out_ach_data["description"] = desc + + # copy the rest of the data + out_ach_data.update(ach) + + # add links to icon, icongray, and icon_gray + base_icon_url = r'https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps' + icon_hash = out_ach_data.get("icon", None) + if icon_hash: + out_ach_data["icon"] = f'{base_icon_url}/{app_id}/{icon_hash}' + else: + out_ach_data["icon"] = "" + + icongray_hash = out_ach_data.get("icongray", None) + if icongray_hash: + out_ach_data["icongray"] = f'{base_icon_url}/{app_id}/{icongray_hash}' + else: + out_ach_data["icongray"] = "" + + icon_gray_hash = out_ach_data.get("icon_gray", None) + if icon_gray_hash: + del out_ach_data["icon_gray"] # use the old key + out_ach_data["icongray"] = f'{base_icon_url}/{app_id}/{icon_gray_hash}' + + if "hidden" in out_ach_data: + try: + out_ach_data["hidden"] = int(out_ach_data["hidden"]) + except Exception as e: + pass + else: + out_ach_data["hidden"] = 0 + + out_achs_list.append(out_ach_data) + + return out_achs_list + +def generate_all_ach_watcher_schemas( + base_out_dir : str, + appid: int, + app_name : str, + app_exe : str, + achs: list[dict], + small_icon_hash : str) -> None: + + ach_watcher_out_dir = os.path.join(base_out_dir, "Achievement Watcher", "steam_cache", "schema") + print(f"generating schemas for Achievement Watcher in: {ach_watcher_out_dir}") + + if app_exe: + print(f"detected app exe: '{app_exe}'") + else: + print(f"[X] couldn't detect app exe") + + # if not achs: + # print("[X] No achievements were found for Achievement Watcher") + # return + + small_icon_url = '' + if small_icon_hash: + small_icon_url = f"https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/{appid}/{small_icon_hash}.jpg" + images_base_url = r'https://cdn.cloudflare.steamstatic.com/steam/apps' + ach_watcher_base_schema = { + "appid": appid, + "name": app_name, + "binary": app_exe, + "achievement": { + "total": len(achs), + }, + "img": { + "header": f"{images_base_url}/{appid}/header.jpg", + "background": f"{images_base_url}/{appid}/page_bg_generated_v6b.jpg", + "portrait": f"{images_base_url}/{appid}/library_600x900.jpg", + "hero": f"{images_base_url}/{appid}/library_hero.jpg", + "icon": small_icon_url, + }, + "apiVersion": 1, + } + + langs : set[str] = set() + for ach in achs: + displayNameLangs = ach.get("displayName", None) + if displayNameLangs and type(displayNameLangs) == dict: + langs.update(list(displayNameLangs.keys())) + + descriptionLangs = ach.get("description", None) + if descriptionLangs and type(descriptionLangs) == dict: + langs.update(list(descriptionLangs.keys())) + + if "token" in langs: + langs.remove("token") + + tokenKey = __ClosestDictKey("token", langs) + if tokenKey: + langs.remove(tokenKey) + + if not langs: + print("[X] Couldn't detect supported languages, assuming English is the only supported language for Achievement Watcher") + langs = ["english"] + + for lang in langs: + out_schema_folder = os.path.join(ach_watcher_out_dir, lang) + if not os.path.exists(out_schema_folder): + os.makedirs(out_schema_folder) + time.sleep(0.050) + + out_schema = copy.copy(ach_watcher_base_schema) + out_schema["achievement"]["list"] = __generate_ach_watcher_schema(lang, appid, achs) + out_schema_file = os.path.join(out_schema_folder, f'{appid}.db') + with open(out_schema_file, "wt", encoding='utf-8') as f: + json.dump(out_schema, f, ensure_ascii=False, indent=2) diff --git a/generate_emu_config_old/external_components/app_details.py b/generate_emu_config_old/external_components/app_details.py new file mode 100644 index 0000000..e8ee7b3 --- /dev/null +++ b/generate_emu_config_old/external_components/app_details.py @@ -0,0 +1,234 @@ +import os +import sys +import traceback +import json +import queue +import threading +import time +import requests +import urllib.parse +from external_components import ( + safe_name +) + +def __downloader_thread(q : queue.Queue[tuple[str, str]]): + while True: + url, path = q.get() + if not url: + q.task_done() + return + + # try 3 times + for download_trial in range(3): + try: + r = requests.get(url) + r.raise_for_status() + if r.status_code == requests.codes.ok: # if download was successfull + with open(path, "wb") as f: + f.write(r.content) + + break + except Exception as e: + print(f"Error downloading from '{url}'", file=sys.stderr) + traceback.print_exception(e, file=sys.stderr) + + time.sleep(0.1) + + q.task_done() + +def __remove_url_query(url : str) -> str: + url_parts = urllib.parse.urlsplit(url) + url_parts_list = list(url_parts) + url_parts_list[3] = '' # remove query + return str(urllib.parse.urlunsplit(url_parts_list)) + +def __download_screenshots( + base_out_dir : str, + appid : int, + app_details : dict, + download_screenshots : bool, + download_thumbnails : bool): + if not download_screenshots and not download_thumbnails: + return + + screenshots : list[dict[str, object]] = app_details.get(f'{appid}', {}).get('data', {}).get('screenshots', []) + if not screenshots: + print(f'[?] no screenshots or thumbnails are available') + return + + screenshots_out_dir = os.path.join(base_out_dir, "screenshots") + if download_screenshots: + print(f"downloading screenshots in: {screenshots_out_dir}") + if not os.path.exists(screenshots_out_dir): + os.makedirs(screenshots_out_dir) + time.sleep(0.025) + + thumbnails_out_dir = os.path.join(screenshots_out_dir, "thumbnails") + if download_thumbnails: + print(f"downloading screenshots thumbnails in: {thumbnails_out_dir}") + if not os.path.exists(thumbnails_out_dir): + os.makedirs(thumbnails_out_dir) + time.sleep(0.025) + + q : queue.Queue[tuple[str, str]] = queue.Queue() + + max_threads = 20 + for i in range(max_threads): + threading.Thread(target=__downloader_thread, args=(q,), daemon=True).start() + + for scrn in screenshots: + if download_screenshots: + full_image_url = scrn.get('path_full', None) + if full_image_url: + full_image_url_sanitized = __remove_url_query(full_image_url) + image_hash_name = f'{full_image_url_sanitized.rsplit("/", 1)[-1]}'.rstrip() + if image_hash_name: + q.put((full_image_url_sanitized, os.path.join(screenshots_out_dir, image_hash_name))) + else: + print(f'[X] cannot download screenshot from url: "{full_image_url}", failed to get image name') + + if download_thumbnails: + thumbnail_url = scrn.get('path_thumbnail', None) + if thumbnail_url: + thumbnail_url_sanitized = __remove_url_query(thumbnail_url) + image_hash_name = f'{thumbnail_url_sanitized.rsplit("/", 1)[-1]}'.rstrip() + if image_hash_name: + q.put((thumbnail_url_sanitized, os.path.join(thumbnails_out_dir, image_hash_name))) + else: + print(f'[X] cannot download screenshot thumbnail from url: "{thumbnail_url}", failed to get image name') + + q.join() + + for i in range(max_threads): + q.put((None, None)) + + q.join() + + print(f"finished downloading app screenshots") + +PREFERED_VIDS = [ + 'trailer', 'gameplay', 'announcement' +] + +def __download_videos(base_out_dir : str, appid : int, app_details : dict): + videos : list[dict[str, object]] = app_details.get(f'{appid}', {}).get('data', {}).get('movies', []) + if not videos: + print(f'[?] no videos were found') + return + + videos_out_dir = os.path.join(base_out_dir, "videos") + print(f"downloading app videos in: {videos_out_dir}") + + first_vid : tuple[str, str] = None + prefered_vid : tuple[str, str] = None + for vid in videos: + vid_name = f"{vid.get('name', '')}" + webm_url = vid.get('webm', {}).get("480", None) + mp4_url = vid.get('mp4', {}).get("480", None) + + ext : str = None + prefered_url : str = None + if mp4_url: + prefered_url = mp4_url + ext = 'mp4' + elif webm_url: + prefered_url = webm_url + ext = 'webm' + else: # no url is found + print(f'[X] no url is found for video "{vid_name}"') + continue + + vid_url_sanitized = __remove_url_query(prefered_url) + vid_name_in_url = f'{vid_url_sanitized.rsplit("/", 1)[-1]}'.rstrip() + vid_name = safe_name.create_safe_name(vid_name) + if vid_name: + vid_name = f'{vid_name}.{ext}' + else: + vid_name = vid_name_in_url + + if vid_name: + if not first_vid: + first_vid = (vid_url_sanitized, vid_name) + + if any(vid_name.lower().find(candidate) > -1 for candidate in PREFERED_VIDS): + prefered_vid = (vid_url_sanitized, vid_name) + + if prefered_vid: + break + else: + print(f'[X] cannot download video from url: "{prefered_url}", failed to get vido name') + + if not first_vid and not prefered_vid: + print(f'[X] no video url could be found') + return + elif not prefered_vid: + prefered_vid = first_vid + + if not os.path.exists(videos_out_dir): + os.makedirs(videos_out_dir) + time.sleep(0.05) + + q : queue.Queue[tuple[str, str]] = queue.Queue() + + max_threads = 1 + for i in range(max_threads): + threading.Thread(target=__downloader_thread, args=(q,), daemon=True).start() + + # TODO download all videos + print(f'donwloading video: "{prefered_vid[1]}"') + q.put((prefered_vid[0], os.path.join(videos_out_dir, prefered_vid[1]))) + q.join() + + for i in range(max_threads): + q.put((None, None)) + + q.join() + + print(f"finished downloading app videos") + + +def download_app_details( + base_out_dir : str, + info_out_dir : str, + appid : int, + download_screenshots : bool, + download_thumbnails : bool, + download_vids : bool): + + details_out_file = os.path.join(info_out_dir, "app_details.json") + print(f"downloading app details in: {details_out_file}") + + app_details : dict = None + last_exception : Exception | str = None + # try 3 times + for download_trial in range(3): + try: + r = requests.get(f'http://store.steampowered.com/api/appdetails?appids={appid}&format=json') + if r.status_code == requests.codes.ok: # if download was successfull + result : dict = r.json() + json_ok = result.get(f'{appid}', {}).get('success', False) + if json_ok: + app_details = result + break + else: + last_exception = "JSON success was False" + except Exception as e: + last_exception = e + + time.sleep(0.1) + + if not app_details: + err = "[X] failed to download app details" + if last_exception: + err += f', last error: "{last_exception}"' + + print(err) + return + + with open(details_out_file, "wt", encoding='utf-8') as f: + json.dump(app_details, f, ensure_ascii=False, indent=2) + + __download_screenshots(base_out_dir, appid, app_details, download_screenshots, download_thumbnails) + + if download_vids: + __download_videos(base_out_dir, appid, app_details) diff --git a/generate_emu_config_old/external_components/app_images.py b/generate_emu_config_old/external_components/app_images.py new file mode 100644 index 0000000..63139f1 --- /dev/null +++ b/generate_emu_config_old/external_components/app_images.py @@ -0,0 +1,94 @@ +import os +import threading +import time +import requests + + +def download_app_images( + base_out_dir : str, + appid : int, + clienticon : str, + icon : str, + logo : str, + logo_small : str): + + icons_out_dir = os.path.join(base_out_dir, "images") + print(f"downloading common app images in: {icons_out_dir}") + + def downloader_thread(image_name : str, image_url : str): + # try 3 times + for download_trial in range(3): + try: + r = requests.get(image_url) + if r.status_code == requests.codes.ok: # if download was successfull + with open(os.path.join(icons_out_dir, image_name), "wb") as f: + f.write(r.content) + + break + except Exception as ex: + pass + + time.sleep(0.1) + + app_images_names = [ + r'capsule_184x69.jpg', + r'capsule_231x87.jpg', + r'capsule_231x87_alt_assets_0.jpg', + r'capsule_467x181.jpg', + r'capsule_616x353.jpg', + r'capsule_616x353_alt_assets_0.jpg', + r'library_600x900.jpg', + r'library_600x900_2x.jpg', + r'library_hero.jpg', + r'broadcast_left_panel.jpg', + r'broadcast_right_panel.jpg', + r'page.bg.jpg', + r'page_bg_raw.jpg', + r'page_bg_generated.jpg', + r'page_bg_generated_v6b.jpg', + r'header.jpg', + r'header_alt_assets_0.jpg', + r'hero_capsule.jpg', + r'logo.png', + ] + + if not os.path.exists(icons_out_dir): + os.makedirs(icons_out_dir) + time.sleep(0.050) + + threads_list : list[threading.Thread] = [] + for image_name in app_images_names: + image_url = f'https://cdn.cloudflare.steamstatic.com/steam/apps/{appid}/{image_name}' + t = threading.Thread(target=downloader_thread, args=(image_name, image_url), daemon=True) + threads_list.append(t) + t.start() + + community_images_url = f'https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/{appid}' + if clienticon: + image_url = f'{community_images_url}/{clienticon}.ico' + t = threading.Thread(target=downloader_thread, args=('clienticon.ico', image_url), daemon=True) + threads_list.append(t) + t.start() + + if icon: + image_url = f'{community_images_url}/{icon}.jpg' + t = threading.Thread(target=downloader_thread, args=('icon.jpg', image_url), daemon=True) + threads_list.append(t) + t.start() + + if logo: + image_url = f'{community_images_url}/{logo}.jpg' + t = threading.Thread(target=downloader_thread, args=('logo.jpg', image_url), daemon=True) + threads_list.append(t) + t.start() + + if logo_small: + image_url = f'{community_images_url}/{logo_small}.jpg' + t = threading.Thread(target=downloader_thread, args=('logo_small.jpg', image_url), daemon=True) + threads_list.append(t) + t.start() + + for t in threads_list: + t.join() + + print(f"finished downloading common app images") \ No newline at end of file diff --git a/generate_emu_config_old/external_components/cdx_gen.py b/generate_emu_config_old/external_components/cdx_gen.py new file mode 100644 index 0000000..e3a06ae --- /dev/null +++ b/generate_emu_config_old/external_components/cdx_gen.py @@ -0,0 +1,157 @@ +import os + +__cdx_ini = ''' +### мллллл м +### Алллл плл лВ ппплллллллм пппппллВллм мВлллп +### Блллп Бллп ппллллА пллл Блллп +### Вллл п ллВ плллБ АллВллл +### Вллл млллллм ллл пллл мллллллм Бллллл +### лллА Аллллп плВ ллл лллВллВ Алл лллВллл +### Бллл ллллА лл ллл Алллллллллллп лллБ Бллл +### Алллм мллпВллм млл Влл лллБлллА млллА Алллм +### плллллп плллВп ллп АлллА плллллллВлп пВллм +### мллллллБ +### пппллВмммммлВлллВпп +### +### +### Game data is stored at %SystemDrive%\\Users\\Public\\Documents\\Steam\\CODEX\\{cdx_id} +### + +[Settings] +### +### Game identifier (http://store.steampowered.com/app/{cdx_id}) +### +AppId={cdx_id} +### +### Steam Account ID, set it to 0 to get a random Account ID +### +#AccountId=0 +### +### Name of the current player +### +UserName=Player2 +### +### Language that will be used in the game +### +Language=english +### +### Enable lobby mode +### +LobbyEnabled=1 +### +### Lobby port to listen on +### +#LobbyPort=31183 +### +### Enable/Disable Steam overlay +### +Overlays=1 +### +### Set Steam connection to offline mode +### +Offline=0 +### + +[Interfaces] +### +### Steam Client API interface versions +### +SteamAppList=STEAMAPPLIST_INTERFACE_VERSION001 +SteamApps=STEAMAPPS_INTERFACE_VERSION008 +SteamClient=SteamClient017 +SteamController=SteamController008 +SteamFriends=SteamFriends017 +SteamGameServer=SteamGameServer013 +SteamGameServerStats=SteamGameServerStats001 +SteamHTMLSurface=STEAMHTMLSURFACE_INTERFACE_VERSION_005 +SteamHTTP=STEAMHTTP_INTERFACE_VERSION003 +SteamInput=SteamInput002 +SteamInventory=STEAMINVENTORY_INTERFACE_V003 +SteamMatchGameSearch=SteamMatchGameSearch001 +SteamMatchMaking=SteamMatchMaking009 +SteamMatchMakingServers=SteamMatchMakingServers002 +SteamMusic=STEAMMUSIC_INTERFACE_VERSION001 +SteamMusicRemote=STEAMMUSICREMOTE_INTERFACE_VERSION001 +SteamNetworking=SteamNetworking006 +SteamNetworkingSockets=SteamNetworkingSockets008 +SteamNetworkingUtils=SteamNetworkingUtils003 +SteamParentalSettings=STEAMPARENTALSETTINGS_INTERFACE_VERSION001 +SteamParties=SteamParties002 +SteamRemotePlay=STEAMREMOTEPLAY_INTERFACE_VERSION001 +SteamRemoteStorage=STEAMREMOTESTORAGE_INTERFACE_VERSION014 +SteamScreenshots=STEAMSCREENSHOTS_INTERFACE_VERSION003 +SteamTV=STEAMTV_INTERFACE_V001 +SteamUGC=STEAMUGC_INTERFACE_VERSION015 +SteamUser=SteamUser021 +SteamUserStats=STEAMUSERSTATS_INTERFACE_VERSION012 +SteamUtils=SteamUtils010 +SteamVideo=STEAMVIDEO_INTERFACE_V002 +### + +[DLC] +### +### Automatically unlock all DLCs +### +DLCUnlockall=0 +### +### Identifiers for DLCs +### +#ID=Name +{cdx_dlc_list} +### + +[AchievementIcons] +### +### Bitmap Icons for Achievements +### +#halloween_8 Achieved=steam_settings\\img\\halloween_8.jpg +#halloween_8 Unachieved=steam_settings\\img\\unachieved\\halloween_8.jpg +{cdx_ach_list} +### + +[Crack] +00ec7837693245e3=b7d5bc716512b5d6 + +''' + + +def generate_cdx_ini( + base_out_dir : str, + appid: int, + dlc: list[tuple[int, str]], + achs: list[dict]) -> None: + + cdx_ini_path = os.path.join(base_out_dir, "steam_emu.ini") + print(f"generating steam_emu.ini for CODEX emulator in: {cdx_ini_path}") + + dlc_list = [f"{d[0]}={d[1]}" for d in dlc] + achs_list = [] + for ach in achs: + icon = ach.get("icon", None) + if icon: + icon = f"steam_settings\\img\\{icon}" + else: + icon = 'steam_settings\\img\\steam_default_icon_unlocked.jpg' + + icon_gray = ach.get("icon_gray", None) + if icon_gray: + icon_gray = f"steam_settings\\img\\{icon_gray}" + else: + icon_gray = 'steam_settings\\img\\steam_default_icon_locked.jpg' + + icongray = ach.get("icongray", None) + if icongray: + icon_gray = f"steam_settings\\img\\{icongray}" + + achs_list.append(f'{ach["name"]} Achieved={icon}') # unlocked + achs_list.append(f'{ach["name"]} Unachieved={icon_gray}') # locked + + formatted_ini = __cdx_ini.format( + cdx_id = appid, + cdx_dlc_list = "\n".join(dlc_list), + cdx_ach_list = "\n".join(achs_list) + ) + + with open(cdx_ini_path, "wt", encoding='utf-8') as f: + f.writelines(formatted_ini) + diff --git a/generate_emu_config_old/external_components/safe_name.py b/generate_emu_config_old/external_components/safe_name.py new file mode 100644 index 0000000..e0cbb20 --- /dev/null +++ b/generate_emu_config_old/external_components/safe_name.py @@ -0,0 +1,22 @@ + +import re + + +ALLOWED_CHARS = set([ + '`', '~', '!', '@', + '#', '$', '%', '&', + '(', ')', '-', '_', + '=', '+', '[', '{', + ']', '}', ';', '\'', + ',', '.', ' ', '\t', + '®', '™', +]) + +def create_safe_name(app_name : str): + safe_name = ''.join(c for c in f'{app_name}' if c.isalnum() or c in ALLOWED_CHARS)\ + .rstrip()\ + .rstrip('.')\ + .replace('\t', ' ') + safe_name = re.sub('\s\s+', ' ', safe_name) + return safe_name + diff --git a/generate_emu_config_old/generate_emu_config.py b/generate_emu_config_old/generate_emu_config.py new file mode 100644 index 0000000..5b754f1 --- /dev/null +++ b/generate_emu_config_old/generate_emu_config.py @@ -0,0 +1,1096 @@ +import pathlib +import time +from stats_schema_achievement_gen import achievements_gen +from external_components import ( + ach_watcher_gen, cdx_gen, app_images, app_details, safe_name +) +from controller_config_generator import parse_controller_vdf +from steam.client import SteamClient +from steam.webauth import WebAuth +from steam.enums.common import EResult +from steam.enums.emsg import EMsg +from steam.core.msg import MsgProto +import os +import sys +import json +import requests +import threading +import queue +import shutil +import traceback + + +#steam ids with public profiles that own a lot of games +# https://steamladder.com/ladder/games/ +# in browser console: +#const links = $x("/html/body/div[3]/table/tbody/tr/td[2]/a[@href]/@href"); +#console.clear(); +#for (let index = 0; index < links.length; index++) { +# const usr_link = links[index].textContent.split('/').filter(s => s); +# const usr_id = usr_link[usr_link.length - 1] +# console.log(usr_id) +#} +TOP_OWNER_IDS = list(dict.fromkeys([ + 76561198213148949, + 76561198108581917, + 76561198028121353, + 76561197979911851, + 76561198355625888, + 76561198237402290, + 76561197969050296, + 76561198152618007, + 76561198001237877, + 76561198037867621, + 76561198001678750, + 76561198217186687, + 76561198094227663, + 76561197993544755, + 76561197963550511, + 76561198095049646, + 76561197973009892, + 76561197969810632, + 76561198388522904, + 76561198864213876, + 76561198166734878, + # 76561198017975643, + # 76561198044596404, + # 76561197976597747, + # 76561197962473290, + # 76561197976968076, + # 76561198235911884, + # 76561198313790296, + # 76561198407953371, + # 76561198063574735, + # 76561198122859224, + # 76561198154462478, + # 76561197996432822, + # 76561197979667190, + # 76561198139084236, + # 76561198842864763, + # 76561198096081579, + # 76561198019712127, + # 76561198033715344, + # 76561198121398682, + # 76561198027233260, + # 76561198104323854, + # 76561197995070100, + # 76561198001221571, + # 76561198005337430, + # 76561198085065107, + # 76561198027214426, + # 76561198062901118, + # 76561198008181611, + # 76561198124872187, + # 76561198048373585, + # 76561197974742349, + # 76561198040421250, + # 76561198017902347, + # 76561198010615256, + # 76561197970825215, + # 76561198077213101, + # 76561197971011821, + # 76561197992133229, + # 76561197963534359, + # 76561198077248235, + # 76561198152760885, + # 76561198256917957, + # 76561198326510209, + # 76561198019009765, + # 76561198047438206, + # 76561198128158703, + # 76561198037809069, + # 76561198121336040, + # 76561198102767019, + # 76561198063728345, + # 76561198082995144, + # 76561197981111953, + # 76561197995008105, + # 76561198109083829, + # 76561197968410781, + # 76561198808371265, + # 76561198025858988, + # 76561198252374474, + # 76561198382166453, + # 76561198396723427, + # 76561197992548975, + # 76561198134044398, + # 76561198029503957, + # 76561197990233857, + # 76561197971026489, + # 76561197965978376, + # 76561197976796589, + # 76561197994616562, + # 76561197984235967, + # 76561197992967892, + # 76561198097945516, + # 76561198251835488, + # 76561198281128349, + # 76561198044387084, + # 76561198015685843, + # 76561197993312863, + # 76561198020125851, + # 76561198006391846, + # 76561198158932704, + # 76561198039492467, + # 76561198035552258, + # 76561198031837797, + # 76561197982718230, + # 76561198025653291, + # 76561197972951657, + # 76561198269242105, + # 76561198004332929, + # 76561197972378106, + # 76561197962630138, + # 76561198192399786, + # 76561198119667710, + # 76561198120120943, + # 76561198015992850, + # 76561198096632451, + # 76561198008797636, + # 76561198118726910, + # 76561198018254158, + # 76561198061393233, + # 76561198086250077, + # 76561198025391492, + # 76561198050474710, + # 76561197997477460, + # 76561198105279930, + # 76561198026221141, + # 76561198443388781, + # 76561197981228012, + # 76561197986240493, + # 76561198003041763, + # 76561198056971296, + # 76561198072936438, + # 76561198264362271, + # 76561198101049562, + # 76561198831075066, + # 76561197991699268, + # 76561198042965266, + # 76561198019555404, + # 76561198111433283, + # 76561197984010356, + # 76561198427572372, + # 76561198071709714, + # 76561198034213886, + # 76561198846208086, + # 76561197991613008, + # 76561197978640923, + # 76561198009596142, + # 76561199173688191, + # 76561198294806446, + # 76561197992105918, + # 76561198155124847, + # 76561198032614383, + # 76561198051740093, + # 76561198051725954, + # 76561198048151962, + # 76561198172367910, + # 76561198043532513, + # 76561198029532782, + # 76561198106145311, + # 76561198020746864, + # 76561198122276418, + # 76561198844130640, + # 76561198890581618, + # 76561198021180815, + # 76561198046642155, + # 76561197985091630, + # 76561198119915053, + # 76561198318547224, + # 76561198426000196, + # 76561197988052802, + # 76561198008549198, + # 76561198054210948, + # 76561198028011423, + # 76561198026306582, + # 76561198079227501, + # 76561198070220549, + # 76561198034503074, + # 76561198172925593, + # 76561198286209051, + # 76561197998058239, + # 76561198057648189, + # 76561197982273259, + # 76561198093579202, + # 76561198035612474, + # 76561197970307937, + # 76561197996825541, + # 76561197981027062, + # 76561198019841907, + # 76561197970727958, + # 76561197967716198, + # 76561197970545939, + # 76561198315929726, + # 76561198093753361, + # 76561198413266831, + # 76561198045540632, + # 76561198015514779, + # 76561198004532679, + # 76561198080773680, + # 76561198079896896, + # 76561198005299723, + # 76561198337784749, + # 76561198150126284, + # 76561197988445370, + # 76561198258304011, + # 76561198321551799, + # 76561197973701057, + # 76561197973230221, + # 76561198002535276, + # 76561198100306249, + # 76561198116086535, + # 76561197970970678, + # 76561198085238363, + # 76561198007200913, + # 76561198025111129, + # 76561198068747739, + # 76561197970539274, + # 76561198148627568, + # 76561197970360549, + # 76561198098314980, + # 76561197972529138, + # 76561198007403855, + # 76561197977403803, + # 76561198124865933, + # 76561197981323238, + # 76561197960330700, + # 76561198217979953, + # 76561197960366517, + # 76561198044067612, + # 76561197967197052, + # 76561198027066612, + # 76561198072833066, + # 76561198033967307, + # 76561198104561325, + # 76561198272374716, + # 76561197970127197, + # 76561197970257188, + # 76561198026921217, + # 76561198027904347, + # 76561198062469228, + # 76561198026278913, + # 76561197970548935, + # 76561197966617426, + # 76561198356842617, + # 76561198034276722, + # 76561198355953202, + # 76561197986603983, + # 76561197967923946, + # 76561197961542845, + # 76561198121938079, + # 76561197992357639, + # 76561198002536379, + # 76561198017054389, + # 76561198031129658, + # 76561198020728639, +])) + +# extra features/options to disable +EXTRA_FEATURES_DISABLE = { + 'configs.main.ini': { + 'main::connectivity': { + 'disable_networking': (1, 'disable all steam networking interface functionality'), + 'disable_source_query': (1, 'do not send server details to the server browser, only works for game servers'), + 'disable_sharing_stats_with_gameserver': (1, 'prevent sharing stats and achievements with any game server, this also disables the interface ISteamGameServerStats'), + }, + }, +} + +# extra convenient features/options to enable +EXTRA_FEATURES_CONVENIENT = { + 'configs.main.ini': { + 'main::general': { + 'new_app_ticket': (1, 'generate new app auth ticket'), + 'gc_token': (1, 'generate/embed GC token inside new App Ticket'), + 'enable_account_avatar': (1, 'enable avatar functionality'), + }, + 'main::connectivity': { + 'disable_lan_only': (1, 'prevent hooking OS networking APIs and allow any external requests'), + 'share_leaderboards_over_network': (1, 'enable sharing leaderboards scores with people playing the same game on the same network'), + 'download_steamhttp_requests': (1, 'attempt to download external HTTP(S) requests made via Steam_HTTP::SendHTTPRequest()'), + }, + }, + 'configs.overlay.ini': { + 'overlay::general': { + 'enable_experimental_overlay': (1, 'XXX USE AT YOUR OWN RISK XXX, enable the experimental overlay, might cause crashes or other problems'), + 'disable_warning_any': (1, 'disable any warning in the overlay'), + }, + } +} + + +def get_exe_dir(relative = False): + # https://pyinstaller.org/en/stable/runtime-information.html + if relative: + return os.path.curdir + + if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): + return os.path.dirname(sys.executable) + else: + return os.path.dirname(os.path.abspath(__file__)) + +def get_stats_schema(client, game_id, owner_id): + message = MsgProto(EMsg.ClientGetUserStats) + message.body.game_id = game_id + message.body.schema_local_version = -1 + message.body.crc_stats = 0 + message.body.steam_id_for_user = owner_id + + client.send(message) + return client.wait_msg(EMsg.ClientGetUserStatsResponse, timeout=5) + +def download_achievement_images(game_id : int, image_names : set[str], output_folder : str): + print(f"downloading achievements images inside '{output_folder }', images count = {len(image_names)}") + q : queue.Queue[str] = queue.Queue() + + def downloader_thread(): + while True: + name = q.get() + if name is None: + q.task_done() + return + + succeeded = False + for u in ["https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/", "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/"]: + url = "{}{}/{}".format(u, game_id, name) + try: + response = requests.get(url, allow_redirects=True) + response.raise_for_status() + image_data = response.content + with open(os.path.join(output_folder, name), "wb") as f: + f.write(image_data) + succeeded = True + break + except Exception as e: + print("HTTPError downloading", url, file=sys.stderr) + traceback.print_exception(e, file=sys.stderr) + if not succeeded: + print("error could not download", name) + + q.task_done() + + num_threads = 50 + for i in range(num_threads): + threading.Thread(target=downloader_thread, daemon=True).start() + + for name in image_names: + q.put(name) + q.join() + + for i in range(num_threads): + q.put(None) + q.join() + print("finished downloading achievements images") + +def generate_achievement_stats(client, game_id : int, output_directory, backup_directory) -> list[dict]: + stats_schema_found = None + print(f"finding achievements stats...") + for id in TOP_OWNER_IDS: + #print(f"finding achievements stats using account ID {id}...") + out = get_stats_schema(client, game_id, id) + if out is not None and len(out.body.schema) > 0: + stats_schema_found = out + #print(f"found achievement stats using account ID {id}") + break + + if stats_schema_found is None: # nothing found + print(f"[X] app id {game_id} has not achievements") + return [] + + achievement_images_dir = os.path.join(output_directory, "img") + images_to_download : set[str] = set() + + with open(os.path.join(backup_directory, f'UserGameStatsSchema_{game_id}.bin'), 'wb') as f: + f.write(stats_schema_found.body.schema) + ( + achievements, stats, + copy_default_unlocked_img, copy_default_locked_img + ) = achievements_gen.generate_stats_achievements(stats_schema_found.body.schema, output_directory) + + for ach in achievements: + icon = f"{ach.get('icon', '')}".strip() + if icon: + images_to_download.add(icon) + icon_gray = f"{ach.get('icon_gray', '')}".strip() + if icon_gray: + images_to_download.add(icon_gray) + + if images_to_download: + if not os.path.exists(achievement_images_dir): + os.makedirs(achievement_images_dir) + if copy_default_unlocked_img: + shutil.copy(os.path.join(get_exe_dir(), "steam_default_icon_unlocked.jpg"), achievement_images_dir) + if copy_default_locked_img: + shutil.copy(os.path.join(get_exe_dir(), "steam_default_icon_locked.jpg"), achievement_images_dir) + download_achievement_images(game_id, images_to_download, achievement_images_dir) + + return achievements + +def get_ugc_info(client, published_file_id): + return client.send_um_and_wait('PublishedFile.GetDetails#1', { + 'publishedfileids': [published_file_id], + 'includetags': False, + 'includeadditionalpreviews': False, + 'includechildren': False, + 'includekvtags': False, + 'includevotes': False, + 'short_description': True, + 'includeforsaledata': False, + 'includemetadata': False, + 'language': 0 + }) + +def download_published_file(client, published_file_id, backup_directory): + ugc_info = get_ugc_info(client, published_file_id) + + if (ugc_info is None): + print("failed getting published file", published_file_id) + return None + + file_details = ugc_info.body.publishedfiledetails[0] + if (file_details.result != EResult.OK): + print("failed getting published file", published_file_id, file_details.result) + return None + + if not os.path.exists(backup_directory): + os.makedirs(backup_directory) + + with open(os.path.join(backup_directory, "info.txt"), "w") as f: + f.write(str(ugc_info.body)) + + if len(file_details.file_url) > 0: + try: + response = requests.get(file_details.file_url, allow_redirects=True) + response.raise_for_status() + data = response.content + with open(os.path.join(backup_directory, file_details.filename.replace("/", "_").replace("\\", "_")), "wb") as f: + f.write(data) + return data + except Exception as e: + print(f"Error downloading from '{file_details.file_url}'", file=sys.stderr) + traceback.print_exception(e, file=sys.stderr) + return None + else: + print("Could not download file", published_file_id, "no url (you can ignore this if the game doesn't need a controller config)") + return None + + +def get_inventory_info(client, game_id): + return client.send_um_and_wait('Inventory.GetItemDefMeta#1', { + 'appid': game_id + }) + +def generate_inventory(client, game_id): + inventory = get_inventory_info(client, game_id) + if inventory.header.eresult != EResult.OK: + return None + + url = f"https://api.steampowered.com/IGameInventory/GetItemDefArchive/v0001?appid={game_id}&digest={inventory.body.digest}" + try: + response = requests.get(url, allow_redirects=True) + response.raise_for_status() + return response.content + except Exception as e: + print(f"Error downloading from '{url}'", file=sys.stderr) + traceback.print_exception(e, file=sys.stderr) + return None + +def parse_branches(branches: dict) -> list[dict]: + ret = [] + for branch_name in branches: + branch_data: dict = branches[branch_name] + branch_info = { + 'name': branch_name, + 'description': f'{branch_data.get("description", "")}', + 'protected': False, + 'build_id': 0, # dummy + 'time_updated': int(time.time()), # dummy + } + # password protected + if 'pwdrequired' in branch_data: + try: + protected = f'{branch_data["pwdrequired"]}'.lower() + branch_info["protected"] = protected == "true" or protected == "1" + except Exception as e: + pass + + # build id + try: + buildid = int( f'{branch_data.get("buildid", 0)}' ) + branch_info["build_id"] = buildid + except Exception as e: + pass + + # time updated + if 'timeupdated' in branch_data: + try: + timeupdated = int( f'{branch_data["timeupdated"]}' ) + branch_info["time_updated"] = timeupdated + except Exception as e: + pass + + ret.append(branch_info) + + return ret + +# DLC, Depots, Branches +def get_depots_infos(raw_infos): + try: + dlc_list = set() + depot_app_list = set() + all_depots = set() + all_branches = [] + try: + dlc_list = set(map(lambda a: int(f"{a}".strip()), raw_infos["extended"]["listofdlc"].split(","))) + except Exception: + pass + + if "depots" in raw_infos: + depots : dict[str, object] = raw_infos["depots"] + for dep in depots: + depot_info = depots[dep] + if "dlcappid" in depot_info: + dlc_list.add(int(depot_info["dlcappid"])) + if "depotfromapp" in depot_info: + depot_app_list.add(int(depot_info["depotfromapp"])) + + if dep.isnumeric(): + all_depots.add(int(dep)) + elif f'{dep}'.lower() == 'branches': + all_branches.extend(parse_branches(depot_info)) + + return (dlc_list, depot_app_list, all_depots, all_branches) + except Exception: + print("could not get dlc infos, are there any dlcs ?") + return (set(), set(), set()) + + +def help(): + exe_name = os.path.basename(sys.argv[0]) + print(f"\nUsage: {exe_name} [Switches] appid appid appid ... ") + print(f" Example: {exe_name} 421050 420 480") + print(f" Example: {exe_name} -shots -thumbs -vid -imgs -name -cdx -aw -clean -de 421050 480") + print(f" Example: {exe_name} -shots -thumbs -vid -imgs -name -cdx -aw -clean -de -cve 421050") + print(f" Example: {exe_name} -shots -thumbs -vid -imgs -name -cdx -aw -clean -cve 421050") + print("\nSwitches:") + print(" -shots: download screenshots for each app if they're available") + print(" -thumbs: download screenshots thumbnails for each app if they're available") + print(" -vid: download the first video available for each app: trailer, gameplay, announcement, etc...") + print(" -imgs: download common images for each app: Steam generated background, icon, logo, etc...") + print(" -name: save the output of each app in a folder with the same name as the app, unsafe characters are discarded") + print(" -cdx: generate .ini file for CODEX Steam emu for each app") + print(" -aw: generate schemas of all possible languages for Achievement Watcher") + print(" -clean: delete any folder/file with the same name as the output before generating any data") + print(" -anon: login as an anonymous account, these have very limited access and cannot get all app details") + print(" -token: save refresh_token to disk, the logged-on account will be saved") + print(" -de: disable some extra features by generating the corresponding config files in steam_settings folder") + print(" -cve: enable some convenient extra features by generating the corresponding config files in steam_settings folder") + print(" -reldir: generate temp files/folders, and expect input files, relative to the current working directory") + print(" -skip_ach: skip downloading & generating achievements and their images") + print(" -skip_con: skip downloading & generating controller configuration files") + print(" -skip_inv: skip downloading & generating inventory data (items.json & default_items.json)") + print("\nAll switches are optional except app id, at least 1 app id must be provided") + print("\nAutomate the login prompt:") + print(" * You can create a file called 'my_login.txt' beside the script, then add your username on the first line") + print(" and your password on the second line.") + print(" * You can set these 2 environment variables (will override 'my_login.txt'):") + print(" GSE_CFG_USERNAME") + print(" GSE_CFG_PASSWORD") + print("") + + +def merge_dict(dest: dict, src: dict): + # merge similar keys, but don't overwrite values + for kv in src.items(): + v_dest = dest.get(kv[0], None) + if isinstance(kv[1], dict) and isinstance(v_dest, dict): + merge_dict(v_dest, kv[1]) + elif kv[0] not in dest: + dest[kv[0]] = kv[1] + +def write_ini_file(base_path: str, out_ini: dict): + for file in out_ini.items(): + with open(os.path.join(base_path, file[0]), 'wt', encoding='utf-8') as f: + for item in file[1].items(): + f.write('[' + str(item[0]) + ']\n') # section + for kv in item[1].items(): + if kv[1][1]: # comment + f.write('# ' + str(kv[1][1]) + '\n') + f.write(str(kv[0]) + '=' + str(kv[1][0]) + '\n') # key/value pair + f.write('\n') + +def main(): + USERNAME = "" + PASSWORD = "" + + DISABLE_EXTRA = False + CONVENIENT_EXTRA = False + DOWNLOAD_SCREESHOTS = False + DOWNLOAD_THUMBNAILS = False + DOWNLOAD_VIDEOS = False + DOWNLOAD_COMMON_IMAGES = False + SAVE_APP_NAME = False + GENERATE_CODEX_INI = False + GENERATE_ACHIEVEMENT_WATCHER_SCHEMAS = False + CLEANUP_BEFORE_GENERATING = False + ANON_LOGIN = False + SAVE_REFRESH_TOKEN = False + RELATIVE_DIR = False + SKIP_ACH = False + SKIP_CONTROLLER = False + SKIP_INVENTORY = False + + prompt_for_unavailable = True + + if len(sys.argv) < 2: + help() + sys.exit(1) + + appids : set[int] = set() + for appid in sys.argv[1:]: + if f'{appid}'.isnumeric(): + appids.add(int(appid)) + elif f'{appid}'.lower() == '-shots': + DOWNLOAD_SCREESHOTS = True + elif f'{appid}'.lower() == '-thumbs': + DOWNLOAD_THUMBNAILS = True + elif f'{appid}'.lower() == '-vid': + DOWNLOAD_VIDEOS = True + elif f'{appid}'.lower() == '-imgs': + DOWNLOAD_COMMON_IMAGES = True + elif f'{appid}'.lower() == '-name': + SAVE_APP_NAME = True + elif f'{appid}'.lower() == '-cdx': + GENERATE_CODEX_INI = True + elif f'{appid}'.lower() == '-aw': + GENERATE_ACHIEVEMENT_WATCHER_SCHEMAS = True + elif f'{appid}'.lower() == '-clean': + CLEANUP_BEFORE_GENERATING = True + elif f'{appid}'.lower() == '-anon': + ANON_LOGIN = True + elif f'{appid}'.lower() == '-token': + SAVE_REFRESH_TOKEN = True + elif f'{appid}'.lower() == '-de': + DISABLE_EXTRA = True + elif f'{appid}'.lower() == '-cve': + CONVENIENT_EXTRA = True + elif f'{appid}'.lower() == '-reldir': + RELATIVE_DIR = True + elif f'{appid}'.lower() == '-skip_ach': + SKIP_ACH = True + elif f'{appid}'.lower() == '-skip_con': + SKIP_CONTROLLER = True + elif f'{appid}'.lower() == '-skip_inv': + SKIP_INVENTORY = True + else: + print(f'[X] invalid switch: {appid}') + help() + sys.exit(1) + + if not appids: + print(f'[X] no app id was provided') + help() + sys.exit(1) + + client = SteamClient() + if ANON_LOGIN: + result = client.anonymous_login() + trials = 5 + while result != EResult.OK and trials > 0: + time.sleep(1000) + result = client.anonymous_login() + trials -= 1 + else: + # first read the 'my_login.txt' file + my_login_file = os.path.join(get_exe_dir(RELATIVE_DIR), "my_login.txt") + if not ANON_LOGIN and os.path.isfile(my_login_file): + filedata = [''] + with open(my_login_file, "r", encoding="utf-8") as f: + filedata = f.readlines() + filedata = list(map(lambda s: s.replace("\r", "").replace("\n", ""), filedata)) + filedata = [l for l in filedata if l] + if len(filedata) == 1: + USERNAME = filedata[0] + elif len(filedata) == 2: + USERNAME, PASSWORD = filedata[0], filedata[1] + + # then allow the env vars to override the login details + env_username = os.environ.get('GSE_CFG_USERNAME', None) + env_password = os.environ.get('GSE_CFG_PASSWORD', None) + if env_username: + USERNAME = env_username + if env_password: + PASSWORD = env_password + + # the file to save/load credentials + REFRESH_TOKENS = os.path.join(get_exe_dir(RELATIVE_DIR), "refresh_tokens.json") + refresh_tokens = {} + if os.path.isfile(REFRESH_TOKENS): + with open(REFRESH_TOKENS) as f: + try: + lf = json.load(f) + refresh_tokens = lf if isinstance(lf, dict) else {} + except: + pass + + # select username from credentials if not already persent + if not USERNAME: + users = {i: user for i, user in enumerate(refresh_tokens, 1)} + if len(users) != 0: + for i, user in users.items(): + print(f"{i}: {user}") + while True: + try: + num=int(input("Choose an account to login (0 for add account): ")) + except ValueError: + print('Please type a number'); continue + break + USERNAME = users.get(num) + + # still no username? ask user + if not USERNAME: + USERNAME = input("Steam user: ") + + REFRESH_TOKEN = refresh_tokens.get(USERNAME) + + webauth, result = WebAuth(), None + while result in ( + EResult.TryAnotherCM, EResult.ServiceUnavailable, + EResult.InvalidPassword, None): + + if result in (EResult.TryAnotherCM, EResult.ServiceUnavailable): + if prompt_for_unavailable and result == EResult.ServiceUnavailable: + while True: + answer = input("Steam is down. Keep retrying? [y/n]: ").lower() + if answer in 'yn': break + + prompt_for_unavailable = False + if answer == 'n': break + + client.reconnect(maxdelay=15) + elif result == EResult.InvalidPassword: + print("invalid password or refresh_token,") + print(f"correct the password or/and delete '{REFRESH_TOKENS}' and try again.") + exit(1) + + if not REFRESH_TOKEN: + try: + webauth.cli_login(USERNAME, PASSWORD) + except Exception as e: + print(f'Unknown exception: {e}, maybe some account info is wrong?') + exit(1) + USERNAME, PASSWORD = webauth.username, webauth.password + REFRESH_TOKEN = webauth.refresh_token + + result = client.login(USERNAME, PASSWORD, REFRESH_TOKEN) + + if SAVE_REFRESH_TOKEN: + with open(REFRESH_TOKENS, 'w') as f: + refresh_tokens.update({USERNAME: REFRESH_TOKEN}) + json.dump(refresh_tokens, f, indent=4) + + # read and prepend top_owners_ids.txt + top_owners_file = os.path.join(get_exe_dir(RELATIVE_DIR), "top_owners_ids.txt") + if os.path.isfile(top_owners_file): + filedata = [''] + with open(top_owners_file, "r", encoding="utf-8") as f: + filedata = f.readlines() + filedata = list(map(lambda s: s.replace("\r", "").replace("\n", "").strip(), filedata)) + filedata = [l for l in filedata if len(l) > 1 and l.isdecimal()] + all_ids = list(map(lambda s: int(s), filedata)) + TOP_OWNER_IDS[:0] = all_ids + + # prepend user account ID as a top owner + if not ANON_LOGIN: + TOP_OWNER_IDS.insert(0, client.steam_id.as_64) + + for appid in appids: + out_config_app_ini = {} + + print(f"********* generating info for app id {appid} *********") + raw = client.get_product_info(apps=[appid]) + game_info : dict = raw["apps"][appid] + + game_info_common : dict = game_info.get("common", {}) + app_name = game_info_common.get("name", "") + app_name_on_disk = f"{appid}" + if app_name: + print(f"App name on store: '{app_name}'") + if SAVE_APP_NAME: + sanitized_name = safe_name.create_safe_name(app_name) + if sanitized_name: + app_name_on_disk = f'{sanitized_name}-{appid}' + else: + app_name = f"Unknown_Steam_app_{appid}" # we need this for later use in the Achievement Watcher + print(f"[X] Couldn't find app name on store") + + root_backup_dir = os.path.join(get_exe_dir(RELATIVE_DIR), "backup") + backup_dir = os.path.join(root_backup_dir, f"{appid}") + if not os.path.exists(backup_dir): + os.makedirs(backup_dir) + + root_out_dir = "output" + base_out_dir = os.path.join(root_out_dir, app_name_on_disk) + emu_settings_dir = os.path.join(base_out_dir, "steam_settings") + info_out_dir = os.path.join(base_out_dir, "info") + + if CLEANUP_BEFORE_GENERATING: + print("cleaning output folder before generating any data") + base_dir_path = pathlib.Path(base_out_dir) + if base_dir_path.is_file(): + base_dir_path.unlink() + time.sleep(0.05) + elif base_dir_path.is_dir(): + shutil.rmtree(base_dir_path) + time.sleep(0.05) + + while base_dir_path.exists(): + time.sleep(0.05) + + if not os.path.exists(emu_settings_dir): + os.makedirs(emu_settings_dir) + + if not os.path.exists(info_out_dir): + os.makedirs(info_out_dir) + + print(f"output dir: '{base_out_dir}'") + + with open(os.path.join(info_out_dir, "product_info.json"), "wt", encoding='utf-8') as f: + json.dump(game_info, f, ensure_ascii=False, indent=2) + + app_details.download_app_details( + base_out_dir, info_out_dir, + appid, + DOWNLOAD_SCREESHOTS, + DOWNLOAD_THUMBNAILS, + DOWNLOAD_VIDEOS) + + clienticon : str = None + icon : str = None + logo : str = None + logo_small : str = None + achievements : list[dict] = [] + languages : list[str] = [] + app_exe = '' + if game_info_common: + if "clienticon" in game_info_common: + clienticon = f"{game_info_common['clienticon']}" + + if "icon" in game_info_common: + icon = f"{game_info_common['icon']}" + + if "logo" in game_info_common: + logo = f"{game_info_common['logo']}" + + if "logo_small" in game_info_common: + logo_small = f"{game_info_common['logo_small']}" + + #print(f"generating achievement stats") + #if "community_visible_stats" in game_info_common: #NOTE: checking this seems to skip stats on a few games so it's commented out + if not SKIP_ACH: + achievements = generate_achievement_stats(client, appid, emu_settings_dir, backup_dir) + + if "supported_languages" in game_info_common: + langs: dict[str, dict] = game_info_common["supported_languages"] + for lang in langs: + support: str = langs[lang].get("supported", "").lower() + if support == "true" or support == "1": + languages.append(f'{lang}'.lower()) + + if languages: + with open(os.path.join(emu_settings_dir, "supported_languages.txt"), 'wt', encoding='utf-8') as f: + for lang in languages: + f.write(f'{lang}\n') + + with open(os.path.join(emu_settings_dir, "steam_appid.txt"), 'w') as f: + f.write(str(appid)) + + dlc_config_list : list[tuple[int, str]] = [] + dlc_list, depot_app_list, all_depots, all_branches = get_depots_infos(game_info) + dlc_raw = {} + if dlc_list: + dlc_raw = client.get_product_info(apps=dlc_list)["apps"] + for dlc in dlc_raw: + dlc_name = '' + try: + dlc_name = f'{dlc_raw[dlc]["common"]["name"]}' + except Exception: + pass + + if not dlc_name: + dlc_name = f"Unknown Steam app {dlc}" + + dlc_config_list.append((dlc, dlc_name)) + + # we set unlock_all=0 nonetheless, to make the emu lock DLCs, otherwise everything is allowed + # some games use that as a detection mechanism + merge_dict(out_config_app_ini, { + 'configs.app.ini': { + 'app::dlcs': { + 'unlock_all': (0, 'should the emu report all DLCs as unlocked, default=1'), + } + } + }) + for x in dlc_config_list: + merge_dict(out_config_app_ini, { + 'configs.app.ini': { + 'app::dlcs': { + x[0]: (x[1], ''), + } + } + }) + # write the data as soon as possible in case a later step caused an exception + write_ini_file(emu_settings_dir, out_config_app_ini) + + if all_depots: + with open(os.path.join(emu_settings_dir, "depots.txt"), 'wt', encoding="utf-8") as f: + for game_depot in all_depots: + f.write(f"{game_depot}\n") + + if all_branches: + with open(os.path.join(emu_settings_dir, "branches.json"), "wt", encoding='utf-8') as f: + json.dump(all_branches, f, ensure_ascii=False, indent=2) + + + config_generated = False + if "config" in game_info: + if not SKIP_CONTROLLER and "steamcontrollerconfigdetails" in game_info["config"]: + controller_details = game_info["config"]["steamcontrollerconfigdetails"] + print('downloading controller vdf files') + for id in controller_details: + details = controller_details[id] + controller_type = "" + enabled_branches = "" + if "controller_type" in details: + controller_type = details["controller_type"] + if "enabled_branches" in details: + enabled_branches = details["enabled_branches"] + print(f'downloading controller data, file id = {id}, controller type = {controller_type}') + + out_vdf = download_published_file(client, int(id), os.path.join(backup_dir, f'{controller_type}-{str(id)}')) + if out_vdf is not None and not config_generated: + if (controller_type in ["controller_xbox360", "controller_xboxone", "controller_steamcontroller_gordon"] and (("default" in enabled_branches) or ("public" in enabled_branches))): + print(f'controller type is supported') + parse_controller_vdf.generate_controller_config(out_vdf.decode('utf-8'), os.path.join(emu_settings_dir, "controller")) + config_generated = True + if not SKIP_CONTROLLER and "steamcontrollertouchconfigdetails" in game_info["config"]: + controller_details = game_info["config"]["steamcontrollertouchconfigdetails"] + for id in controller_details: + details = controller_details[id] + controller_type = "" + enabled_branches = "" + if "controller_type" in details: + controller_type = details["controller_type"] + if "enabled_branches" in details: + enabled_branches = details["enabled_branches"] + print(id, controller_type) + out_vdf = download_published_file(client, int(id), os.path.join(backup_dir, controller_type + str(id))) + if "launch" in game_info["config"]: + launch_configs = game_info["config"]["launch"] + with open(os.path.join(info_out_dir, "launch_config.json"), "wt", encoding='utf-8') as f: + json.dump(launch_configs, f, ensure_ascii=False, indent=2) + + first_app_exe : str = None + prefered_app_exe : str = None + unwanted_app_exes = ["launch", "start", "play", "try", "demo", "_vr",] + for cfg in launch_configs.values(): + if "executable" in cfg: + app_exe = f'{cfg["executable"]}' + + if app_exe.lower().endswith(".exe"): + app_exe = app_exe.replace("\\", "/").split('/')[-1] + if first_app_exe is None: + first_app_exe = app_exe + if all(app_exe.lower().find(unwanted_exe) < 0 for unwanted_exe in unwanted_app_exes): + prefered_app_exe = app_exe + break + + if prefered_app_exe: + app_exe = prefered_app_exe + elif first_app_exe: + app_exe = first_app_exe + + if GENERATE_ACHIEVEMENT_WATCHER_SCHEMAS: + ach_watcher_gen.generate_all_ach_watcher_schemas( + base_out_dir, + appid, + app_name, + app_exe, + achievements, + icon) + + if GENERATE_CODEX_INI: + cdx_gen.generate_cdx_ini( + base_out_dir, + appid, + dlc_config_list, + achievements) + + if DOWNLOAD_COMMON_IMAGES: + app_images.download_app_images( + base_out_dir, + appid, + clienticon, + icon, + logo, + logo_small) + + if DISABLE_EXTRA: + merge_dict(out_config_app_ini, EXTRA_FEATURES_DISABLE) + + if CONVENIENT_EXTRA: + merge_dict(out_config_app_ini, EXTRA_FEATURES_CONVENIENT) + + if out_config_app_ini: + write_ini_file(emu_settings_dir, out_config_app_ini) + + inventory_data = None + if not SKIP_INVENTORY: + inventory_data = generate_inventory(client, appid) + if inventory_data is not None: + out_inventory = {} + default_items = {} + inventory = json.loads(inventory_data.rstrip(b"\x00")) + raw_inventory = json.dumps(inventory, indent=4) + with open(os.path.join(backup_dir, "inventory.json"), "w") as f: + f.write(raw_inventory) + for i in inventory: + index = str(i["itemdefid"]) + x = {} + for t in i: + if i[t] is True: + x[t] = "true" + elif i[t] is False: + x[t] = "false" + else: + x[t] = str(i[t]) + out_inventory[index] = x + default_items[index] = {"quantity": 1} + + with open(os.path.join(emu_settings_dir, "items.json"), "wt", encoding='utf-8') as f: + json.dump(out_inventory, f, ensure_ascii=False, indent=2) + + with open(os.path.join(emu_settings_dir, "default_items.json"), "wt", encoding='utf-8') as f: + json.dump(default_items, f, ensure_ascii=False, indent=2) + + with open(os.path.join(backup_dir, "product_info.json"), "wt", encoding='utf-8') as f: + json.dump(game_info, f, ensure_ascii=False, indent=2) + + with open(os.path.join(backup_dir, "dlc_product_info.json"), "wt", encoding='utf-8') as f: + json.dump(dlc_raw, f, ensure_ascii=False, indent=2) + + print(f"######### done for app id {appid} #########\n\n") + +if __name__ == "__main__": + try: + main() + except Exception as e: + print("Unexpected error:") + print(e) + print("-----------------------") + for line in traceback.format_exception(e): + print(line) + print("-----------------------") + sys.exit(1) + diff --git a/generate_emu_config_old/icon/Froyoshark-Enkel-Steam.ico b/generate_emu_config_old/icon/Froyoshark-Enkel-Steam.ico new file mode 100644 index 0000000..d0d856f Binary files /dev/null and b/generate_emu_config_old/icon/Froyoshark-Enkel-Steam.ico differ diff --git a/generate_emu_config_old/icon/LICENSE.md b/generate_emu_config_old/icon/LICENSE.md new file mode 100644 index 0000000..4b10906 --- /dev/null +++ b/generate_emu_config_old/icon/LICENSE.md @@ -0,0 +1,3 @@ +Icon by: [FroyoShark](https://www.iconarchive.com/artist/froyoshark.html) +License: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/) +Source: [icon archive: Steam Icon](https://www.iconarchive.com/show/enkel-icons-by-froyoshark/Steam-icon.html) diff --git a/generate_emu_config_old/output/1599600/info/app_details.json b/generate_emu_config_old/output/1599600/info/app_details.json new file mode 100644 index 0000000..e7181ee --- /dev/null +++ b/generate_emu_config_old/output/1599600/info/app_details.json @@ -0,0 +1,322 @@ +{ + "1599600": { + "success": true, + "data": { + "type": "game", + "name": "PlateUp!", + "steam_appid": 1599600, + "required_age": 0, + "is_free": false, + "controller_support": "full", + "detailed_description": "Up to four players build and run a restaurant from scratch, choosing dishes, buying and placing appliances – some of which can be daisy-chained together to create ambitious automatic kitchens – cooking food and serving customers.

Players have free rein to design their restaurant which will expand and develop between shifts – with additional content and challenges unlocked through progression.

Can you cook, serve and manage your way through 15 hectic days in your restaurant and unlock a brand-new franchise?



  • Classic co-op cooking action, with a wide selection of mains, sides, sauces, toppings, desserts, and starters.
  • Choose your equipment, lay out your kitchen, curate your menu and plate up your dishes.
  • From bubbling soups to sublime salads, tender steaks to hearty pies, there's something for everyone.



  • Look after front-of-house: seating customers, delivering orders, and managing patience.
  • Equip your restaurant to handle the most fickle of customers and deliver them what they need, right when they need it.
  • Co-operate with your team like a well-olive-oiled machine or build a name for yourself going it alone.
  • Exceed your goals and take your franchise to greater heights at a new location, bringing with you new unlocks and upgrade



  • Upgrade and rearrange your restaurant to your personal taste: when the restaurant closes for the day, the planning begins!
  • Decide what new equipment to purchase, and place it wherever you want.
  • Want to go high-tech? Install the turbo-ovens, crank up the conveyors, and make way for the robo-kitchen of the future.
  • Fancy something a little more... fancy? Curate your art collection, fix up that wallpaper, enlist a friend as a maître d' and get ready to provide the culinary experience of a lifetime.



  • Exceed your goals and start over at your next location, bringing with you new unlocks and upgrades.
  • Tailor your brand towards gourmet dining, or fine-tune your fast food franchise.
  • Every restaurant is procedurally-generated with its own climate, customers and conditions.
  • Return to your franchise HQ to view your achievements, customise your characters and upgrade your kit, ready for your next adventure!
", + "about_the_game": "Up to four players build and run a restaurant from scratch, choosing dishes, buying and placing appliances – some of which can be daisy-chained together to create ambitious automatic kitchens – cooking food and serving customers.

Players have free rein to design their restaurant which will expand and develop between shifts – with additional content and challenges unlocked through progression.

Can you cook, serve and manage your way through 15 hectic days in your restaurant and unlock a brand-new franchise?



  • Classic co-op cooking action, with a wide selection of mains, sides, sauces, toppings, desserts, and starters.
  • Choose your equipment, lay out your kitchen, curate your menu and plate up your dishes.
  • From bubbling soups to sublime salads, tender steaks to hearty pies, there's something for everyone.



  • Look after front-of-house: seating customers, delivering orders, and managing patience.
  • Equip your restaurant to handle the most fickle of customers and deliver them what they need, right when they need it.
  • Co-operate with your team like a well-olive-oiled machine or build a name for yourself going it alone.
  • Exceed your goals and take your franchise to greater heights at a new location, bringing with you new unlocks and upgrade



  • Upgrade and rearrange your restaurant to your personal taste: when the restaurant closes for the day, the planning begins!
  • Decide what new equipment to purchase, and place it wherever you want.
  • Want to go high-tech? Install the turbo-ovens, crank up the conveyors, and make way for the robo-kitchen of the future.
  • Fancy something a little more... fancy? Curate your art collection, fix up that wallpaper, enlist a friend as a maître d' and get ready to provide the culinary experience of a lifetime.



  • Exceed your goals and start over at your next location, bringing with you new unlocks and upgrades.
  • Tailor your brand towards gourmet dining, or fine-tune your fast food franchise.
  • Every restaurant is procedurally-generated with its own climate, customers and conditions.
  • Return to your franchise HQ to view your achievements, customise your characters and upgrade your kit, ready for your next adventure!
", + "short_description": "Cook and serve your dishes, design and decorate your restaurants, and expand your culinary kingdom with new unlocks, abilities and dishes in procedurally-generated locations. Classic cooking action with permanent roguelite progression. Hire your friends - or do it all yourself!", + "supported_languages": "English, French, German, Spanish - Spain, Japanese, Polish, Portuguese - Brazil, Russian, Simplified Chinese, Traditional Chinese, Korean, Turkish", + "header_image": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/header.jpg?t=1727951205", + "capsule_image": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/capsule_231x87.jpg?t=1727951205", + "capsule_imagev5": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/capsule_184x69.jpg?t=1727951205", + "website": "https://www.plateupgame.com", + "pc_requirements": { + "minimum": "Minimum:
  • Processor: Quad Core I5 or AMD equivalent
  • Memory: 8 GB RAM
  • Graphics: Intel HD Graphics 530 or AMD equivalent
  • Storage: 2 GB available space
", + "recommended": "Recommended:
  • Processor: Quad Core I5 / Ryzen 5
  • Memory: 16 GB RAM
  • Graphics: GTX 960 or AMD equivalent
  • Storage: 2 GB available space
" + }, + "mac_requirements": [], + "linux_requirements": [], + "legal_notice": "©2022, It's happening. Licensed by Yogscast Games", + "developers": [ + "It's happening" + ], + "publishers": [ + "Yogscast Games" + ], + "demos": [ + { + "appid": 1755940, + "description": "" + } + ], + "price_overview": { + "currency": "EUR", + "initial": 1950, + "final": 1950, + "discount_percent": 0, + "initial_formatted": "", + "final_formatted": "19,50€" + }, + "packages": [ + 566472 + ], + "package_groups": [ + { + "name": "default", + "title": "Buy PlateUp!", + "description": "", + "selection_text": "Select a purchase option", + "save_text": "", + "display_type": 0, + "is_recurring_subscription": "false", + "subs": [ + { + "packageid": 566472, + "percent_savings_text": " ", + "percent_savings": 0, + "option_text": "PlateUp! - 19,50€", + "option_description": "", + "can_get_free_license": "0", + "is_free_license": false, + "price_in_cents_with_discount": 1950 + } + ] + } + ], + "platforms": { + "windows": true, + "mac": false, + "linux": false + }, + "categories": [ + { + "id": 2, + "description": "Single-player" + }, + { + "id": 1, + "description": "Multi-player" + }, + { + "id": 9, + "description": "Co-op" + }, + { + "id": 38, + "description": "Online Co-op" + }, + { + "id": 39, + "description": "Shared/Split Screen Co-op" + }, + { + "id": 24, + "description": "Shared/Split Screen" + }, + { + "id": 22, + "description": "Steam Achievements" + }, + { + "id": 28, + "description": "Full controller support" + }, + { + "id": 30, + "description": "Steam Workshop" + }, + { + "id": 23, + "description": "Steam Cloud" + }, + { + "id": 43, + "description": "Remote Play on TV" + }, + { + "id": 44, + "description": "Remote Play Together" + }, + { + "id": 62, + "description": "Family Sharing" + } + ], + "genres": [ + { + "id": "1", + "description": "Action" + }, + { + "id": "4", + "description": "Casual" + }, + { + "id": "23", + "description": "Indie" + }, + { + "id": "2", + "description": "Strategy" + } + ], + "screenshots": [ + { + "id": 0, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_8c944c593113598b6446b6b5d07962a10fe79ec6.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_8c944c593113598b6446b6b5d07962a10fe79ec6.1920x1080.jpg?t=1727951205" + }, + { + "id": 1, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_2fb45e66d1b4e8c3d8fe6743fad278bcc082c2d5.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_2fb45e66d1b4e8c3d8fe6743fad278bcc082c2d5.1920x1080.jpg?t=1727951205" + }, + { + "id": 2, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_833de2e09f19972bb9e7db021c793da6afdab8a0.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_833de2e09f19972bb9e7db021c793da6afdab8a0.1920x1080.jpg?t=1727951205" + }, + { + "id": 3, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_5cdb7d8147767fece03a9a69a10af64a2e0c5e47.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_5cdb7d8147767fece03a9a69a10af64a2e0c5e47.1920x1080.jpg?t=1727951205" + }, + { + "id": 4, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_ac60173eb6d72af743d65c118b3e9df7453dcb61.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_ac60173eb6d72af743d65c118b3e9df7453dcb61.1920x1080.jpg?t=1727951205" + }, + { + "id": 5, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_022cd021471aa30b4522143b309243c33e2811b9.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_022cd021471aa30b4522143b309243c33e2811b9.1920x1080.jpg?t=1727951205" + }, + { + "id": 6, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_0b174229c080e33bfae7aedb9c5376429ac3cc9c.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_0b174229c080e33bfae7aedb9c5376429ac3cc9c.1920x1080.jpg?t=1727951205" + }, + { + "id": 7, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_eda5d4d3ec3450638f06cffb7bc761fc6818efae.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_eda5d4d3ec3450638f06cffb7bc761fc6818efae.1920x1080.jpg?t=1727951205" + }, + { + "id": 8, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_a848cd4473408a4d766a2f6d8c7409d22cb3acac.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_a848cd4473408a4d766a2f6d8c7409d22cb3acac.1920x1080.jpg?t=1727951205" + }, + { + "id": 9, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_2cd851def59b9c08bedd71a42a2cbfa79e8c754a.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_2cd851def59b9c08bedd71a42a2cbfa79e8c754a.1920x1080.jpg?t=1727951205" + }, + { + "id": 10, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_8b1464149e9c6600e7de43319bbe5c227c64f5fa.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_8b1464149e9c6600e7de43319bbe5c227c64f5fa.1920x1080.jpg?t=1727951205" + }, + { + "id": 11, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_cfefe6cf0bbf27b3b79021f6041e81f99bcc20e7.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_cfefe6cf0bbf27b3b79021f6041e81f99bcc20e7.1920x1080.jpg?t=1727951205" + }, + { + "id": 12, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_fa843228931fc4a62a7572cc83653e0dc02730f1.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_fa843228931fc4a62a7572cc83653e0dc02730f1.1920x1080.jpg?t=1727951205" + }, + { + "id": 13, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_5cbfe9ca7aff4ffaef25693e823ca6c906328b54.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_5cbfe9ca7aff4ffaef25693e823ca6c906328b54.1920x1080.jpg?t=1727951205" + }, + { + "id": 14, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_fe77145d29b130099a81d0119456693bbf12adb7.600x338.jpg?t=1727951205", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/ss_fe77145d29b130099a81d0119456693bbf12adb7.1920x1080.jpg?t=1727951205" + } + ], + "movies": [ + { + "id": 256899319, + "name": "Launch Trailer", + "thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/256899319/movie.293x165.jpg?t=1659620731", + "webm": { + "480": "http://video.akamai.steamstatic.com/store_trailers/256899319/movie480_vp9.webm?t=1659620731", + "max": "http://video.akamai.steamstatic.com/store_trailers/256899319/movie_max_vp9.webm?t=1659620731" + }, + "mp4": { + "480": "http://video.akamai.steamstatic.com/store_trailers/256899319/movie480.mp4?t=1659620731", + "max": "http://video.akamai.steamstatic.com/store_trailers/256899319/movie_max.mp4?t=1659620731" + }, + "highlight": true + } + ], + "recommendations": { + "total": 13959 + }, + "achievements": { + "total": 26, + "highlighted": [ + { + "name": "Steaks Were Made", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/cf8e7333881792385701b7cfd85f1e27d1a7bfe0.jpg" + }, + { + "name": "Stirring Things Up", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/cf3660012d6cfe286d118b256791f2b434c90172.jpg" + }, + { + "name": "Piece of the Action", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/36d3d0d14cec6492b73f21f6e09eca4604cfe196.jpg" + }, + { + "name": "A New Leaf", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/6251ddf410f13bbb4cde4dfca97a83857104d41f.jpg" + }, + { + "name": "Soggy Bottom", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/9144ef4c3447c80ead03df7230587aac73a3a511.jpg" + }, + { + "name": "Something Fishy", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/0a18ca860bc1c17b096290eb42b8a1b13e214f9f.jpg" + }, + { + "name": "Man's Best Friend?", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/934d3a1b0283fc99662bca6d081c0559ef93c8c3.jpg" + }, + { + "name": "Least Important Meal", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/b193d2a2f881716f2364b85a2fdc05572577a1bd.jpg" + }, + { + "name": "Burger Prince", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/4dd21bd02267a273d08d3ba4db272c8dff8d19b7.jpg" + }, + { + "name": "This Is Fine", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/1599600/3bb663e137a4fcb6669e12b137b001fbad67180e.jpg" + } + ] + }, + "release_date": { + "coming_soon": false, + "date": "4 Aug, 2022" + }, + "support_info": { + "url": "https://plateupgame.com", + "email": "support@plateupgame.com" + }, + "background": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/page_bg_generated_v6b.jpg?t=1727951205", + "background_raw": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/page.bg.jpg?t=1727951205", + "content_descriptors": { + "ids": [], + "notes": null + }, + "ratings": { + "dejus": { + "rating": "12", + "descriptors": "Drogas lícitas", + "use_age_gate": "true", + "required_age": "12" + }, + "steam_germany": { + "rating_generated": "1", + "rating": "0", + "required_age": "0", + "banned": "0", + "use_age_gate": "0", + "descriptors": "" + } + } + } + } +} \ No newline at end of file diff --git a/generate_emu_config_old/output/1599600/info/launch_config.json b/generate_emu_config_old/output/1599600/info/launch_config.json new file mode 100644 index 0000000..d64c43d --- /dev/null +++ b/generate_emu_config_old/output/1599600/info/launch_config.json @@ -0,0 +1,10 @@ +{ + "1": { + "executable": "PlateUp/PlateUp.exe", + "arguments": "-appid 1599600", + "description_loc": { + "english": "Launch" + }, + "description": "Launch" + } +} \ No newline at end of file diff --git a/generate_emu_config_old/output/1599600/info/product_info.json b/generate_emu_config_old/output/1599600/info/product_info.json new file mode 100644 index 0000000..dd7284b --- /dev/null +++ b/generate_emu_config_old/output/1599600/info/product_info.json @@ -0,0 +1,443 @@ +{ + "appid": "1599600", + "common": { + "name": "PlateUp!", + "type": "Game", + "oslist": "windows", + "osarch": "", + "osextended": "", + "logo": "26f97a270c9e4716a7b253984ca8669bba2f863a", + "logo_small": "26f97a270c9e4716a7b253984ca8669bba2f863a_thumb", + "icon": "8ab51cc26c5b54c8858bf95538d71f728b460611", + "clienticon": "6cc2e797ba3f4f212c5987c99ecf4ba283930798", + "clienttga": "5a587903a883ae347d9bbfd9472ebd799ef4763e", + "releasestate": "released", + "name_localized": { + "schinese": "速速上菜!", + "tchinese": "速速上菜!", + "koreana": "플레이트업!", + "japanese": "プレートアップ!" + }, + "languages": { + "english": "1", + "german": "1", + "french": "1", + "koreana": "1", + "spanish": "1", + "schinese": "1", + "tchinese": "1", + "russian": "1", + "japanese": "1", + "polish": "1", + "turkish": "1", + "brazilian": "1" + }, + "steam_deck_compatibility": { + "category": "3", + "test_timestamp": "1662681600", + "tested_build_id": "9455410", + "tests": { + "0": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_DefaultControllerConfigFullyFunctional" + }, + "1": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_ControllerGlyphsMatchDeckDevice" + }, + "2": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_InterfaceTextIsLegible" + }, + "3": { + "display": "4", + "token": "#SteamDeckVerified_TestResult_DefaultConfigurationIsPerformant" + } + }, + "configuration": { + "supported_input": "gamepad", + "requires_manual_keyboard_invoke": "0", + "requires_non_controller_launcher_nav": "0", + "primary_player_is_controller_slot_0": "0", + "non_deck_display_glyphs": "0", + "small_text": "0", + "requires_internet_for_setup": "0", + "requires_internet_for_singleplayer": "0", + "recommended_runtime": "proton-stable", + "requires_h264": "0", + "gamescope_frame_limiter_not_supported": "0" + } + }, + "controller_support": "full", + "small_capsule": { + "english": "capsule_231x87.jpg", + "schinese": "capsule_231x87_schinese.jpg", + "tchinese": "capsule_231x87_tchinese.jpg", + "koreana": "capsule_231x87_koreana.jpg" + }, + "header_image": { + "english": "header.jpg", + "schinese": "header_schinese.jpg", + "tchinese": "header_tchinese.jpg", + "koreana": "header_koreana.jpg" + }, + "library_assets": { + "library_capsule": "en,zh-cn,zh-tw,ko", + "library_hero": "en", + "library_logo": "en,ko,zh-cn,zh-tw", + "logo_position": { + "pinned_position": "BottomLeft", + "width_pct": "73.61634980389326", + "height_pct": "100" + } + }, + "library_assets_full": { + "library_capsule": { + "image": { + "english": "library_600x900.jpg", + "schinese": "library_600x900_schinese.jpg", + "tchinese": "library_600x900_tchinese.jpg", + "koreana": "library_600x900_koreana.jpg" + }, + "image2x": { + "english": "library_600x900_2x.jpg", + "schinese": "library_600x900_schinese_2x.jpg", + "tchinese": "library_600x900_tchinese_2x.jpg", + "koreana": "library_600x900_koreana_2x.jpg" + } + }, + "library_hero": { + "image": { + "english": "library_hero.jpg" + }, + "image2x": { + "english": "library_hero_2x.jpg" + } + }, + "library_logo": { + "image": { + "english": "logo.png", + "koreana": "logo_koreana.png", + "schinese": "logo_schinese.png", + "tchinese": "logo_tchinese.png" + }, + "logo_position": { + "pinned_position": "BottomLeft", + "width_pct": "73.61634980389326", + "height_pct": "100" + }, + "image2x": { + "english": "logo_2x.png", + "koreana": "logo_koreana_2x.png", + "schinese": "logo_schinese_2x.png", + "tchinese": "logo_tchinese_2x.png" + } + } + }, + "store_asset_mtime": "1723038856", + "associations": { + "0": { + "type": "developer", + "name": "It's happening" + }, + "1": { + "type": "publisher", + "name": "Yogscast Games" + }, + "2": { + "type": "franchise", + "name": "Yogscast Games" + } + }, + "primary_genre": "23", + "genres": { + "0": "1", + "1": "4", + "2": "23", + "3": "2" + }, + "category": { + "category_2": "1", + "category_1": "1", + "category_9": "1", + "category_38": "1", + "category_39": "1", + "category_24": "1", + "category_44": "1", + "category_28": "1", + "category_33": "1", + "category_23": "1", + "category_43": "1", + "category_22": "1", + "category_45": "1", + "category_46": "1", + "category_30": "1", + "category_62": "1" + }, + "supported_languages": { + "english": { + "supported": "true" + }, + "french": { + "supported": "true" + }, + "german": { + "supported": "true" + }, + "spanish": { + "supported": "true" + }, + "japanese": { + "supported": "true" + }, + "polish": { + "supported": "true" + }, + "brazilian": { + "supported": "true" + }, + "russian": { + "supported": "true" + }, + "schinese": { + "supported": "true" + }, + "tchinese": { + "supported": "true" + }, + "koreana": { + "supported": "true" + }, + "turkish": { + "supported": "true" + } + }, + "steam_release_date": "1659621689", + "community_visible_stats": "1", + "workshop_visible": "1", + "community_hub_visible": "1", + "gameid": "1599600", + "store_tags": { + "0": "1685", + "1": "12472", + "2": "3920", + "3": "3959", + "4": "1643", + "5": "3841", + "6": "1716", + "7": "4726", + "8": "5125", + "9": "4136", + "10": "7332", + "11": "597", + "12": "4840", + "13": "7481", + "14": "3843", + "15": "9", + "16": "42804", + "17": "4791", + "18": "4182", + "19": "19" + }, + "review_score": "9", + "review_percentage": "95" + }, + "extended": { + "developer": "It's happening", + "publisher": "Yogscast Games", + "homepage": "https://www.plateupgame.com" + }, + "config": { + "installdir": "PlateUp", + "launch": { + "1": { + "executable": "PlateUp/PlateUp.exe", + "arguments": "-appid 1599600", + "description_loc": { + "english": "Launch" + }, + "description": "Launch" + } + }, + "uselaunchcommandline": "1" + }, + "depots": { + "baselanguages": "english", + "workshopdepot": "1599600", + "1599601": { + "config": { + "oslist": "windows" + }, + "manifests": { + "public": { + "gid": "3511304844048280730", + "size": "1394090112", + "download": "401764176" + }, + "crash-fix-test": { + "gid": "3754009520993631004", + "size": "1394071616", + "download": "401544576" + }, + "crossplaybeta": { + "gid": "6594253868093343203", + "size": "1397661267", + "download": "401897600" + } + }, + "encryptedmanifests": { + "ch_pr": { + "gid": "36D567E3C6EDBF76DAE9537825B2FDE5", + "size": "F2BA04F6CF9DBBF0787861494F533A6A", + "download": "4A1B08395CE0C1C1C422D56D7363EE4C" + }, + "chef": { + "gid": "FE64F23927880259A04CE8DB878D918A", + "size": "90B55476BAA2E495B2E587AF276718C5", + "download": "6B2E75D19C1D8663F0762C1F090E3DC1" + }, + "development": { + "gid": "CE4A112CAC82A33E53AA298F2C529D37", + "size": "EAF100AEF364DC5AFD7937F6EBF0673E", + "download": "4D9C0240869BF08DAB124AC4731A2ECC" + }, + "discordbetaaccess": { + "gid": "C0842BFE32F9F5C8CADD479E3B21E49E", + "size": "C346FF77F32785FDFAE4A835647F217F", + "download": "79018ADC6D516835369BE55B33D4CC8E" + }, + "japan": { + "gid": "817B69EE9BD3090BEA5F225BC6E05ED5", + "size": "4EC9FEDE0FFE8596F4476172A0EF69E6", + "download": "7DEC42894D7187042A87C966E83FD73B" + }, + "secret": { + "gid": "BEFDC25DD1BAB568E31EE4E264832F61", + "size": "C52474E52F801694CDB3725A0219C8A1", + "download": "CEEF42E455759C9D8D98807745A51DF8" + }, + "creator": { + "gid": "1466323502A7DB72D4021991A4A9CFA8", + "size": "FE31C5D5087E9A314C5B0A8558E66D3B", + "download": "16E7D860E992B1D95C8CEF867797E93E" + }, + "crossplaystaging": { + "gid": "B78FB53D3CB814D531A90BAD0E9EC1E3", + "size": "57CA11ABADFB2AE9184FD395FA1D221D", + "download": "00C6ED64019A1A53576C8C05E3979F87" + }, + "playtest": { + "gid": "C6E4EB704BBF7ECDBA8F8552F51B9D12", + "size": "6482BB9F09AF187DD335DBC5C963BA79", + "download": "68B689343F81AF7401CB2CF8B1A4DF27" + }, + "playtest2": { + "gid": "4522E87851833CEE8625443478AABE00", + "size": "C864E0496731294B4E07D6F9AABF7120", + "download": "18F24E98C694F5986E8226B08188FA83" + } + } + }, + "1599602": { + "config": { + "oslist": "windows" + } + }, + "branches": { + "public": { + "buildid": "15591994", + "timeupdated": "1725468206" + }, + "ch_pr": { + "buildid": "10759092", + "pwdrequired": "1", + "timeupdated": "1678805610" + }, + "chef": { + "buildid": "9251549", + "pwdrequired": "1", + "timeupdated": "1659606643" + }, + "development": { + "buildid": "13189763", + "pwdrequired": "1", + "timeupdated": "1705444518" + }, + "discordbetaaccess": { + "buildid": "9355221", + "pwdrequired": "1", + "timeupdated": "1661039040" + }, + "japan": { + "buildid": "11468716", + "pwdrequired": "1", + "timeupdated": "1686754875" + }, + "secret": { + "buildid": "12841040", + "pwdrequired": "1", + "timeupdated": "1701361864" + }, + "crash-fix-test": { + "buildid": "15335463", + "description": "Test for Environment crash", + "timeupdated": "1723404695" + }, + "creator": { + "buildid": "15548843", + "pwdrequired": "1", + "timeupdated": "1725050086" + }, + "crossplaybeta": { + "buildid": "15776693", + "description": "branch dedicated for crossplay", + "timeupdated": "1727881044" + }, + "crossplaystaging": { + "buildid": "15776693", + "pwdrequired": "1", + "timeupdated": "1726871838" + }, + "playtest": { + "buildid": "15591994", + "pwdrequired": "1", + "timeupdated": "1725464710" + }, + "playtest2": { + "buildid": "15776695", + "pwdrequired": "1", + "timeupdated": "1726871859" + } + } + }, + "ufs": { + "quota": "100000000", + "maxnumfiles": "1000", + "savefiles": { + "0": { + "root": "WinAppDataLocalLow", + "path": "It's Happening/PlateUp", + "pattern": "*.plateupsave", + "recursive": "1" + } + }, + "rootoverrides": { + "0": { + "root": "WinAppDataLocalLow", + "os": "Linux", + "oscompare": "=", + "useinstead": "LinuxHome", + "pathtransforms": { + "0": { + "find": "It's Happening/PlateUp", + "replace": ".config/unity3d/It's Happening/PlateUp" + } + } + } + } + }, + "_missing_token": false, + "_change_number": 25512918, + "_sha": "cdfcc36ba29461619a05c8bc44aa9fa0bf94c8f1", + "_size": 10292 +} \ No newline at end of file diff --git a/generate_emu_config_old/output/1599600/steam_settings/achievements.json b/generate_emu_config_old/output/1599600/steam_settings/achievements.json new file mode 100644 index 0000000..7047ca2 --- /dev/null +++ b/generate_emu_config_old/output/1599600/steam_settings/achievements.json @@ -0,0 +1,938 @@ +[ + { + "hidden": 0, + "displayName": { + "english": "Steaks Were Made", + "german": "Es wurden Steaks gemacht", + "french": "\u00c0 point", + "koreana": "\uc2a4\ud14c\uc774\ud06c \uc870\ub9ac \uc644\ub8cc", + "spanish": "Se han preparado filetes", + "schinese": "\u725b\u6392\u5df2\u714e\u597d", + "tchinese": "\u725b\u6392\u6e96\u5099\u597d\u4e86", + "russian": "\u0414\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0435\u0439\u043a", + "japanese": "\u30b9\u30c6\u30fc\u30ad\u304c\u713c\u3051\u307e\u3057\u305f", + "polish": "Stek gotowy", + "turkish": "Biftekler Haz\u0131rland\u0131", + "brazilian": "Sorteio do Fil\u00e9", + "token": "NEW_ACHIEVEMENT_2_0_NAME" + }, + "description": { + "english": "Serve a steak to a customer", + "german": "Serviere einem Gast ein Steak", + "french": "Servez un steak", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \uc2a4\ud14c\uc774\ud06c\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve un filete a un cliente", + "schinese": "\u5c06\u725b\u6392\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5df2\u5c07\u725b\u6392\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0435\u0439\u043a \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u30b9\u30c6\u30fc\u30ad\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj stek klientowi", + "turkish": "Bir m\u00fc\u015fteriye biftek servis et", + "brazilian": "Sirva fil\u00e9 para um cliente", + "token": "NEW_ACHIEVEMENT_2_0_DESC" + }, + "icon": "img/cf8e7333881792385701b7cfd85f1e27d1a7bfe0.jpg", + "icon_gray": "img/192c8cfe583de2d8be7d3960f8a76a4c8e3c96be.jpg", + "name": "DISH_STEAK" + }, + { + "hidden": 0, + "displayName": { + "english": "Stirring Things Up", + "german": "Aufgeheizt", + "french": "Et que \u00e7a saute !", + "koreana": "\ud718\uc813\uae30", + "spanish": "Ambiente revuelto", + "schinese": "\u7ffb\u7092\u98df\u6750", + "tchinese": "\u5feb\u624b\u4f86\u5feb\u7092", + "russian": "\u0412\u0437\u0431\u0430\u043b\u0442\u044b\u0432\u0430\u044f", + "japanese": "\u3088\u304f\u6df7\u305c\u3066", + "polish": "Zmieszane i usma\u017cone", + "turkish": "\u0130\u015fler K\u0131zard\u0131", + "brazilian": "Refogando Refogado", + "token": "NEW_ACHIEVEMENT_2_1_NAME" + }, + "description": { + "english": "Serve a stir fry to a customer", + "german": "Serviere einem Gast Gem\u00fcsepfanne", + "french": "Servez un saut\u00e9", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \ubcf6\uc74c\uc694\ub9ac\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve un revuelto a un cliente", + "schinese": "\u5c06\u7092\u83dc\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5c07\u5feb\u7092\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0438\u0440-\u0444\u0440\u0430\u0439 \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u7092\u3081\u7269\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj stir-fry klientowi", + "turkish": "Bir m\u00fc\u015fteriye sebze k\u0131zartmas\u0131 servis et", + "brazilian": "Sirva refogado para um cliente", + "token": "NEW_ACHIEVEMENT_2_1_DESC" + }, + "icon_gray": "img/0093f205209654df1c656d9b6022186cf2919f90.jpg", + "icon": "img/cf3660012d6cfe286d118b256791f2b434c90172.jpg", + "name": "DISH_STIR_FRY" + }, + { + "hidden": 0, + "displayName": { + "english": "Piece of the Action", + "german": "Ein Teil der Action", + "french": "Un air d'Italie", + "koreana": "\ud55c \uc870\uac01\uc758 \ubaab", + "spanish": "De porciones va la cosa", + "schinese": "\u5206\u5272\u5927\u5757\u98df\u7269", + "tchinese": "\u7fa9\u5f0f\u98a8\u60c5", + "russian": "\u041a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u0430\u043d\u0430\u043d\u0430\u0441\u043e\u0432?", + "japanese": "\u30ab\u30c3\u30c8\u3067\u3059\u304b\u30db\u30fc\u30eb\u3067\u3059\u304b\uff1f", + "polish": "R\u00f3wne kawa\u0142ki", + "turkish": "Bir Dilim Olsa Ke\u015fke", + "brazilian": "Peda\u00e7o da A\u00e7\u00e3o", + "token": "NEW_ACHIEVEMENT_2_2_NAME" + }, + "description": { + "english": "Serve a pizza to a customer", + "german": "Serviere einem Gast eine Pizza", + "french": "Servez une pizza", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \ud53c\uc790\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve pizza a un cliente", + "schinese": "\u5c06\u62ab\u8428\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5df2\u5c07\u62ab\u85a9\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u043f\u0438\u0446\u0446\u0443 \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u30d4\u30b6\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj pizz\u0119 klientowi", + "turkish": "Bir m\u00fc\u015fteriye pizza servis et", + "brazilian": "Sirva pizza para um cliente", + "token": "NEW_ACHIEVEMENT_2_2_DESC" + }, + "icon_gray": "img/3cac68bcef70bd8894157ed2f0f48d91dbbc7ea5.jpg", + "icon": "img/36d3d0d14cec6492b73f21f6e09eca4604cfe196.jpg", + "name": "DISH_PIZZA" + }, + { + "hidden": 0, + "displayName": { + "english": "A New Leaf", + "german": "Ein neues Blatt", + "french": "Bon comme la romaine", + "koreana": "\uc2e0\uc120\ud55c \uc78e", + "spanish": "Brotes verdes", + "schinese": "\u4e00\u7247\u65b0\u9c9c\u53f6\u5b50", + "tchinese": "\u852c\u679c\u7576\u7136\u8981\u65b0\u9bae", + "russian": "\u0427\u0438\u0441\u0442\u044b\u0439 \u043b\u0438\u0441\u0442", + "japanese": "\u3068\u308c\u305f\u3066\u65b0\u9bae", + "polish": "Nowy li\u015b\u0107", + "turkish": "Yeni Bir Yaprak", + "brazilian": "Um Nova Folha", + "token": "NEW_ACHIEVEMENT_2_3_NAME" + }, + "description": { + "english": "Serve a salad to a customer", + "german": "Serviere einem Gast einen Salat", + "french": "Servez une salade", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \uc0d0\ub7ec\ub4dc\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve ensalada a un cliente", + "schinese": "\u5c06\u6c99\u62c9\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5c07\u6c99\u62c9\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u0441\u0430\u043b\u0430\u0442 \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u30b5\u30e9\u30c0\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj sa\u0142atk\u0119 klientowi", + "turkish": "Bir m\u00fc\u015fteriye salata servis et", + "brazilian": "Serviu salada para um cliente", + "token": "NEW_ACHIEVEMENT_2_3_DESC" + }, + "icon_gray": "img/ac11799f84911688d25fcca446490d0d653a732e.jpg", + "icon": "img/6251ddf410f13bbb4cde4dfca97a83857104d41f.jpg", + "name": "DISH_SALAD" + }, + { + "hidden": 0, + "displayName": { + "english": "Soggy Bottom", + "german": "Feuchter Boden", + "french": "Fond humide", + "koreana": "\ucd09\ucd09\ud55c \ubc14\ub2e5", + "spanish": "Base esponjosa", + "schinese": "\u539a\u997c\u76ae", + "tchinese": "\u7f8e\u5473\u85cf\u9921\u4e2d", + "russian": "\u041c\u043e\u043a\u0440\u044b\u0439 \u043d\u0438\u0437", + "japanese": "\u4e2d\u306f\u3075\u3093\u308f\u308a", + "polish": "Wilgotny sp\u00f3d", + "turkish": "Yumu\u015fak Dipli", + "brazilian": "Fundinho Queimado", + "token": "NEW_ACHIEVEMENT_2_4_NAME" + }, + "description": { + "english": "Serve a pie to a customer", + "german": "Serviere einem Gast einen Kuchen", + "french": "Servez une tarte", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \ud30c\uc774\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve tarta a un cliente", + "schinese": "\u5c06\u6c34\u679c\u6d3e\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5c07\u6d3e\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u043f\u0438\u0440\u043e\u0433 \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u30d1\u30a4\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj ciasto klientowi", + "turkish": "Bir m\u00fc\u015fteriye turta servis et", + "brazilian": "Sirva torta para um cliente", + "token": "NEW_ACHIEVEMENT_2_4_DESC" + }, + "icon_gray": "img/9e16b74748c8aa0b9f58494637fefe251048f26b.jpg", + "icon": "img/9144ef4c3447c80ead03df7230587aac73a3a511.jpg", + "name": "DISH_PIE" + }, + { + "hidden": 0, + "displayName": { + "english": "Something Fishy", + "german": "Es riecht nach Fisch", + "french": "Dare darne", + "koreana": "\uc0dd\uc120 \ub0c4\uc0c8", + "spanish": "Un asunto espinoso", + "schinese": "\u9c7c\u8165\u4e4b\u7269", + "tchinese": "\u9bae\u5473\u85cf\u4e0d\u4f4f", + "russian": "\u0427\u0435\u043c \u044d\u0442\u043e \u043f\u0430\u0445\u043d\u0435\u0442?", + "japanese": "\u6d77\u306e\u3081\u3050\u307f", + "polish": "Co\u015b rybnego", + "turkish": "Ay\u0131kla K\u0131l\u00e7\u0131\u011f\u0131n\u0131", + "brazilian": "Cheiro Estranho", + "token": "NEW_ACHIEVEMENT_2_5_NAME" + }, + "description": { + "english": "Serve a fish to a customer", + "german": "Serviere einem Gast Fisch", + "french": "Servez un poisson", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \uc0dd\uc120\uc744 \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve pescado a un cliente", + "schinese": "\u5c06\u9c7c\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5c07\u6d77\u9b5a\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u0440\u044b\u0431\u0443 \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u9b5a\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj ryb\u0119 klientowi", + "turkish": "Bir m\u00fc\u015fteriye bal\u0131k servis et", + "brazilian": "Sirva peixe para um cliente", + "token": "NEW_ACHIEVEMENT_2_5_DESC" + }, + "icon": "img/0a18ca860bc1c17b096290eb42b8a1b13e214f9f.jpg", + "icon_gray": "img/92a5e404b5547d0a51a0bd1eff9a566d816ced81.jpg", + "name": "DISH_FISH" + }, + { + "hidden": 0, + "displayName": { + "english": "Man's Best Friend?", + "german": "Des Menschen bester Freund?", + "french": "Le meilleur ami de l'homme ?", + "koreana": "\uc0ac\ub78c\uc758 \uac00\uc7a5 \uc88b\uc740 \uce5c\uad6c?", + "spanish": "\u00bfEl mejor amigo del hombre?", + "schinese": "\u4eba\u7c7b\u76ca\u53cb\uff1f", + "tchinese": "\u8212\u5fc3\u98df\u7269\u5c11\u4e0d\u5f97", + "russian": "\u041b\u0443\u0447\u0448\u0438\u0439 \u0434\u0440\u0443\u0433 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430?", + "japanese": "\u30a2\u30c4\u30a2\u30c4\u3092\u3069\u3046\u305e", + "polish": "Najlepszy przyjaciel cz\u0142owieka?", + "turkish": "Olsa ve Yesek", + "brazilian": "Melhor Amigo do Homem?", + "token": "NEW_ACHIEVEMENT_2_6_NAME" + }, + "description": { + "english": "Serve a hotdog to a customer", + "german": "Serviere einem Gast einen Hotdog", + "french": "Servez un hotdog", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \ud56b\ub3c4\uadf8\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve un perrito a un cliente", + "schinese": "\u5c06\u70ed\u72d7\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5c07\u71b1\u72d7\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u0445\u043e\u0442-\u0434\u043e\u0433 \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u30db\u30c3\u30c8\u30c9\u30c3\u30b0\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj hot doga klientowi", + "turkish": "Bir m\u00fc\u015fteriye sosisli sandvi\u00e7 servis et", + "brazilian": "Sirva cachorro-quente para um cliente", + "token": "NEW_ACHIEVEMENT_2_6_DESC" + }, + "icon_gray": "img/cd55007af77144d030f512afe1ebd4074b4df1e4.jpg", + "icon": "img/934d3a1b0283fc99662bca6d081c0559ef93c8c3.jpg", + "name": "DISH_HOTDOG" + }, + { + "hidden": 0, + "displayName": { + "english": "Least Important Meal", + "german": "Unwichtigste Mahlzeit", + "french": "Sur le pouce", + "koreana": "\uac00\uc7a5 \uc911\uc694\ud558\uc9c0 \uc54a\uc740 \uc2dd\uc0ac", + "spanish": "La comida menos importante", + "schinese": "\u65e0\u5173\u7d27\u8981\u7684\u4e00\u9910", + "tchinese": "\u7f8e\u597d\u4e00\u5929\u5f9e\u65e9\u9910\u958b\u59cb", + "russian": "\u0421\u0430\u043c\u044b\u0439 \u043d\u0435\u0432\u0430\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u0435\u043c \u043f\u0438\u0449\u0438", + "japanese": "\u4e00\u65e5\u306e\u59cb\u307e\u308a", + "polish": "Najmniej wa\u017cny posi\u0142ek", + "turkish": "En \u00d6nemsiz \u00d6\u011f\u00fcn", + "brazilian": "A Refei\u00e7\u00e3o Menos Importante", + "token": "NEW_ACHIEVEMENT_2_7_NAME" + }, + "description": { + "english": "Serve a breakfast to a customer", + "german": "Serviere einem Gast Fr\u00fchst\u00fcck", + "french": "Servez un petit-d\u00e9jeuner", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \uc544\uce68 \uc2dd\uc0ac\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve un desayuno a un cliente", + "schinese": "\u5c06\u65e9\u9910\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5c07\u65e9\u9910\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u0437\u0430\u0432\u0442\u0440\u0430\u043a \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u671d\u98df\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj \u015bniadanie klientowi", + "turkish": "Bir m\u00fc\u015fteriye kahvalt\u0131 servis et", + "brazilian": "Sirva caf\u00e9 da manh\u00e3 para um cliente", + "token": "NEW_ACHIEVEMENT_2_7_DESC" + }, + "icon": "img/b193d2a2f881716f2364b85a2fdc05572577a1bd.jpg", + "icon_gray": "img/943b0135c2afe8b95161287d67544a613de0c689.jpg", + "name": "DISH_BREAKFAST" + }, + { + "hidden": 0, + "displayName": { + "english": "Burger Prince", + "german": "Burger-Prinz", + "french": "Burger Prince", + "koreana": "\ubc84\uac70 \ud504\ub9b0\uc2a4", + "spanish": "El pr\u00edncipe de las hamburguesas", + "schinese": "\u6c49\u5821\u738b\u5b50", + "tchinese": "\u71b1\u91cf\u7206\u71c8\u3001\u5fc3\u60c5\u6eff\u5206", + "russian": "\u0411\u0443\u0440\u0433\u0435\u0440 \u041f\u0440\u0438\u043d\u0446", + "japanese": "\u304a\u597d\u307f\u306e\u30c8\u30c3\u30d4\u30f3\u30b0\u306f\uff1f", + "polish": "Ksi\u0105\u017c\u0119 burger\u00f3w", + "turkish": "Hamburger Prensi", + "brazilian": "Pr\u00edncipe do Burg\u00e3o", + "token": "NEW_ACHIEVEMENT_2_8_NAME" + }, + "description": { + "english": "Serve a burger to a customer", + "german": "Serviere einem Gast einen Burger", + "french": "Servez un burger", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \ubc84\uac70\ub97c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve una hamburguesa a un cliente", + "schinese": "\u5c06\u6c49\u5821\u7aef\u7ed9\u5ba2\u4eba", + "tchinese": "\u5df2\u5c07\u6f22\u5821\u9001\u5230\u9867\u5ba2\u684c\u4e0a", + "russian": "\u041f\u043e\u0434\u0430\u0439\u0442\u0435 \u0431\u0443\u0440\u0433\u0435\u0440 \u0433\u043e\u0441\u0442\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u30cf\u30f3\u30d0\u30fc\u30ac\u30fc\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Podaj burgera klientowi", + "turkish": "Bir m\u00fc\u015fteriye hamburger servis et", + "brazilian": "Sirva hamb\u00farguer para um cliente", + "token": "NEW_ACHIEVEMENT_2_8_DESC" + }, + "icon_gray": "img/6473b1c1da531302ca57bba1d3cb5ebc7bd400db.jpg", + "icon": "img/4dd21bd02267a273d08d3ba4db272c8dff8d19b7.jpg", + "name": "DISH_BURGER" + }, + { + "hidden": 0, + "displayName": { + "english": "This Is Fine", + "german": "Das ist sch\u00f6n", + "french": "\u00c7a va bien se passer", + "koreana": "\uc774\uac74 \uad1c\ucc2e\uc544\uc694", + "spanish": "No pasa nada", + "schinese": "\u8fd9\u6837\u5f88\u597d", + "tchinese": "\u7121\u5927\u4e8b", + "russian": "\u0423\u043b\u044b\u0431\u0430\u0435\u043c\u0441\u044f \u0438 \u043c\u0430\u0448\u0435\u043c", + "japanese": "\u65e5\u5e38\u8336\u98ef\u4e8b", + "polish": "Nic si\u0119 nie sta\u0142o", + "turkish": "Sorun Yok", + "brazilian": "Tudo Tranquilo", + "token": "NEW_ACHIEVEMENT_2_9_NAME" + }, + "description": { + "english": "Complete a day when the restaurant has been on fire for more than 15 seconds", + "german": "Schlie\u00dfe einen Tag ab, an dem das Restaurant mehr als 15 Sekunden lang brennt", + "french": "Terminez une journ\u00e9e o\u00f9 le restaurant fut en feu pendant plus de 15 secondes", + "koreana": "\ub808\uc2a4\ud1a0\ub791\uc5d0\uc11c 15\ucd08\uac00 \ub118\ub294 \uc2dc\uac04 \ub3d9\uc548 \ubd88\uc774 \ub0ac\uc744 \ub54c \ud558\ub8e8\ub97c \uc644\ub8cc\ud558\uc138\uc694", + "spanish": "Completa un d\u00eda donde se haya producido un incendio en el restaurante durante m\u00e1s de 15 segundos", + "schinese": "\u56e0\u4e3a\u9910\u9986\u7740\u706b\u8d85\u8fc7\u4e8615\u79d2\u949f\uff0c\u7ed3\u675f\u4e00\u5929", + "tchinese": "\u5982\u9910\u5ef3\u8d77\u706b\u8d85\u904e15\u79d2\uff0c\u4e7e\u8106\u7d50\u675f\u9019\u4e00\u5929\u5427\uff01", + "russian": "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u0434\u0435\u043d\u044c, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0441\u0442\u043e\u0440\u0430\u043d \u0433\u043e\u0440\u0435\u043b \u0431\u043e\u043b\u0435\u0435 15 \u0441\u0435\u043a\u0443\u043d\u0434", + "japanese": "\u30ec\u30b9\u30c8\u30e9\u30f3\u304c15\u79d2\u4ee5\u4e0a\u706b\u707d\u3092\u8d77\u3053\u3057\u305f\u307e\u307e\u4e00\u65e5\u3092\u7d42\u3048\u308b\u3002", + "polish": "Uko\u0144cz dzie\u0144, w kt\u00f3rym w restauracji przez ponad 15 sekund b\u0119dzie trwa\u0107 po\u017car", + "turkish": "Restoranda 15 saniyeden uzun s\u00fcren bir yang\u0131n\u0131n \u00e7\u0131kt\u0131\u011f\u0131 bir g\u00fcn\u00fc tamamla", + "brazilian": "Conclua um dia quando o restaurante estava pegando fogo por mais de 15 segundos", + "token": "NEW_ACHIEVEMENT_2_9_DESC" + }, + "icon": "img/3bb663e137a4fcb6669e12b137b001fbad67180e.jpg", + "icon_gray": "img/7d6ed3d308ddeb8bd7a6c94d597b2f532a0fa4f0.jpg", + "name": "FIRE_RECOVERY" + }, + { + "hidden": 0, + "displayName": { + "english": "Fireman", + "german": "Feuerwehrmann", + "french": "Pompier", + "koreana": "\uc18c\ubc29\uad00", + "spanish": "Bombero", + "schinese": "\u6d88\u9632\u5458", + "tchinese": "\u6253\u706b\u5eda\u5e2b", + "russian": "\u041f\u043e\u0436\u0430\u0440\u043d\u044b\u0439", + "japanese": "\u708e\u4e0a\u4e2d", + "polish": "Stra\u017cak", + "turkish": "\u0130tfaiyeci", + "brazilian": "Bombeiro", + "token": "NEW_ACHIEVEMENT_2_10_NAME" + }, + "description": { + "english": "Complete a day with 10 appliances on fire at once", + "german": "Schlie\u00dfe einen Tag ab, an dem 10 Haushaltsger\u00e4te gleichzeitig brennen", + "french": "Terminez une journ\u00e9e o\u00f9 10 appareils \u00e9taient en feu, en m\u00eame temps", + "koreana": "\ud55c \ubc88\uc5d0 \uae30\uad6c 10\uac1c\uc5d0 \ubd88\uc744 \ucf1c\uace0 \ud558\ub8e8\ub97c \uc644\ub8cc\ud558\uc138\uc694", + "spanish": "Completa un d\u00eda con 10 electrodom\u00e9sticos incendiados a la vez", + "schinese": "\u4e00\u6b2110\u4ef6\u5bb6\u7535\u7740\u706b\uff0c\u7ed3\u675f\u4e00\u5929", + "tchinese": "\u598210\u7a2e\u5668\u5177\u540c\u6642\u8d77\u706b\uff0c\u4e7e\u8106\u7d50\u675f\u9019\u4e00\u5929\u5427\uff01", + "russian": "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u0434\u0435\u043d\u044c \u0441 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0433\u043e\u0440\u0435\u043d\u0438\u0435\u043c 10 \u043f\u0440\u0438\u0431\u043e\u0440\u043e\u0432", + "japanese": "10\u53f0\u306e\u5668\u5177\u304c\u540c\u6642\u306b\u706b\u707d\u3092\u8d77\u3053\u3057\u305f\u307e\u307e\u4e00\u65e5\u3092\u7d42\u3048\u308b\u3002", + "polish": "Uko\u0144cz dzie\u0144 z 10 sprz\u0119tami kuchennymi na ogniu", + "turkish": "Ayn\u0131 anda 10 aletin yanmaya ba\u015flad\u0131\u011f\u0131 bir g\u00fcn\u00fc tamamla", + "brazilian": "Conclua um dia com 10 equipamentos pegando fogo ao mesmo tempo", + "token": "NEW_ACHIEVEMENT_2_10_DESC" + }, + "icon": "img/9a8b8fa54ad18087d69461c92401a3f091b936ec.jpg", + "icon_gray": "img/aa66ea809eccf7dfda7fe37415d3b956287ceeb1.jpg", + "name": "FIRE_BRIGADE" + }, + { + "hidden": 0, + "displayName": { + "english": "Flawless Timing", + "german": "Makelloses Timing", + "french": "\u00c0 point nomm\u00e9", + "koreana": "\uc644\ubcbd\ud55c \ud0c0\uc774\ubc0d", + "spanish": "El momento justo", + "schinese": "\u5b8c\u7f8e\u8ba1\u65f6", + "tchinese": "\u670d\u52d9\u9031\u5230", + "russian": "\u0421\u0435\u043a\u0443\u043d\u0434\u0430 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443", + "japanese": "\u5b8c\u74a7\u306a\u5bfe\u5fdc", + "polish": "Bezb\u0142\u0119dne wyczucie czasu", + "turkish": "Kusursuz Zamanlama", + "brazilian": "Timing Perfeito", + "token": "NEW_ACHIEVEMENT_2_11_NAME" + }, + "description": { + "english": "Serve a customer with less than a second to spare", + "german": "Bediene einen Gast mit weniger als einer verschwendeten Sekunde", + "french": "Servez un client moins d'une seconde avant l'\u00e9ch\u00e9ance", + "koreana": "1\ucd08\ub3c4 \uc9c0\uccb4\ud558\uc9c0 \uc54a\uace0 \uc190\ub2d8\uc5d0\uac8c \uc11c\ube59\ud558\uc138\uc694", + "spanish": "Sirve a un cliente con menos de un segundo disponible", + "schinese": "\u6ca1\u6709\u6d6a\u8d39\u4e00\u79d2\u949f\u5c31\u670d\u52a1\u4e86\u4e00\u540d\u987e\u5ba2", + "tchinese": "\u57281\u79d2\u5167\u62db\u5f85\u9867\u5ba2", + "russian": "\u041e\u0431\u0441\u043b\u0443\u0436\u0438\u0442\u0435 \u0433\u043e\u0441\u0442\u044f \u0441 \u0437\u0430\u043f\u0430\u0441\u043e\u043c \u043c\u0435\u043d\u0435\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b", + "japanese": "1\u79d2\u672a\u6e80\u3067\u304a\u5ba2\u3055\u3093\u306b\u30b5\u30fc\u30d3\u30b9\u3092\u63d0\u4f9b\u3059\u308b\u3002", + "polish": "Obs\u0142u\u017c klienta na mniej ni\u017c jedn\u0105 sekund\u0119 przed czasem", + "turkish": "Bir m\u00fc\u015fteriye bir saniyeden az s\u00fcre kalm\u0131\u015fken servis yap", + "brazilian": "Sirva um cliente com menos de um segundo sobrando", + "token": "NEW_ACHIEVEMENT_2_11_DESC" + }, + "icon_gray": "img/f3683e2dcdb56c083730c02fb54a500754bde342.jpg", + "icon": "img/622f7da40f7bf1cc7669643e91a2a8a212378ca4.jpg", + "name": "FLAWLESS_TIMING" + }, + { + "hidden": 0, + "displayName": { + "english": "Health Inspector?", + "german": "Gesundheitsinspektor?", + "french": "Inspection sanitaire ?", + "koreana": "\uc704\uc0dd \uac80\uc0ac\uad00?", + "spanish": "\u00bfInspector de sanidad?", + "schinese": "\u536b\u751f\u68c0\u67e5\u5458\uff1f", + "tchinese": "\u8868\u73fe\u7cfe\u5bdf\u968a", + "russian": "\u0421\u0430\u043d\u0438\u0442\u0430\u0440\u043d\u044b\u0439 \u0438\u043d\u0441\u043f\u0435\u043a\u0442\u043e\u0440?", + "japanese": "\u885b\u751f\u691c\u67fb\u306e\u65e5\uff1f", + "polish": "Inspektor BHP?", + "turkish": "Sa\u011fl\u0131k Denetmeni Nerede?", + "brazilian": "Inspetor Sanit\u00e1rio?", + "token": "NEW_ACHIEVEMENT_2_12_NAME" + }, + "description": { + "english": "Complete a day with a mess on at least 10 tiles", + "german": "Schlie\u00dfe einen Tag ab, an dem mindestens 10 Felder in Unordnung sind", + "french": "Terminez une journ\u00e9e avec au moins 10 tuiles en d\u00e9sordre", + "koreana": "10\uac1c \uc774\uc0c1\uc758 \ud0c0\uc77c\uc744 \uc5c9\ub9dd\uc73c\ub85c \ub9cc\ub4e4\uace0 \ud558\ub8e8\ub97c \uc644\ub8cc\ud558\uc138\uc694", + "spanish": "Completa un d\u00eda con un embrollo en 10 baldosas o m\u00e1s", + "schinese": "\u641e\u4e71\u4e86\u81f3\u5c1110\u5757\u5730\u7816\uff0c\u7ed3\u675f\u4e00\u5929", + "tchinese": "\u572810\u500b\u78da\u584a\u6df7\u4e82\uff0c\u4e7e\u8106\u76f4\u63a5\u7d50\u675f\u9019\u4e00\u5929\u5427\uff01", + "russian": "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u0434\u0435\u043d\u044c \u0441 \u0431\u0435\u0441\u043f\u043e\u0440\u044f\u0434\u043a\u043e\u043c \u043d\u0430 \u043c\u0438\u043d\u0438\u043c\u0443\u043c 10 \u043f\u043b\u0438\u0442\u043a\u0430\u0445", + "japanese": "10\u30bf\u30a4\u30eb\u4ee5\u4e0a\u304c\u6c5a\u308c\u305f\u307e\u307e\u4e00\u65e5\u3092\u7d42\u3048\u308b\u3002", + "polish": "Uko\u0144cz dzie\u0144 z nieporz\u0105dkiem na co najmniej 10 polach", + "turkish": "En az 10 birim alan\u0131n kirlendi\u011fi bir g\u00fcn\u00fc tamamla", + "brazilian": "Conclua um dia com uma bagun\u00e7a em pelo menos 10 espa\u00e7os", + "token": "NEW_ACHIEVEMENT_2_12_DESC" + }, + "icon": "img/5ca7107dd17f2157a89c12078c3e6bd7d493c47e.jpg", + "icon_gray": "img/14b7c02224e3f8cb45f7f2c5f0079cc7b867c4bb.jpg", + "name": "WHAT_A_STATE" + }, + { + "hidden": 0, + "displayName": { + "english": "Oh No", + "german": "Oh Nein", + "french": "Bol des ardents", + "koreana": "\ub9d9\uc18c\uc0ac", + "spanish": "Vaya tela", + "schinese": "\u54ce\u5440\u4e0d\u597d", + "tchinese": "\u73a9\u51fa\u706b\u4e86\uff01", + "russian": "\u041e \u043d\u0435\u0442!", + "japanese": "\u3061\u3087\u3063\u3068\u3057\u305f\u4e0d\u6ce8\u610f", + "polish": "O, nie", + "turkish": "Olamaz", + "brazilian": "Eita", + "token": "NEW_ACHIEVEMENT_2_13_NAME" + }, + "description": { + "english": "Set a customer on fire", + "german": "Setze einen Gast in Brand", + "french": "Enflammez un client", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \ubd88\uc744 \ubd99\uc774\uc138\uc694", + "spanish": "Prende fuego a un cliente", + "schinese": "\u8ba9\u4e00\u540d\u987e\u5ba2\u53d1\u706b", + "tchinese": "\u9867\u5ba2\u4e5f\u8d77\u706b\u4e86", + "russian": "\u041f\u043e\u0434\u043e\u0436\u0433\u043b\u0438 \u0433\u043e\u0441\u0442\u044f", + "japanese": "\u304a\u5ba2\u3055\u3093\u306b\u706b\u3092\u70b9\u3051\u308b\u3002", + "polish": "Podpal klienta", + "turkish": "Bir m\u00fc\u015fterinin yanmas\u0131na yol a\u00e7", + "brazilian": "Coloque fogo em um cliente", + "token": "NEW_ACHIEVEMENT_2_13_DESC" + }, + "icon_gray": "img/c755cc05cd8bb36d7dc0a47f544444877f15d457.jpg", + "icon": "img/f17e088b7cf40982b084b6a84585f3e3d1266d03.jpg", + "name": "OH_NO" + }, + { + "hidden": 0, + "displayName": { + "english": "Charcoal Factory", + "german": "Holzkohle-Fabrik", + "french": "Charbonni\u00e8re", + "koreana": "\uc11d\ud0c4 \uacf5\uc7a5", + "spanish": "F\u00e1brica de carb\u00f3n", + "schinese": "\u6728\u70ad\u5de5\u5382", + "tchinese": "\u5feb\u8b8a\u70e4\u8089\u5e97\u4e86\uff01", + "russian": "\u0423\u0433\u043e\u043b\u044c\u043d\u0430\u044f \u0444\u0430\u0431\u0440\u0438\u043a\u0430", + "japanese": "\u70ad\u713c\u304d\u5de5\u5834", + "polish": "Sk\u0142ad w\u0119gla", + "turkish": "K\u00f6m\u00fcr Fabrikas\u0131", + "brazilian": "F\u00e1brica de Carv\u00e3o", + "token": "NEW_ACHIEVEMENT_2_14_NAME" + }, + "description": { + "english": "Cook something on a Danger Hob with an activated Gas Safety Override", + "german": "Koche etwas auf einer gef\u00e4hrlichen Kochstelle mit aktivierter Gas\u00fcberbr\u00fcckung", + "french": "Cuisinez quelque chose sur la cuisini\u00e8re dangereuse, avec le d\u00e9passement de gaz activ\u00e9", + "koreana": "\uac00\uc2a4 \uc81c\uc5b4\uc7a5\uce58\ub97c \ucf1c\uace0 \uc704\ud5d8\ud55c \uc694\ub9ac\ud310\uc5d0\uc11c \ubb54\uac00\ub97c \uc694\ub9ac\ud558\uc138\uc694", + "spanish": "Cocina algo en un fog\u00f3n peligroso con una v\u00e1lvula de seguridad de gas activada", + "schinese": "\u6253\u5f00\u8d85\u91cf\u7528\u6c14\u5b89\u5168\u9600\uff0c\u5728\u4e00\u4e2a\u5371\u9669\u7089\u7076\u4e0a\u70f9\u996a\u98df\u7269", + "tchinese": "\u5230\u5df2\u555f\u7528\u706b\u529b\u89e3\u653e\u88dd\u7f6e\u9ad8\u5371\u74e6\u65af\u7210\u4e0a\u716e\u6771\u897f", + "russian": "\u041f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u044c\u0442\u0435 \u0447\u0442\u043e-\u0442\u043e \u043d\u0430 \u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u043b\u0438\u0442\u0435 \u0441 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0433\u0430\u0437\u043e\u0432\u044b\u043c \u0431\u043b\u043e\u043a\u0438\u0440\u0430\u0442\u043e\u0440\u043e\u043c", + "japanese": "\u30ac\u30b9\u5f37\u5316\u72b6\u614b\u306e\u30b9\u30fc\u30d1\u30fc\u30b3\u30f3\u30ed\u3067\u6599\u7406\u3059\u308b\u3002", + "polish": "Ugotuj co\u015b na ekstremalnej kuchence z w\u0142\u0105czonym boosterem gazu", + "turkish": "Gaz A\u015f\u0131m\u0131 etkinken Tehlikeli Ocakta bir \u015fey pi\u015fir", + "brazilian": "Cozinhe algo em um Boca de Fog\u00e3o com Perigo com o Controle Manual de Seguran\u00e7a de G\u00e1s ativado", + "token": "NEW_ACHIEVEMENT_2_14_DESC" + }, + "icon_gray": "img/81f0bdfd271c45035e0d3c1bfa85adf6a7f366e7.jpg", + "icon": "img/bdc4249bc11526f262cd5b0adb4e8e3866234b55.jpg", + "name": "CHARCOAL_FACTORY" + }, + { + "hidden": 0, + "displayName": { + "english": "Safety Last", + "german": "Sicherheit ist nicht so wichtig", + "french": "La s\u00e9curit\u00e9, c'est pour les nuls", + "koreana": "\uc548\uc804\uc740 \ucc28\uc120", + "spanish": "La seguridad es lo \u00faltimo", + "schinese": "\u5b89\u5168\u6700\u4f4e", + "tchinese": "\u5b89\u5168\u81f3\u4e0a", + "russian": "\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c", + "japanese": "\u5371\u967a\u884c\u70ba", + "polish": "Bezpiecze\u0144stwo si\u0119 nie liczy", + "turkish": "Sonra G\u00fcvenlik", + "brazilian": "Seguran\u00e7a Em \u00daltimo Lugar", + "token": "NEW_ACHIEVEMENT_2_15_NAME" + }, + "description": { + "english": "Wear Trainers while holding a Sharp Knife", + "german": "Trage mit einem scharfen Messer in der Hand Turnschuhe", + "french": "Portez des baskets en tenant un couteau aiguis\u00e9", + "koreana": "\ub0a0\uce74\ub85c\uc6b4 \uce7c\uc744 \ub4e4\uace0 \uc6b4\ub3d9\ud654\ub97c \uc2e0\uc73c\uc138\uc694", + "spanish": "Lleva zapatillas deportivas mientras sostienes un cuchillo afilado", + "schinese": "\u624b\u62ff\u4e00\u628a\u950b\u5229\u9910\u5200\uff0c\u7a7f\u4e0a\u8fd0\u52a8\u978b", + "tchinese": "\u624b\u6301\u92d2\u5229\u7684\u83dc\u5200\u6642\u7a7f\u4e0a\u7403\u978b", + "russian": "\u041d\u043e\u0441\u0438\u0442\u0435 \u043a\u0440\u043e\u0441\u0441\u043e\u0432\u043a\u0438, \u0434\u0435\u0440\u0436\u0430 \u0432 \u0440\u0443\u043a\u0430\u0445 \u043e\u0441\u0442\u0440\u044b\u0439 \u043d\u043e\u0436", + "japanese": "\u30ca\u30a4\u30d5\u3092\u6301\u3063\u305f\u307e\u307e\u30b9\u30dd\u30fc\u30c4\u30b7\u30e5\u30fc\u30ba\u3092\u5c65\u304f\u3002", + "polish": "Noszono adidasy, trzymaj\u0105c ostry n\u00f3\u017c", + "turkish": "Bir Keskin B\u0131\u00e7ak tutarken Spor Ayakkab\u0131 giy", + "brazilian": "Vista T\u00eanis de Corrida enquanto segura uma Faca Afiada", + "token": "NEW_ACHIEVEMENT_2_15_DESC" + }, + "icon_gray": "img/623699ae1d9bc19d41fd3a06014ee0b601799f3b.jpg", + "icon": "img/2e95f022d01fafbf4cc2bbb48f36cb08ee3e245b.jpg", + "name": "SAFETY_LAST" + }, + { + "hidden": 0, + "displayName": { + "english": "Circle Line", + "german": "Kreisbahn", + "french": "La boucle est boucl\u00e9e", + "koreana": "\uc21c\ud658\uc120", + "spanish": "Ciclo completo", + "schinese": "\u5faa\u73af\u7ebf", + "tchinese": "\u54ea\u88e1\u958b\u59cb\u3001\u54ea\u88e1\u7d50\u675f", + "russian": "\u0416\u0438\u0437\u043d\u044c \u0446\u0438\u043a\u043b\u0438\u0447\u043d\u0430", + "japanese": "\u74b0\u72b6\u7dda", + "polish": "Pe\u0142ny kr\u0105g", + "turkish": "D\u00f6nd\u00fc Dola\u015ft\u0131", + "brazilian": "Ciclo Completo", + "token": "NEW_ACHIEVEMENT_2_16_NAME" + }, + "description": { + "english": "Convey an item back to where it started", + "german": "Bef\u00f6rdere ein Objekt dorthin zur\u00fcck, wo es am Anfang war", + "french": "Ramenez un plat l\u00e0 \u00e0 son point de d\u00e9part", + "koreana": "\uc544\uc774\ud15c\uc744 \uc2dc\uc791\ud588\ub358 \uacf3\uc73c\ub85c \ub3cc\ub824 \ub193\uc73c\uc138\uc694", + "spanish": "Devuelve un objeto a su lugar de origen", + "schinese": "\u628a\u4e00\u6837\u4e1c\u897f\u5f04\u56de\u6210\u539f\u672c\u6a21\u6837", + "tchinese": "\u5c07\u7269\u54c1\u9001\u56de\u958b\u59cb\u4f4d\u7f6e", + "russian": "\u0412\u0435\u0440\u043d\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435", + "japanese": "\u30b3\u30f3\u30d9\u30e4\u3067\u30a2\u30a4\u30c6\u30e0\u3092\u5143\u306e\u5834\u6240\u306b\u623b\u3059\u3002", + "polish": "Dostarcz jedzenie z powrotem do miejsca pocz\u0105tkowego", + "turkish": "Bir \u00f6\u011fe ba\u015flad\u0131\u011f\u0131 yere geri ta\u015f\u0131ns\u0131n", + "brazilian": "Fa\u00e7a um item retornar ao ponto inicial com uma esteira", + "token": "NEW_ACHIEVEMENT_2_16_DESC" + }, + "icon": "img/6dfe76287e92fb4c8e69c08d73d5a2501dcc7b02.jpg", + "icon_gray": "img/516922c2f59d5c58d74a67d0005daa620f2bf004.jpg", + "name": "CIRCLE_LINE" + }, + { + "hidden": 0, + "displayName": { + "english": "Chef School", + "german": "Kochschule", + "french": "\u00c9cole des chefs", + "koreana": "\uc694\ub9ac\uc0ac \ud559\uad50", + "spanish": "Escuela de chefs", + "schinese": "\u53a8\u5e08\u5b66\u6821", + "tchinese": "\u5927\u5eda\u990a\u6210\u8a18", + "russian": "\u0428\u043a\u043e\u043b\u0430 \u0448\u0435\u0444\u043e\u0432", + "japanese": "\u30b7\u30a7\u30d5\u990a\u6210\u5b66\u6821", + "polish": "Szko\u0142a gastronomiczna", + "turkish": "\u015eef Okulu", + "brazilian": "Escola de Chef", + "token": "NEW_ACHIEVEMENT_2_17_NAME" + }, + "description": { + "english": "Activate Practice Mode during preparation time", + "german": "Aktiviere den \u00dcbungsmodus w\u00e4hrend der Zubereitungszeit", + "french": "Activez le mode Entra\u00eenement pendant la phase de pr\u00e9paration", + "koreana": "\uc900\ube44 \uc2dc\uac04 \ub3d9\uc548 \uc5f0\uc2b5 \ubaa8\ub4dc\ub97c \ud65c\uc131\ud654\ud558\uc138\uc694", + "spanish": "Activa el modo Pr\u00e1ctica durante el tiempo de preparaci\u00f3n", + "schinese": "\u5728\u51c6\u5907\u9636\u6bb5\u6fc0\u6d3b\u7ec3\u4e60\u6a21\u5f0f", + "tchinese": "\u5728\u6e96\u5099\u671f\u9593\u555f\u7528\u7df4\u7fd2\u6a21\u5f0f", + "russian": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0439\u0442\u0435 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0438\u044f", + "japanese": "\u6e96\u5099\u671f\u9593\u4e2d\u306b\u7df4\u7fd2\u30e2\u30fc\u30c9\u3092\u958b\u59cb\u3059\u308b\u3002", + "polish": "Aktywuj tryb \u0107wicze\u0144 podczas przygotowa\u0144", + "turkish": "Haz\u0131rl\u0131k s\u00fcresinde Al\u0131\u015ft\u0131rma Modunu etkinle\u015ftir", + "brazilian": "Ative o Modo Treino durante o tempo de prepara\u00e7\u00e3o", + "token": "NEW_ACHIEVEMENT_2_17_DESC" + }, + "icon_gray": "img/103ee7b2c3eebc7a5e33fc8153f432707f90cb22.jpg", + "icon": "img/c8da2ebf19d362e479cf4e1773fe58dd8e2eeab2.jpg", + "name": "CHEF_SCHOOL" + }, + { + "hidden": 0, + "displayName": { + "english": "New Chef Plus", + "german": "Neuer Koch Plus", + "french": "New Chef Plus", + "koreana": "\uc0c8\ub85c\uc6b4 \uc694\ub9ac\uc0ac \ud50c\ub7ec\uc2a4", + "spanish": "Nuevo chef plus", + "schinese": "\u65b0\u53a8\u5e08\u5347\u7ea7", + "tchinese": "\u65b0\u5927\u5eda\u4e0a\u4efb", + "russian": "\u041d\u043e\u0432\u044b\u0439 \u0448\u0435\u0444+", + "japanese": "\u30b7\u30a7\u30d5\u306e\u65b0\u898f\u63a1\u7528", + "polish": "Nowy szef kuchni plus", + "turkish": "Yeni \u015eef \u00d6tesi", + "brazilian": "Novo Chefe Superior", + "token": "NEW_ACHIEVEMENT_2_18_NAME" + }, + "description": { + "english": "Create a franchise", + "german": "Erschaffe ein Franchise", + "french": "Cr\u00e9ez une franchise", + "koreana": "\ud504\ub79c\ucc28\uc774\uc988\ub97c \ub9cc\ub4dc\uc138\uc694", + "spanish": "Crea una franquicia", + "schinese": "\u5efa\u7acb\u4e00\u4e2a\u52a0\u76df\u8fde\u9501\u5e97", + "tchinese": "\u6210\u7acb\u52a0\u76df\u5e97", + "russian": "\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0440\u0430\u043d\u0448\u0438\u0437\u0443", + "japanese": "\u30d5\u30e9\u30f3\u30c1\u30e3\u30a4\u30ba\u3092\u8a2d\u7acb\u3059\u308b\u3002", + "polish": "Stw\u00f3rz franczyz\u0119", + "turkish": "Bir \u015fube kur", + "brazilian": "Crie uma franquia", + "token": "NEW_ACHIEVEMENT_2_18_DESC" + }, + "icon_gray": "img/31e82c1478b9dae6304b16308fdf5f4ab413dc77.jpg", + "icon": "img/e2005fdbdf59bb25c6b09cc0cb36b03a384c1ca1.jpg", + "name": "NEW_CHEF_PLUS" + }, + { + "hidden": 0, + "displayName": { + "english": "Overtime 5", + "german": "\u00dcberstunde 5", + "french": "Heures supp' 5", + "koreana": "\ucd08\uacfc\uadfc\ubb34 5", + "spanish": "Horas extra 5", + "schinese": "5\u6b21\u52a0\u73ed", + "tchinese": "\u52a0\u66425", + "russian": "5 \u0441\u0432\u0435\u0440\u0445\u0443\u0440\u043e\u0447\u043d\u044b\u0445", + "japanese": "\u6642\u9593\u5916\u52b4\u50cd5\u65e5\u76ee", + "polish": "Nadgodziny 5. dnia", + "turkish": "Mesai 5", + "brazilian": "Hora Extra 5", + "token": "NEW_ACHIEVEMENT_2_19_NAME" + }, + "description": { + "english": "Reach Overtime Day 5", + "german": "Erreiche \u00dcberstundentag 5", + "french": "Atteignez la 5e journ\u00e9e heure sup'", + "koreana": "\ucd08\uacfc\uadfc\ubb34 \ub0a0 5\uc77c\uc744 \ub2ec\uc131\ud558\uc138\uc694", + "spanish": "Alcanza el d\u00eda 5 de horas extra", + "schinese": "\u52a0\u73ed\u65e5\u8fbe\u52305\u6b21", + "tchinese": "\u6311\u6230\u52a0\u73ed\u65e5\u7b2c5\u5929", + "russian": "\u0420\u0430\u0431\u043e\u0442\u0430\u0439\u0442\u0435 \u0441\u0432\u0435\u0440\u0445\u0443\u0440\u043e\u0447\u043d\u043e 5 \u0434\u043d\u0435\u0439", + "japanese": "\u6642\u9593\u5916\u52b4\u50cd\u304c5\u65e5\u306b\u5165\u308b\u3002", + "polish": "Osi\u0105gnij nadgodziny 5. dnia", + "turkish": "5. Fazla Mesai G\u00fcn\u00fcne ula\u015f", + "brazilian": "Alcance Dia de Hora Extra 5", + "token": "NEW_ACHIEVEMENT_2_19_DESC" + }, + "icon": "img/919d63e4e5eeb217c754122008ad08b3e4dc6973.jpg", + "icon_gray": "img/597e11393e0c2131446e883a1a89b4947ac7b537.jpg", + "name": "DAY_20" + }, + { + "hidden": 0, + "displayName": { + "english": "Overtime 10", + "german": "\u00dcberstunde 10", + "french": "Heures supp' 10", + "koreana": "\ucd08\uacfc\uadfc\ubb34 10", + "spanish": "Horas extra 10", + "schinese": "10\u6b21\u52a0\u73ed", + "tchinese": "\u52a0\u73ed\u65e510", + "russian": "10 \u0441\u0432\u0435\u0440\u0445\u0443\u0440\u043e\u0447\u043d\u044b\u0445", + "japanese": "\u6642\u9593\u5916\u52b4\u50cd10\u65e5\u76ee", + "polish": "Nadgodziny 10. dnia", + "turkish": "Mesai 10", + "brazilian": "Horas Extra 10", + "token": "NEW_ACHIEVEMENT_2_20_NAME" + }, + "description": { + "english": "Reach Overtime Day 10", + "german": "Erreiche \u00dcberstundentag 10", + "french": "Atteignez la 10e journ\u00e9e heure sup'", + "koreana": "\ucd08\uacfc\uadfc\ubb34 \ub0a0 10\uc77c\uc744 \ub2ec\uc131\ud558\uc138\uc694", + "spanish": "Alcanza el d\u00eda 10 de horas extra", + "schinese": "\u52a0\u73ed\u65e5\u8fbe\u523010\u6b21", + "tchinese": "\u6311\u6230\u52a0\u73ed\u65e5\u7b2c10\u5929", + "russian": "\u0420\u0430\u0431\u043e\u0442\u0430\u0439\u0442\u0435 \u0441\u0432\u0435\u0440\u0445\u0443\u0440\u043e\u0447\u043d\u043e 10 \u0434\u043d\u0435\u0439", + "japanese": "\u6642\u9593\u5916\u52b4\u50cd\u304c10\u65e5\u306b\u5165\u308b\u3002", + "polish": "Osi\u0105gnij nadgodziny 10. dnia", + "turkish": "10. Fazla Mesai G\u00fcn\u00fcne ula\u015f", + "brazilian": "Alcance Dia de Hora Extra 10", + "token": "NEW_ACHIEVEMENT_2_20_DESC" + }, + "icon": "img/a7334dd92f511210399bbb479c5b6eeefce82714.jpg", + "icon_gray": "img/4348f777bd80b847d21842b855e49c77f6b62735.jpg", + "name": "DAY_25" + }, + { + "hidden": 0, + "displayName": { + "english": "Overtime 15", + "german": "\u00dcberstunde 15", + "french": "Heures supp' 15", + "koreana": "\ucd08\uacfc\uadfc\ubb34 15", + "spanish": "Horas extra 15", + "schinese": "15\u6b21\u52a0\u73ed", + "tchinese": "\u52a0\u73ed\u65e515", + "russian": "15 \u0441\u0432\u0435\u0440\u0445\u0443\u0440\u043e\u0447\u043d\u044b\u0445", + "japanese": "\u6642\u9593\u5916\u52b4\u50cd15\u65e5\u76ee", + "polish": "Nadgodziny 15. dnia", + "turkish": "Mesai 15", + "brazilian": "Horas Extra 15", + "token": "NEW_ACHIEVEMENT_2_21_NAME" + }, + "description": { + "english": "Reach Overtime Day 15", + "german": "Erreiche \u00dcberstundentag 15", + "french": "Atteignez la 15e journ\u00e9e heure sup'", + "koreana": "\ucd08\uacfc\uadfc\ubb34 \ub0a0 15\uc77c\uc744 \ub2ec\uc131\ud558\uc138\uc694", + "spanish": "Alcanza el d\u00eda 15 de horas extra", + "schinese": "\u52a0\u73ed\u65e515\u6b21", + "tchinese": "\u6311\u6230\u52a0\u73ed\u65e5\u7b2c15\u5929", + "russian": "\u0420\u0430\u0431\u043e\u0442\u0430\u0439\u0442\u0435 \u0441\u0432\u0435\u0440\u0445\u0443\u0440\u043e\u0447\u043d\u043e 15 \u0434\u043d\u0435\u0439", + "japanese": "\u6642\u9593\u5916\u52b4\u50cd\u304c15\u65e5\u306b\u5165\u308b\u3002", + "polish": "Osi\u0105gnij nadgodziny 15. dnia", + "turkish": "15. Fazla Mesai G\u00fcn\u00fcne ula\u015f", + "brazilian": "Alcance Dia de Hora Extra 15", + "token": "NEW_ACHIEVEMENT_2_21_DESC" + }, + "icon_gray": "img/35f0d61b25d8ca9997453da6f3a0b15fe9ce0748.jpg", + "icon": "img/3467ecbe5c438dbbb35a6d0ffc44afa77c70f468.jpg", + "name": "DAY_30" + }, + { + "hidden": 0, + "displayName": { + "english": "Learning By Doing", + "german": "Lernen durch Handeln", + "french": "Apprentissage par la pratique", + "koreana": "\uacbd\ud5d8\uc73c\ub85c \ubc30\uc6b0\uae30", + "spanish": "La pr\u00e1ctica hace al maestro", + "schinese": "\u8fb9\u505a\u8fb9\u5b66", + "tchinese": "\u6d3b\u5b78\u6d3b\u7528", + "russian": "\u0423\u0447\u0438\u043c\u0441\u044f, \u0434\u0435\u043b\u0430\u044f", + "japanese": "\u5b9f\u5730\u7814\u4fee", + "polish": "Nauka w praktyce", + "turkish": "Pratikle \u00d6\u011frenme", + "brazilian": "Aprendizado Pr\u00e1tico", + "token": "NEW_ACHIEVEMENT_2_22_NAME" + }, + "description": { + "english": "Throw away a cooked fish in the tutorial", + "german": "Wirf beim Tutorial einen gekochten Fisch weg", + "french": "Jetez un poisson cuit durant le didacticiel", + "koreana": "\ud29c\ud1a0\ub9ac\uc5bc\uc5d0\uc11c \uc870\ub9ac\ud55c \uc0dd\uc120\uc744 \ubc84\ub9ac\uc138\uc694", + "spanish": "Tira un pescado cocinado en el tutorial", + "schinese": "\u5728\u6559\u7a0b\u91cc\u628a\u505a\u597d\u7684\u9c7c\u6254\u6389", + "tchinese": "\u5728\u6559\u5b78\u904e\u7a0b\u4e2d\u4e1f\u6389\u4e00\u5c3e\u716e\u719f\u7684\u9b5a", + "russian": "\u0412\u044b\u0431\u0440\u043e\u0441\u044c\u0442\u0435 \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u0440\u044b\u0431\u0443 \u0432 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0438", + "japanese": "\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb\u3067\u6599\u7406\u3057\u305f\u9b5a\u3092\u6368\u3066\u308b\u3002", + "polish": "Wyrzu\u0107 gotow\u0105 ryb\u0119 w samouczku", + "turkish": "\u00d6\u011freticide pi\u015firilen bir bal\u0131\u011f\u0131 \u00e7\u00f6pe at", + "brazilian": "Jogue fora um peixe preparado no tutorial", + "token": "NEW_ACHIEVEMENT_2_22_DESC" + }, + "icon": "img/27d076c694bc02741d62605eda447834790e0cac.jpg", + "icon_gray": "img/6125ff4a4de4f97407907d057b88f64948767711.jpg", + "name": "LEARNING_BY_DOING" + }, + { + "hidden": 0, + "displayName": { + "english": "Anti-social", + "german": "Antisozial", + "french": "Antisocial", + "koreana": "\ube44\uc0ac\uad50\uc801", + "spanish": "Antisocial", + "schinese": "\u53cd\u793e\u4f1a", + "tchinese": "\u500b\u4ebaSOLO\u9a37", + "russian": "\u0418\u043d\u0442\u0440\u043e\u0432\u0435\u0440\u0442", + "japanese": "\u5185\u5411\u7684", + "polish": "Odludek", + "turkish": "Antisosyal", + "brazilian": "Antissocial", + "token": "NEW_ACHIEVEMENT_2_23_NAME" + }, + "description": { + "english": "Complete a day without anyone serving a customer directly", + "german": "Schlie\u00dfe einen Tag ab, an dem niemand einen Gast direkt bedient", + "french": "Terminez une journ\u00e9e sans servir directement un seul client", + "koreana": "\uc190\ub2d8\uc5d0\uac8c \uc9c1\uc811 \uc11c\ube59\ud558\ub294 \uc0ac\ub78c \uc5c6\uc774 \ud558\ub8e8\ub97c \uc644\ub8cc\ud558\uc138\uc694", + "spanish": "Completa un d\u00eda sin que nadie sirva directamente a un cliente", + "schinese": "\u6574\u6574\u4e00\u5929\u6ca1\u6709\u76f4\u63a5\u670d\u52a1\u987e\u5ba2\u7684\u4eba", + "tchinese": "\u5728\u7121\u4eba\u62db\u5f85\u9867\u5ba2\u7684\u60c5\u6cc1\u4e0b\u5b8c\u6210\u4e00\u5929", + "russian": "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u0434\u0435\u043d\u044c, \u043d\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044f \u0433\u043e\u0441\u0442\u0435\u0439 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e", + "japanese": "\u304a\u5ba2\u3055\u3093\u3092\u76f4\u63a5\u63a5\u5ba2\u305b\u305a\u306b\u4e00\u65e5\u3092\u7d42\u3048\u308b\u3002", + "polish": "Uko\u0144cz dzie\u0144 bez bezpo\u015bredniej obs\u0142ugi klienta", + "turkish": "Hi\u00e7 kimsenin bir m\u00fc\u015fteriye do\u011frudan servis yapmad\u0131\u011f\u0131 bir g\u00fcn\u00fc tamamla", + "brazilian": "Conclua um dia sem ningu\u00e9m servir um cliente diretamente", + "token": "NEW_ACHIEVEMENT_2_23_DESC" + }, + "icon": "img/3434a350c17a299feac2b221e8d035ff704c61f7.jpg", + "icon_gray": "img/e933651004d0380f6021a154c788a5c21cb2b130.jpg", + "name": "ANTISOCIAL" + }, + { + "hidden": 0, + "displayName": { + "english": "Work Smart", + "german": "Bitte warten", + "french": "Patientez SVP", + "koreana": "\uae30\ub2e4\ub824 \uc8fc\uc138\uc694", + "spanish": "Un momentito", + "schinese": "\u8bf7\u7a0d\u7b49", + "tchinese": "\u7a0d\u7b49\u4e00\u4e0b", + "russian": "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435", + "japanese": "\u52b9\u7387\u91cd\u8996", + "polish": "Prosz\u0119 czeka\u0107", + "turkish": "L\u00fctfen Bekleyin", + "brazilian": "Por Favor, Esperem", + "token": "NEW_ACHIEVEMENT_2_24_NAME" + }, + "description": { + "english": "Complete a day without any player leaving the tile they started on", + "german": "Sorg daf\u00fcr, dass die erste Gruppe, die ankommt, am Ende des Tages immer noch darauf wartet zu bestellen", + "french": "Faites attendre le premier groupe de clients jusqu'\u00e0 la fermeture", + "koreana": "\ud558\ub8e8\uac00 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \ucc98\uc74c \ub3c4\ucc29\ud55c \uadf8\ub8f9\uc774 \uc8fc\ubb38\ud558\ub294 \uac83\uc744 \uae30\ub2e4\ub9ac\uac8c \ud558\uc138\uc694", + "spanish": "No atiendas al primer grupo que llegue y deja que el d\u00eda termine", + "schinese": "\u4e00\u5929\u7ed3\u675f\u65f6\uff0c\u8ba9\u7b2c\u4e00\u6279\u5230\u6765\u7684\u987e\u5ba2\u4e00\u76f4\u7b49\u7740\u8ba2\u9910", + "tchinese": "\u9996\u7fa4\u9867\u5ba2\u5230\u5e97\uff0c\u5728\u672c\u65e5\u7d50\u675f\u524d\u4f9d\u7136\u5728\u7b49\u9ede\u9910", + "russian": "\u0417\u0430\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0435\u0440\u0432\u0443\u044e \u043f\u0440\u0438\u0431\u044b\u0432\u0448\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0443 \u0436\u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043a\u0430\u0437 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0434\u043d\u044f", + "japanese": "\u30d7\u30ec\u30a4\u30e4\u30fc\u306e\u8ab0\u304b\u304c\u30b9\u30bf\u30fc\u30c8\u5730\u70b9\u306e\u30bf\u30a4\u30eb\u304b\u3089\u79fb\u52d5\u3059\u308b\u3053\u3068\u306a\u304f\u4e00\u65e5\u3092\u7d42\u3048\u308b\u3002", + "polish": "Ka\u017c czeka\u0107 pierwszej grupie klient\u00f3w na z\u0142o\u017cenie zam\u00f3wienia do ko\u0144ca dnia", + "turkish": "G\u00fcn sona erdi\u011finde restorana ilk gelen grup h\u00e2l\u00e2 sipari\u015flerini bekliyor olsun", + "brazilian": "Fa\u00e7a com que o primeiro grupo a chegar ainda esteja esperando o pedido quando o dia terminar", + "token": "NEW_ACHIEVEMENT_2_24_DESC" + }, + "icon": "img/0ac9c3fa39f7f37b68ecae62defb30d36e6e01ac.jpg", + "icon_gray": "img/bcc7d7bd05b4bf6099e9b463cfcba2e7bd148ad0.jpg", + "name": "WORK_SMART" + }, + { + "hidden": 0, + "displayName": { + "english": "Please Wait", + "german": "Arbeite mit K\u00f6pfchen", + "french": "G\u00e9nie culinaire", + "koreana": "\ub611\ub611\ud558\uac8c \uadfc\ubb34", + "spanish": "Excelencia laboral", + "schinese": "\u667a\u80fd\u5de5\u4f5c", + "tchinese": "\u7cbe\u660e\u5206\u5de5", + "russian": "\u0420\u0430\u0431\u043e\u0442\u0430\u0439 \u0443\u043c\u043e\u043c", + "japanese": "\u5c11\u3005\u304a\u5f85\u3061\u304f\u3060\u3055\u3044", + "polish": "Pracuj m\u0105drze", + "turkish": "Zeki \u00c7al\u0131\u015fmak Laz\u0131m", + "brazilian": "Trabalho Inteligente", + "token": "NEW_ACHIEVEMENT_2_25_NAME" + }, + "description": { + "english": "Have the first group to arrive still be waiting to order when the day ends", + "german": "Schlie\u00dfe einen Tag ab, an dem kein Spieler sein Startfeld verl\u00e4sst", + "french": "Terminez une journ\u00e9e sans qu'un seul joueur quitte la tuile o\u00f9 il l'a d\u00e9but\u00e9e", + "koreana": "\ud50c\ub808\uc774\uc5b4\uac00 \uc2dc\uc791\ud55c \ud0c0\uc77c\uc5d0\uc11c \ubc97\uc5b4\ub098\uc9c0 \uc54a\uace0 \ud558\ub8e8\ub97c \uc644\ub8cc\ud558\uc138\uc694", + "spanish": "Completa un d\u00eda sin que ning\u00fan jugador haya abandonado su baldosa de inicio", + "schinese": "\u4e00\u5929\u7ed3\u675f\u65f6\uff0c\u6ca1\u6709\u4e00\u4e2a\u73a9\u5bb6\u79bb\u5f00\u4ed6\u4eec\u5f00\u59cb\u7684\u5730\u7816", + "tchinese": "\u5728\u7121\u4efb\u4f55\u73a9\u5bb6\u96e2\u958b\u521d\u59cb\u78da\u584a\u7684\u60c5\u6cc1\u4e0b\u5b8c\u6210\u4e00\u5929", + "russian": "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u0434\u0435\u043d\u044c, \u0433\u0434\u0435 \u043d\u0438 \u043e\u0434\u0438\u043d \u0438\u0433\u0440\u043e\u043a \u043d\u0435 \u043f\u043e\u043a\u0438\u043d\u0443\u043b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043b\u0438\u0442\u043a\u0438", + "japanese": "\u6700\u521d\u306e\u5165\u5e97\u3057\u305f\u30b0\u30eb\u30fc\u30d7\u306b\u9589\u5e97\u307e\u3067\u6ce8\u6587\u3092\u5f85\u305f\u305b\u308b\u3002", + "polish": "Uko\u0144cz dzie\u0144 bez opuszczenia przez gracza pola pocz\u0105tkowego", + "turkish": "T\u00fcm oyuncular g\u00fcn\u00fc ba\u015flad\u0131klar\u0131 birimde bitirsinler", + "brazilian": "Conclua um dia sem que nenhum jogador saia do espa\u00e7o onde come\u00e7ou", + "token": "NEW_ACHIEVEMENT_2_25_DESC" + }, + "icon": "img/b65f1308e10841db2b29afcd388c9e7e3aef805d.jpg", + "icon_gray": "img/450ef477d6e12c92d9e89a92a952e6847a19631d.jpg", + "name": "PLEASE_WAIT" + } +] \ No newline at end of file diff --git a/generate_emu_config_old/output/1599600/steam_settings/branches.json b/generate_emu_config_old/output/1599600/steam_settings/branches.json new file mode 100644 index 0000000..a3f8773 --- /dev/null +++ b/generate_emu_config_old/output/1599600/steam_settings/branches.json @@ -0,0 +1,93 @@ +[ + { + "name": "public", + "description": "", + "protected": false, + "build_id": 15591994, + "time_updated": 1725468206 + }, + { + "name": "ch_pr", + "description": "", + "protected": true, + "build_id": 10759092, + "time_updated": 1678805610 + }, + { + "name": "chef", + "description": "", + "protected": true, + "build_id": 9251549, + "time_updated": 1659606643 + }, + { + "name": "development", + "description": "", + "protected": true, + "build_id": 13189763, + "time_updated": 1705444518 + }, + { + "name": "discordbetaaccess", + "description": "", + "protected": true, + "build_id": 9355221, + "time_updated": 1661039040 + }, + { + "name": "japan", + "description": "", + "protected": true, + "build_id": 11468716, + "time_updated": 1686754875 + }, + { + "name": "secret", + "description": "", + "protected": true, + "build_id": 12841040, + "time_updated": 1701361864 + }, + { + "name": "crash-fix-test", + "description": "Test for Environment crash", + "protected": false, + "build_id": 15335463, + "time_updated": 1723404695 + }, + { + "name": "creator", + "description": "", + "protected": true, + "build_id": 15548843, + "time_updated": 1725050086 + }, + { + "name": "crossplaybeta", + "description": "branch dedicated for crossplay", + "protected": false, + "build_id": 15776693, + "time_updated": 1727881044 + }, + { + "name": "crossplaystaging", + "description": "", + "protected": true, + "build_id": 15776693, + "time_updated": 1726871838 + }, + { + "name": "playtest", + "description": "", + "protected": true, + "build_id": 15591994, + "time_updated": 1725464710 + }, + { + "name": "playtest2", + "description": "", + "protected": true, + "build_id": 15776695, + "time_updated": 1726871859 + } +] \ No newline at end of file diff --git a/generate_emu_config_old/output/1599600/steam_settings/configs.app.ini b/generate_emu_config_old/output/1599600/steam_settings/configs.app.ini new file mode 100644 index 0000000..a9be423 --- /dev/null +++ b/generate_emu_config_old/output/1599600/steam_settings/configs.app.ini @@ -0,0 +1,4 @@ +[app::dlcs] +# should the emu report all DLCs as unlocked, default=1 +unlock_all=0 + diff --git a/generate_emu_config_old/output/1599600/steam_settings/depots.txt b/generate_emu_config_old/output/1599600/steam_settings/depots.txt new file mode 100644 index 0000000..fe43232 --- /dev/null +++ b/generate_emu_config_old/output/1599600/steam_settings/depots.txt @@ -0,0 +1,2 @@ +1599601 +1599602 diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/0093f205209654df1c656d9b6022186cf2919f90.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/0093f205209654df1c656d9b6022186cf2919f90.jpg new file mode 100644 index 0000000..1009923 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/0093f205209654df1c656d9b6022186cf2919f90.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/0a18ca860bc1c17b096290eb42b8a1b13e214f9f.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/0a18ca860bc1c17b096290eb42b8a1b13e214f9f.jpg new file mode 100644 index 0000000..496a4bf Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/0a18ca860bc1c17b096290eb42b8a1b13e214f9f.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/0ac9c3fa39f7f37b68ecae62defb30d36e6e01ac.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/0ac9c3fa39f7f37b68ecae62defb30d36e6e01ac.jpg new file mode 100644 index 0000000..8a59c89 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/0ac9c3fa39f7f37b68ecae62defb30d36e6e01ac.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/103ee7b2c3eebc7a5e33fc8153f432707f90cb22.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/103ee7b2c3eebc7a5e33fc8153f432707f90cb22.jpg new file mode 100644 index 0000000..3a7ab68 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/103ee7b2c3eebc7a5e33fc8153f432707f90cb22.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/14b7c02224e3f8cb45f7f2c5f0079cc7b867c4bb.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/14b7c02224e3f8cb45f7f2c5f0079cc7b867c4bb.jpg new file mode 100644 index 0000000..b9099dd Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/14b7c02224e3f8cb45f7f2c5f0079cc7b867c4bb.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/192c8cfe583de2d8be7d3960f8a76a4c8e3c96be.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/192c8cfe583de2d8be7d3960f8a76a4c8e3c96be.jpg new file mode 100644 index 0000000..0680d43 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/192c8cfe583de2d8be7d3960f8a76a4c8e3c96be.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/27d076c694bc02741d62605eda447834790e0cac.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/27d076c694bc02741d62605eda447834790e0cac.jpg new file mode 100644 index 0000000..e693631 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/27d076c694bc02741d62605eda447834790e0cac.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/2e95f022d01fafbf4cc2bbb48f36cb08ee3e245b.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/2e95f022d01fafbf4cc2bbb48f36cb08ee3e245b.jpg new file mode 100644 index 0000000..dc44b7b Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/2e95f022d01fafbf4cc2bbb48f36cb08ee3e245b.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/31e82c1478b9dae6304b16308fdf5f4ab413dc77.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/31e82c1478b9dae6304b16308fdf5f4ab413dc77.jpg new file mode 100644 index 0000000..f3f6b6f Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/31e82c1478b9dae6304b16308fdf5f4ab413dc77.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/3434a350c17a299feac2b221e8d035ff704c61f7.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/3434a350c17a299feac2b221e8d035ff704c61f7.jpg new file mode 100644 index 0000000..68e5c0e Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/3434a350c17a299feac2b221e8d035ff704c61f7.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/3467ecbe5c438dbbb35a6d0ffc44afa77c70f468.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/3467ecbe5c438dbbb35a6d0ffc44afa77c70f468.jpg new file mode 100644 index 0000000..a15cb66 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/3467ecbe5c438dbbb35a6d0ffc44afa77c70f468.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/35f0d61b25d8ca9997453da6f3a0b15fe9ce0748.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/35f0d61b25d8ca9997453da6f3a0b15fe9ce0748.jpg new file mode 100644 index 0000000..c1e9789 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/35f0d61b25d8ca9997453da6f3a0b15fe9ce0748.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/36d3d0d14cec6492b73f21f6e09eca4604cfe196.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/36d3d0d14cec6492b73f21f6e09eca4604cfe196.jpg new file mode 100644 index 0000000..ae4b1cd Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/36d3d0d14cec6492b73f21f6e09eca4604cfe196.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/3bb663e137a4fcb6669e12b137b001fbad67180e.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/3bb663e137a4fcb6669e12b137b001fbad67180e.jpg new file mode 100644 index 0000000..374abc7 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/3bb663e137a4fcb6669e12b137b001fbad67180e.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/3cac68bcef70bd8894157ed2f0f48d91dbbc7ea5.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/3cac68bcef70bd8894157ed2f0f48d91dbbc7ea5.jpg new file mode 100644 index 0000000..ca9c393 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/3cac68bcef70bd8894157ed2f0f48d91dbbc7ea5.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/4348f777bd80b847d21842b855e49c77f6b62735.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/4348f777bd80b847d21842b855e49c77f6b62735.jpg new file mode 100644 index 0000000..7a89ebe Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/4348f777bd80b847d21842b855e49c77f6b62735.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/450ef477d6e12c92d9e89a92a952e6847a19631d.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/450ef477d6e12c92d9e89a92a952e6847a19631d.jpg new file mode 100644 index 0000000..f159e72 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/450ef477d6e12c92d9e89a92a952e6847a19631d.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/4dd21bd02267a273d08d3ba4db272c8dff8d19b7.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/4dd21bd02267a273d08d3ba4db272c8dff8d19b7.jpg new file mode 100644 index 0000000..fff91bd Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/4dd21bd02267a273d08d3ba4db272c8dff8d19b7.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/516922c2f59d5c58d74a67d0005daa620f2bf004.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/516922c2f59d5c58d74a67d0005daa620f2bf004.jpg new file mode 100644 index 0000000..6a17837 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/516922c2f59d5c58d74a67d0005daa620f2bf004.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/597e11393e0c2131446e883a1a89b4947ac7b537.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/597e11393e0c2131446e883a1a89b4947ac7b537.jpg new file mode 100644 index 0000000..59d0a40 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/597e11393e0c2131446e883a1a89b4947ac7b537.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/5ca7107dd17f2157a89c12078c3e6bd7d493c47e.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/5ca7107dd17f2157a89c12078c3e6bd7d493c47e.jpg new file mode 100644 index 0000000..120a4c2 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/5ca7107dd17f2157a89c12078c3e6bd7d493c47e.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/6125ff4a4de4f97407907d057b88f64948767711.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/6125ff4a4de4f97407907d057b88f64948767711.jpg new file mode 100644 index 0000000..0be6f85 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/6125ff4a4de4f97407907d057b88f64948767711.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/622f7da40f7bf1cc7669643e91a2a8a212378ca4.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/622f7da40f7bf1cc7669643e91a2a8a212378ca4.jpg new file mode 100644 index 0000000..1c0336c Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/622f7da40f7bf1cc7669643e91a2a8a212378ca4.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/623699ae1d9bc19d41fd3a06014ee0b601799f3b.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/623699ae1d9bc19d41fd3a06014ee0b601799f3b.jpg new file mode 100644 index 0000000..0fd22c8 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/623699ae1d9bc19d41fd3a06014ee0b601799f3b.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/6251ddf410f13bbb4cde4dfca97a83857104d41f.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/6251ddf410f13bbb4cde4dfca97a83857104d41f.jpg new file mode 100644 index 0000000..d50873a Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/6251ddf410f13bbb4cde4dfca97a83857104d41f.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/6473b1c1da531302ca57bba1d3cb5ebc7bd400db.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/6473b1c1da531302ca57bba1d3cb5ebc7bd400db.jpg new file mode 100644 index 0000000..5488fcb Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/6473b1c1da531302ca57bba1d3cb5ebc7bd400db.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/6dfe76287e92fb4c8e69c08d73d5a2501dcc7b02.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/6dfe76287e92fb4c8e69c08d73d5a2501dcc7b02.jpg new file mode 100644 index 0000000..560d7fc Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/6dfe76287e92fb4c8e69c08d73d5a2501dcc7b02.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/7d6ed3d308ddeb8bd7a6c94d597b2f532a0fa4f0.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/7d6ed3d308ddeb8bd7a6c94d597b2f532a0fa4f0.jpg new file mode 100644 index 0000000..a302393 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/7d6ed3d308ddeb8bd7a6c94d597b2f532a0fa4f0.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/81f0bdfd271c45035e0d3c1bfa85adf6a7f366e7.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/81f0bdfd271c45035e0d3c1bfa85adf6a7f366e7.jpg new file mode 100644 index 0000000..3ade91f Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/81f0bdfd271c45035e0d3c1bfa85adf6a7f366e7.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/9144ef4c3447c80ead03df7230587aac73a3a511.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/9144ef4c3447c80ead03df7230587aac73a3a511.jpg new file mode 100644 index 0000000..444dbb7 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/9144ef4c3447c80ead03df7230587aac73a3a511.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/919d63e4e5eeb217c754122008ad08b3e4dc6973.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/919d63e4e5eeb217c754122008ad08b3e4dc6973.jpg new file mode 100644 index 0000000..7a221fb Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/919d63e4e5eeb217c754122008ad08b3e4dc6973.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/92a5e404b5547d0a51a0bd1eff9a566d816ced81.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/92a5e404b5547d0a51a0bd1eff9a566d816ced81.jpg new file mode 100644 index 0000000..58cdea4 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/92a5e404b5547d0a51a0bd1eff9a566d816ced81.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/934d3a1b0283fc99662bca6d081c0559ef93c8c3.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/934d3a1b0283fc99662bca6d081c0559ef93c8c3.jpg new file mode 100644 index 0000000..ee9768d Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/934d3a1b0283fc99662bca6d081c0559ef93c8c3.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/943b0135c2afe8b95161287d67544a613de0c689.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/943b0135c2afe8b95161287d67544a613de0c689.jpg new file mode 100644 index 0000000..db7daa0 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/943b0135c2afe8b95161287d67544a613de0c689.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/9a8b8fa54ad18087d69461c92401a3f091b936ec.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/9a8b8fa54ad18087d69461c92401a3f091b936ec.jpg new file mode 100644 index 0000000..54671fe Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/9a8b8fa54ad18087d69461c92401a3f091b936ec.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/9e16b74748c8aa0b9f58494637fefe251048f26b.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/9e16b74748c8aa0b9f58494637fefe251048f26b.jpg new file mode 100644 index 0000000..5bb57d2 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/9e16b74748c8aa0b9f58494637fefe251048f26b.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/a7334dd92f511210399bbb479c5b6eeefce82714.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/a7334dd92f511210399bbb479c5b6eeefce82714.jpg new file mode 100644 index 0000000..0e8c97e Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/a7334dd92f511210399bbb479c5b6eeefce82714.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/aa66ea809eccf7dfda7fe37415d3b956287ceeb1.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/aa66ea809eccf7dfda7fe37415d3b956287ceeb1.jpg new file mode 100644 index 0000000..5b6e2cd Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/aa66ea809eccf7dfda7fe37415d3b956287ceeb1.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/ac11799f84911688d25fcca446490d0d653a732e.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/ac11799f84911688d25fcca446490d0d653a732e.jpg new file mode 100644 index 0000000..83181f8 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/ac11799f84911688d25fcca446490d0d653a732e.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/b193d2a2f881716f2364b85a2fdc05572577a1bd.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/b193d2a2f881716f2364b85a2fdc05572577a1bd.jpg new file mode 100644 index 0000000..371e3c5 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/b193d2a2f881716f2364b85a2fdc05572577a1bd.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/b65f1308e10841db2b29afcd388c9e7e3aef805d.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/b65f1308e10841db2b29afcd388c9e7e3aef805d.jpg new file mode 100644 index 0000000..ac4414c Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/b65f1308e10841db2b29afcd388c9e7e3aef805d.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/bcc7d7bd05b4bf6099e9b463cfcba2e7bd148ad0.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/bcc7d7bd05b4bf6099e9b463cfcba2e7bd148ad0.jpg new file mode 100644 index 0000000..85d95ff Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/bcc7d7bd05b4bf6099e9b463cfcba2e7bd148ad0.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/bdc4249bc11526f262cd5b0adb4e8e3866234b55.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/bdc4249bc11526f262cd5b0adb4e8e3866234b55.jpg new file mode 100644 index 0000000..bf265ae Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/bdc4249bc11526f262cd5b0adb4e8e3866234b55.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/c755cc05cd8bb36d7dc0a47f544444877f15d457.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/c755cc05cd8bb36d7dc0a47f544444877f15d457.jpg new file mode 100644 index 0000000..aa44cee Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/c755cc05cd8bb36d7dc0a47f544444877f15d457.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/c8da2ebf19d362e479cf4e1773fe58dd8e2eeab2.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/c8da2ebf19d362e479cf4e1773fe58dd8e2eeab2.jpg new file mode 100644 index 0000000..8b6d06e Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/c8da2ebf19d362e479cf4e1773fe58dd8e2eeab2.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/cd55007af77144d030f512afe1ebd4074b4df1e4.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/cd55007af77144d030f512afe1ebd4074b4df1e4.jpg new file mode 100644 index 0000000..884e9db Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/cd55007af77144d030f512afe1ebd4074b4df1e4.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/cf3660012d6cfe286d118b256791f2b434c90172.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/cf3660012d6cfe286d118b256791f2b434c90172.jpg new file mode 100644 index 0000000..fb420f8 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/cf3660012d6cfe286d118b256791f2b434c90172.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/cf8e7333881792385701b7cfd85f1e27d1a7bfe0.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/cf8e7333881792385701b7cfd85f1e27d1a7bfe0.jpg new file mode 100644 index 0000000..34b9235 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/cf8e7333881792385701b7cfd85f1e27d1a7bfe0.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/e2005fdbdf59bb25c6b09cc0cb36b03a384c1ca1.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/e2005fdbdf59bb25c6b09cc0cb36b03a384c1ca1.jpg new file mode 100644 index 0000000..c6047ef Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/e2005fdbdf59bb25c6b09cc0cb36b03a384c1ca1.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/e933651004d0380f6021a154c788a5c21cb2b130.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/e933651004d0380f6021a154c788a5c21cb2b130.jpg new file mode 100644 index 0000000..550cd32 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/e933651004d0380f6021a154c788a5c21cb2b130.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/f17e088b7cf40982b084b6a84585f3e3d1266d03.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/f17e088b7cf40982b084b6a84585f3e3d1266d03.jpg new file mode 100644 index 0000000..1e8a128 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/f17e088b7cf40982b084b6a84585f3e3d1266d03.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/img/f3683e2dcdb56c083730c02fb54a500754bde342.jpg b/generate_emu_config_old/output/1599600/steam_settings/img/f3683e2dcdb56c083730c02fb54a500754bde342.jpg new file mode 100644 index 0000000..c935859 Binary files /dev/null and b/generate_emu_config_old/output/1599600/steam_settings/img/f3683e2dcdb56c083730c02fb54a500754bde342.jpg differ diff --git a/generate_emu_config_old/output/1599600/steam_settings/steam_appid.txt b/generate_emu_config_old/output/1599600/steam_settings/steam_appid.txt new file mode 100644 index 0000000..f78c591 --- /dev/null +++ b/generate_emu_config_old/output/1599600/steam_settings/steam_appid.txt @@ -0,0 +1 @@ +1599600 \ No newline at end of file diff --git a/generate_emu_config_old/output/1599600/steam_settings/supported_languages.txt b/generate_emu_config_old/output/1599600/steam_settings/supported_languages.txt new file mode 100644 index 0000000..8008edf --- /dev/null +++ b/generate_emu_config_old/output/1599600/steam_settings/supported_languages.txt @@ -0,0 +1,12 @@ +english +french +german +spanish +japanese +polish +brazilian +russian +schinese +tchinese +koreana +turkish diff --git a/generate_emu_config_old/output/238370/info/app_details.json b/generate_emu_config_old/output/238370/info/app_details.json new file mode 100644 index 0000000..d6ab57a --- /dev/null +++ b/generate_emu_config_old/output/238370/info/app_details.json @@ -0,0 +1,381 @@ +{ + "238370": { + "success": true, + "data": { + "type": "game", + "name": "Magicka 2", + "steam_appid": 238370, + "required_age": 0, + "is_free": false, + "controller_support": "full", + "dlc": [ + 393830, + 393831, + 414651 + ], + "detailed_description": "

Digital Deluxe Edition

Exclusive Deluxe Edition content:

  • Warlord Robe Set
  • Magicka Orchestra Soundtrack
  • Digital Interactive Map
  • Cultist Robe Set


About the Game

The world’s most irreverent co-op action adventure returns! In the next chapter of Magicka, players ascend from the ruins of Aldrheim to experience a Midgård almost wiped free of Wizards after the Wizard Wars, with the few that do remain having either gone mad or extremely hostile toward all others.

To rid the world of evil, again, up to four Wizards, and their guide Vlad, will traverse Midgård armed with the next iteration of the famous Magicka dynamic spellcasting system, as players reprise their roles as the most overpowered, unpredictably funny Wizards ever known to fantasy!

Learn to Spell Again... Again!


Ye olde hybrid elements Steam and Ice from Magicka 1 are back, joined by the brand new Poison! This means tons of new spells to cast at friends and foes - complete with larger explosions and greatly improved graphics!

Learn to Spell Again


As an all-powerful Wizard, you will have thousands of spells at your fingertips to experiment and defeat evil with, use them together with special Magicks to annihilate foes or give necessary aid to your companions.
  • Combine up to five elements at a time and work together with—or against—your friends for that full Magicka co-op experience.
  • Four Player Friendly Fire Compatible Co-op
  • Full co-op support! All levels and game modes in Magicka 2 will be supported for four player co-op with hot join, checkpoints, and other supportive features and functionality.
  • Friendly fire is always on, promoting emergent gameplay humor as players accidentally hurt or kill their friends in their attempts to annihilate enemies.

Be the Wizard You Want to Be!


With tons of robes, staffs, and weapons you can play as the robed Wizard of your choice to wreak havoc amongst hordes of fantasy creatures as you see fit. Magicka 2's dynamic spellcasting system can be used in many different ways, offering hours of experimentation for players to figure out which spells belong in their repertoire. Add both co-op and friendly fire on top of that and you have a recipe for hilarious disasters.

Replay the Next Chapter with Artifacts


Magicka 2 offers players a story-driven campaign mode set in a lush fantasy world influenced heavily by Nordic folklore. New to the franchise are "Artifacts," which act as different switches and options for players to customize and change the gameplay experience, adding more replayability when utilized.", + "about_the_game": "The world’s most irreverent co-op action adventure returns! In the next chapter of Magicka, players ascend from the ruins of Aldrheim to experience a Midgård almost wiped free of Wizards after the Wizard Wars, with the few that do remain having either gone mad or extremely hostile toward all others.

To rid the world of evil, again, up to four Wizards, and their guide Vlad, will traverse Midgård armed with the next iteration of the famous Magicka dynamic spellcasting system, as players reprise their roles as the most overpowered, unpredictably funny Wizards ever known to fantasy!

Learn to Spell Again... Again!


Ye olde hybrid elements Steam and Ice from Magicka 1 are back, joined by the brand new Poison! This means tons of new spells to cast at friends and foes - complete with larger explosions and greatly improved graphics!

Learn to Spell Again


As an all-powerful Wizard, you will have thousands of spells at your fingertips to experiment and defeat evil with, use them together with special Magicks to annihilate foes or give necessary aid to your companions.
  • Combine up to five elements at a time and work together with—or against—your friends for that full Magicka co-op experience.
  • Four Player Friendly Fire Compatible Co-op
  • Full co-op support! All levels and game modes in Magicka 2 will be supported for four player co-op with hot join, checkpoints, and other supportive features and functionality.
  • Friendly fire is always on, promoting emergent gameplay humor as players accidentally hurt or kill their friends in their attempts to annihilate enemies.

Be the Wizard You Want to Be!


With tons of robes, staffs, and weapons you can play as the robed Wizard of your choice to wreak havoc amongst hordes of fantasy creatures as you see fit. Magicka 2's dynamic spellcasting system can be used in many different ways, offering hours of experimentation for players to figure out which spells belong in their repertoire. Add both co-op and friendly fire on top of that and you have a recipe for hilarious disasters.

Replay the Next Chapter with Artifacts


Magicka 2 offers players a story-driven campaign mode set in a lush fantasy world influenced heavily by Nordic folklore. New to the franchise are "Artifacts," which act as different switches and options for players to customize and change the gameplay experience, adding more replayability when utilized.", + "short_description": "The world’s most irreverent co-op action adventure returns! In the next chapter of Magicka, players ascend from the ruins of Aldrheim to experience a Midgård almost wiped free of Wizards after the Wizard Wars, with the few that do remain having either gone mad or extremely hostile toward all others", + "supported_languages": "English, French, Italian, German, Spanish - Spain, Polish, Portuguese - Brazil, Russian", + "header_image": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/header.jpg?t=1709831158", + "capsule_image": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/capsule_231x87.jpg?t=1709831158", + "capsule_imagev5": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/capsule_184x69.jpg?t=1709831158", + "website": "http://www.magicka2.com", + "pc_requirements": { + "minimum": "Minimum:
  • OS *: Windows 7, 8 or 10
  • Processor: CPU: 3GHz Dual Core (Intel Pentium G3220 or higher / AMD A4-4000 or higher)
  • Memory: 2 GB RAM
  • Graphics: Nvidia GeForce 550 or better / ATI Radeon HD 5850 or better
  • Storage: 3 GB available space
  • Sound Card: DirectX Compatible Sound Card
", + "recommended": "Recommended:
  • OS *: Windows 7, 8 or 10
  • Processor: 2.8GHz Quad Core (Intel Core i5-2300 or higher / AMD A8-3850 or higher)
  • Memory: 4 GB RAM
  • Graphics: Nvidia GeForce 640 or better / ATI Radeon HD 6670 or better
  • Storage: 3 GB available space
  • Sound Card: DirectX Compatible Sound Card
" + }, + "mac_requirements": { + "minimum": "Minimum:
  • OS: OSX 10.7
  • Processor: Intel Core i5, 1.7GHz Dual-Core
  • Memory: 4 GB RAM
  • Graphics: Intel HD Graphics 4000
  • Storage: 3 GB available space
", + "recommended": "Recommended:
  • OS: OSX 10.7
  • Processor: Intel Core i5, 2.5GHz
  • Memory: 4 GB RAM
  • Graphics: Radeon HD 6750M
  • Storage: 3 GB available space
" + }, + "linux_requirements": { + "minimum": "Minimum:
  • OS: Ubuntu 12.04
  • Processor: 3GHz Dual Core (Intel Pentium G3220 or higher / AMD A4-4000 or higher)
  • Memory: 2 GB RAM
  • Graphics: Nvidia GeForce 550 or better / ATI Radeon HD 5850 or better
  • Storage: 3 GB available space
", + "recommended": "Recommended:
  • OS: Ubuntu 14.04 LTS
  • Processor: 2.8GHz Quad Core (Intel Core i5-2300 or higher / AMD A8-3850 or higher)
  • Memory: 4 GB RAM
  • Graphics: Nvidia GeForce 640 or better / ATI Radeon HD 6670 or better
  • Storage: 3 GB available space
" + }, + "legal_notice": "Paradox Interactive, MAGICKA® Copyright© [2015] Paradox Interactive AB All rights reserved. www.paradoxplaza.com", + "developers": [ + "Pieces Interactive" + ], + "publishers": [ + "Paradox Interactive" + ], + "price_overview": { + "currency": "EUR", + "initial": 1499, + "final": 1499, + "discount_percent": 0, + "initial_formatted": "", + "final_formatted": "14,99€" + }, + "packages": [ + 66740, + 66741, + 61815 + ], + "package_groups": [ + { + "name": "default", + "title": "Buy Magicka 2", + "description": "", + "selection_text": "Select a purchase option", + "save_text": "", + "display_type": 0, + "is_recurring_subscription": "false", + "subs": [ + { + "packageid": 61815, + "percent_savings_text": " ", + "percent_savings": 0, + "option_text": "Magicka 2 Upgrade Pack - 9,--€", + "option_description": "", + "can_get_free_license": "0", + "is_free_license": false, + "price_in_cents_with_discount": 900 + }, + { + "packageid": 66740, + "percent_savings_text": " ", + "percent_savings": 0, + "option_text": "Magicka 2 - 14,99€", + "option_description": "", + "can_get_free_license": "0", + "is_free_license": false, + "price_in_cents_with_discount": 1499 + }, + { + "packageid": 66741, + "percent_savings_text": " ", + "percent_savings": 0, + "option_text": "Magicka 2 Deluxe Edition - 23,99€", + "option_description": "", + "can_get_free_license": "0", + "is_free_license": false, + "price_in_cents_with_discount": 2399 + } + ] + } + ], + "platforms": { + "windows": true, + "mac": true, + "linux": true + }, + "categories": [ + { + "id": 2, + "description": "Single-player" + }, + { + "id": 1, + "description": "Multi-player" + }, + { + "id": 9, + "description": "Co-op" + }, + { + "id": 24, + "description": "Shared/Split Screen" + }, + { + "id": 22, + "description": "Steam Achievements" + }, + { + "id": 28, + "description": "Full controller support" + }, + { + "id": 29, + "description": "Steam Trading Cards" + }, + { + "id": 41, + "description": "Remote Play on Phone" + }, + { + "id": 42, + "description": "Remote Play on Tablet" + }, + { + "id": 43, + "description": "Remote Play on TV" + }, + { + "id": 44, + "description": "Remote Play Together" + }, + { + "id": 62, + "description": "Family Sharing" + } + ], + "genres": [ + { + "id": "1", + "description": "Action" + }, + { + "id": "25", + "description": "Adventure" + } + ], + "screenshots": [ + { + "id": 0, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_41b744c738cc2d394378ccd1b1bf5e1db0163b64.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_41b744c738cc2d394378ccd1b1bf5e1db0163b64.1920x1080.jpg?t=1709831158" + }, + { + "id": 1, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_ab78099a447154ad202a1043a2a051c35df7a586.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_ab78099a447154ad202a1043a2a051c35df7a586.1920x1080.jpg?t=1709831158" + }, + { + "id": 2, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_b270b4da37c5fd3daa6c0d9d2b75064f32679556.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_b270b4da37c5fd3daa6c0d9d2b75064f32679556.1920x1080.jpg?t=1709831158" + }, + { + "id": 3, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_acc283cf39ad175376cc75fd718a8738e3d91372.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_acc283cf39ad175376cc75fd718a8738e3d91372.1920x1080.jpg?t=1709831158" + }, + { + "id": 4, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_1af2c0b9659e116ed200c994900074e496ef1d07.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_1af2c0b9659e116ed200c994900074e496ef1d07.1920x1080.jpg?t=1709831158" + }, + { + "id": 5, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_251d8a4113b2ea042e97364b2088a78d597ee5da.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_251d8a4113b2ea042e97364b2088a78d597ee5da.1920x1080.jpg?t=1709831158" + }, + { + "id": 6, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_9ae2227cbe35c9f59aa6f9f684533681dfa63531.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_9ae2227cbe35c9f59aa6f9f684533681dfa63531.1920x1080.jpg?t=1709831158" + }, + { + "id": 7, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_ae67d31d038cf9f8a91f3da77b1f4775a533de8d.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_ae67d31d038cf9f8a91f3da77b1f4775a533de8d.1920x1080.jpg?t=1709831158" + }, + { + "id": 8, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_c44be8f4cea776373a4932166bcce7a824b78eef.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_c44be8f4cea776373a4932166bcce7a824b78eef.1920x1080.jpg?t=1709831158" + }, + { + "id": 9, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_c2084c76f23e6e6109eb6c25684912e5b8d55844.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_c2084c76f23e6e6109eb6c25684912e5b8d55844.1920x1080.jpg?t=1709831158" + }, + { + "id": 10, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_bb56b1d567d71a3b70a2756c4aae2263f3d2c2eb.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_bb56b1d567d71a3b70a2756c4aae2263f3d2c2eb.1920x1080.jpg?t=1709831158" + }, + { + "id": 11, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_13da82f226d2510aa1c1d30850b516f9eb609f32.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_13da82f226d2510aa1c1d30850b516f9eb609f32.1920x1080.jpg?t=1709831158" + }, + { + "id": 12, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_b696c03b76933a711fbca30ef58fab189f230002.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_b696c03b76933a711fbca30ef58fab189f230002.1920x1080.jpg?t=1709831158" + }, + { + "id": 13, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_47c50c9541280f4e6fbd34fee32e7529883fb37e.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_47c50c9541280f4e6fbd34fee32e7529883fb37e.1920x1080.jpg?t=1709831158" + }, + { + "id": 14, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_a87b107c505eaa694078c2a57661ffcf2bce1684.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_a87b107c505eaa694078c2a57661ffcf2bce1684.1920x1080.jpg?t=1709831158" + }, + { + "id": 15, + "path_thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_58ab0660af4d94131056672791c396b5e821eabd.600x338.jpg?t=1709831158", + "path_full": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/ss_58ab0660af4d94131056672791c396b5e821eabd.1920x1080.jpg?t=1709831158" + } + ], + "movies": [ + { + "id": 2039712, + "name": "Magicka 2 - Release Trailer [EU]", + "thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/2039712/movie.293x165.jpg?t=1561035141", + "webm": { + "480": "http://video.akamai.steamstatic.com/store_trailers/2039712/movie480.webm?t=1561035141", + "max": "http://video.akamai.steamstatic.com/store_trailers/2039712/movie_max.webm?t=1561035141" + }, + "mp4": { + "480": "http://video.akamai.steamstatic.com/store_trailers/2039712/movie480.mp4?t=1561035141", + "max": "http://video.akamai.steamstatic.com/store_trailers/2039712/movie_max.mp4?t=1561035141" + }, + "highlight": true + }, + { + "id": 2032930, + "name": "Magicka 2 Announcement trailer [EU]", + "thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/2032930/movie.293x165.jpg?t=1561035148", + "webm": { + "480": "http://video.akamai.steamstatic.com/store_trailers/2032930/movie480.webm?t=1561035148", + "max": "http://video.akamai.steamstatic.com/store_trailers/2032930/movie_max.webm?t=1561035148" + }, + "mp4": { + "480": "http://video.akamai.steamstatic.com/store_trailers/2032930/movie480.mp4?t=1561035148", + "max": "http://video.akamai.steamstatic.com/store_trailers/2032930/movie_max.mp4?t=1561035148" + }, + "highlight": true + }, + { + "id": 2037662, + "name": "Magicka 2 - Pre-Order Trailer [EU]", + "thumbnail": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/2037662/movie.293x165.jpg?t=1587505318", + "webm": { + "480": "http://video.akamai.steamstatic.com/store_trailers/2037662/movie480.webm?t=1587505318", + "max": "http://video.akamai.steamstatic.com/store_trailers/2037662/movie_max.webm?t=1587505318" + }, + "mp4": { + "480": "http://video.akamai.steamstatic.com/store_trailers/2037662/movie480.mp4?t=1587505318", + "max": "http://video.akamai.steamstatic.com/store_trailers/2037662/movie_max.mp4?t=1587505318" + }, + "highlight": true + } + ], + "recommendations": { + "total": 8711 + }, + "achievements": { + "total": 47, + "highlighted": [ + { + "name": "My Loot!", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/37d1602bfad43e55524ee5688f27235587d9e294.jpg" + }, + { + "name": "Respect Your Elders", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/afca50efa1538df0f3d8bc30045555bad12fee0f.jpg" + }, + { + "name": "Burying the Past", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/3952d1696676c256b39db171f182af3f777392c7.jpg" + }, + { + "name": "Humble Beginnings", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/a22fa7fba27953922eaaa4f87546257d6311bfc0.jpg" + }, + { + "name": "Serious Damage!", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/e077f6fca64292888f89b474d4d48463f6daac14.jpg" + }, + { + "name": "Terrible Terrible Damage!", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/ba82d8777e5da4a24194cd669768ebaa8fddc37e.jpg" + }, + { + "name": "Nurse", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/265b106ca0820acdd9a248ab9e915de9826cd9af.jpg" + }, + { + "name": "Doctor", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/7c418b23fece97b6ace0e09c153752144956df7e.jpg" + }, + { + "name": "Miracle Worker", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/22bfd24bd617da5a43b5eb7c84822a1064c7421f.jpg" + }, + { + "name": "I Meant To Do That", + "path": "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/238370/31779b5b7730535662bb4a7df83753c3774b1b58.jpg" + } + ] + }, + "release_date": { + "coming_soon": false, + "date": "26 May, 2015" + }, + "support_info": { + "url": "http://www.paradoxplaza.com/support", + "email": "support@paradoxplaza.com" + }, + "background": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/page_bg_generated_v6b.jpg?t=1709831158", + "background_raw": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/page.bg.jpg?t=1709831158", + "content_descriptors": { + "ids": [], + "notes": null + }, + "ratings": { + "esrb": { + "rating": "t", + "descriptors": "Blood and Gore\r\nMild Language\r\nViolence", + "interactive_elements": "Users Interact" + }, + "pegi": { + "rating": "16", + "descriptors": "Violence" + }, + "dejus": { + "rating_generated": "1", + "rating": "14", + "required_age": "14", + "banned": "0", + "use_age_gate": "0", + "descriptors": "Violência\nLinguagem imprópria" + }, + "steam_germany": { + "rating_generated": "1", + "rating": "16", + "required_age": "16", + "banned": "0", + "use_age_gate": "0", + "descriptors": "Drastische Gewalt" + } + } + } + } +} \ No newline at end of file diff --git a/generate_emu_config_old/output/238370/info/launch_config.json b/generate_emu_config_old/output/238370/info/launch_config.json new file mode 100644 index 0000000..ebc1caf --- /dev/null +++ b/generate_emu_config_old/output/238370/info/launch_config.json @@ -0,0 +1,37 @@ +{ + "0": { + "executable": "engine/Magicka2.exe", + "workingdir": "engine", + "description": "Play Magicka 2", + "type": "none", + "config": { + "oslist": "windows" + } + }, + "1": { + "executable": "engine/Magicka2", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "linux", + "osarch": "32" + } + }, + "2": { + "executable": "engine/Magicka2_x64", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "linux", + "osarch": "64" + } + }, + "3": { + "executable": "engine/Magicka2.app", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "macos" + } + } +} \ No newline at end of file diff --git a/generate_emu_config_old/output/238370/info/product_info.json b/generate_emu_config_old/output/238370/info/product_info.json new file mode 100644 index 0000000..15319d6 --- /dev/null +++ b/generate_emu_config_old/output/238370/info/product_info.json @@ -0,0 +1,1038 @@ +{ + "appid": "238370", + "common": { + "name": "Magicka 2", + "type": "Game", + "releasestate": "released", + "icon": "6c1ca2ff2c0f87c4d0a5378a9dbc7b7277bd239b", + "clienticon": "c9d0e3c1f94425b3b7b3b4fcae255bb797e90cd8", + "clienttga": "19af58740bc931ed31252b303854bb2796c3eb9c", + "clienticns": "db7fa19e0472abc26a778d8240ac1721ca1bbc2c", + "logo": "c541f56b343320cccfdab1f9b9a87230e6e0b341", + "logo_small": "c541f56b343320cccfdab1f9b9a87230e6e0b341_thumb", + "oslist": "windows,macos,linux", + "languages": { + "english": "1", + "german": "1", + "french": "1", + "italian": "1", + "spanish": "1", + "russian": "1", + "polish": "1", + "brazilian": "1" + }, + "linuxclienticon": "74e501a95d22b8fdf584d3e3a2b83ac7aefca5a4", + "eulas": { + "0": { + "id": "238370_eula_0", + "name": "Magicka 2 EULA", + "url": "https://store.steampowered.com//eula/238370_eula_0", + "version": "1" + } + }, + "steam_deck_compatibility": { + "category": "1", + "test_timestamp": "1645574400", + "tested_build_id": "3982521", + "tests": { + "0": { + "display": "2", + "token": "#SteamDeckVerified_TestResult_SteamOSDoesNotSupport" + } + }, + "configuration": { + "supported_input": "simultaneous_gamepad_mouse", + "requires_manual_keyboard_invoke": "0", + "requires_non_controller_launcher_nav": "0", + "primary_player_is_controller_slot_0": "0", + "non_deck_display_glyphs": "1", + "small_text": "0", + "requires_internet_for_setup": "0", + "requires_internet_for_singleplayer": "0", + "recommended_runtime": "proton-7.0-1", + "requires_h264": "0" + } + }, + "controller_support": "full", + "small_capsule": { + "english": "capsule_231x87.jpg" + }, + "header_image": { + "english": "header.jpg" + }, + "library_assets": { + "library_capsule": "en", + "library_hero": "en", + "library_logo": "en", + "logo_position": { + "pinned_position": "CenterCenter", + "width_pct": "100", + "height_pct": "100" + } + }, + "library_assets_full": { + "library_capsule": { + "image": { + "english": "library_600x900.jpg" + }, + "image2x": { + "english": "library_600x900_2x.jpg" + } + }, + "library_hero": { + "image": { + "english": "library_hero.jpg" + }, + "image2x": { + "english": "library_hero_2x.jpg" + } + }, + "library_logo": { + "image": { + "english": "logo.png" + }, + "image2x": { + "english": "logo_2x.png" + }, + "logo_position": { + "pinned_position": "CenterCenter", + "width_pct": "100", + "height_pct": "100" + } + } + }, + "store_asset_mtime": "1615973693", + "associations": { + "0": { + "type": "developer", + "name": "Pieces Interactive" + }, + "1": { + "type": "publisher", + "name": "Paradox Interactive" + }, + "2": { + "type": "franchise", + "name": "Magicka" + } + }, + "primary_genre": "1", + "genres": { + "0": "1", + "1": "25" + }, + "category": { + "category_1": "1", + "category_2": "1", + "category_9": "1", + "category_24": "1", + "category_22": "1", + "category_29": "1", + "category_28": "1", + "category_33": "1", + "category_44": "1", + "category_43": "1", + "category_41": "1", + "category_42": "1", + "category_45": "1", + "category_46": "1", + "category_62": "1" + }, + "supported_languages": { + "english": { + "supported": "true", + "subtitles": "true" + }, + "french": { + "supported": "true", + "subtitles": "true" + }, + "italian": { + "supported": "true", + "subtitles": "true" + }, + "german": { + "supported": "true", + "subtitles": "true" + }, + "spanish": { + "supported": "true", + "subtitles": "true" + }, + "polish": { + "supported": "true", + "subtitles": "true" + }, + "brazilian": { + "supported": "true", + "subtitles": "true" + }, + "russian": { + "supported": "true", + "subtitles": "true" + } + }, + "steam_release_date": "1432652400", + "community_visible_stats": "1", + "community_hub_visible": "1", + "gameid": "238370", + "store_tags": { + "0": "4057", + "1": "1685", + "2": "21", + "3": "3859", + "4": "1719", + "5": "19", + "6": "3843", + "7": "4136", + "8": "3841", + "9": "122", + "10": "4166", + "11": "5711", + "12": "1775", + "13": "1684", + "14": "1695", + "15": "7368", + "16": "4182", + "17": "4345", + "18": "10397", + "19": "5851" + }, + "review_score": "8", + "review_percentage": "82" + }, + "extended": { + "checkpkgstate": "1", + "developer": "Pieces Interactive", + "gamedir": "", + "homepage": "http://www.magicka2.com", + "icon": "", + "noservers": "0", + "sourcegame": "1", + "state": "eStateComingSoonNoPreload", + "visibleonlywhensubscribed": "1", + "publisher": "Paradox Interactive", + "listofdlc": "343980,343981,343982,352860,352861,352862,352870,352871,352872,352873,352874,352875,353120,354390,393830,393831,414650,414651", + "dlcavailableonstore": "1" + }, + "config": { + "contenttype": "3", + "installdir": "Magicka 2", + "launch": { + "0": { + "executable": "engine/Magicka2.exe", + "workingdir": "engine", + "description": "Play Magicka 2", + "type": "none", + "config": { + "oslist": "windows" + } + }, + "1": { + "executable": "engine/Magicka2", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "linux", + "osarch": "32" + } + }, + "2": { + "executable": "engine/Magicka2_x64", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "linux", + "osarch": "64" + } + }, + "3": { + "executable": "engine/Magicka2.app", + "description": "Play Magicka 2", + "workingdir": "engine", + "config": { + "oslist": "macos" + } + } + }, + "steamcontrollertemplateindex": "1", + "steamcontrollertouchtemplateindex": "1", + "steamcontrollertouchconfigdetails": { + "2069657566": { + "controller_type": "controller_mobile_touch", + "enabled_branches": "default", + "use_action_block": "false" + } + }, + "steamcontrollerconfigdetails": { + "551563382": { + "controller_type": "controller_steamcontroller_gordon", + "enabled_branches": "default", + "use_action_block": "false" + } + } + }, + "depots": { + "overridescddb": "1", + "baselanguages": "english,german,french,italian,spanish,russian,polish,brazilian", + "228984": { + "config": { + "oslist": "windows" + }, + "depotfromapp": "228980", + "sharedinstall": "1" + }, + "228990": { + "config": { + "oslist": "windows" + }, + "depotfromapp": "228980", + "sharedinstall": "1" + }, + "238371": { + "systemdefined": "1", + "config": { + "oslist": "windows" + }, + "manifests": { + "public": { + "gid": "4722487876550547005", + "size": "3126586661", + "download": "3037827376" + } + }, + "encryptedmanifests": { + "1_0_1_3": { + "gid": "1F8ECBCF7B1816DC5077CE481229E541", + "size": "0E2ED2A291E2E60EFFDB2AF2A4DFD362", + "download": "AAFE100964BDC5BD28ED2AA1BAFBAFC5" + }, + "1_0_1_4": { + "gid": "5CDF3D12FA91812FB807C8025C1F516A", + "size": "FF863A1B5FA97ECBE0F7A0E92FDB2E29", + "download": "3C40D9DE30AB7F9A60810E82B91CCE6E" + }, + "1_0_1_5": { + "gid": "1F90EF256B1735929ED07F21404A7661", + "size": "C85D53E94140655CA6ECF5D2651A2904", + "download": "90D0682E7A2F1C3213F8AAF28C7BDF65" + }, + "1_1_0_0": { + "gid": "8BC67724703EF9102B288BC73F83C684", + "size": "91C29CA5DC777ED096836490D8B63B6D", + "download": "14307662AACA699407E326E6565D6AAB" + }, + "1_1_0_0_v3": { + "gid": "8EC6C5981DCACAEC4D3FF7EFAE16FA6C", + "size": "6A3317178621939B0615130EB0AEAD4D", + "download": "FE1FD9A00C931BE0A984A14F985E159E" + }, + "1_2_1_0": { + "gid": "D36A2C34BCF705A49D3C0066FB6032DD", + "size": "9BC3A2FE95E92D5BFB83E2B3A124AF1E", + "download": "C8F733519D83E6C2D55B447687649190" + }, + "dev": { + "gid": "C4A6D6837AE82BF7BE9BB4F9AC604F03", + "size": "96F16B3905F54BFD63854EFF3107B3E7", + "download": "32435FAA19311A6D64B0B2A9DFBA10D7" + }, + "development": { + "gid": "70C274AC71C68DDB3B69BC87C982D2BC", + "size": "2232CC9DA1E93F27F4873B855C33F96B", + "download": "986C4872D70994DC3B74B4B8BB4DA68A" + }, + "dlc_1": { + "gid": "F2209AEAB99909B124B90C850F7CC69A", + "size": "64D8F509797E15C2AE8BB7C48551A937", + "download": "6AE1F0D7F1E616D3474B87A47D02AF77" + }, + "dlc_2": { + "gid": "0DE3C846B1C48935B89FFEF992C2A31F", + "size": "A6371A0F2B5A91050A8584561A6C02D8", + "download": "C2627F876CEB25428A92E858C5B88410" + }, + "dlc_2_sh": { + "gid": "5F74D84BD426AF6A4019DBC5A0E6031C", + "size": "53BC67AD0959030797E048F84F04739C", + "download": "938A340EFADDED43943C821E9C5EC197" + }, + "early_access": { + "gid": "01050CE80F97DBB0FB73F9E4D3922124", + "size": "197D8174E5A6F207CF4DDC68702626F6", + "download": "7F6A11CB77598FAA21EC56EC01B054DA" + }, + "enzyme": { + "gid": "A13FD9FA9FE56A7EAF57659027AD2C09", + "size": "D52D27BDF078A3955B813A09FFB0238C", + "download": "7BC0DFD4A61CB6EED3518EA0CF5BE0D0" + }, + "gm_6": { + "gid": "9FE7008918604AD52D2ED45D88AF5C0C", + "size": "A2169859E9FC358D27F59FCB85A526C5", + "download": "824C1EF7225DC4B8495E8C6519286C57" + }, + "gm_6_1": { + "gid": "41B62FBFDD2C82DBD8C5E2951EBAF28E", + "size": "BD460B6A526094CCC576A0858CFF8CA1", + "download": "3C0755DF91FACC9D1758AA5AF5A3C584" + }, + "master": { + "gid": "BB6AD432DCFF4BD70DC4A9F66E63A10D", + "size": "00EA8937DA01D28E32E5A66F72CB300F", + "download": "C981388CB9418C3C691E821DF2FD286C" + } + } + }, + "353120": { + "manifests": { + "public": { + "gid": "8753634293660869213", + "size": "343535983", + "download": "104647760" + } + }, + "encryptedmanifests": { + "1_0_1_3": { + "gid": "4B42CF1311A3A53C3C321EA5CB6222CA", + "size": "F03542992CFD78DBABFF1AE6C20E7E04", + "download": "C3A570B7DC4BE256A900A52EEAA9CA64" + }, + "1_0_1_4": { + "gid": "3D1B151C9B42851252EC5A9482207D74", + "size": "20EF48A943F9263BB8C51EBA6DC93E02", + "download": "29E81977E001F24474D83E5EAD9429C4" + }, + "1_0_1_5": { + "gid": "6C7C7D225DC169FCE2DE71B044B09104", + "size": "41A2482852F88976E562EA2F50979962", + "download": "69F700E8E0BBC5179FEF88055DBA7D87" + }, + "1_1_0_0": { + "gid": "0A97C900ED8BFDB8DE342015C9625973", + "size": "C73B061D42BFB3E91C745EBAFAB54B32", + "download": "C0E08CD3B0C86D5F89ABBDE9728CEF9F" + }, + "1_1_0_0_v3": { + "gid": "3F852EC9B83A325E1FCBDBC4238DFF65", + "size": "F8DF3716EC101EE51994776EC2F0BF28", + "download": "6078A4F022F685964CE47F005533FA69" + }, + "1_2_1_0": { + "gid": "4B0743B1E62CFF5233B983D0870F3166", + "size": "43FCEB17DBEAD47D5B61AD7C625E47F5", + "download": "76DEF3A6F5D5C4734425CF461A691106" + }, + "dev": { + "gid": "F5D7C1A7CE9305BB0F9C9D2801E33448", + "size": "80ADB377413057CE8DA2FE8E545A7D4B", + "download": "3A11E5BD75E2D262CF1FB2D5C8B5728F" + }, + "development": { + "gid": "335C765A9B1587B4E1771F06C3B1D558", + "size": "5204F298000FE52A7E306EDEF6FA8457", + "download": "3B950BD094355D12BF00D77486139E45" + }, + "dlc_1": { + "gid": "0E3AD1CB42177332B995E4C69C40D356", + "size": "3611099E9CE1A04A693D1B45074817E2", + "download": "CA85B793983125901D7DA705BDC0FAC6" + }, + "dlc_2": { + "gid": "1FF05007553F07961E54A8A87AB39372", + "size": "3CAE24D953C1205890DD728E2E5DCC34", + "download": "EA1D91C00D841DA0599904C8AD517A5B" + }, + "dlc_2_sh": { + "gid": "DA1C90312A9B189F4071D8D8219BF3B9", + "size": "61F1D58CAA4C8BD200E182482CF99C11", + "download": "81F8D880B15F93B4D2472BD602B56182" + }, + "early_access": { + "gid": "59E507BD728A66E41723DD3D95AE9072", + "size": "F998E0418029DA522CC2018F316C6037", + "download": "A40DA4D63D8330ECACE40DE6E7678863" + }, + "enzyme": { + "gid": "5A9096D8041BE0556D0B6DDCBA2513A7", + "size": "FABAA3C1EF7C6CD8161132001DCC42AF", + "download": "3002F08544CF426C55741878530BFEE6" + }, + "gm_6": { + "gid": "7DC2DEC3F15B136B541ECC88B22129B4", + "size": "1033F3AD9903122602C9E6ADCDEC4569", + "download": "3AC0935072AF2CF06D05DE483D13638A" + }, + "gm_6_1": { + "gid": "6BA1E03EA3082A9E3BE622C64EB7F18C", + "size": "724B709EC4E1A81B2D95FD6BB180F622", + "download": "909F8CA933894F6CE8AAE4629F2FA4C8" + }, + "master": { + "gid": "330399036DC03850797F7491729011CB", + "size": "C4D90AA5FB586CA18558A37DA55BA58C", + "download": "9CA4541F45BA7D41F7F1281007AF37FF" + } + }, + "dlcappid": "353120" + }, + "354390": { + "manifests": { + "public": { + "gid": "4304180385385745678", + "size": "49364429", + "download": "48980992" + } + }, + "encryptedmanifests": { + "1_0_1_3": { + "gid": "0CE13CB28E0CA2578209DE3F16E990F2", + "size": "9CCE902BCF0156ED3F84EB8070157545", + "download": "471B122A62F3C8C68DBD83E17FB601BF" + }, + "1_0_1_4": { + "gid": "94652B27B8438C4D63F3F0685986DC86", + "size": "0C0C6D8B3F75375C7F4BF8D0B5337D5C", + "download": "6BF3358241D8F5F27BBD3B96EB6439FA" + }, + "1_0_1_5": { + "gid": "E2FCE8B43BB6429B8D28F50BA330E27A", + "size": "8CDCDB96627E354DC7505F881ED8CC39", + "download": "3FD7531AE6B99D0738799DE628AE15C5" + }, + "1_1_0_0": { + "gid": "EFB33F286DCFF2556750CE5E873C197C", + "size": "F3DE202383F8A9D13420FBDB07463CF3", + "download": "BA33624E511E9E105E25F559CD31A267" + }, + "1_1_0_0_v3": { + "gid": "25A1705FF60762EE53833CF38191028E", + "size": "671E4C35D54CB6B9A2A556BAB40BCF43", + "download": "1F806F8A1095A3804B82E0DDA48DC54C" + }, + "1_2_1_0": { + "gid": "EA9306335CF35113D9A753D1B7CD6534", + "size": "70490C3F7BD104F283BF0C190EDCBB8B", + "download": "055E1D74985E9B98D73DB6052DF66F5B" + }, + "dev": { + "gid": "6B08495D68998ED31CF5FD0EA23ED62C", + "size": "1B763E6F6F641AF188E33F73E515668B", + "download": "313C2715120F21EEE73BF0AAB9823661" + }, + "development": { + "gid": "D1DF7B0B66593A6B29691F65E5AF0C26", + "size": "FE31C89CD65E3B20DE576F01CA1D8D4E", + "download": "7BA72C7C413FB78A6035ACA659679AA9" + }, + "dlc_1": { + "gid": "03BA3F18DF260BB2FD771370D5E65004", + "size": "B519DCEC75D60220058B5ACB43A6915A", + "download": "4D5FCBD259171F844194FF1F018F01E6" + }, + "dlc_2": { + "gid": "56AB3A9446E1390C40C846AC82EDE12C", + "size": "F2EE53661ECCAB4001530652600C5E96", + "download": "098E1798A94763705089F8AF60B7777A" + }, + "dlc_2_sh": { + "gid": "E2A3A9FBDDFFAA5AA1CFA35E3D5A3CCD", + "size": "610BA408EA627DA4D4E95CC960A06A53", + "download": "A502E25265F586DF8FFAD40CC3DF6F44" + }, + "early_access": { + "gid": "6195C9CDF0F9724EFD4F016FECC8BD01", + "size": "4516F959E977EC032385C41A6551E102", + "download": "2A62BFFB87D52CF19E2816E99A1F8DBD" + }, + "enzyme": { + "gid": "633EB6224B62F9F42A3442FF4B58B414", + "size": "FC3F52763C67C63AFAFB30649E767626", + "download": "F6AF0CA872DC3853A00B0987B91D4B4D" + }, + "gm_6": { + "gid": "A13B78E26D9B61B6EBE6CDD9C54D5B68", + "size": "80A707E6317567C871C3E4DAF4C71517", + "download": "7803F94085031954C7B2310018122A1B" + }, + "gm_6_1": { + "gid": "B8331C22999B5B709F980D09C658493C", + "size": "032AC498B9CCE298EBC475908A43C14F", + "download": "ACB0B00E41E582AF9D15EACE6D262A1E" + }, + "master": { + "gid": "EB5643FEFB32F2A2379F88C62F887B60", + "size": "F95F6BCA8A33A949674A9B6984267E52", + "download": "BEE1415539B8D0B3C5742122F084322E" + } + }, + "dlcappid": "354390" + }, + "238372": { + "config": { + "oslist": "linux" + }, + "manifests": { + "public": { + "gid": "6830296416247391615", + "size": "3108736752", + "download": "3020588384" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "2D786A18762E5025628B30BC4555ED8D", + "size": "BAB9DB3FABE0294AA2A4ECEFD697248E", + "download": "888C2AEE7C51E58A88469F0D18F75F05" + }, + "1_1_0_0_v3": { + "gid": "AC1BB7AED4D6A9B2226DC5D0045E76F1", + "size": "D3740BF0F147F8CCA1C803DC24DFE1F5", + "download": "4CFA4E83687C0FB478DBF91B1CAB8391" + }, + "1_2_1_0": { + "gid": "27DB8ECCEBC662BCFE4AD94DAC80E0F7", + "size": "A19708D6CBBD0D954FE5949CE018B320", + "download": "9487F76B50EAFF4A4EAFE1B356ECCFD9" + }, + "development": { + "gid": "0DFA84610CDA6F1285CBAD451A828687", + "size": "324FBBB2DB0968373E0E1B7A736699B3", + "download": "C45530A384B3A5ECB8EED630321885DE" + }, + "dlc_1": { + "gid": "EAD1D6E4BDF5B0B030C680AADE04BC10", + "size": "9E8FC642208231F766C4040D0B5F063A", + "download": "38EF38875C8C5BF0A0C3AC034BB4B097" + }, + "dlc_2": { + "gid": "CC62D0AEB42CBE2AD9B3BB295F4FC366", + "size": "091BC4BC2D3F12028377F12AC44B61BB", + "download": "50C9AE908C065D6E2A3D5239F4F90E69" + }, + "dlc_2_sh": { + "gid": "DB415084AC035DA11C0DF807F185FE19", + "size": "FEB960BC634A2AC207767005DE413CB5", + "download": "D5DFE4C40B2AB0097A725FBD8FEAF5FD" + }, + "early_access": { + "gid": "B4CFB55E284CF1B3C88605B41002D239", + "size": "615692F762B716E599FBFA29B44BFCE8", + "download": "6BD02B25E244FFBA9BF9AB25BFA8AB50" + }, + "enzyme": { + "gid": "F8F6E5639C91BEDD8A2AEAC885F118B4", + "size": "541861DE7876A25A3C323BBB883E01B2", + "download": "396C5592BC83CA57FABAF32536DB7682" + }, + "master": { + "gid": "BF5F486702CB49BDB0A375C73DDA9446", + "size": "57BF546E55231D511A36B730D5C9954A", + "download": "B73E88F06A427471A65D06A934E7A4F9" + } + } + }, + "238373": { + "config": { + "oslist": "macos" + }, + "manifests": { + "public": { + "gid": "3339522036327649421", + "size": "3106330089", + "download": "3019218640" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "B51E782F34D56C1715B6A2445B3CF9DB", + "size": "CFE44459B1FDEF6BC487C0ADF09375B6", + "download": "59A3D57A0A1E652F0B6F67B0E48D4FC2" + }, + "1_1_0_0_v3": { + "gid": "C112DE50D08AF0FDE24B376D0169D3AF", + "size": "3506583E918F3651B0130582A839208C", + "download": "B89A2B90D1106FDFE8DAD1E1897B7ED6" + }, + "1_2_1_0": { + "gid": "1E1B410D417219F12A31A6BA11544F8F", + "size": "E79D8ADF6AD737FDF56BE2BC9C73F525", + "download": "DC4481B317C23D18B35972298C99F5B0" + }, + "development": { + "gid": "8D7F3C78F953C4F032427689335C0444", + "size": "CC3B2539200487D7E9B5C51FA0CD2211", + "download": "F979B970271E51E01684CFDD7F0EB3E2" + }, + "dlc_1": { + "gid": "E696C42AF67E9397B2AF14612BD29DD3", + "size": "7FF59D6BDE4EA86EFBDD266D28079623", + "download": "F653C181DCBD0A363A42A66D5F810F9A" + }, + "dlc_2": { + "gid": "626D010BC91FCAC728A9878866F39B99", + "size": "7BCAB250A15663C557DC2836EDC8765C", + "download": "AD3904BA9BA9CBE72959045C18B848A6" + }, + "dlc_2_sh": { + "gid": "F4252187ED5921EBAC7217BC41058130", + "size": "EE5F6F883A21E1BF1E783DD45C622EDE", + "download": "1F0C176C800B9ADFE58693212CCC5C35" + }, + "early_access": { + "gid": "31527A7229A1394E47E93462304C7ACC", + "size": "0DB5DE375C5EBA24C77732F40F7D4F91", + "download": "467A085A277B041881E137A90813A41C" + }, + "enzyme": { + "gid": "D4737F6155BE351AEB3BA15B96B49B26", + "size": "75B0496C65AAA3255C4A6EED5DEF8022", + "download": "34F17204D0FD2FE1B7C13DE871030FAE" + }, + "master": { + "gid": "70AECB37AE8BBACC24D7E801E9F4A662", + "size": "2B9B2A487BB4AB0426D5942811D3FD31", + "download": "24A1F6977C525511CB6A8119C157E5FD" + } + } + }, + "238374": { + "config": { + "oslist": "windows" + }, + "manifests": { + "public": { + "gid": "3116099421414652121", + "size": "24457579", + "download": "7325424" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "B533ABA939C20A1D082AA44CCCD98328", + "size": "E9D9EDB6CBD4650011980E15DCF33B19", + "download": "70E7EB73A9AF4482FCD03899618B2675" + }, + "1_1_0_0_v3": { + "gid": "D9CCDFD5F930448233874C6C93ECD0D4", + "size": "9319B3FDD90A461474143DB973DFE90B", + "download": "5D766318E786103839ACD3A7722AFE0F" + }, + "1_2_1_0": { + "gid": "E9B7BA02FCB883BC1644BDBABF1FA2C7", + "size": "40E124CAE6A93B45144BC10C535818BA", + "download": "46E1F434FD35A3133561E0451B1148EF" + }, + "development": { + "gid": "8096CCC84464F569BA6989359A41BECF", + "size": "5AC65736D43D8985740296A599D48C27", + "download": "1D12E74527911D1DCA205ACE5A4D97A3" + }, + "dlc_1": { + "gid": "22ED0D129105219A9DA55C85F87D9C4B", + "size": "6D84056FB92FC375CA0EDEE751A76638", + "download": "F6007515F2CAD768EF75258E5B88386B" + }, + "dlc_2": { + "gid": "E860FCD9416E2149F7C52D713B50FA3A", + "size": "F6084F68F14C0759BC3F8A4DEBA1F8E3", + "download": "81FCB6523D8378FEBFC6D8C4894B41B7" + }, + "dlc_2_sh": { + "gid": "89745964BEF579E6965F453AA5E5514B", + "size": "A6BF2DA12BB379FFA7E56C7332592031", + "download": "EFA957B28DE6645892A4F2EA0A81B3BF" + }, + "early_access": { + "gid": "532B0700AC37C93807E9F4A7CA021D91", + "size": "0B848AE77829DE7D706012A3A6094D52", + "download": "C27D567D5931AC6E279DE93F156D6C95" + }, + "enzyme": { + "gid": "ED726E71DC2899A4ED275C3885072D1F", + "size": "24863BE795D5C1CBA7EB48C98A3F0CD2", + "download": "E3A0C43FAB7912E4A981DD1BB68F52E5" + }, + "master": { + "gid": "051B96CBA7639DBEA505751318774416", + "size": "E6A9198EDB513FC5C7257DFF90BAE993", + "download": "D042CE1B0307F959F8755D5C1D5F909E" + } + } + }, + "238375": { + "config": { + "oslist": "linux", + "osarch": "32" + }, + "manifests": { + "public": { + "gid": "7961351643475508039", + "size": "14189908", + "download": "4272816" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "C4024A8196E47DB856596F9C2624184A", + "size": "9AD187517679E5233B4D59D3CD5A2FC6", + "download": "D4EEB29C9577501DB6080A6D6B5BB153" + }, + "1_1_0_0_v3": { + "gid": "9CA9996DB927303510763C407C68D64C", + "size": "C3687262C4402E88F03FFABDCBE79316", + "download": "CB0246CFCCA66A1C11B961C4D6D7FB96" + }, + "1_2_1_0": { + "gid": "E8AB95B5EDEC3A9BDE63DCB0B5124CF3", + "size": "596B0F1F2D026214D290C1642D9D95D0", + "download": "42C6161934E18E350B65041DB9B7CC85" + }, + "development": { + "gid": "ECB16A3546FD85A7B1E4A411979067D0", + "size": "70F0961CD3BC28D3EBE2E4A37BD97B99", + "download": "05B5EFDD883282EEA71443E4F3F921A6" + }, + "dlc_1": { + "gid": "DA5F1E2871CF71891C92817D05FC0695", + "size": "9964E77BD284153CC302EBF82B3635BC", + "download": "B89A37AC9ED643C73F76F781A7EC0CE9" + }, + "dlc_2": { + "gid": "C810D3A06902635DACC9D9FAC7E237D5", + "size": "67FFC37B0680BF3247D7A61DD41B3043", + "download": "9CD6B16A6FA37755D959D7CD5E217C30" + }, + "dlc_2_sh": { + "gid": "6A76773FAF38BB953CDA1FBF2826A76F", + "size": "25E05D386F5B2624C3A2ACBDCC2FB0F4", + "download": "5259BDE5B3EF0A5BD96A32EC16EC8F35" + }, + "early_access": { + "gid": "3630E5B65FB06ED044DC8651DF6074EE", + "size": "957E723A4759BC0A278F003B353AF047", + "download": "18D42EDD365DA916986A1054388FC11A" + }, + "enzyme": { + "gid": "7C788D22FFBF26EE748AA290FE264CEC", + "size": "54DEBD725016397E21A70D62DB0899ED", + "download": "2A4FF42E458B1F25D62B00ECEEC8A37E" + }, + "master": { + "gid": "0121DC9CEF2F5048DA6EF2B2D6868FCC", + "size": "12CFB44977C1CDE55B7F60E780F2263C", + "download": "CC3AA8FC9F9265FC5E8F27E5FD461607" + } + } + }, + "238377": { + "config": { + "oslist": "linux", + "osarch": "64" + }, + "manifests": { + "public": { + "gid": "3015461552370049559", + "size": "13748004", + "download": "4091856" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "14F06D265AC5F87165630CBCC615110D", + "size": "A449BD7030E5CEF19E9BE35F063D5B58", + "download": "F20B6837B52CE933D07E58F4C973B013" + }, + "1_1_0_0_v3": { + "gid": "47FDC1524F7DE0B1179322DD25AAF4F7", + "size": "91A4FF87D25552E9CA70A73706C355C3", + "download": "B8DA4A4CC44EE28787CD0BF31D28AD82" + }, + "1_2_1_0": { + "gid": "E3AE7EC3AE8118B632266502FCB38771", + "size": "E5EDF8E20DCAF041E8E415DC406DD972", + "download": "EC6DE8143C10CF15D0058E1DC28C114E" + }, + "development": { + "gid": "3F7FBEE42AF1D5F257E8768BAB223F87", + "size": "73C4FD016F4BB19502A85579F771DE96", + "download": "3C7D87D365920BE86A6390ADE85996ED" + }, + "dlc_1": { + "gid": "DB54E6D2EDDA7D50A1139C678C8E873E", + "size": "0C1F5B8F0F50D77249C14C6306804965", + "download": "D8CEE748356CF478D59D50009D2058C8" + }, + "dlc_2": { + "gid": "CAD6176B50F30867107BA83F8090B838", + "size": "AB0B9E160EE0F107EA5F461425C30A0A", + "download": "0AF771AFF1F1D23B4C2A1FFBB1D16CBC" + }, + "dlc_2_sh": { + "gid": "E86905E971425AC478DA0073EDBAB58F", + "size": "812EB7DDAACF3E862B02D149E359F61D", + "download": "5B02FA18096EB3D63070D3CDC5678919" + }, + "early_access": { + "gid": "B3727459DB929D260393A2804907AA2F", + "size": "8728149E3841D31A56BE8EF517BA811A", + "download": "7FA6A0425C484827702A3DCF73F5A82E" + }, + "enzyme": { + "gid": "8133E98AFDD50D43DFEA1C56A240FECF", + "size": "E795618ADCB6D6A0D09B01B9CDF0488D", + "download": "796F1A48E5943CC3E53F15C47FB24349" + }, + "master": { + "gid": "D327C96FD5D006E9E1B1BDD587B33CC1", + "size": "654E54D0F9B4B0901B589645EF8CD375", + "download": "75014A292FCB80703C2861DDDBD66D52" + } + } + }, + "238376": { + "config": { + "oslist": "macos" + }, + "manifests": { + "public": { + "gid": "8208414792312360470", + "size": "14179513", + "download": "3444960" + } + }, + "encryptedmanifests": { + "1_1_0_0": { + "gid": "A082F9368B96CA29D72E3DA14A1E7F5B", + "size": "0C3F716F8D4D97C2C67E9FB47E7A0E43", + "download": "C78635CA5A0934E41119088D12D49F2F" + }, + "1_1_0_0_v3": { + "gid": "21FB4C6D0EDFC6F041F8F41231A1CA0F", + "size": "1063D0BF54CFDCC0CCC60984569BCA1F", + "download": "909FAD3E913120B4E1920828182A29A5" + }, + "1_2_1_0": { + "gid": "2E23C0C7813CE4C1144F96173376E8F7", + "size": "412AB235E044692413569859373846A8", + "download": "E798F3228816F227009272DCE41BA62E" + }, + "development": { + "gid": "4AD6E926E73451CF1FC5B39F9F4C2687", + "size": "E6ACCF6F1DACACC4BB643BDA9708F208", + "download": "9001451E999C75219DFA7D3159BE287A" + }, + "dlc_1": { + "gid": "5FBDAB77F377350246FB98D55B48223C", + "size": "7855D0A5E60C36B0438F497F25E6E67B", + "download": "2096F2614A39AD0635E515FB79CC1051" + }, + "dlc_2": { + "gid": "92EE480EC2141FBC3D45350BAF55FA05", + "size": "2987796374E7EFEFEFCEE5D48B7AE4C2", + "download": "F8813DF90C42E14FF8C4A18A4EE323DC" + }, + "dlc_2_sh": { + "gid": "2C8E2D3E648A9E37AC349CC26E8B34A1", + "size": "37E251867C8D11D7DF61F0915676D076", + "download": "320CEFB48B0493276BF5D34C80BFC79D" + }, + "early_access": { + "gid": "82FE25EC4FAACC6C00425CEBF3F9CC89", + "size": "CBE6E07926EF444FA5B6554E648E1537", + "download": "63AB872A7A99D01EB2E915BC8ADB1B2E" + }, + "enzyme": { + "gid": "E45434266E3D034CFE47FF5EF6196477", + "size": "DFD76C1D655F06EDEAA815135215CF87", + "download": "AC4250D61C64DE175D486182F006094C" + }, + "master": { + "gid": "E2C175F6E18FA051419B67889B74AF0B", + "size": "8FB8708118742A913226BD0EE412B30F", + "download": "41A47B4E2CFDB6979BF32836B93FCAC0" + } + } + }, + "branches": { + "public": { + "buildid": "3982521", + "timeupdated": "1562252380" + }, + "1_0_1_3": { + "buildid": "661720", + "pwdrequired": "1" + }, + "1_0_1_4": { + "buildid": "668796", + "pwdrequired": "1" + }, + "1_0_1_5": { + "buildid": "728859", + "pwdrequired": "1" + }, + "1_1_0_0": { + "buildid": "773817", + "pwdrequired": "1" + }, + "1_1_0_0_v3": { + "buildid": "773817", + "pwdrequired": "1" + }, + "1_2_1_0": { + "buildid": "939506", + "pwdrequired": "1" + }, + "dev": { + "buildid": "740930", + "pwdrequired": "1" + }, + "development": { + "buildid": "3981993", + "pwdrequired": "1", + "timeupdated": "1562239021" + }, + "dlc_1": { + "buildid": "748516", + "pwdrequired": "1" + }, + "dlc_2": { + "buildid": "869382", + "pwdrequired": "1" + }, + "dlc_2_sh": { + "buildid": "869382", + "pwdrequired": "1" + }, + "early_access": { + "buildid": "773817", + "pwdrequired": "1" + }, + "enzyme": { + "buildid": "939506", + "pwdrequired": "1" + }, + "gm_6": { + "buildid": "626044", + "pwdrequired": "1" + }, + "gm_6_1": { + "buildid": "639965", + "pwdrequired": "1" + }, + "master": { + "buildid": "3982521", + "pwdrequired": "1", + "timeupdated": "1562249233" + } + } + }, + "ufs": { + "quota": "10000000", + "maxnumfiles": "10" + }, + "_missing_token": false, + "_change_number": 24981165, + "_sha": "0a036f41996b4919278619e9259eb13cf739ee4a", + "_size": 28621 +} \ No newline at end of file diff --git a/generate_emu_config_old/output/238370/steam_settings/branches.json b/generate_emu_config_old/output/238370/steam_settings/branches.json new file mode 100644 index 0000000..fbb0d79 --- /dev/null +++ b/generate_emu_config_old/output/238370/steam_settings/branches.json @@ -0,0 +1,121 @@ +[ + { + "name": "public", + "description": "", + "protected": false, + "build_id": 3982521, + "time_updated": 1562252380 + }, + { + "name": "1_0_1_3", + "description": "", + "protected": true, + "build_id": 661720, + "time_updated": 1726429304 + }, + { + "name": "1_0_1_4", + "description": "", + "protected": true, + "build_id": 668796, + "time_updated": 1726429304 + }, + { + "name": "1_0_1_5", + "description": "", + "protected": true, + "build_id": 728859, + "time_updated": 1726429304 + }, + { + "name": "1_1_0_0", + "description": "", + "protected": true, + "build_id": 773817, + "time_updated": 1726429304 + }, + { + "name": "1_1_0_0_v3", + "description": "", + "protected": true, + "build_id": 773817, + "time_updated": 1726429304 + }, + { + "name": "1_2_1_0", + "description": "", + "protected": true, + "build_id": 939506, + "time_updated": 1726429304 + }, + { + "name": "dev", + "description": "", + "protected": true, + "build_id": 740930, + "time_updated": 1726429304 + }, + { + "name": "development", + "description": "", + "protected": true, + "build_id": 3981993, + "time_updated": 1562239021 + }, + { + "name": "dlc_1", + "description": "", + "protected": true, + "build_id": 748516, + "time_updated": 1726429304 + }, + { + "name": "dlc_2", + "description": "", + "protected": true, + "build_id": 869382, + "time_updated": 1726429304 + }, + { + "name": "dlc_2_sh", + "description": "", + "protected": true, + "build_id": 869382, + "time_updated": 1726429304 + }, + { + "name": "early_access", + "description": "", + "protected": true, + "build_id": 773817, + "time_updated": 1726429304 + }, + { + "name": "enzyme", + "description": "", + "protected": true, + "build_id": 939506, + "time_updated": 1726429304 + }, + { + "name": "gm_6", + "description": "", + "protected": true, + "build_id": 626044, + "time_updated": 1726429304 + }, + { + "name": "gm_6_1", + "description": "", + "protected": true, + "build_id": 639965, + "time_updated": 1726429304 + }, + { + "name": "master", + "description": "", + "protected": true, + "build_id": 3982521, + "time_updated": 1562249233 + } +] \ No newline at end of file diff --git a/generate_emu_config_old/output/238370/steam_settings/configs.app.ini b/generate_emu_config_old/output/238370/steam_settings/configs.app.ini new file mode 100644 index 0000000..1dda69f --- /dev/null +++ b/generate_emu_config_old/output/238370/steam_settings/configs.app.ini @@ -0,0 +1,22 @@ +[app::dlcs] +# should the emu report all DLCs as unlocked, default=1 +unlock_all=0 +353120=Magicka 2 - Midgård Interactive Map +352870=Magicka 2 - Cultist Robe +352871=Magicka 2 - Cultist Staff of Aeons +352872=Magicka 2 - Cultist Ritual Sword +352873=Magicka 2 - Epic Warlord Dragon Armor +352874=Magicka 2 - Epic Crystal Staff +352875=Magicka 2 - Epic Soul Screecher Sword +343980=Magicka 2 - Ritual sickle +343981=Magicka 2 - Peace Treaty staff +343982=Magicka 2 - Warlock robe +393830=Magicka 2: Gates of Midgård Challenge pack +393831=Magicka 2: Three Cardinals Robe Pack +354390=Magicka 1 Orchestral soundtrack +414650=Magicka 2: Chirpy Staff +414651=Magicka 2: Ice, Death and Fury +352860=Magicka 2 - Headmaster Robe +352861=Magicka 2 - Headmaster Sword +352862=Magicka 2 - Headmaster Staff + diff --git a/generate_emu_config_old/output/238370/steam_settings/controller/In-Game.txt b/generate_emu_config_old/output/238370/steam_settings/controller/In-Game.txt new file mode 100644 index 0000000..2e6c818 --- /dev/null +++ b/generate_emu_config_old/output/238370/steam_settings/controller/In-Game.txt @@ -0,0 +1 @@ +Move=LJOY=joystick_move diff --git a/generate_emu_config_old/output/238370/steam_settings/controller/Menu.txt b/generate_emu_config_old/output/238370/steam_settings/controller/Menu.txt new file mode 100644 index 0000000..2e6c818 --- /dev/null +++ b/generate_emu_config_old/output/238370/steam_settings/controller/Menu.txt @@ -0,0 +1 @@ +Move=LJOY=joystick_move diff --git a/generate_emu_config_old/output/238370/steam_settings/depots.txt b/generate_emu_config_old/output/238370/steam_settings/depots.txt new file mode 100644 index 0000000..3652658 --- /dev/null +++ b/generate_emu_config_old/output/238370/steam_settings/depots.txt @@ -0,0 +1,11 @@ +353120 +238371 +238372 +238373 +238374 +238375 +238376 +238377 +354390 +228984 +228990 diff --git a/generate_emu_config_old/output/238370/steam_settings/steam_appid.txt b/generate_emu_config_old/output/238370/steam_settings/steam_appid.txt new file mode 100644 index 0000000..bdc4df1 --- /dev/null +++ b/generate_emu_config_old/output/238370/steam_settings/steam_appid.txt @@ -0,0 +1 @@ +238370 \ No newline at end of file diff --git a/generate_emu_config_old/output/238370/steam_settings/supported_languages.txt b/generate_emu_config_old/output/238370/steam_settings/supported_languages.txt new file mode 100644 index 0000000..69f77e9 --- /dev/null +++ b/generate_emu_config_old/output/238370/steam_settings/supported_languages.txt @@ -0,0 +1,8 @@ +english +french +italian +german +spanish +polish +brazilian +russian diff --git a/generate_emu_config_old/output/480/info/launch_config.json b/generate_emu_config_old/output/480/info/launch_config.json new file mode 100644 index 0000000..db24125 --- /dev/null +++ b/generate_emu_config_old/output/480/info/launch_config.json @@ -0,0 +1,6 @@ +{ + "0": { + "executable": "SteamWorksExample.exe", + "type": "none" + } +} \ No newline at end of file diff --git a/generate_emu_config_old/output/480/info/product_info.json b/generate_emu_config_old/output/480/info/product_info.json new file mode 100644 index 0000000..0aac5fb --- /dev/null +++ b/generate_emu_config_old/output/480/info/product_info.json @@ -0,0 +1,155 @@ +{ + "appid": "480", + "common": { + "name": "Spacewar", + "eulas": { + "0": { + "id": "480_eula_0", + "name": "Spacewar EULA", + "url": "http://store.steampowered.com/eula/480_eula_0" + }, + "1": { + "id": "480_eula_1", + "name": "Spacewar EULA 1", + "url": "http://store.steampowered.com/eula/480_eula_1", + "countries": "US" + } + }, + "requireskbmouse": "1", + "type": "Game", + "releasestate": "released", + "steamchinaapproved": "1", + "releasestatesteamchina": "released", + "oslist": "windows,macos,linux", + "osarch": "", + "osextended": "", + "controller_support": "full", + "associations": { + "0": { + "type": "publisher", + "name": "Telltale Games" + } + }, + "primary_genre": "0", + "category": { + "category_28": "1", + "category_33": "1", + "category_44": "1" + }, + "community_visible_stats": "1", + "workshop_visible": "1", + "gameid": "480" + }, + "extended": { + "developer": "Valve", + "gamedir": "spacewar", + "homepage": "", + "icon": "", + "noservers": "1", + "serverbrowsername": "Spacewar", + "state": "eStateAvailable", + "vacmacmodulecache": "160", + "vacmodulecache": "203", + "vacmodulefilename": "sourceinit.dat", + "visibleonlywheninstalled": "1", + "disableshaderreporting": "1", + "publisher": "Telltale Games", + "listofdlc": "110902,447130" + }, + "config": { + "usemms": "1", + "launch": { + "0": { + "executable": "SteamWorksExample.exe", + "type": "none" + } + }, + "contenttype": "3", + "installdir": "Spacewar", + "nativesteamcontroller": "1", + "checkforupdatesbeforelaunch": "1", + "testchange": "2", + "steamcontrollertemplateindex": "1", + "steamcontrollerconfigdetails": { + "1417465272": { + "controller_type": "controller_steamcontroller_gordon", + "enabled_branches": "default,previous,private", + "use_action_block": "true" + }, + "1761888411": { + "controller_type": "controller_xboxone", + "enabled_branches": "default,previous,private", + "use_action_block": "false" + } + }, + "steamconfigurator3rdpartynative": "65535", + "steam_china_only": { + "steam_china_enable_duration_control": "0" + } + }, + "depots": { + "229006": { + "config": { + "oslist": "windows" + }, + "depotfromapp": "228980", + "sharedinstall": "1" + }, + "481": { + "manifests": { + "public": { + "gid": "3183503801510301321", + "size": "1906055", + "download": "797632" + }, + "previous": { + "gid": "8382873932604653347", + "size": "1752776", + "download": "841424" + } + }, + "encryptedmanifests": { + "private": { + "gid": "89A09467D33499F8ED88480C22A2B962", + "size": "3F5CBBE518C2058886C5E37A62D1E6F1", + "download": "5A5D38347D011C6ACF52287D279FDBDA" + } + } + }, + "workshopdepot": "480", + "baselanguages": "", + "privatebranches": "1", + "branches": { + "public": { + "buildid": "3538192", + "timeupdated": "1549489971" + }, + "previous": { + "buildid": "316058", + "description": "SDK 1.30", + "timeupdated": "1503510482" + }, + "private": { + "buildid": "316281", + "pwdrequired": "1", + "timeupdated": "1506539230" + } + } + }, + "ufs": { + "sync_while_suspended": "1", + "quota": "4096", + "maxnumfiles": "10" + }, + "sysreqs": { + "windows": { + "supported": "1", + "cpu_min": "42", + "ram_min": "42" + } + }, + "_missing_token": false, + "_change_number": 25200962, + "_sha": "71055fab92d9008e56bcd86c66681062c8285bd1", + "_size": 3229 +} \ No newline at end of file diff --git a/generate_emu_config_old/output/480/steam_settings/branches.json b/generate_emu_config_old/output/480/steam_settings/branches.json new file mode 100644 index 0000000..baa1d1f --- /dev/null +++ b/generate_emu_config_old/output/480/steam_settings/branches.json @@ -0,0 +1,23 @@ +[ + { + "name": "public", + "description": "", + "protected": false, + "build_id": 3538192, + "time_updated": 1549489971 + }, + { + "name": "previous", + "description": "SDK 1.30", + "protected": false, + "build_id": 316058, + "time_updated": 1503510482 + }, + { + "name": "private", + "description": "", + "protected": true, + "build_id": 316281, + "time_updated": 1506539230 + } +] \ No newline at end of file diff --git a/generate_emu_config_old/output/480/steam_settings/configs.app.ini b/generate_emu_config_old/output/480/steam_settings/configs.app.ini new file mode 100644 index 0000000..d04b600 --- /dev/null +++ b/generate_emu_config_old/output/480/steam_settings/configs.app.ini @@ -0,0 +1,6 @@ +[app::dlcs] +# should the emu report all DLCs as unlocked, default=1 +unlock_all=0 +447130=ticket test DLC +110902=pieterw test DLC + diff --git a/generate_emu_config_old/output/480/steam_settings/controller/menu_controls.txt b/generate_emu_config_old/output/480/steam_settings/controller/menu_controls.txt new file mode 100644 index 0000000..2da1387 --- /dev/null +++ b/generate_emu_config_old/output/480/steam_settings/controller/menu_controls.txt @@ -0,0 +1,6 @@ +menu_select=A +menu_cancel=B +menu_up=DLJOYUP +menu_down=DLJOYDOWN +menu_right=DLJOYRIGHT +menu_left=DLJOYLEFT diff --git a/generate_emu_config_old/output/480/steam_settings/controller/ship_controls.txt b/generate_emu_config_old/output/480/steam_settings/controller/ship_controls.txt new file mode 100644 index 0000000..2255d05 --- /dev/null +++ b/generate_emu_config_old/output/480/steam_settings/controller/ship_controls.txt @@ -0,0 +1,3 @@ +pause_menu=START +fire_lasers=DRTRIGGER +analog_controls=LJOY=joystick_move diff --git a/generate_emu_config_old/output/480/steam_settings/depots.txt b/generate_emu_config_old/output/480/steam_settings/depots.txt new file mode 100644 index 0000000..71880ec --- /dev/null +++ b/generate_emu_config_old/output/480/steam_settings/depots.txt @@ -0,0 +1,2 @@ +481 +229006 diff --git a/generate_emu_config_old/output/480/steam_settings/steam_appid.txt b/generate_emu_config_old/output/480/steam_settings/steam_appid.txt new file mode 100644 index 0000000..7ad8022 --- /dev/null +++ b/generate_emu_config_old/output/480/steam_settings/steam_appid.txt @@ -0,0 +1 @@ +480 \ No newline at end of file diff --git a/generate_emu_config_old/output/stats.txt b/generate_emu_config_old/output/stats.txt new file mode 100644 index 0000000..dbe9667 --- /dev/null +++ b/generate_emu_config_old/output/stats.txt @@ -0,0 +1,256 @@ +game_win=int +kills_quarry=int +kills_hunter=int +ability_counter=int +ability_flash=int +ability_humiliate=int +ability_disguise=int +ability_reveal=int +game_win_admiral=int +game_win_assassin=int +game_win_brute=int +game_win_dodger=int +game_win_doxy=int +game_win_duchess=int +game_win_prince=int +game_win_tracker=int +vignette_eat=int +player_xp=int +date_last_win=int +date_last_play=int +ability_disguise_used=int +game_played=int +kills_quarry_killstreak=int +played_admiral_skin0=int +played_admiral_skin1=int +played_admiral_skin2=int +played_admiral_skin3=int +played_assassin_skin0=int +played_assassin_skin1=int +played_assassin_skin2=int +played_assassin_skin3=int +played_brute_skin0=int +played_brute_skin1=int +played_brute_skin2=int +played_brute_skin3=int +played_dodger_skin0=int +played_dodger_skin1=int +played_dodger_skin2=int +played_dodger_skin3=int +played_doxy_skin0=int +played_doxy_skin1=int +played_doxy_skin2=int +played_doxy_skin3=int +played_duchess_skin0=int +played_duchess_skin1=int +played_duchess_skin2=int +played_duchess_skin3=int +played_prince_skin0=int +played_prince_skin1=int +played_prince_skin2=int +played_prince_skin3=int +played_tracker_skin0=int +played_tracker_skin1=int +played_tracker_skin2=int +played_tracker_skin3=int +seconds_in_vignette=int +ability_selected_counter=int +ability_selected_disguise=int +ability_selected_flash=int +ability_selected_humiliate=int +ability_selected_reveal=int +kills_quarry_ability=int +kills_quarry_exposed=int +kills_quarry_vignette=int +total_favour=int +game_started=int +total_favour_admiral=int +total_favour_assassin=int +total_favour_brute=int +total_favour_dodger=int +total_favour_doxy=int +total_favour_duchess=int +total_favour_prince=int +total_favour_tracker=int +played_admiral_skin4=int +played_admiral_skin5=int +played_assassin_skin4=int +played_assassin_skin5=int +played_brute_skin4=int +played_brute_skin5=int +played_dodger_skin4=int +played_dodger_skin5=int +played_doxy_skin4=int +played_doxy_skin5=int +played_duchess_skin4=int +played_duchess_skin5=int +played_prince_skin4=int +played_prince_skin5=int +played_tracker_skin4=int +played_tracker_skin5=int +game_win_custom=int +kills_quarry_custom=int +kills_hunter_custom=int +ability_counter_custom=int +ability_flash_custom=int +ability_humiliate_custom=int +ability_disguise_custom=int +ability_reveal_custom=int +vignette_eat_custom=int +ability_disguise_used_custom=int +game_played_custom=int +kills_quarry_killstreak_custom=int +seconds_in_vignette_custom=int +kills_quarry_ability_custom=int +kills_quarry_exposed_custom=int +kills_quarry_vignette_custom=int +total_favour_custom=int +game_started_custom=int +perk_selected_incognito=int +perk_selected_scavenger=int +perk_selected_gambler=int +perk_selected_chameleon=int +perk_selected_resourceful=int +perk_selected_none=int +game_played_dm=int +game_played_dm_custom=int +ability_disrupt=int +ability_selected_disrupt=int +ability_subvert=int +ability_selected_subvert=int +ability_disrupt_custom=int +ability_subvert_custom=int +total_favour_soothsayer=int +total_favour_moujik=int +played_soothsayer_skin0=int +played_soothsayer_skin1=int +played_soothsayer_skin2=int +played_soothsayer_skin3=int +played_moujik_skin0=int +played_moujik_skin1=int +played_moujik_skin2=int +played_moujik_skin3=int +game_win_soothsayer=int +game_win_moujik=int +selected_admiral_taunt0=int +selected_admiral_taunt1=int +selected_admiral_taunt2=int +selected_admiral_taunt3=int +selected_assassin_taunt0=int +selected_assassin_taunt1=int +selected_assassin_taunt2=int +selected_assassin_taunt3=int +selected_brute_taunt0=int +selected_brute_taunt1=int +selected_brute_taunt2=int +selected_brute_taunt3=int +selected_dodger_taunt0=int +selected_dodger_taunt1=int +selected_dodger_taunt2=int +selected_dodger_taunt3=int +selected_doxy_taunt0=int +selected_doxy_taunt1=int +selected_doxy_taunt2=int +selected_doxy_taunt3=int +selected_duchess_taunt0=int +selected_duchess_taunt1=int +selected_duchess_taunt2=int +selected_duchess_taunt3=int +selected_prince_taunt0=int +selected_prince_taunt1=int +selected_prince_taunt2=int +selected_prince_taunt3=int +selected_tracker_taunt0=int +selected_tracker_taunt1=int +selected_tracker_taunt2=int +selected_tracker_taunt3=int +selected_soothsayer_taunt0=int +selected_soothsayer_taunt1=int +selected_soothsayer_taunt2=int +selected_moujik_taunt0=int +selected_moujik_taunt1=int +selected_moujik_taunt2=int +selected_hunter_slap1=int +selected_hunter_slap2=int +game_played_el=int +game_played_el_custom=int +game_win_privateer=int +total_favour_privateer=int +played_privateer_skin0=int +played_privateer_skin1=int +played_privateer_skin2=int +played_privateer_skin3=int +selected_privateer_taunt0=int +selected_privateer_taunt1=int +selected_privateer_taunt2=int +game_win_saurianhunter=int +total_favour_saurianhunter=int +played_saurianhunter_skin0=int +played_saurianhunter_skin1=int +played_saurianhunter_skin2=int +played_saurianhunter_skin3=int +selected_saurianhunter_taunt0=int +selected_saurianhunter_taunt1=int +selected_saurianhunter_taunt2=int +ability_selected_piebomb=int +ability_selected_piebomb_custom=int +piebomb_kills=int +piebomb_kills_custom=int +piebomb_stuns=int +piebomb_stuns_custom=int +perk_selected_determined=int +perk_selected_nimble=int +game_win_gentleman=int +total_favour_gentleman=int +played_gentleman_skin0=int +played_gentleman_skin1=int +played_gentleman_skin2=int +played_gentleman_skin3=int +selected_gentleman_taunt0=int +selected_gentleman_taunt1=int +selected_gentleman_taunt2=int +game_win_blackwidow=int +total_favour_blackwidow=int +played_blackwidow_skin0=int +played_blackwidow_skin1=int +played_blackwidow_skin2=int +played_blackwidow_skin3=int +selected_blackwidow_taunt0=int +selected_blackwidow_taunt1=int +selected_blackwidow_taunt2=int +game_win_gokudo=int +total_favour_gokudo=int +played_gokudo_skin0=int +played_gokudo_skin1=int +played_gokudo_skin2=int +played_gokudo_skin3=int +selected_gokudo_taunt0=int +selected_gokudo_taunt1=int +selected_gokudo_taunt2=int +game_win_adventurer=int +total_favour_adventurer=int +played_adventurer_skin0=int +played_adventurer_skin1=int +played_adventurer_skin2=int +played_adventurer_skin3=int +selected_adventurer_taunt0=int +selected_adventurer_taunt1=int +selected_adventurer_taunt2=int +game_win_perk_none=int +game_win_perk_incognito=int +game_win_perk_scavenger=int +game_win_perk_gambler=int +game_win_perk_chameleon=int +game_win_perk_resourceful=int +game_win_perk_determined=int +game_win_perk_nimble=int +game_win_hunt=int +game_win_deathmatch=int +game_win_elimination=int +game_win_lvl_music_hall=int +game_win_lvl_museum=int +game_win_lvl_shanty_town=int +game_win_lvl_backstage=int +game_win_lvl_chrono_capacitor=int +game_win_lvl_library=int +game_win_lvl_arboretum=int \ No newline at end of file diff --git a/generate_emu_config_old/package_linux.sh b/generate_emu_config_old/package_linux.sh new file mode 100644 index 0000000..8433dd8 --- /dev/null +++ b/generate_emu_config_old/package_linux.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + + +if [ "$(id -u)" -ne 0 ]; then + echo "Please run as root" >&2 + exit 1 +fi + +build_dir="bin/linux" +out_dir="bin/package/linux" +script_dir=$( cd -- "$( dirname -- "${0}" )" &> /dev/null && pwd ) + +[[ -d "$script_dir/$build_dir" ]] || { + echo "[X] build folder wasn't found" >&2 + exit 1 +} + +apt update || exit 1 +apt install tar -y || exit 1 + +mkdir -p "$script_dir/$out_dir" + +archive_file="$script_dir/$out_dir/generate_emu_config-linux.tar.bz2" +[[ -f "$archive_file" ]] && rm -f "$archive_file" + +pushd "$script_dir/$build_dir" +tar -c -j -vf "$archive_file" $(ls -d */) +popd diff --git a/generate_emu_config_old/package_win.bat b/generate_emu_config_old/package_win.bat new file mode 100644 index 0000000..9c95bfe --- /dev/null +++ b/generate_emu_config_old/package_win.bat @@ -0,0 +1,52 @@ +@echo off +setlocal EnableDelayedExpansion +cd /d "%~dp0" + +set /a "MAX_THREADS=2" +if defined NUMBER_OF_PROCESSORS ( + :: use 70% + set /a "MAX_THREADS=%NUMBER_OF_PROCESSORS% * 70 / 100" + if %MAX_THREADS% lss 1 ( + set /a "MAX_THREADS=1" + ) +) + +set "ROOT=%cd%" +set "BUILD_DIR=%ROOT%\bin\win" +set "OUT_DIR=%ROOT%\bin\package\win" + +set /a "PKG_EXE_MEM_PERCENT=90" +set /a "PKG_EXE_DICT_SIZE_MB=384" +set "PKG_EXE=..\..\third-party\deps\win\7za\7za.exe" +if not exist "%PKG_EXE%" ( + 1>&2 echo:packager wasn't found + goto :end_script_with_err +) + +if not exist "%BUILD_DIR%" ( + 1>&2 echo:build folder wasn't found + goto :end_script_with_err +) + +if not exist "%OUT_DIR%" ( + mkdir "%OUT_DIR%" +) + +set "ACHIVE_FILE=%OUT_DIR%\generate_emu_config-win.7z" +if exist "%ACHIVE_FILE%" ( + del /f /q "%ACHIVE_FILE%" +) + +call "%PKG_EXE%" a "%ACHIVE_FILE%" "%BUILD_DIR%\*" -t7z -slp -ssw -mx -myx -mmemuse=p%PKG_EXE_MEM_PERCENT% -ms=on -mqs=off -mf=on -mhc+ -mhe- -m0=LZMA2:d=%PKG_EXE_DICT_SIZE_MB%m -mmt=%MAX_THREADS% -mmtf+ -mtm- -mtc- -mta- -mtr+ || ( + goto :end_script_with_err +) + +goto :end_script + +:end_script + endlocal + exit /b 0 + +:end_script_with_err + endlocal + exit /b 1 diff --git a/generate_emu_config_old/rebuild_linux.sh b/generate_emu_config_old/rebuild_linux.sh new file mode 100644 index 0000000..e13b6a9 --- /dev/null +++ b/generate_emu_config_old/rebuild_linux.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + + +venv=".env-linux" +out_dir="bin/linux" +build_temp_dir="bin/tmp/linux" + +[[ -d "$out_dir" ]] && rm -r -f "$out_dir" +mkdir -p "$out_dir" + +[[ -d "$build_temp_dir" ]] && rm -r -f "$build_temp_dir" + +rm -f *.spec + +chmod 777 "./$venv/bin/activate" +source "./$venv/bin/activate" + +echo building generate_emu_config... +pyinstaller "generate_emu_config.py" --distpath "$out_dir" -y --clean --onedir --name "generate_emu_config" --noupx --console -i "NONE" --collect-submodules "steam" --workpath "$build_temp_dir" --specpath "$build_temp_dir" || exit 1 + +echo building parse_controller_vdf... +pyinstaller "controller_config_generator/parse_controller_vdf.py" --distpath "$out_dir" -y --clean --onedir --name "parse_controller_vdf" --noupx --console -i "NONE" --workpath "$build_temp_dir" --specpath "$build_temp_dir" || exit 1 + +echo building parse_achievements_schema... +pyinstaller "stats_schema_achievement_gen/achievements_gen.py" --distpath "$out_dir" -y --clean --onedir --name "parse_achievements_schema" --noupx --console -i "NONE" --workpath "$build_temp_dir" --specpath "$build_temp_dir" || exit 1 + +cp -f "steam_default_icon_locked.jpg" "$out_dir/generate_emu_config" +cp -f "steam_default_icon_unlocked.jpg" "$out_dir/generate_emu_config" +cp -f "README.md" "$out_dir/generate_emu_config" +echo "Check the README" > "$out_dir/generate_emu_config/my_login.EXAMPLE.txt" +echo "Check the README" > "$out_dir/generate_emu_config/top_owners_ids.EXAMPLE.txt" +echo "You can use a website like: https://steamladder.com/games/" >> "$out_dir/generate_emu_config/top_owners_ids.EXAMPLE.txt" + +echo; +echo ============= +echo Built inside: "$out_dir/" + +[[ -d "$build_temp_dir" ]] && rm -r -f "$build_temp_dir" + +deactivate diff --git a/generate_emu_config_old/rebuild_win.bat b/generate_emu_config_old/rebuild_win.bat new file mode 100644 index 0000000..e63a025 --- /dev/null +++ b/generate_emu_config_old/rebuild_win.bat @@ -0,0 +1,71 @@ +@echo off +setlocal EnableDelayedExpansion +cd /d "%~dp0" + +set "ROOT=%cd%" +set "VENV=%ROOT%\.env-win" +set "OUT_DIR=%ROOT%\bin\win" +set "BUILD_TEMP_DIR=%ROOT%\bin\tmp\win" +set "ICON_FILE=%ROOT%\icon\Froyoshark-Enkel-Steam.ico" + +set /a "LAST_ERR_CODE=0" + +set "SIGNER_TOOL=..\..\third-party\build\win\cert\sign_helper.bat" +if not exist "%SIGNER_TOOL%" ( + 1>&2 echo:signing tool wasn't found + set /a "LAST_ERR_CODE=1" + goto :end_script +) + +if exist "%OUT_DIR%" ( + rmdir /s /q "%OUT_DIR%" +) +mkdir "%OUT_DIR%" + +if exist "%BUILD_TEMP_DIR%" ( + rmdir /s /q "%BUILD_TEMP_DIR%" +) + +call "%VENV%\Scripts\activate.bat" + +echo:building generate_emu_config... +pyinstaller "generate_emu_config.py" --distpath "%OUT_DIR%" -y --clean --onedir --name "generate_emu_config" --noupx --console -i "%ICON_FILE%" --collect-submodules "steam" --workpath "%BUILD_TEMP_DIR%" --specpath "%BUILD_TEMP_DIR%" || ( + set /a "LAST_ERR_CODE=1" + goto :end_script +) +call "%SIGNER_TOOL%" "%OUT_DIR%\generate_emu_config\generate_emu_config.exe" + +echo:building parse_controller_vdf... +pyinstaller "controller_config_generator\parse_controller_vdf.py" --distpath "%OUT_DIR%" -y --clean --onedir --name "parse_controller_vdf" --noupx --console -i "NONE" --workpath "%BUILD_TEMP_DIR%" --specpath "%BUILD_TEMP_DIR%" || ( + set /a "LAST_ERR_CODE=1" + goto :end_script +) +call "%SIGNER_TOOL%" "%OUT_DIR%\parse_controller_vdf\parse_controller_vdf.exe" + +echo:building parse_achievements_schema... +pyinstaller "stats_schema_achievement_gen\achievements_gen.py" --distpath "%OUT_DIR%" -y --clean --onedir --name "parse_achievements_schema" --noupx --console -i "NONE" --workpath "%BUILD_TEMP_DIR%" --specpath "%BUILD_TEMP_DIR%" || ( + set /a "LAST_ERR_CODE=1" + goto :end_script +) +call "%SIGNER_TOOL%" "%OUT_DIR%\parse_achievements_schema\parse_achievements_schema.exe" + +copy /y "steam_default_icon_locked.jpg" "%OUT_DIR%\generate_emu_config\" +copy /y "steam_default_icon_unlocked.jpg" "%OUT_DIR%\generate_emu_config\" +copy /y "README.md" "%OUT_DIR%\generate_emu_config\" +echo Check the README>> "%OUT_DIR%\generate_emu_config\my_login.EXAMPLE.txt" +echo Check the README>> "%OUT_DIR%\generate_emu_config\top_owners_ids.EXAMPLE.txt" +echo You can use a website like: https://steamladder.com/games/>> "%OUT_DIR%\generate_emu_config\top_owners_ids.EXAMPLE.txt" + +echo: +echo:============= +echo:Built inside: "%OUT_DIR%\" + +goto :end_script + +:end_script + if exist "%BUILD_TEMP_DIR%" ( + rmdir /s /q "%BUILD_TEMP_DIR%" + ) + + endlocal + exit /b %LAST_ERR_CODE% diff --git a/generate_emu_config_old/recreate_venv_linux.sh b/generate_emu_config_old/recreate_venv_linux.sh new file mode 100644 index 0000000..1be9219 --- /dev/null +++ b/generate_emu_config_old/recreate_venv_linux.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + + +if [ "$(id -u)" -ne 0 ]; then + echo "Please run as root" >&2 + exit 1 +fi + +python_package="python3.12" +venv=".env-linux" +reqs_file="requirements.txt" +script_dir=$( cd -- "$( dirname -- "${0}" )" &> /dev/null && pwd ) + +apt update -y || exit 1 +apt install software-properties-common -y +add-apt-repository ppa:deadsnakes/ppa -y +apt update -y || exit 1 +apt install "$python_package" -y || exit 1 +apt install "$python_package-dev" -y || exit 1 +apt install "$python_package-venv" -y || exit 1 +apt install python3-dev -y || exit 1 + +[[ -d "$script_dir/$venv" ]] && rm -r -f "$script_dir/$venv" + +$python_package -m venv "$script_dir/$venv" || exit 1 +sleep 1 + +chmod 777 "$script_dir/$venv/bin/activate" +source "$script_dir/$venv/bin/activate" + +pip install -r "$script_dir/$reqs_file" +exit_code=$? + +deactivate +exit $exit_code diff --git a/generate_emu_config_old/recreate_venv_win.bat b/generate_emu_config_old/recreate_venv_win.bat new file mode 100644 index 0000000..9b93127 --- /dev/null +++ b/generate_emu_config_old/recreate_venv_win.bat @@ -0,0 +1,29 @@ +@echo off +cd /d "%~dp0" + +set "ROOT=%cd%" +set "VENV=%ROOT%\.env-win" +set "REQS_FILE=%ROOT%\requirements.txt" + +set /a "LAST_ERR_CODE=0" + +if exist "%VENV%" ( + rmdir /s /q "%VENV%" +) + +python -m venv "%VENV%" || ( + set /a "LAST_ERR_CODE=1" + goto :end_script +) + +timeout /t 1 /nobreak + +call "%VENV%\Scripts\activate.bat" +pip install -r "%REQS_FILE%" +set /a "LAST_ERR_CODE=%ERRORLEVEL%" +call "%VENV%\Scripts\deactivate.bat" + +goto :end_script + +:end_script + exit /b %LAST_ERR_CODE% diff --git a/generate_emu_config_old/requirements.txt b/generate_emu_config_old/requirements.txt new file mode 100644 index 0000000..eb7e1ae --- /dev/null +++ b/generate_emu_config_old/requirements.txt @@ -0,0 +1,4 @@ +steam[client] @ git+https://github.com/detiam/steam_websocket@b8239912e6a190f490aede529c08b5049096bdc8 +pyinstaller +requests +certifi diff --git a/generate_emu_config_old/stats_schema_achievement_gen/achievements_gen.py b/generate_emu_config_old/stats_schema_achievement_gen/achievements_gen.py new file mode 100644 index 0000000..4e4e7fe --- /dev/null +++ b/generate_emu_config_old/stats_schema_achievement_gen/achievements_gen.py @@ -0,0 +1,164 @@ +import vdf +import sys +import os +import json +import copy +import traceback + + +STAT_TYPE_INT = '1' +STAT_TYPE_FLOAT = '2' +STAT_TYPE_AVGRATE = '3' +STAT_TYPE_BITS = '4' + +def generate_stats_achievements( + schema, config_directory + ) -> tuple[list[dict], list[dict], bool, bool]: + schema = vdf.binary_loads(schema) + # print(schema) + achievements_out : list[dict] = [] + stats_out : list[dict] = [] + + for appid in schema: + sch = schema[appid] + stat_info = sch['stats'] + for s in stat_info: + stat = stat_info[s] + if stat['type'] == STAT_TYPE_BITS: + achs = stat['bits'] + for ach_num in achs: + out = {} + ach = achs[ach_num] + out['hidden'] = 0 + for x in ach['display']: + value = ach['display'][x] + if f'{x}'.lower() == 'name': + x = 'displayName' + elif f'{x}'.lower() == 'desc': + x = 'description' + elif x == 'Hidden' or f'{x}'.lower() == 'hidden': + x = 'hidden' + try: + value = int(value) + except Exception as e: + pass + out[x] = value + out['name'] = ach['name'] + if 'progress' in ach: + out['progress'] = ach['progress'] + achievements_out += [out] + else: + out = {} + out['default'] = 0 + out['name'] = stat['name'] + if 'min' in stat: + out['min'] = stat['min'] + if stat['type'] == STAT_TYPE_INT: + out['type'] = 'int' + elif stat['type'] == STAT_TYPE_FLOAT: + out['type'] = 'float' + elif stat['type'] == STAT_TYPE_AVGRATE: + out['type'] = 'avgrate' + if 'Default' in stat: + out['default'] = stat['Default'] + elif 'default' in stat: + out['default'] = stat['default'] + + stats_out += [out] + #print(stat_info[s]) + + copy_default_unlocked_img = False + copy_default_locked_img = False + output_ach = copy.deepcopy(achievements_out) + for out_ach in output_ach: + icon = out_ach.get("icon", None) + if icon: + out_ach["icon"] = f"img/{icon}" + else: + out_ach["icon"] = r'img/steam_default_icon_unlocked.jpg' + copy_default_unlocked_img = True + + icon_gray = out_ach.get("icon_gray", None) + if icon_gray: + out_ach["icon_gray"] = f"img/{icon_gray}" + else: + out_ach["icon_gray"] = r'img/steam_default_icon_locked.jpg' + copy_default_locked_img = True + + icongray = out_ach.get("icongray", None) + if icongray: + out_ach["icongray"] = f"{icongray}" + + output_stats : list[str] = [] + for s in stats_out: + default_num = 0 + if f"{s['type']}".lower() == 'int': + try: + default_num = int(s['default']) + except ValueError: + try: + default_num = int(float(s['default'])) + except ValueError: + # we set this to min if someone is failed to set to a fucking int value. and after this and still throwing error I gonna throw the dev out of the windows whoever misstyped that!!! + # fixes 282800 | STAT_OJ46_C12 (<---THIS ONE) + if 'min' in s: + default_num = int(s['min']) + else: + raise ValueError('min not exist in (s) and no way to get the data. please report with the appid') + else: + default_num = float(s['default']) + output_stats.append(f"{s['name']}={s['type']}={default_num}\n") + + # print(output_ach) + # print(output_stats) + + if not os.path.exists(config_directory): + os.makedirs(config_directory) + + if output_ach: + with open(os.path.join(config_directory, "achievements.json"), 'wt', encoding='utf-8') as f: + json.dump(output_ach, f, indent=2) + + if output_stats: + with open(os.path.join(config_directory, "stats.txt"), 'wt', encoding='utf-8') as f: + f.writelines(output_stats) + + return (achievements_out, stats_out, + copy_default_unlocked_img, copy_default_locked_img) + +def help(): + exe_name = os.path.basename(sys.argv[0]) + print(f"\nUsage: {exe_name} UserGameStatsSchema_480.bin [UserGameStatsSchema_2370.bin] ... ") + print(f" Example: {exe_name} UserGameStatsSchema_480.bin") + print(f" Example: {exe_name} UserGameStatsSchema_480.bin UserGameStatsSchema_2370.bin") + print("\nAt least 1 .bin file must be provided\n") + +if __name__ == '__main__': + if len(sys.argv) < 2: + help() + sys.exit(1) + + for bin_file in sys.argv[1:]: + try: + print(f"parsing schema file '{bin_file}'") + schema: bytes = b'' + with open(bin_file, 'rb') as f: + schema = f.read() + if schema: + filename = os.path.basename(bin_file) + outdir = os.path.join(f"{filename}_output", "steam_settings") + print(f"output dir: '{outdir}'") + generate_stats_achievements(schema, outdir) + else: + print("[X] couldn't load file", file=sys.stderr) + + print('**********************************\n') + except Exception as e: + print("Unexpected error:") + print(e) + print("-----------------------") + for line in traceback.format_exception(e): + print(line) + print('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n') + + sys.exit(0) diff --git a/generate_emu_config_old/stats_schema_achievement_gen/vdf/__init__.py b/generate_emu_config_old/stats_schema_achievement_gen/vdf/__init__.py new file mode 100644 index 0000000..6b47213 --- /dev/null +++ b/generate_emu_config_old/stats_schema_achievement_gen/vdf/__init__.py @@ -0,0 +1,521 @@ +""" +Module for deserializing/serializing to and from VDF +""" +__version__ = "3.4" +__author__ = "Rossen Georgiev" + +import re +import sys +import struct +from binascii import crc32 +from io import BytesIO +from io import StringIO as unicodeIO + +try: + from collections.abc import Mapping +except: + from collections import Mapping + +from vdf.vdict import VDFDict + +# Py2 & Py3 compatibility +if sys.version_info[0] >= 3: + string_type = str + int_type = int + BOMS = '\ufffe\ufeff' + + def strip_bom(line): + return line.lstrip(BOMS) +else: + from StringIO import StringIO as strIO + string_type = basestring + int_type = long + BOMS = '\xef\xbb\xbf\xff\xfe\xfe\xff' + BOMS_UNICODE = '\\ufffe\\ufeff'.decode('unicode-escape') + + def strip_bom(line): + return line.lstrip(BOMS if isinstance(line, str) else BOMS_UNICODE) + +# string escaping +_unescape_char_map = { + r"\n": "\n", + r"\t": "\t", + r"\v": "\v", + r"\b": "\b", + r"\r": "\r", + r"\f": "\f", + r"\a": "\a", + r"\\": "\\", + r"\?": "?", + r"\"": "\"", + r"\'": "\'", +} +_escape_char_map = {v: k for k, v in _unescape_char_map.items()} + +def _re_escape_match(m): + return _escape_char_map[m.group()] + +def _re_unescape_match(m): + return _unescape_char_map[m.group()] + +def _escape(text): + return re.sub(r"[\n\t\v\b\r\f\a\\\?\"']", _re_escape_match, text) + +def _unescape(text): + return re.sub(r"(\\n|\\t|\\v|\\b|\\r|\\f|\\a|\\\\|\\\?|\\\"|\\')", _re_unescape_match, text) + +# parsing and dumping for KV1 +def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): + """ + Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a VDF) + to a Python object. + + ``mapper`` specifies the Python object used after deserializetion. ``dict` is + used by default. Alternatively, ``collections.OrderedDict`` can be used if you + wish to preserve key order. Or any object that acts like a ``dict``. + + ``merge_duplicate_keys`` when ``True`` will merge multiple KeyValue lists with the + same key into one instead of overwriting. You can se this to ``False`` if you are + using ``VDFDict`` and need to preserve the duplicates. + """ + if not issubclass(mapper, Mapping): + raise TypeError("Expected mapper to be subclass of dict, got %s" % type(mapper)) + if not hasattr(fp, 'readline'): + raise TypeError("Expected fp to be a file-like object supporting line iteration") + + stack = [mapper()] + expect_bracket = False + + re_keyvalue = re.compile(r'^("(?P(?:\\.|[^\\"])*)"|(?P#?[a-z0-9\-\_\\\?$%<>]+))' + r'([ \t]*(' + r'"(?P(?:\\.|[^\\"])*)(?P")?' + r'|(?P(?:(? ])+)' + r'|(?P{[ \t]*)(?P})?' + r'))?', + flags=re.I) + + for lineno, line in enumerate(fp, 1): + if lineno == 1: + line = strip_bom(line) + + line = line.lstrip() + + # skip empty and comment lines + if line == "" or line[0] == '/': + continue + + # one level deeper + if line[0] == "{": + expect_bracket = False + continue + + if expect_bracket: + raise SyntaxError("vdf.parse: expected openning bracket", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 1, line)) + + # one level back + if line[0] == "}": + if len(stack) > 1: + stack.pop() + continue + + raise SyntaxError("vdf.parse: one too many closing parenthasis", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + # parse keyvalue pairs + while True: + match = re_keyvalue.match(line) + + if not match: + try: + line += next(fp) + continue + except StopIteration: + raise SyntaxError("vdf.parse: unexpected EOF (open key quote?)", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + key = match.group('key') if match.group('qkey') is None else match.group('qkey') + val = match.group('qval') + if val is None: + val = match.group('val') + if val is not None: + val = val.rstrip() + if val == "": + val = None + + if escaped: + key = _unescape(key) + + # we have a key with value in parenthesis, so we make a new dict obj (level deeper) + if val is None: + if merge_duplicate_keys and key in stack[-1]: + _m = stack[-1][key] + # we've descended a level deeper, if value is str, we have to overwrite it to mapper + if not isinstance(_m, mapper): + _m = stack[-1][key] = mapper() + else: + _m = mapper() + stack[-1][key] = _m + + if match.group('eblock') is None: + # only expect a bracket if it's not already closed or on the same line + stack.append(_m) + if match.group('sblock') is None: + expect_bracket = True + + # we've matched a simple keyvalue pair, map it to the last dict obj in the stack + else: + # if the value is line consume one more line and try to match again, + # until we get the KeyValue pair + if match.group('vq_end') is None and match.group('qval') is not None: + try: + line += next(fp) + continue + except StopIteration: + raise SyntaxError("vdf.parse: unexpected EOF (open quote for value?)", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + stack[-1][key] = _unescape(val) if escaped else val + + # exit the loop + break + + if len(stack) != 1: + raise SyntaxError("vdf.parse: unclosed parenthasis or quotes (EOF)", + (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + + return stack.pop() + + +def loads(s, **kwargs): + """ + Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON + document) to a Python object. + """ + if not isinstance(s, string_type): + raise TypeError("Expected s to be a str, got %s" % type(s)) + + try: + fp = unicodeIO(s) + except TypeError: + fp = strIO(s) + + return parse(fp, **kwargs) + + +def load(fp, **kwargs): + """ + Deserialize ``fp`` (a ``.readline()``-supporting file-like object containing + a JSON document) to a Python object. + """ + return parse(fp, **kwargs) + + +def dumps(obj, pretty=False, escaped=True): + """ + Serialize ``obj`` to a VDF formatted ``str``. + """ + if not isinstance(obj, Mapping): + raise TypeError("Expected data to be an instance of``dict``") + if not isinstance(pretty, bool): + raise TypeError("Expected pretty to be of type bool") + if not isinstance(escaped, bool): + raise TypeError("Expected escaped to be of type bool") + + return ''.join(_dump_gen(obj, pretty, escaped)) + + +def dump(obj, fp, pretty=False, escaped=True): + """ + Serialize ``obj`` as a VDF formatted stream to ``fp`` (a + ``.write()``-supporting file-like object). + """ + if not isinstance(obj, Mapping): + raise TypeError("Expected data to be an instance of``dict``") + if not hasattr(fp, 'write'): + raise TypeError("Expected fp to have write() method") + if not isinstance(pretty, bool): + raise TypeError("Expected pretty to be of type bool") + if not isinstance(escaped, bool): + raise TypeError("Expected escaped to be of type bool") + + for chunk in _dump_gen(obj, pretty, escaped): + fp.write(chunk) + + +def _dump_gen(data, pretty=False, escaped=True, level=0): + indent = "\t" + line_indent = "" + + if pretty: + line_indent = indent * level + + for key, value in data.items(): + if escaped and isinstance(key, string_type): + key = _escape(key) + + if isinstance(value, Mapping): + yield '%s"%s"\n%s{\n' % (line_indent, key, line_indent) + for chunk in _dump_gen(value, pretty, escaped, level+1): + yield chunk + yield "%s}\n" % line_indent + else: + if escaped and isinstance(value, string_type): + value = _escape(value) + + yield '%s"%s" "%s"\n' % (line_indent, key, value) + + +# binary VDF +class BASE_INT(int_type): + def __repr__(self): + return "%s(%d)" % (self.__class__.__name__, self) + +class UINT_64(BASE_INT): + pass + +class INT_64(BASE_INT): + pass + +class POINTER(BASE_INT): + pass + +class COLOR(BASE_INT): + pass + +BIN_NONE = b'\x00' +BIN_STRING = b'\x01' +BIN_INT32 = b'\x02' +BIN_FLOAT32 = b'\x03' +BIN_POINTER = b'\x04' +BIN_WIDESTRING = b'\x05' +BIN_COLOR = b'\x06' +BIN_UINT64 = b'\x07' +BIN_END = b'\x08' +BIN_INT64 = b'\x0A' +BIN_END_ALT = b'\x0B' + +def binary_loads(b, mapper=dict, merge_duplicate_keys=True, alt_format=False, raise_on_remaining=True): + """ + Deserialize ``b`` (``bytes`` containing a VDF in "binary form") + to a Python object. + + ``mapper`` specifies the Python object used after deserializetion. ``dict` is + used by default. Alternatively, ``collections.OrderedDict`` can be used if you + wish to preserve key order. Or any object that acts like a ``dict``. + + ``merge_duplicate_keys`` when ``True`` will merge multiple KeyValue lists with the + same key into one instead of overwriting. You can se this to ``False`` if you are + using ``VDFDict`` and need to preserve the duplicates. + """ + if not isinstance(b, bytes): + raise TypeError("Expected s to be bytes, got %s" % type(b)) + + return binary_load(BytesIO(b), mapper, merge_duplicate_keys, alt_format, raise_on_remaining) + +def binary_load(fp, mapper=dict, merge_duplicate_keys=True, alt_format=False, raise_on_remaining=False): + """ + Deserialize ``fp`` (a ``.read()``-supporting file-like object containing + binary VDF) to a Python object. + + ``mapper`` specifies the Python object used after deserializetion. ``dict` is + used by default. Alternatively, ``collections.OrderedDict`` can be used if you + wish to preserve key order. Or any object that acts like a ``dict``. + + ``merge_duplicate_keys`` when ``True`` will merge multiple KeyValue lists with the + same key into one instead of overwriting. You can se this to ``False`` if you are + using ``VDFDict`` and need to preserve the duplicates. + """ + if not hasattr(fp, 'read') or not hasattr(fp, 'tell') or not hasattr(fp, 'seek'): + raise TypeError("Expected fp to be a file-like object with tell()/seek() and read() returning bytes") + if not issubclass(mapper, Mapping): + raise TypeError("Expected mapper to be subclass of dict, got %s" % type(mapper)) + + # helpers + int32 = struct.Struct(' 1: + stack.pop() + continue + break + + key = read_string(fp) + + if t == BIN_NONE: + if merge_duplicate_keys and key in stack[-1]: + _m = stack[-1][key] + else: + _m = mapper() + stack[-1][key] = _m + stack.append(_m) + elif t == BIN_STRING: + stack[-1][key] = read_string(fp) + elif t == BIN_WIDESTRING: + stack[-1][key] = read_string(fp, wide=True) + elif t in (BIN_INT32, BIN_POINTER, BIN_COLOR): + val = int32.unpack(fp.read(int32.size))[0] + + if t == BIN_POINTER: + val = POINTER(val) + elif t == BIN_COLOR: + val = COLOR(val) + + stack[-1][key] = val + elif t == BIN_UINT64: + stack[-1][key] = UINT_64(uint64.unpack(fp.read(int64.size))[0]) + elif t == BIN_INT64: + stack[-1][key] = INT_64(int64.unpack(fp.read(int64.size))[0]) + elif t == BIN_FLOAT32: + stack[-1][key] = float32.unpack(fp.read(float32.size))[0] + else: + raise SyntaxError("Unknown data type at offset %d: %s" % (fp.tell() - 1, repr(t))) + + if len(stack) != 1: + raise SyntaxError("Reached EOF, but Binary VDF is incomplete") + if raise_on_remaining and fp.read(1) != b'': + fp.seek(-1, 1) + raise SyntaxError("Binary VDF ended at offset %d, but there is more data remaining" % (fp.tell() - 1)) + + return stack.pop() + +def binary_dumps(obj, alt_format=False): + """ + Serialize ``obj`` to a binary VDF formatted ``bytes``. + """ + buf = BytesIO() + binary_dump(obj, buf, alt_format) + return buf.getvalue() + +def binary_dump(obj, fp, alt_format=False): + """ + Serialize ``obj`` to a binary VDF formatted ``bytes`` and write it to ``fp`` filelike object + """ + if not isinstance(obj, Mapping): + raise TypeError("Expected obj to be type of Mapping") + if not hasattr(fp, 'write'): + raise TypeError("Expected fp to have write() method") + + for chunk in _binary_dump_gen(obj, alt_format=alt_format): + fp.write(chunk) + +def _binary_dump_gen(obj, level=0, alt_format=False): + if level == 0 and len(obj) == 0: + return + + int32 = struct.Struct('= 3: + _iter_values = 'values' + _range = range + _string_type = str + import collections.abc as _c + class _kView(_c.KeysView): + def __iter__(self): + return self._mapping.iterkeys() + class _vView(_c.ValuesView): + def __iter__(self): + return self._mapping.itervalues() + class _iView(_c.ItemsView): + def __iter__(self): + return self._mapping.iteritems() +else: + _iter_values = 'itervalues' + _range = xrange + _string_type = basestring + _kView = lambda x: list(x.iterkeys()) + _vView = lambda x: list(x.itervalues()) + _iView = lambda x: list(x.iteritems()) + + +class VDFDict(dict): + def __init__(self, data=None): + """ + This is a dictionary that supports duplicate keys and preserves insert order + + ``data`` can be a ``dict``, or a sequence of key-value tuples. (e.g. ``[('key', 'value'),..]``) + The only supported type for key is str. + + Get/set duplicates is done by tuples ``(index, key)``, where index is the duplicate index + for the specified key. (e.g. ``(0, 'key')``, ``(1, 'key')``...) + + When the ``key`` is ``str``, instead of tuple, set will create a duplicate and get will look up ``(0, key)`` + """ + self.__omap = [] + self.__kcount = Counter() + + if data is not None: + if not isinstance(data, (list, dict)): + raise ValueError("Expected data to be list of pairs or dict, got %s" % type(data)) + self.update(data) + + def __repr__(self): + out = "%s(" % self.__class__.__name__ + out += "%s)" % repr(list(self.iteritems())) + return out + + def __len__(self): + return len(self.__omap) + + def _verify_key_tuple(self, key): + if len(key) != 2: + raise ValueError("Expected key tuple length to be 2, got %d" % len(key)) + if not isinstance(key[0], int): + raise TypeError("Key index should be an int") + if not isinstance(key[1], _string_type): + raise TypeError("Key value should be a str") + + def _normalize_key(self, key): + if isinstance(key, _string_type): + key = (0, key) + elif isinstance(key, tuple): + self._verify_key_tuple(key) + else: + raise TypeError("Expected key to be a str or tuple, got %s" % type(key)) + return key + + def __setitem__(self, key, value): + if isinstance(key, _string_type): + key = (self.__kcount[key], key) + self.__omap.append(key) + elif isinstance(key, tuple): + self._verify_key_tuple(key) + if key not in self: + raise KeyError("%s doesn't exist" % repr(key)) + else: + raise TypeError("Expected either a str or tuple for key") + super(VDFDict, self).__setitem__(key, value) + self.__kcount[key[1]] += 1 + + def __getitem__(self, key): + return super(VDFDict, self).__getitem__(self._normalize_key(key)) + + def __delitem__(self, key): + key = self._normalize_key(key) + result = super(VDFDict, self).__delitem__(key) + + start_idx = self.__omap.index(key) + del self.__omap[start_idx] + + dup_idx, skey = key + self.__kcount[skey] -= 1 + tail_count = self.__kcount[skey] - dup_idx + + if tail_count > 0: + for idx in _range(start_idx, len(self.__omap)): + if self.__omap[idx][1] == skey: + oldkey = self.__omap[idx] + newkey = (dup_idx, skey) + super(VDFDict, self).__setitem__(newkey, self[oldkey]) + super(VDFDict, self).__delitem__(oldkey) + self.__omap[idx] = newkey + + dup_idx += 1 + tail_count -= 1 + if tail_count == 0: + break + + if self.__kcount[skey] == 0: + del self.__kcount[skey] + + return result + + def __iter__(self): + return iter(self.iterkeys()) + + def __contains__(self, key): + return super(VDFDict, self).__contains__(self._normalize_key(key)) + + def __eq__(self, other): + if isinstance(other, VDFDict): + return list(self.items()) == list(other.items()) + else: + return False + + def __ne__(self, other): + return not self.__eq__(other) + + def clear(self): + super(VDFDict, self).clear() + self.__kcount.clear() + self.__omap = list() + + def get(self, key, *args): + return super(VDFDict, self).get(self._normalize_key(key), *args) + + def setdefault(self, key, default=None): + if key not in self: + self.__setitem__(key, default) + return self.__getitem__(key) + + def pop(self, key): + key = self._normalize_key(key) + value = self.__getitem__(key) + self.__delitem__(key) + return value + + def popitem(self): + if not self.__omap: + raise KeyError("VDFDict is empty") + key = self.__omap[-1] + return key[1], self.pop(key) + + def update(self, data=None, **kwargs): + if isinstance(data, dict): + data = data.items() + elif not isinstance(data, list): + raise TypeError("Expected data to be a list or dict, got %s" % type(data)) + + for key, value in data: + self.__setitem__(key, value) + + def iterkeys(self): + return (key[1] for key in self.__omap) + + def keys(self): + return _kView(self) + + def itervalues(self): + return (self[key] for key in self.__omap) + + def values(self): + return _vView(self) + + def iteritems(self): + return ((key[1], self[key]) for key in self.__omap) + + def items(self): + return _iView(self) + + def get_all_for(self, key): + """ Returns all values of the given key """ + if not isinstance(key, _string_type): + raise TypeError("Key needs to be a string.") + return [self[(idx, key)] for idx in _range(self.__kcount[key])] + + def remove_all_for(self, key): + """ Removes all items with the given key """ + if not isinstance(key, _string_type): + raise TypeError("Key need to be a string.") + + for idx in _range(self.__kcount[key]): + super(VDFDict, self).__delitem__((idx, key)) + + self.__omap = list(filter(lambda x: x[1] != key, self.__omap)) + + del self.__kcount[key] + + def has_duplicates(self): + """ + Returns ``True`` if the dict contains keys with duplicates. + Recurses through any all keys with value that is ``VDFDict``. + """ + for n in getattr(self.__kcount, _iter_values)(): + if n != 1: + return True + + def dict_recurse(obj): + for v in getattr(obj, _iter_values)(): + if isinstance(v, VDFDict) and v.has_duplicates(): + return True + elif isinstance(v, dict): + return dict_recurse(v) + return False + + return dict_recurse(self) diff --git a/generate_emu_config_old/steam_default_icon_locked.jpg b/generate_emu_config_old/steam_default_icon_locked.jpg new file mode 100644 index 0000000..7f52ca7 Binary files /dev/null and b/generate_emu_config_old/steam_default_icon_locked.jpg differ diff --git a/generate_emu_config_old/steam_default_icon_unlocked.jpg b/generate_emu_config_old/steam_default_icon_unlocked.jpg new file mode 100644 index 0000000..47de868 Binary files /dev/null and b/generate_emu_config_old/steam_default_icon_unlocked.jpg differ