Skip to content

Fixed improper parsing of particles with version 5.2#270

Merged
Exactol merged 4 commits into
ruarai:masterfrom
Natanxp2:fix_particles_5_2
Jul 12, 2025
Merged

Fixed improper parsing of particles with version 5.2#270
Exactol merged 4 commits into
ruarai:masterfrom
Natanxp2:fix_particles_5_2

Conversation

@Natanxp2
Copy link
Copy Markdown
Contributor

@Natanxp2 Natanxp2 commented Jul 2, 2025

Changes

  • BSP.cs compared the wrong Item to particleKeys ( value from prop instead of the key )
  • Fixed improper parsing of pcf 5.2

Followed Valve Developer Wiki to make parsing changes

Important Note

These changes were made and tested in my packing tool ( bspPack ) stripped out of CompilePal packing functionality.
I do not currently have access to windows to properly test them in CompilePal.

EDIT: Added a commit to fully close #143

@Natanxp2 Natanxp2 changed the title Fix improper parsing of particles with version 5.2 Fixed improper parsing of particles with version 5.2 Jul 2, 2025
@maxdup
Copy link
Copy Markdown
Collaborator

maxdup commented Jul 2, 2025

Related issue #143

@maxdup
Copy link
Copy Markdown
Collaborator

maxdup commented Jul 3, 2025

For the most part, this is a step in the right direction.
However, I believe the wiki is wrong when it says:

struct CDmxElement
{
	unsigned int typeNameIndex; // String dictionary index
	unsigned int elementNameIndex; // String dictionary index
	unsigned char dataSignature[16]; // Globally unique identifier
};

My previous research shows that the real struct is in fact

struct CDmxElement
{
	unsigned short typeNameIndex; // String dictionary index
        unsigned short elementDescIndex; // String dictionary index
	unsigned int elementNameIndex; // String dictionary index
	unsigned char dataSignature[16]; // Globally unique identifier
};

typeNameIndex is always a ushort across all versions. v5 introduces a description string.
(Note: these two are the same length in bytes so it's easy to confuse)

I haven't looked into PCF in a LONG time, so I advise to double check carefully. Without having ran the code myself, my intuition is that typeNameIndex isn't going to be read properly in many cases because of this.

@maxdup
Copy link
Copy Markdown
Collaborator

maxdup commented Jul 3, 2025

Also you've missed this one

int typeID = reader.ReadUInt16();

which is a uint32 in v5 (as stated by the wiki)

I'm really happy someone is looking into this btw <3

@Natanxp2
Copy link
Copy Markdown
Contributor Author

Natanxp2 commented Jul 3, 2025

Thanks for catching that typeID!
I would not be surprised if wiki was wrong, it also states that The string dictionary starts with the number of strings to follow. For Binary 4 PCF 2, the number is an (unsigned?) int, otherwise, an (unsigned?) short. but from testing it seems to also be an int for Binary 5 PCF 2.

I'll look into the structure more, 2 shorts would make sense there

@Natanxp2
Copy link
Copy Markdown
Contributor Author

Natanxp2 commented Jul 3, 2025

all_pcfs.txt

It's difficult to tell if it's
short nameIndex
short descriptionIndex

or
int nameIndex

I checked all 5.2 pcfs from momentum mod ( I believe that also includes all cs:go pcfs ) and last 2 bytes of the nameIndex are always 00 00. If it's meant to be a descriptionIndex it seems to be unused. Do you have any pcfs where that is not the case?

@Natanxp2
Copy link
Copy Markdown
Contributor Author

Natanxp2 commented Jul 3, 2025

Added a commit to always prepend "materials" and "models" to fully close #143
Since it's in the same issue I hope you don't mind me not uploading it as a separate PR

@maxdup
Copy link
Copy Markdown
Collaborator

maxdup commented Jul 3, 2025

all_pcfs.txt

It's difficult to tell if it's short nameIndex short descriptionIndex

or int nameIndex

I checked all 5.2 pcfs from momentum mod ( I believe that also includes all cs:go pcfs ) and 2 last bytes of the nameIndex are always 00 00. If it's meant to be a descriptionIndex it seems to be unused. Do you have any pcfs where that is not the case?

I'll have a look when I have the time, very glad to close the books on this old issue ^^

@Natanxp2 Natanxp2 force-pushed the fix_particles_5_2 branch from 36cf4c0 to f0ebf4c Compare July 3, 2025 17:41
@Natanxp2
Copy link
Copy Markdown
Contributor Author

Natanxp2 commented Jul 3, 2025

If you don't manage to find any pcfs that don't have those bytes as 00 00 I think it's still safer to just read the name as ushort and skip next 2 bytes. There would need to be over 65535 strings in a pcf to use them anyway and I don't think any pcf even approaches that number. If you somehow manage to confirm it's an int I'll rebase and drop this last commit but I think it's safe to merge like this

@maxdup
Copy link
Copy Markdown
Collaborator

maxdup commented Jul 4, 2025

tldr: I've refreshed my memory by looking at the portal 2 and csgo files. nameIndex being a short or an int is not going to have any incidence as far as I can tell from all official pcf flles.

That being said, I'm still going to make a case for the ushort description to anyone willing to hear me out (altho pointless it might be)

Pcf stores all its strings in an array. I was attempting to be as thorough as possible when I wrote my own pcf parser back in the days. One thing I took the time to verify was the strings that were unaccounted for.

In portal 2 and csgo, there are only 3 strings that come up all the time: "DmElement", "name" and "type_dictionary".
The structs provided by the VDC don't ever point to them.

For "DmElement", it seems somewhat obvious that it's an adequate description for the CDmxElement struct.
it's hella redundant, but I've come to the conclusion that every CDmxElement points to the the "DmElement" string. Which happens to be the string [0] in every case. Could be a jump in logic on my part but I'm sticking to it :p

I have not found the reason behind "name" and "type_dictionary". Those strings are a mystery to me to this day.

Good luck to everyone on your future reverse engineering journeys ✌️

@Natanxp2
Copy link
Copy Markdown
Contributor Author

Natanxp2 commented Jul 4, 2025

Thank you for looking into this!
I agree that short is way more likely to be the case.
In case this ever becomes a problem ( which I very much doubt it will ) I left a comment explaining the situation in the code.
Unless any more changes are requested it should be safe to merge

@Exactol Exactol merged commit f86213c into ruarai:master Jul 12, 2025
@Natanxp2 Natanxp2 deleted the fix_particles_5_2 branch July 13, 2025 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PCF parsing improvements

3 participants