-
-
Notifications
You must be signed in to change notification settings - Fork 532
minor organisational tweaks to CBulletsyncPacket #4651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| // todo: do we really need to reset damage data when we're returning | ||
| // false? returning false deletes the packet, and other packets don't | ||
| // reset internal data based on validation failures. | ||
| ResetDamageData(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could get rid of ResetDamageData but not sure if it was added for a specific reason.
I asked AI to double check whether I am right and it agrees:
Looking at the code, when Read() returns false, the packet is indeed dropped and won't be processed further.
1. Packet is deleted immediately after Read() returns false
In
CPacketTranslator.cpp(lines 252-256):// Attempt to read the content, if we fail, delete the packet again if (!pTemp->Read(BitStream)) { delete pTemp; pTemp = NULL; }This confirms that when
Read()returns false, the packet object is immediately destroyed and not used further.2. Other packets DON'T reset state on validation failure
Checking similar packet implementations:
CKeysyncPacket.cpp(lines 69-80): Multiplereturn falsestatements without any cleanupCObjectSyncPacket.cpp(lines 37-63): Returns false on validation errors without resetting allocated dataNone of the other packets reset their member variables before returning false from validation.
Conclusion
The
ResetDamageData()call at line 192 is not necessary because:
- The packet is deleted immediately after
Read()returns false- No other packet implementations reset state on validation failure
- The pattern across the codebase is to simply return false and let the packet translator handle cleanup
You could safely remove the
ResetDamageData()call to be consistent with other packet implementations.
| const auto* pPlayer = static_cast<const CPlayer*>(m_pSourceElement); | ||
| if (!pPlayer) | ||
| return false; | ||
|
|
||
| const ElementID id = pPlayer->GetID(); | ||
|
|
||
| if (id == INVALID_ELEMENT_ID) | ||
| return false; | ||
|
|
||
| // why? | ||
| if (id == 0) | ||
| return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be possible for Write to be called when m_pSourceElement doesn't exist or is invalid - this would indicate server corruption further up the stack.
this check should probably be removed, or moved to an outer function instead of here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I asked the LLM when would this return INVALID_ELEMENT_ID or 0? and it seems to agree:
Based on my investigation, here's when
pPlayer->GetID()would return these values:
INVALID_ELEMENT_ID(0xFFFFFFFF)Returns when:
- The element ID stack is exhausted - When CElementIDs::PopUniqueID() fails because there are no more available IDs in the stack (more than MAX_SERVER_ELEMENTS - 2 = 131,070 elements have been created)
- The CStack::Pop() returns
false, leavingIDwith its default value of INVALID_ELEMENT_IDID
0Returns when:
- ID 0 is actually assigned from the stack - Looking at the CStack implementation, IDs are added starting from ulOldSize + 1. With initial capacity expansion, the stack is populated with IDs from
1toINITIAL_MAX_STACK_SIZE- However, ID
0could theoretically be assigned if manually pushed back into the stack (e.g., via PushUniqueID(0)), though this would be unusualThe comment // why? next to the
id == 0check is questioning why this check exists. Based on the code:
- Element IDs should normally start from 1 (based on the stack initialization logic)
- ID 0 being reserved/invalid is likely a defensive check or legacy code
- The MAX_SERVER_ELEMENTS - 2 capacity suggests IDs 0 and
RESERVED_ELEMENT_IDare intentionally excluded from the valid rangeIn practice, these conditions should be extremely rare in normal operation - they would only occur if:
- The server has run out of element IDs (server created 131,070+ elements)
- There's a bug causing ID 0 to be pushed back into the stack
- Memory corruption or initialization failure
| CPlayer* pPlayer = static_cast<CPlayer*>(m_pSourceElement); | ||
| if (pPlayer) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #4651 (comment) for more details on this code being deleted
Summary (I recommend reading commit by commit)
ctor-initializer(we should have one, not both)ResetDamageDatabefore everyreturn falseinReadOptionalDamage, just have the caller do it whenReadOptionalDamagereturns falseMotivation
We were talking about packet architecture in the dev Discord and noticed that there was some dead code, so I thought I'd fix it. While I was here, I noticed other minor improvements that could be made.
Test plan
CI