Closed snake-biscuits closed 1 year ago
respawn.titanfall.Grid
& LevelInfo
(and their children) are both base.MappedArray/Struct
already.
Their lumps are one occurrence of each struct.
All SpecialLumpClasses should be treated like this, even though most are dynamically sized
Same goes for GameLumpClasses.
__init__
with no args should create a valid "empty" lump on as_bytes()
call
What args specifically to use for __init__
will vary depending on the lump (user-only interface)
It'd also be neat to implement a common __eq__
that compares Lump.as_bytes
if bsp.SPECIAL_LUMP == bsp.branch.SpecialLump():
... # lump is basically empty
Broke a lot of stuff doing this refactor today
Need to run a MegaTest & some casual use before closing this issue
Also haven't done much in the way of docs
Autogenerated docs can do without the special cases for from_bytes
methods
The new __init__
methods for list
based SpecialLumpClasses
have type hints at least.
We should also be testing all SpecialLumpClass __init__
& as_bytes
methods
from_bytes
tests (so long as test maps represent all mapped lumps)GameLumpClasses (GameLump_SPRP) should be counted as SpecialLumpClasses
GameLumpClasses also need a refactor (for apex_legends at least) to hook lumps.BspLump for dynamic prop loading
Should address the absurd RAM use present in #80
.from_bytes()
should map alumps.BspLump
to reduce memory use
This means we'll be resolving #80 as part of this issue
Allow automatic conversions; might need to remap some member names
Ties into #73
Also haven't done much in the way of docs Autogenerated docs can do without the special cases for
from_bytes
methods The new__init__
methods forlist
basedSpecialLumpClasses
have type hints at least.
When closing this issue, we need to start putting together docs for how to use the new __init__
methods when
The ideal use case would be creating a .bsp
w/ bsp_tool
(e.g. compiling, cross-branch conversion)
Haven't tried anything like that yet though, so we'd have to prototype & try a test case
A .from_stream(stream: io.BytesIO)
alternate __init__
would actually make a lot of sense
iirc every .from_bytes(raw_lump: bytes)
creates a bytestream internally
We could just wrap .from_stream
when we call .from_bytes
Though we do make assumptions about the stream ending with the lump
Limiting streams to lump size is nice for security too... (not to mention checking bounds errors)
I'm not even sure it's possible to determine some special lump lengths without the header
Could be relevant to #21
Use a
bytearray
forStaticPropClass
if undefined (derive length fromprop_count
)
The new GameLump_SPRP
are so nice & tidy now that I don't want to mess them up w/ this idea
Plus it's not too hard to whip up a quick MappedArray
to start building a new StaticPropClass
A bytearray
utility class w/ hex editor views etc. for whipping up a quick MappedArray
could be cool tho
Could come in handy for reversing infinity_ward.modern_warfare
structs etc.
The current way SpecialLumpClasses are loaded from
.bsp
s involves feeding the raw lump bytes to a function However, in the code we thing of SpecialLumpClasses as classes, but LumpClasses have.from_bytes
an alternate__init__
This also messes with generating documentation for SpecialLumpClasses with a fixed structure (e.g. 1xstruct LevelInfo
)It would be more useful to think of SpecialLumpClasses as a single, often dynamically sized, structure We already refactored LumpClasses to have their own
__init__
methods for easier use, but SpecialLumpClasses must be fed bytesCreating a blank of any lump type & populating it after is far more useful, and doesn't require memorising stubs
Required Changes:
__init__
->from_bytes
@classmethod
for each SpecialLumpClass:_preload_lump
BspClass methods need to calling SpecialLumpClass.from_bytes()
, rather than__init__
ExternalLumpManager.__getattr__
.ent
(shared.Entities
)__init__
methods for each SpecialLumpClass (if nessecary) Calling with no arguments should create a valid "empty lump"super.__init__()
should be good enough for list subclasses, but test that theory just in caseAll Special Lump Classes:
id_software.quake.MipTextureLump
id_software.quake2.Visibility
id_software.quake3.Visibility
respawn.apex_legends.LevelInfo
respawn.titanfall.EntityPartitions
respawn.titanfall.Grid
respawn.titanfall_x360.Grid_x360
respawn.titanfall.LevelInfo
shared.Entities
shared.PakFile
shared.TextureDataStringData
valve_physics.CollideLump
valve_physics.Displacement
strata,strata.PhysicsDisplacement
Phase 2: Game Lump Classes
We need to do the same conversion for the following GameLump & Lump Classes:
valve.source.GameLump_SPRP
valve.source.StaticPropv4
->source.SPRPv4
valve.source.StaticPropv5
->source.SPRPv5
valve.source.StaticPropv6
->source.SPRPv6
valve.left4dead.StaticPropv8
->left4dead.SPRPv8
valve.left4dead2.StaticPropv9
->left4dead2.SPRPv9
valve.orange_box.StaticPropv10
->orange_box.SPRPv10
valve.orange_box_x360.StaticPropv4_x360
->orange_box_x360.SPRPv4_x360
valve.orange_box_x360.StaticPropv5_x360
->orange_box_x360.SPRPv5_x360
valve.orange_box_x360.StaticPropv6_x360
->orange_box_x360.SPRPv6_x360
valve.orange_box_x360.StaticPropv10_x360
->orange_box_x360.SPRPv10_x360
valve.sdk_2013.StaticPropv10
->sdk_2013.SPRPv10
valve.sdk_2013.StaticPropv11
->sdk_2013.SPRPv11
valve.sdk_2013_x360.StaticPropv8_x360
->sdk_2013_x360.SPRPv8_x360
valve.sdk_2013_x360.StaticPropv9_x360
->sdk_2013_x360.SPRPv9_x360
valve.sdk_2013_x360.StaticPropv10_x360
->sdk_2013_x360.SPRPv10_x360
valve.sdk_2013_x360.StaticPropv11_x360
->sdk_2013_x360.SPRPv11_x360
nexon.vindictus.GameLump_SPRP
valve.source.StaticPropv6
&nexon.vindictus.StaticPropScale
->vindictus.SPRPv6
respawn.titanfall.GameLump_SPRP
respawn.titanfall.StaticPropv12
->titanfall.SPRPv12
respawn.titanfall_x360.GameLump_SPRP_x360
respawn.titanfall_x360.StaticPropv12_x360
->titanfall_x360.SPRPv12_x360
respawn.titanfall2.GameLump_SPRP
respawn.titanfall2.StaticPropv13
->titanfall2.SPRPv13
GameLump
classes to work the same asSpecialLumpClasses
__init__
creates an empty lump for population.from_bytes()
@classmethod
replaces old__init__
StaticPropClass
is part of class definition (similar tolumps.BspLump
).from_bytes()
should map alumps.BspLump
to reduce memory use (see #80)GameLump
subclasses, instead of lambdas wrapping__init__
StaticPropClass
in.as_bytes()
bytearray
forStaticPropClass
if undefined (derive length fromprop_count
)