valvepython / vdf Goto Github PK
View Code? Open in Web Editor NEW๐ Package for working with Valve's text and binary KeyValue format
Home Page: https://pypi.org/project/vdf/
License: MIT License
๐ Package for working with Valve's text and binary KeyValue format
Home Page: https://pypi.org/project/vdf/
License: MIT License
Is there anything that can be done by the library user to have this file parsed correctly?
The problematic field is this one:
"installdir" "The Legend of Liฤu Thiam Ting"
Thanks
Reference existing issue from old repo: rossengeorgiev/vdf-parser#3
I'm trying to read and edit the shortcuts.vdf
file, but something is going wrong, as I get the error SyntaxError: Unterminated cstring (offset: 1)
. Is it me that is doing something wrong, or is this a bug?
My code:
import vdf
shortcutsFileLocation = "/home/user/.steam/steam/userdata/1234/config/localconfig.vdf"
shortcutsFile = open(shortcutsFileLocation, "rb")
shortcutsBytes = shortcutsFile.read()
shortcuts = vdf.binary_loads(shortcutsBytes)
Trying to use this for my build tool, I'm getting some errors when the parser tries to deal with Paths such as when parsing:
"appbuild"
{
"appid" "111111111"
"desc" "Description you want"
"buildoutput" "D:\SteamSDK\tools\ContentBuilder\output"
"contentroot" ""
"setlive" "internaltest"
"preview" "0"
"local" ""
"depots"
{
"111111111" "D:\SteamSDK\tools\ContentBuilder\scripts\generic_depot.vdf"
}
}
This is what it's returning
"appbuild"
{
"appid" "111111111"
"desc" "Description you want"
"buildoutput" "D:\\SteamSDK\tools\\ContentBuilder\\output"
"contentroot" ""
"setlive" "internaltest"
"preview" "0"
"local" ""
"depots"
{
"111111111" "D:\\SteamSDK\tools\\ContentBuilder\\scripts\\generic_depot.vdf"
}
}
Notice D:\SteamSDK\tools\ContentBuilder\scripts\generic_depot.vdf
Where \tools it's only giving one backslash because \t is an escape command.
I am using this library to read and write to shortcuts.vdf which Steam uses to store non-Steam game shortcuts. While testing, I found that encoded non-ASCII strings were using utf-16 which caused Steam to incorrectly parse the file.
Line 368 in f2fd3da
I propose adding a new optional parameter to binary_dumps() (with utf-16 as a default) to allow encoding using utf-8. I have tested this in my fork of this library and Steam successfully parsed the resulting vdf file.
Input file demo.vdf:
"controller_mappings"
{
"group"
{
"id" "0"
}
"group"
{
"id" "1"
}
}
Test script:
import vdf
with open("demo.vdf") as fp:
v = vdf.load(fp, mapper=vdf.VDFDict)
print(type(v))
print(type(v['controller_mappings']))
print(vdf.dumps(v, pretty=True))
Expected output:
(demo.vdf)
Actual output:
<class 'vdf.vdict.VDFDict'>
<class 'vdf.vdict.VDFDict'>
"controller_mappings"
{
"group"
{
"id" "0"
"id" "1"
}
}
Not only is this incorrect, but no error is thrown: the resulting data structure is silently malformed and passed along.
Hello
I got an exception while trying the example on duplicates.
When reassigning a duplicate and after printing the duplicate, get_all_for('key') fails with
>>> d[(1, 'key')] = 123 # reassign specific duplicate
>>> d.get_all_for('key')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files\Python310\lib\site-packages\vdf\vdict.py", line 190, in get_all_for
return [self[(idx, key)] for idx in _range(self.__kcount[key])]
File "C:\Program Files\Python310\lib\site-packages\vdf\vdict.py", line 190, in <listcomp>
return [self[(idx, key)] for idx in _range(self.__kcount[key])]
File "C:\Program Files\Python310\lib\site-packages\vdf\vdict.py", line 87, in __getitem__
return super(VDFDict, self).__getitem__(self._normalize_key(key))
KeyError: (2, 'key')
is it a bug or the examples are not up to date?
Request for adding a function to read vtex_c file and get the image bytes, or the file as an IO/Pillow Image.
Some tests not passed in Fedora 32:
=================================== FAILURES ===================================
__________________________ BinaryVDF.test_loads_utf16 __________________________
self = <tests.test_binary_vdf.BinaryVDF testMethod=test_loads_utf16>
def test_loads_utf16(self):
> self.assertEqual({'aaa': b'b\x00b\x00\xff\xffb\x00b\x00'.decode('utf-16le')}, vdf.binary_loads(b'\x05aaa\x00b\x00b\x00\xff\xffb\x00b\x00\x00\x00\x08'))
E AssertionError: {'aaa': 'bb\uffffbb'} != {'aaa': 'ๆๆ\uffffๆๆ'}
E - {'aaa': 'bb\uffffbb'}
E ? ^^ ^^
E
E + {'aaa': 'ๆๆ\uffffๆๆ'}
E ? ^^ ^^
tests/test_binary_vdf.py:188: AssertionError
But tests passed in Fedora 33 and no such issue. Full F32 build log.
Additional information:
Fedora 32
3.8.7
From my shortcuts.vdf file, Halo Infinite has the appid C0 83 BF F8 which in python when read is displayed as the following.
`
print(d["shortcuts"]["103"]["appid"])
-121666624
`
Steam uses the appid for grid images. It seems like the byte data is being read as uint32 instead of int32 by steam. The same thing happens with all shortcuts ids I've checked.
`
print(d["shortcuts"]["103"]["icon"])
C:\Program Files (x86)\Steam\userdata\XYZ\config\grid\4173300672_icon.ico
`
Ideally the behavior should change to:
utf-8
by defaultSyntaxError
can carry extra info about where the issue is exactly. This will help with debugging issues.
https://docs.python.org/2/library/exceptions.html#exceptions.SyntaxError
Should improve debugging in cases like #23
At least Dota 2 interprets \'
as they are.
The alternative format uses 0x0b
as END instead of 0x08
, otherwise it exactly the same. I have no idea why that is. Is it a programming typo, 0x0B
looks like 0x08
? Maybe it's supposed to be different. Say a format for on disk, rather than just data interchange over the steam network. Explains the CRC32, but why change the format?
Samples files:
0x08
- [steamdir]/appcache/appinfo.vdf
0x0B
- [steamdir]/userdata/[account id]/570/remote/cfg/chat.cfg
VBKV
, followed by 4 bytes CRC32 of the rest, then binary vdfApparently the VDF format supports definitions for merging files.
#base
will merge KVs from the specified file with the ones from the current#include
will appendI don't see how that could be implemented in the module reliably. It should be fairly simple to implement at application level for the specific use case. That leaves allowing .#
symbol to be used as unquoted key or value, which is currently not supported
Building python-vdf version 3.3 with python 3.10 at at https://build.opensuse.org/package/show/games:tools/python-vdf fails with the following error:
When I try to read binary files such as appcache/appinfo.vdf
or appcache/packageinfo.vdf
, I always see the same error:
SyntaxError: Unknown data type at index 5: b"'"
I tried using alt_format=True
but it just errors too :/
import vdf
with open('~/.steam/root/appcache/appinfo.vdf', 'rb') as appinfo:
data = vdf.binary_lods(appinfo.read())
vdf fails to parse binary VDF files which contain fields with invalid UTF-8. One such invalid field was discovered in an entry for Spore inside appinfo.vdf. The exception that occurs is:
File "/home/matoking/git/protontricks/env/lib/python3.7/site-packages/vdf/__init__.py", line 337, in binary_loads
stack[-1][key], idx = read_string(s, idx)
File "/home/matoking/git/protontricks/env/lib/python3.7/site-packages/vdf/__init__.py", line 305, in read_string
result = result.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfd in position 12: invalid start byte
I've uploaded a snippet that can be used to reproduce this error here:
https://gist.github.com/Matoking/e2dfe281386ff4eac9022eb0f02d80cd
SteamDB seems to replace the invalid character with a question mark:
https://steamdb.info/app/24720/history/ (the faulty string here is Moje Spore v๏ฟฝtvory)
A similar fix in vdf would mean replacing the result.decode('utf-8')
call with result.decode('utf-8', errors='replace')
or letting the developer decide how to handle errors by passing an optional errors
kwarg.
Unfortunately vdf does not point me to the line responsible for this (or does it via EOF (last lines)?.
I'm was looking for a validate
function but couldn't find it. I'm not sure if the file I'm working with is actually a VDF file.
playlists
{
version stable
versionNum 214
Gamemodes
{
defaults
{
vars
{
///////////////////////////////////////////////////////////////////////////////////
//// Code Required Vars
///////////////////////////////////////////////////////////////////////////////////
max_players 60
max_teams 20
bsp_build_warnings_off 0
cmdlineMapLoad 1
faq_community_count 1
faq_community_url_00 ""
faq_community_version 0
faq_patchnotes_count 1
faq_patchnotes_version 0
idleKickTime_minutes 0
mixtape_onboarding "survival"
observer_mode_check_same_team 1
hover_tank_revive_fix 1
player_freefall_job_enable 1
enable_report 2
enable_three_weapons 0
charselect_intro_countdown_duration 5
wait_for_players_forever 0
///////////////////////////////////////////////////////////////////////////////////
//// Script Required Vars
///////////////////////////////////////////////////////////////////////////////////
canyonlands_hovertanks_circle_index 1
loot_main_weapon_energy_ar_edition 20
loot_main_weapon_lstar_edition 30
waiting_for_players_countdown_seconds 5
waiting_for_players_min_wait 0
waiting_for_players_timeout_seconds 60
waiting_for_players_has_black_screen 1
survival_enable_gladiator_intros 0
character_select_time_max 6
character_select_time_min 6
///////////////////////////////////////////////////////////////////////////////////
//// Character Configurations
///////////////////////////////////////////////////////////////////////////////////
character_dummie hide
character_wattson lock
character_crypto lock
character_random lock
//============= Hide from Normal Use ============//
///////////////////////////////////////////////////////////////////////////////////
//// Character Damage Balances
///////////////////////////////////////////////////////////////////////////////////
leg_hitbox_override_character_wraith "20 21"
leg_hitbox_override_character_lifeline "20 21"
leg_hitbox_override_character_wattson "20 21"
leg_hitbox_override_character_pathfinder "16 26 25 12"
///////////////////////////////////////////////////////////////////////////////////
//// Deathfield
///////////////////////////////////////////////////////////////////////////////////
deathfield_damagePercent_0 0.02
deathfield_damagePercent_1 0.10
deathfield_damagePercent_2 0.15
deathfield_damagePercent_3 0.20
deathfield_damagePercent_4 0.20
deathfield_damagePercent_5 0.25
deathfield_damagePercent_6 0.25
deathfield_damagePercent_7 0.25
deathfield_preShrinkDuration_0 180
deathfield_preShrinkDuration_1 145
deathfield_preShrinkDuration_2 135
deathfield_preShrinkDuration_3 120
deathfield_preShrinkDuration_4 90
deathfield_preShrinkDuration_5 60
deathfield_preShrinkDuration_6 20
deathfield_preShrinkDuration_7 20
deathfield_radius_0 22000
deathfield_radius_1 13000
deathfield_radius_2 8000
deathfield_radius_3 4000
deathfield_radius_4 1500
deathfield_radius_5 750
deathfield_radius_6 100
deathfield_radius_7 1
deathfield_shrinkSpeed_0 160
deathfield_shrinkSpeed_1 130
deathfield_shrinkSpeed_2 120
deathfield_shrinkSpeed_3 100
deathfield_shrinkSpeed_4 80
deathfield_shrinkSpeed_5 80
deathfield_shrinkSpeed_6 100
deathfield_shrinkSpeed_7 100
///////////////////////////////////////////////////////////////////////////////////
//// Airdrops
///////////////////////////////////////////////////////////////////////////////////
//"type:dropCount:preWait:contentsLeft:contentsRight:contentsCenter"
// contents can be expanded with: "contentsL1,contentsL2,contentsL3 ...:contentsR1:contentsC1" using "," as a delimiter
// multiple airdrops can be added per round using " " as a delimiter
//=====================================================================================================================
airdrop_data_round_0 "2:30:care_package_1_L:care_package_1_R:care_package_1_C"
airdrop_data_round_1 "1:15:care_package_2_L:care_package_2_R:care_package_2_C"
airdrop_data_round_2 "1:0:care_package_3_L:care_package_3_R:care_package_3_C"
///////////////////////////////////////////////////////////////////////////////////
//// MTX and Progression
///////////////////////////////////////////////////////////////////////////////////
xp_first_game_amount 0
xp_champion_amount 500
xp_damage_dealt_amount 0.25
xp_friend_amount 3.0
xp_friend_frac 0.05
xp_kill_amount 50
xp_kill_champion_amount 500
xp_kill_leader_amount 50
xp_loot_master_amount 50
xp_respawn_ally_amount 200
xp_revive_ally_amount 25
xp_survival_duration_amount 3.0
xp_top_five_amount 300
xp_win_match_amount 900
xp_first_kill_amount 500
xp_challenge_completed_amount 1
grx_currency_bundle_crafting_common_count 15
grx_currency_bundle_crafting_epic_count 200
grx_currency_bundle_crafting_legendary_count 600
grx_currency_bundle_crafting_rare_count 30
///////////////////////////////////////////////////////////////////////////////////
//// Dialogs
///////////////////////////////////////////////////////////////////////////////////
generic_dialog_header_30 "#MATCHMAKING_PENALTY_ACTIVE"
generic_dialog_message_31 "#MATCHMAKING_PENALTY_1"
generic_dialog_message_32 "#MATCHMAKING_PENALTY_2"
generic_dialog_message_33 "#MATCHMAKING_PENALTY_3"
generic_dialog_message_34 "#MATCHMAKING_PENALTY_4"
generic_dialog_message_35 "#MATCHMAKING_PENALTY_5"
generic_dialog_message_36 "#MATCHMAKING_PENALTY_GE_5"
///////////////////////////////////////////////////////////////////////////////////
//// Hovertanks
///////////////////////////////////////////////////////////////////////////////////
hovertanks_count_intro 1
hovertanks_count_mid 1
hovertanks_chance_intro 1.00
hovertanks_chance_mid 0.33
///////////////////////////////////////////////////////////////////////////////////
//// Gamemodes
///////////////////////////////////////////////////////////////////////////////////
mode_fall_ltm 0
///////////////////////////////////////////////////////////////////////////////////
//// Events
///////////////////////////////////////////////////////////////////////////////////
valentines_event 0
halloween_event 0
///////////////////////////////////////////////////////////////////////////////////
//// Aim Assist
///////////////////////////////////////////////////////////////////////////////////
aimassist_adspull_disabled 1
aimassist_magnet_pc 0.40
aimassist_magnet 0.55
///////////////////////////////////////////////////////////////////////////////////
//// Battlepass
///////////////////////////////////////////////////////////////////////////////////
//battlepass_character_max_xp 25000
//battlepass_character_max_weekly_xp 25000
///////////////////////////////////////////////////////////////////////////////////
//// Misc Configuration
///////////////////////////////////////////////////////////////////////////////////
enable_grx 1
enable_battlepass 1
enable_wraith_alert_effect 1
disable_hud_score_display 0
ranked_in_match_check_party 0
ranked_in_match_check_party_force_team 0
quick_melee_enabled 1
require_training 0
timelimit 30
survival_shields 1
octane_preview 0
player_revive_enabled 1
match_ending_enabled 1
battlechatter_enabled 1
///////////////////////////////////////////////////////////////////////////////////
//// Player Reporting
///////////////////////////////////////////////////////////////////////////////////
report_player_reason_pc_friendly_count 4
report_player_reason_pc_friendly_1 "#REPORT_PLAYER_REASON_LOS"
report_player_reason_pc_friendly_2 "#REPORT_PLAYER_REASON_AIMSNAP"
report_player_reason_pc_friendly_3 "#REPORT_PLAYER_REASON_WEIRDMOVING"
report_player_reason_pc_friendly_4 "#REPORT_PLAYER_REASON_AMMOORRECOIL"
report_player_reason_pc_enemy_count 4
report_player_reason_pc_enemy_1 "#REPORT_PLAYER_REASON_LOS"
report_player_reason_pc_enemy_2 "#REPORT_PLAYER_REASON_AIMSNAP"
report_player_reason_pc_enemy_3 "#REPORT_PLAYER_REASON_WEIRDMOVING"
report_player_reason_pc_enemy_4 "#REPORT_PLAYER_REASON_AMMOORRECOIL"
report_player_reason_console_friendly_count 5
report_player_reason_console_friendly_1 "#REPORT_PLAYER_REASON_OFFENSIVE"
report_player_reason_console_friendly_2 "#REPORT_PLAYER_REASON_SPAWN"
report_player_reason_console_friendly_3 "#REPORT_PLAYER_REASON_HARRASMENT"
report_player_reason_console_friendly_4 "#REPORT_PLAYER_REASON_HATE"
report_player_reason_console_friendly_5 "#REPORT_PLAYER_REASON_SUICIDE"
report_player_reason_console_enemy_count 4
report_player_reason_console_enemy_1 "#REPORT_PLAYER_REASON_LOS"
report_player_reason_console_enemy_2 "#REPORT_PLAYER_REASON_AIMSNAP"
report_player_reason_console_enemy_3 "#REPORT_PLAYER_REASON_WEIRDMOVING"
report_player_reason_console_enemy_4 "#REPORT_PLAYER_REASON_AMMOORRECOIL"
///////////////////////////////////////////////////////////////////////////////////
//// Unknown
///////////////////////////////////////////////////////////////////////////////////
color "254 184 0 255"
///////////////////////////////////////////////////////////////////////////////////
//// Season start/end datetimes (don't delete these)
///////////////////////////////////////////////////////////////////////////////////
season03_reveal_unixtime 1626656230
season03_start_unixtime 1626656230
season03_finish_unixtime 1637272618
season03_hide_unixtime 1637272618
///////////////////////////////////////////////////////////////////////////////////
//// Dev Playlist Vars
///////////////////////////////////////////////////////////////////////////////////
gamemode_select_v2_enable 1 // Enable gamemode select version 2 over 1
beta_watermark 1 // Enable Beta Watermark
survival_quick_chat_enabled 1 // Quips
desertlands_script_train_enable 1 // World's Edge Train
thirdperson_match 0 // Third Person Mode
enable_nessies 1 // Kings Canyon Easter Egg
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
}
maps
{
}
}
survival
{
inherit defaults
}
custom_tdm
{
inherit defaults
}
}
// START OF MP GAMEMODES LINE --------------------------------------------------
Playlists
{
survival_staging_baseline
{
inherit survival
vars
{
max_teams 20
max_players 20
min_players 1
num_squads_in_staging 1
waiting_for_players_spawning_enabled 1
jump_from_plane_enabled 0
wait_for_players_forever 1
scorebar_hide_squads_remaining 1
scorebar_hide_waiting_for_players 1
airdrop_enabled 0
num_static_loot_ticks_to_spawn 0
loot_preprocessing_should_be_skipped 1
charge_pylons_raise_time_override 15 //Shorter time in training
survival_staging_area_enabled 1
make_room_for_new_players 1
//Reconnect is disabled in firing range!
reconnect_disabled 1
}
gamemodes { survival { maps {
mp_rr_canyonlands_staging 1
} } }
}
survival_training
{
inherit survival_firingrange
vars
{
visible 1
ui_slot training
video _temp
name #PL_TRAINING
description #PL_TRAINING_DESC
image training
//
survival_training 1
survival_firingrange 0
pin_match_type training
}
}
survival_firingrange
{
inherit survival_staging_baseline
vars
{
visible 1
ui_slot firing_range
image firing_range
name #PL_FIRINGRANGE
description #PL_FIRINGRANGE_DESC
video _temp
// match teams will not fill with more than one party, up to max_teams of size max_team_size (or less) -- not exceeding max_players
visible 1
// Skip intros:
waiting_for_players_spawning_enabled 1
waiting_for_players_countdown_seconds 0
waiting_for_players_timeout_seconds 1
character_select_time_max 0.0
character_select_time_min 0.0
survival_enable_gladiator_intros 0
jump_from_plane_enabled 0
// No circle:
sur_circle_start_paused 1
// Can change loadouts:
dev_loadout_changeable_at_any_time 1
sur_dev_unrestricted_character_changes 1
character_reselect_enabled 1
charselect_enabled 1
// Bots:
sur_bots_spawn_with_random_weapons 1
//General Gamemode Settings
match_ending_enabled 0
max_teams 1
max_players 3
min_players 1
// Firing Range:
survival_firingrange 1
staging_ultimates_enabled 1
survival_staging_area_enabled 0
//survival_infinite_ammo 1
pin_match_type firing_range
}
}
///////////////////////////////////
/////////// SURVIVAL ///////////
///////////////////////////////////
survival
{
inherit defaults
vars
{
visible 0
battlechatter_enabled 1
name #PL_PLAY_APEX
description #PL_SURVIVAL_SQUADS_DESC
abbreviation #PL_PLAY_APEX
pin_match_type survival
enable_nessies 1
max_teams 20
max_players 60
min_players 60
survival_shields 1
is_ranked_game 0
player_revive_enabled 1
enable_apex_screens 1
skydive_ziplines_enabled 1
}
gamemodes { survival { maps {
mp_rr_desertlands_64k_x_64k 1
mp_rr_desertlands_64k_x_64k_nx 1
mp_rr_canyonlands_64k_x_64k 1
mp_rr_canyonlands_mu1 1
mp_rr_canyonlands_mu1_night 1
mp_rr_canyonlands_staging 1
} } }
}
///////////////////////////////////
/////////// CANYONLANDS ///////////
///////////////////////////////////
defaults
{
vars
{
}
}
ranked
{
inherit defaults
vars
{
panel_image panel_worlds_edge
visible 1
battlechatter_enabled 1
name #PL_Ranked_Leagues
description #PL_survival_ranked_desc
abbreviation #PL_Ranked_Leagues
map_name #MP_RR_DESERTLANDS_64K_X_64K
visible_schedule_block_0 "2021-06-15 10:00:00 -07:00 | 2021-12-03 10:00:00 -07:00"
image ranked_2
video ranked_2
max_teams 20
max_players 60
min_players 60
survival_shields 1
freelance_enabled 1
is_ranked_game 1
ui_slot regular_2
pin_match_type survival
player_revive_enabled 1
enable_apex_screens 1
skydive_ziplines_enabled 1
}
gamemodes { survival { maps {
mp_rr_canyonlands_64k_x_64k 1
mp_rr_canyonlands_mu1 1
mp_rr_desertlands_64k_x_64k 1
mp_rr_desertlands_64k_x_64k_nx 1
mp_rr_canyonlands_mu1_night 1
mp_rr_canyonlands_staging 1
} } }
}
///////////////////////////////////
///////////// LTMs //////////////
///////////////////////////////////
FallLTM
{
inherit defaults
vars
{
name #SHADOW_SQUAD_MODE
description #SHADOW_SQUAD_MODE_DESC
abbreviation #SHADOW_SQUAD_MODE_ABOUT
image shadow_squad
video shadow_squad
visible 1
show_ltm_about_button 1
max_teams 60
max_players 60
min_players 60
survival_shields 1
freelance_enabled 1
is_ranked_game 0
//ui_slot ltm
mode_fall_ltm 1
evil_leviathans 1
player_revive_enabled 0
battlechatter_enabled 1
showLTMAboutButton 1
character_select_time_max 4.0
character_select_time_min 4.0
}
gamemodes { survival { maps {
mp_rr_canyonlands_mu1_night 1
mp_rr_desertlands_64k_x_64k_nx 1
} } }
}
duos
{
inherit defaults
vars
{
name #PL_DES_DUO
description #PL_DES_DUO_SHORT
abbreviation #PL_DES_DUO_LONG
image duos
video duos
sur_bots_spawn_with_random_weapons 1
enable_nessies 1
max_teams 30
max_players 60
min_players 60
survival_shields 1
freelance_enabled 1
visible 1
is_ranked_game 0
player_revive_enabled 1
enable_apex_screens 1
showLTMAboutButton 1
//ui_slot ltm
character_select_time_max 6.0
character_select_time_min 6.0
pin_match_type duo
}
gamemodes { survival { maps {
mp_rr_canyonlands_64k_x_64k 1
mp_rr_canyonlands_mu1 1
mp_rr_desertlands_64k_x_64k 1
mp_rr_desertlands_64k_x_64k_nx 1
mp_rr_canyonlands_mu1_night 1
mp_rr_canyonlands_staging 1
} } }
}
custom_tdm
{
inherit defaults
vars
{
//ui_slot regular_2
image worlds_edge
video worlds_edge
panel_image panel_worlds_edge
visible 1
battlechatter_enabled 1
name custom_tdm
description "You, against them, in a variety of gamemodes"
abbreviation "Team Deathmatch"
lobbytitle "Team Deathmatch"
pin_match_type survival
enable_nessies 0
max_teams 2
max_players 12
min_players 6
survival_shields 1
skydive_ziplines_enabled 0
//TDM Settings
survival_jumpkit_enabled 1
survival_wallrun_enabled 1
survival_infinite_ammo 1
survival_custom_deploy 1
replay_enabled 1
replay_delay 2
default_shield_hp 75
ground_loot_enable 0
lootbin_loot_enable 0
//whitelisted_weapon_0 "mp_weapon_mastiff"
// Intro Settings:
character_select_time_min 3
character_select_time_max 3
charselect_picking_delay_after_all 0
survival_enable_squad_intro 0
survival_enable_gladiator_intros 0
jump_from_plane_enabled 0
match_ending_enabled 0
sur_circle_start_paused 1
}
gamemodes { custom_tdm { maps {
mp_rr_canyonlands_64k_x_64k 1
mp_rr_canyonlands_mu1 1
mp_rr_desertlands_64k_x_64k 1
mp_rr_desertlands_64k_x_64k_nx 1
mp_rr_canyonlands_mu1_night 1
mp_rr_canyonlands_staging 1
} } }
}
custom_tdm_tps
{
inherit custom_tdm
vars
{
thirdperson_match 1
}
gamemodes { custom_tdm { maps {
mp_rr_canyonlands_64k_x_64k 1
mp_rr_canyonlands_mu1 1
mp_rr_desertlands_64k_x_64k 1
mp_rr_desertlands_64k_x_64k_nx 1
mp_rr_canyonlands_mu1_night 1
mp_rr_canyonlands_staging 1
} } }
}
survival_dev
{
inherit survival
vars
{
// Skip intros:
waiting_for_players_spawning_enabled 1
waiting_for_players_countdown_seconds 0
waiting_for_players_timeout_seconds 1
character_select_time_max 0.0
character_select_time_min 0.0
survival_enable_gladiator_intros 0
jump_from_plane_enabled 0
// No circle:
sur_circle_start_paused 1
// Can change loadouts:
dev_loadout_changeable_at_any_time 1
sur_dev_unrestricted_character_changes 1
// Bots:
sur_bots_spawn_with_random_weapons 1
match_ending_enabled 0
}
gamemodes { survival { maps {
mp_rr_canyonlands_64k_x_64k 1
mp_rr_canyonlands_mu1 1
mp_rr_desertlands_64k_x_64k 1
mp_rr_desertlands_64k_x_64k_nx 1
mp_rr_canyonlands_mu1_night 1
mp_rr_canyonlands_staging 1
} } }
}
dev_default
{
inherit survival_dev
vars
{
// The "cmdlineMapLoad" var here makes this playlist be the default in dev:
cmdlineMapLoad 1
// R5DEV-196963
reconnect_disabled 1
}
gamemodes { survival { maps {
mp_rr_canyonlands_64k_x_64k 1
mp_rr_canyonlands_mu1 1
mp_rr_desertlands_64k_x_64k 1
mp_rr_desertlands_64k_x_64k_nx 1
mp_rr_canyonlands_mu1_night 1
mp_rr_canyonlands_staging 1
} } }
}
menufall
{
vars
{
menu_fall_ltm 1
}
gamemodes { survival { maps {
mp_lobby 1
} } }
}
// END OF MP GAMEMODES LINE ----------------------------------------------------
///////////////////////////////////
////////////// DEV //////////////
///////////////////////////////////
}
"LocalizedStrings"
{
"lang"
{
"Language" "english"
"Tokens"
{
"MP_RR_DESERTLANDS_64K_X_64K_NX" "World's Edge After Dark"
"WORLDS_EDGE_NIGHT" "SHADOWFALL WORLD'S EDGE"
"WORLDS_EDGE_NIGHT_DESC" "Dead Legends respawn as Shadows.\nSurvive and escape with final 10 Legends."
"Kings_Canyon_OG" "Kings Canyon"
"KC_MU1" "Kings Canyon Season 2"
"KCAD" "Kings Canyon After Dark"
"Playtest" "Playtest"
"Playtest_Only" "Playtest"
"BETA_BUILD_WATERMARK" "R5Reloaded v1.6-beta"
}
}
}
"KVFileOverrides"
{
}
}
Some of the files I am parsing have objects inside of a list and it throws [ vdf.parse: expected openning bracket ]
as an error pointing to the line with [
"Object"
{
"Key" "Val"
"Object"
[ // <-- Error points to this line
{
"Object"
{
"Key" "Val"
}
"Key" "Val"
}
{
"Object"
{
"Key" "Val"
}
"Key" "Val"
}
]
}
Attempting to parse a Source 2013 gameinfo.txt
file will fail due to '+' characters in some of the subkeys in the SearchPaths
key. Here's an example from Team Fortress 2's gameinfo.txt
:
"SearchPaths"
{
// First, mount all user customizations. This will search for VPKs and subfolders
// and mount them in alphabetical order. The easiest way to distribute a mod is to
// pack up the custom content into a VPK. To "install" a mod, just drop it in this
// folder.
//
// Note that this folder is scanned only when the game is booted.
"game+mod+custom_mod" "tf/custom/*"
Here, the parser should at least be capable of registering game+mod+custom_mod
as a key, but ideally it should separate it into 3 keys for ease-of-use, like so:
{ "game": "tf/custom/*", "mod": "tf/custom/*", "custom_mod": "tf/custom/*" }
=================================== FAILURES ===================================
__________________________ BinaryVDF.test_loads_utf16 __________________________
self = <tests.test_binary_vdf.BinaryVDF testMethod=test_loads_utf16>
def test_loads_utf16(self):
> self.assertEqual({'aaa': b'b\x00b\x00\xff\xffb\x00b\x00'.decode('utf-16le')}, vdf.binary_loads(b'\x05aaa\x00b\x00b\x00\xff\xffb\x00b\x00\x00\x00\x08'))
E AssertionError: {'aaa': 'bb\uffffbb'} != {'aaa': 'ๆๆ\uffffๆๆ'}
E - {'aaa': 'bb\uffffbb'}
E ? ^^ ^^
E
E + {'aaa': 'ๆๆ\uffffๆๆ'}
E ? ^^ ^^
tests/test_binary_vdf.py:188: AssertionError
=========================== short test summary info ============================
FAILED tests/test_binary_vdf.py::BinaryVDF::test_loads_utf16 - AssertionError...
========================= 1 failed, 98 passed in 0.17s =========================
3.11.0rc1
Those are used in richpresence and other places, would be useful for the steam
module eventually.
More info:
SteamRE/SteamKit#108
I'm trying to write a script that uses information from Dota 2's item schema, but when I try to use the vdf module to parse the schema it gives me this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.9/site-packages/vdf/__init__.py", line 208, in load
return parse(fp, **kwargs)
File "/usr/local/lib/python3.9/site-packages/vdf/__init__.py", line 175, in parse
stack[-1][key] = _unescape(val) if escaped else val
TypeError: 'str' object does not support item assignment
I downloaded the schema from here (and I got that URL from Steam's WebAPI), and I get the same error on the PyPI and GitHub versions of the vdf module.
I appreciate any insight or help!
This was when I was using vdf.parse()
on a large .res
file (around 5k lines). At first, I kept getting the error when it got to a key like this:
TestParentKey
{
}
The error mentions the line where the closing bracket is.
After removing the problem key, the error then mentioned the closing bracket of the parent key for all the other keys. A VSCode extension that also supports VDF files can collapse the file just fine, and shows there doesn't seem to be any extra closing brackets.
I can provide the file that is causing this if need be.
As title implies when dumping something like:
"DepotBuildConfig"
{
"DepotID" "123456789"
"contentroot" "d:\\NekoNeko\\Build"
"FileMapping"
{
"LocalPath" ""
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" ".pdb"
}
The path maintains its double backslashes when dumped
"a
b
c"
{
}
I packaged python-vdf
for Arch GNU/Linux in AUR:
Packages: python2-vdf-git, python-vdf-git, python2-vdf, python-vdf
Packages suffixed with -git
are built from git source, others are built from the lastest release tarball
Packages prefixed with python-
are built for Python 3.x, and prefixed with python2-
are built for Python 2.x
You can install them using any AUR helper (the recommended one is pacaur
):
pacaur -S python-vdf
You can also install them manually:
git clone https://aur.archlinux.org/python-vdf.git
cd python-vdf
makepkg -sic
It would be great if you added them to your readme
Parsing fails even with Escaped=False.
vdf.load(open('test.vdf'), merge_duplicate_keys=False, escaped=False)
test.vdf contents:
"ParentKey1"
{
"ValueKey1" ".\path\"
"ParentKey2"
{
"ValueKey2" "2"
}
}
Output
SyntaxError: vdf.parse: one too many closing parenthasis
Also see examples from Valve documentation
https://partner.steamgames.com/doc/sdk/uploading
under headings "Depot Build Script" and "App Build Script"
Used by ValvePython/steam.
Affected package id: 82985
https://sentry.io/share/issue/27c635a7e4c34a8f867df27c644212e7/
That would make parsing stuff like #13 possible. Probably throw in a param whether to throw once reaching bVDF end
It would be useful for users who wish to use tools such as MyPy to have typing support. Ideally, the calls would be fully type-hinted, and with the inclusion of py.typed
, the package would be fully compatible with PEP 561.
If instead, you prefer to do it using stubs, as noted in https://peps.python.org/pep-0561/#stub-only-packages , I have generated some stubs that i use in projects i help maintain. They are available at https://github.com/ABaumher/VDF_Typing . If you have a proper destination for the stubs i can probably draft up a Pull Request to add them in.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.