add old gen_emu and workflows for it

This commit is contained in:
Detanup01
2025-02-04 18:51:34 +01:00
parent 5d5b42264f
commit a625950bd8
123 changed files with 13199 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"

32
.gitignore vendored Normal file
View File

@@ -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

View File

@@ -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.
<br/>
## Usage
```bash
generate_emu_config [options] <app id 1> [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.
<br/>
---
## 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)

View File

@@ -0,0 +1 @@
{}

View File

@@ -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
}

View File

@@ -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"
}
}

View File

@@ -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
}

View File

@@ -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"
{
}
}
}

View File

@@ -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
}

View File

@@ -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
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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"
{
}
}

View File

@@ -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
}

View File

@@ -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"
{
}
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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<qkey>(?:\\.|[^\\"])*)"|(?P<key>#?[a-z0-9\-\_\\\?$%<>]+))'
r'([ \t]*('
r'"(?P<qval>(?:\\.|[^\\"])*)(?P<vq_end>")?'
r'|(?P<val>(?:(?<!/)/(?!/)|[a-z0-9\-\_\\\?\*\.$<> ])+)'
r'|(?P<sblock>{[ \t]*)(?P<eblock>})?'
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('<i')
uint64 = struct.Struct('<Q')
int64 = struct.Struct('<q')
float32 = struct.Struct('<f')
def read_string(fp, wide=False):
buf, end = b'', -1
offset = fp.tell()
# locate string end
while end == -1:
chunk = fp.read(64)
if chunk == b'':
raise SyntaxError("Unterminated cstring (offset: %d)" % offset)
buf += chunk
end = buf.find(b'\x00\x00' if wide else b'\x00')
if wide:
end += end % 2
# rewind fp
fp.seek(end - len(buf) + (2 if wide else 1), 1)
# decode string
result = buf[:end]
if wide:
result = result.decode('utf-16')
elif bytes is not str:
result = result.decode('utf-8', 'replace')
else:
try:
result.decode('ascii')
except:
result = result.decode('utf-8', 'replace')
return result
stack = [mapper()]
CURRENT_BIN_END = BIN_END if not alt_format else BIN_END_ALT
for t in iter(lambda: fp.read(1), b''):
if t == CURRENT_BIN_END:
if len(stack) > 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('<i')
uint64 = struct.Struct('<Q')
int64 = struct.Struct('<q')
float32 = struct.Struct('<f')
for key, value in obj.items():
if isinstance(key, string_type):
key = key.encode('utf-8')
else:
raise TypeError("dict keys must be of type str, got %s" % type(key))
if isinstance(value, Mapping):
yield BIN_NONE + key + BIN_NONE
for chunk in _binary_dump_gen(value, level+1, alt_format=alt_format):
yield chunk
elif isinstance(value, UINT_64):
yield BIN_UINT64 + key + BIN_NONE + uint64.pack(value)
elif isinstance(value, INT_64):
yield BIN_INT64 + key + BIN_NONE + int64.pack(value)
elif isinstance(value, string_type):
try:
value = value.encode('utf-8') + BIN_NONE
yield BIN_STRING
except:
value = value.encode('utf-16') + BIN_NONE*2
yield BIN_WIDESTRING
yield key + BIN_NONE + value
elif isinstance(value, float):
yield BIN_FLOAT32 + key + BIN_NONE + float32.pack(value)
elif isinstance(value, (COLOR, POINTER, int, int_type)):
if isinstance(value, COLOR):
yield BIN_COLOR
elif isinstance(value, POINTER):
yield BIN_POINTER
else:
yield BIN_INT32
yield key + BIN_NONE
yield int32.pack(value)
else:
raise TypeError("Unsupported type: %s" % type(value))
yield BIN_END if not alt_format else BIN_END_ALT
def vbkv_loads(s, mapper=dict, merge_duplicate_keys=True):
"""
Deserialize ``s`` (``bytes`` containing a VBKV 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 s[:4] != b'VBKV':
raise ValueError("Invalid header")
checksum, = struct.unpack('<i', s[4:8])
if checksum != crc32(s[8:]):
raise ValueError("Invalid checksum")
return binary_loads(s[8:], mapper, merge_duplicate_keys, alt_format=True)
def vbkv_dumps(obj):
"""
Serialize ``obj`` to a VBKV formatted ``bytes``.
"""
data = b''.join(_binary_dump_gen(obj, alt_format=True))
checksum = crc32(data)
return b'VBKV' + struct.pack('<i', checksum) + data

View File

@@ -0,0 +1,221 @@
import sys
from collections import Counter
if sys.version_info[0] >= 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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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")

View File

@@ -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)

View File

@@ -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

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

View File

@@ -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)

View File

@@ -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. <br><br>Players have free rein to design their restaurant which will expand and develop between shifts with additional content and challenges unlocked through progression. <br><br>Can you cook, serve and manage your way through 15 hectic days in your restaurant and unlock a brand-new franchise?<br><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_COOK.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Classic co-op cooking action, with a wide selection of mains, sides, sauces, toppings, desserts, and starters.<br></li><li>Choose your equipment, lay out your kitchen, curate your menu and plate up your dishes.<br></li><li>From bubbling soups to sublime salads, tender steaks to hearty pies, there's something for everyone.</li></ul><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_SERVE.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Look after front-of-house: seating customers, delivering orders, and managing patience.<br></li><li>Equip your restaurant to handle the most fickle of customers and deliver them what they need, right when they need it.<br></li><li>Co-operate with your team like a well-olive-oiled machine or build a name for yourself going it alone. <br></li><li>Exceed your goals and take your franchise to greater heights at a new location, bringing with you new unlocks and upgrade</li></ul><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_UPGRADE.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Upgrade and rearrange your restaurant to your personal taste: when the restaurant closes for the day, the planning begins!<br></li><li>Decide what new equipment to purchase, and place it wherever you want.<br></li><li>Want to go high-tech? Install the turbo-ovens, crank up the conveyors, and make way for the robo-kitchen of the future.<br></li><li>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.</li></ul><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_EXPAND.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Exceed your goals and start over at your next location, bringing with you new unlocks and upgrades.<br></li><li>Tailor your brand towards gourmet dining, or fine-tune your fast food franchise.<br></li><li>Every restaurant is procedurally-generated with its own climate, customers and conditions.<br></li><li>Return to your franchise HQ to view your achievements, customise your characters and upgrade your kit, ready for your next adventure!</li></ul>",
"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. <br><br>Players have free rein to design their restaurant which will expand and develop between shifts with additional content and challenges unlocked through progression. <br><br>Can you cook, serve and manage your way through 15 hectic days in your restaurant and unlock a brand-new franchise?<br><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_COOK.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Classic co-op cooking action, with a wide selection of mains, sides, sauces, toppings, desserts, and starters.<br></li><li>Choose your equipment, lay out your kitchen, curate your menu and plate up your dishes.<br></li><li>From bubbling soups to sublime salads, tender steaks to hearty pies, there's something for everyone.</li></ul><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_SERVE.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Look after front-of-house: seating customers, delivering orders, and managing patience.<br></li><li>Equip your restaurant to handle the most fickle of customers and deliver them what they need, right when they need it.<br></li><li>Co-operate with your team like a well-olive-oiled machine or build a name for yourself going it alone. <br></li><li>Exceed your goals and take your franchise to greater heights at a new location, bringing with you new unlocks and upgrade</li></ul><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_UPGRADE.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Upgrade and rearrange your restaurant to your personal taste: when the restaurant closes for the day, the planning begins!<br></li><li>Decide what new equipment to purchase, and place it wherever you want.<br></li><li>Want to go high-tech? Install the turbo-ovens, crank up the conveyors, and make way for the robo-kitchen of the future.<br></li><li>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.</li></ul><br><img class=\"bb_img\" src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1599600/extras/StoreGifs_EXPAND.gif?t=1727951205\" /><br><br><ul class=\"bb_ul\"><li>Exceed your goals and start over at your next location, bringing with you new unlocks and upgrades.<br></li><li>Tailor your brand towards gourmet dining, or fine-tune your fast food franchise.<br></li><li>Every restaurant is procedurally-generated with its own climate, customers and conditions.<br></li><li>Return to your franchise HQ to view your achievements, customise your characters and upgrade your kit, ready for your next adventure!</li></ul>",
"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": "<strong>Minimum:</strong><br><ul class=\"bb_ul\"><li><strong>Processor:</strong> Quad Core I5 or AMD equivalent<br></li><li><strong>Memory:</strong> 8 GB RAM<br></li><li><strong>Graphics:</strong> Intel HD Graphics 530 or AMD equivalent<br></li><li><strong>Storage:</strong> 2 GB available space</li></ul>",
"recommended": "<strong>Recommended:</strong><br><ul class=\"bb_ul\"><li><strong>Processor:</strong> Quad Core I5 / Ryzen 5<br></li><li><strong>Memory:</strong> 16 GB RAM<br></li><li><strong>Graphics:</strong> GTX 960 or AMD equivalent<br></li><li><strong>Storage:</strong> 2 GB available space</li></ul>"
},
"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": ""
}
}
}
}
}

View File

@@ -0,0 +1,10 @@
{
"1": {
"executable": "PlateUp/PlateUp.exe",
"arguments": "-appid 1599600",
"description_loc": {
"english": "Launch"
},
"description": "Launch"
}
}

View File

@@ -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
}

View File

@@ -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"
}
]

View File

@@ -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
}
]

View File

@@ -0,0 +1,4 @@
[app::dlcs]
# should the emu report all DLCs as unlocked, default=1
unlock_all=0

View File

@@ -0,0 +1,2 @@
1599601
1599602

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1 @@
1599600

View File

@@ -0,0 +1,12 @@
english
french
german
spanish
japanese
polish
brazilian
russian
schinese
tchinese
koreana
turkish

View File

@@ -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": "<h1>Digital Deluxe Edition</h1><p><img src=\"https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/238370/extras/Decoration-Banner-DELUXE.png?t=1709831158\" /><h2 class=\"bb_tag\">Exclusive Deluxe Edition content:</h2><ul class=\"bb_ul\"><li>Warlord Robe Set<br></li><li>Magicka Orchestra Soundtrack<br></li><li>Digital Interactive Map<br></li><li>Cultist Robe Set</li></ul></p><br><h1>About the Game</h1>The worlds 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.<br><br>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!<h2 class=\"bb_tag\">Learn to Spell Again... Again!</h2><br>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!<h2 class=\"bb_tag\">Learn to Spell Again</h2><br>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.<br><ul class=\"bb_ul\"><li>Combine up to five elements at a time and work together with—or against—your friends for that full Magicka co-op experience.<br></li><li>Four Player Friendly Fire Compatible Co-op<br></li><li>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.<br></li><li>Friendly fire is always on, promoting emergent gameplay humor as players accidentally hurt or kill their friends in their attempts to annihilate enemies.</li></ul><h2 class=\"bb_tag\">Be the Wizard You Want to Be!</h2><br>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.<h2 class=\"bb_tag\">Replay the Next Chapter with Artifacts</h2><br>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 &quot;Artifacts,&quot; 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 worlds 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.<br><br>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!<h2 class=\"bb_tag\">Learn to Spell Again... Again!</h2><br>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!<h2 class=\"bb_tag\">Learn to Spell Again</h2><br>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.<br><ul class=\"bb_ul\"><li>Combine up to five elements at a time and work together with—or against—your friends for that full Magicka co-op experience.<br></li><li>Four Player Friendly Fire Compatible Co-op<br></li><li>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.<br></li><li>Friendly fire is always on, promoting emergent gameplay humor as players accidentally hurt or kill their friends in their attempts to annihilate enemies.</li></ul><h2 class=\"bb_tag\">Be the Wizard You Want to Be!</h2><br>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.<h2 class=\"bb_tag\">Replay the Next Chapter with Artifacts</h2><br>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 &quot;Artifacts,&quot; which act as different switches and options for players to customize and change the gameplay experience, adding more replayability when utilized.",
"short_description": "The worlds 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": "<strong>Minimum:</strong><br><ul class=\"bb_ul\"><li><strong>OS *:</strong> Windows 7, 8 or 10<br></li><li><strong>Processor:</strong> CPU: 3GHz Dual Core (Intel Pentium G3220 or higher / AMD A4-4000 or higher)<br></li><li><strong>Memory:</strong> 2 GB RAM<br></li><li><strong>Graphics:</strong> Nvidia GeForce 550 or better / ATI Radeon HD 5850 or better<br></li><li><strong>Storage:</strong> 3 GB available space<br></li><li><strong>Sound Card:</strong> DirectX Compatible Sound Card</li></ul>",
"recommended": "<strong>Recommended:</strong><br><ul class=\"bb_ul\"><li><strong>OS *:</strong> Windows 7, 8 or 10<br></li><li><strong>Processor:</strong> 2.8GHz Quad Core (Intel Core i5-2300 or higher / AMD A8-3850 or higher)<br></li><li><strong>Memory:</strong> 4 GB RAM<br></li><li><strong>Graphics:</strong> Nvidia GeForce 640 or better / ATI Radeon HD 6670 or better<br></li><li><strong>Storage:</strong> 3 GB available space<br></li><li><strong>Sound Card:</strong> DirectX Compatible Sound Card</li></ul>"
},
"mac_requirements": {
"minimum": "<strong>Minimum:</strong><br><ul class=\"bb_ul\"><li><strong>OS:</strong> OSX 10.7<br></li><li><strong>Processor:</strong> Intel Core i5, 1.7GHz Dual-Core<br></li><li><strong>Memory:</strong> 4 GB RAM<br></li><li><strong>Graphics:</strong> Intel HD Graphics 4000<br></li><li><strong>Storage:</strong> 3 GB available space</li></ul>",
"recommended": "<strong>Recommended:</strong><br><ul class=\"bb_ul\"><li><strong>OS:</strong> OSX 10.7<br></li><li><strong>Processor:</strong> Intel Core i5, 2.5GHz<br></li><li><strong>Memory:</strong> 4 GB RAM<br></li><li><strong>Graphics:</strong> Radeon HD 6750M<br></li><li><strong>Storage:</strong> 3 GB available space</li></ul>"
},
"linux_requirements": {
"minimum": "<strong>Minimum:</strong><br><ul class=\"bb_ul\"><li><strong>OS:</strong> Ubuntu 12.04<br></li><li><strong>Processor:</strong> 3GHz Dual Core (Intel Pentium G3220 or higher / AMD A4-4000 or higher)<br></li><li><strong>Memory:</strong> 2 GB RAM<br></li><li><strong>Graphics:</strong> Nvidia GeForce 550 or better / ATI Radeon HD 5850 or better<br></li><li><strong>Storage:</strong> 3 GB available space</li></ul>",
"recommended": "<strong>Recommended:</strong><br><ul class=\"bb_ul\"><li><strong>OS:</strong> Ubuntu 14.04 LTS<br></li><li><strong>Processor:</strong> 2.8GHz Quad Core (Intel Core i5-2300 or higher / AMD A8-3850 or higher)<br></li><li><strong>Memory:</strong> 4 GB RAM<br></li><li><strong>Graphics:</strong> Nvidia GeForce 640 or better / ATI Radeon HD 6670 or better<br></li><li><strong>Storage:</strong> 3 GB available space</li></ul>"
},
"legal_notice": "Paradox Interactive, MAGICKA® Copyright© [2015] Paradox Interactive AB All rights reserved. <a href=\"https://steamcommunity.com/linkfilter/?u=http%3A%2F%2Fwww.paradoxplaza.com\" target=\"_blank\" rel=\" noopener\" >www.paradoxplaza.com</a>",
"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"
}
}
}
}
}

View File

@@ -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"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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
}
]

View File

@@ -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

View File

@@ -0,0 +1 @@
Move=LJOY=joystick_move

View File

@@ -0,0 +1 @@
Move=LJOY=joystick_move

View File

@@ -0,0 +1,11 @@
353120
238371
238372
238373
238374
238375
238376
238377
354390
228984
228990

Some files were not shown because too many files have changed in this diff Show More