Package: bspp
Quake 3 .PK3 map info and BSP ParserQuake 3 BSP and PK3 map info extractor for Python 3
with no external dependencies.It can be used as a library within other projects
or as a command line tool.Installation$pipinstallbsppCommand line usagebspp.py [-h] [-j] F [F ...]-jtoggles JSON output - plain text by defaultFfiles (.bsp or .pk3) or directories to processExample 1: get all map info as plain text from a .pk3$python-mbspp.bspp/opt/quake3/baseq3/pak6.pk3

/opt/quake3/baseq3/pak6.pk3
---------------------------

CRC:dd13d69b(sv_currentPak:-585902437)pro-q3dm13==========Mapname:LostWorldIICRC:7d11f295(sv_mapChecksum2098328213)Items-----Lightningcharge.....:×2Bullets..............:×1Smallhealth(green).:×6Combatarmor(red)...:×1Armorshard..........:×8Health(yellow)......:×6Largehealth(orange):×1Megahealth...........:×1Rockets..............:×2Grenades.............:×2Bodyarmor(yellow)..:×1Weapons-------Shotgun..............:×2Rocketlauncher......:×1Lightninggun........:×1Grenadelauncher.....:×1pro-q3dm6=========Mapname:TheCampgroundsIICRC:c61b258e(sv_mapChecksum-971299442)Items-----Quaddamage..........:×1Megahealth...........:×1Largehealth(orange):×3Shotgunshells.......:×2Rockets..............:×4Bodyarmor(yellow)..:×2Combatarmor(red)...:×2Lightningcharge.....:×2Health(yellow)......:×9Bullets..............:×4Slugs................:×3Plasmacells.........:×2Grenades.............:×1Armorshard..........:×5Weapons-------Shotgun..............:×4Grenadelauncher.....:×2Lightninggun........:×2Plasmagun...........:×2Railgun..............:×2Rocketlauncher......:×2pro-q3tourney2==============Mapname:TheProvingGroundsIICRC:e58b1ebd(sv_mapChecksum-443867459)Items-----Bodyarmor(yellow)..:×1Bullets..............:×1Smallhealth(green).:×3Rockets..............:×2Health(yellow)......:×3Combatarmor(red)...:×1Shotgunshells.......:×2Armorshard..........:×16Lightningcharge.....:×1Largehealth(orange):×1Weapons-------Rocketlauncher......:×1Railgun..............:×1Lightninggun........:×1Shotgun..............:×1pro-q3tourney4==============Mapname:VerticalVengeanceIICRC:c143ed0e(sv_mapChecksum-1052513010)Items-----Plasmacells.........:×1Combatarmor(red)...:×2Rockets..............:×1Armorshard..........:×6Health(yellow)......:×6Megahealth...........:×1Bullets..............:×2Smallhealth(green).:×4Slugs................:×1Shotgunshells.......:×1Weapons-------Plasmagun...........:×1Shotgun..............:×1Railgun..............:×1Rocketlauncher......:×1Example 2: get all map info from .pk3 as JSON$python-mbspp.bspp/opt/quake3/baseq3/pak2.pk3[{"pk3_name":"/opt/quake3/baseq3/pak2.pk3","crc":"18912474","maps":[{"map_title":"Hero's Keep","map_name":"q3dm9","crc":"9c64ee6a","aggregated_items":{"ammo_bullets":3,"ammo_rockets":4,"ammo_slugs":3,"item_health_small":6,"item_health_mega":1,"item_health_large":3,"ammo_shells":3,"item_health":8,"ammo_cells":4,"item_armor_shard":14,"item_armor_combat":2,"item_armor_body":1},"aggregated_weapons":{"weapon_shotgun":3,"weapon_plasmagun":3,"weapon_rocketlauncher":1,"weapon_railgun":1},"flags":{"ctf_capable":false,"overload_capable":false,"harvester_capable":false,"ctf_1f_capable":false,"requires_ta":false}},{"map_title":"Across Space","map_name":"q3tourney6_ctf","crc":"e45d877b","aggregated_items":{"item_health_large":4,"item_quad":1,"item_armor_body":1,"ammo_rockets":2,"ammo_bullets":2,"item_health":2},"aggregated_weapons":{"weapon_rocketlauncher":2,"weapon_railgun":2,"weapon_bfg":1},"flags":{"ctf_capable":true,"overload_capable":false,"harvester_capable":false,"ctf_1f_capable":false,"requires_ta":false}}]}]API usageOpen a .PK3 and extract all map info:>>> from bspp import bspp

>>> pk3 = bspp.process_pk3_file("/opt/quake3/baseq3/pak2.pk3")

>>> len(pk3.map_entities)
2

>>> maps = [bspp.pp_map(m) for m in pk3.map_entities]
[Map(map_title="Hero's Keep", map_name='q3dm9', crc=b'\x9cd\xeej', aggregated_items={'ammo_bullets': 3, 
'ammo_rockets': 4, 'ammo_slugs': 3, 'item_health_small': 6, 'item_health_mega': 1, 'item_health_large': 3, 
'ammo_shells': 3, 'item_health': 8, 'ammo_cells': 4, 'item_armor_shard': 14, 'item_armor_combat': 2, 
'item_armor_body': 1}, aggregated_weapons={'weapon_shotgun': 3, 'weapon_plasmagun': 3, 'weapon_rocketlauncher': 1, 
'weapon_railgun': 1}, flags=Flags(ctf_capable=False, overload_capable=False, harvester_capable=False, 
ctf_1f_capable=False, requires_ta=False)), Map(map_title='Across Space', map_name='q3tourney6_ctf', crc=b'\xe4]\x87{', 
aggregated_items={'item_health_large': 4, 'item_quad': 1, 'item_armor_body': 1, 'ammo_rockets': 2, 'ammo_bullets': 2, 
'item_health': 2}, aggregated_weapons={'weapon_rocketlauncher': 2, 'weapon_railgun': 2, 'weapon_bfg': 1}, 
flags=Flags(ctf_capable=True, overload_capable=False, harvester_capable=False, ctf_1f_capable=False, 
equires_ta=False))]DevelopmentThis project prefersPipenv.In order to install development dependencies prepare dev env with:$pipenvsync-dBefore pushing, please check code quality and formatting:$makelintUnderstanding pylinterrors.Test-mapsTest maps: SpineBender by Elfinko; mosh by tetsuo; vrmpack by vamp1re. Thank you all!