Skip to content

fix(ini): Remove superfluous call to INI::getNextTokenOrNull in GenericObjectCreationNugget::parseDebrisObjectNames#2597

Open
Caball009 wants to merge 1 commit into
TheSuperHackers:mainfrom
Caball009:ini_change_next_token
Open

fix(ini): Remove superfluous call to INI::getNextTokenOrNull in GenericObjectCreationNugget::parseDebrisObjectNames#2597
Caball009 wants to merge 1 commit into
TheSuperHackers:mainfrom
Caball009:ini_change_next_token

Conversation

@Caball009

@Caball009 Caball009 commented Apr 13, 2026

Copy link
Copy Markdown

This PR fixes a minor bug in the parsing of the ini OCL model names; every even token would be skipped.

This affects two types of OCL:

  1. ObjectCreationList Name - CreateDebris (doesn't impact game logic AFAIK)
  2. ObjectCreationList Name - CreateObject (does impact game logic AFAIK)

Example of debris with multiple model names:
https://github.com/TheSuperHackers/GeneralsGamePatch/blob/5845293dd12ab10c5f16c6f3116ce526f62dc369/Patch104pZH/GameFilesOriginalZH/Data/INI/ObjectCreationList.ini#L2130-L2138

It should have no effect on the game logic for the default ini files, but it may be different for mods that create ObjectCreationList Name - CreateObject with more than one model name.

GenericObjectCreationNugget::m_names is used for the game logic here:

Int pick = GameLogicRandomValue(0, m_names.size() - 1);

@Caball009 Caball009 added the Minor Severity: Minor < Major < Critical < Blocker label Apr 13, 2026
@Mauller

Mauller commented Apr 13, 2026

Copy link
Copy Markdown

I mentioned this in the other PR, but i think we should just go down to having a single function getNextToken but it can return null.

External code should then check for null on the first token and gracefully handle it instead of throwing like the original variant did.

@Caball009 Caball009 force-pushed the ini_change_next_token branch from ecbefac to a716f4d Compare June 28, 2026 22:12
@Caball009 Caball009 added Gen Relates to Generals ZH Relates to Zero Hour Fix Is fixing something, but is not user facing labels Jun 28, 2026
@Caball009 Caball009 changed the title tweak(ini): Improve consistency in use of INI::getNextTokenOrNull fix(ini): Remove superfluous call to INI::getNextTokenOrNull Jun 28, 2026
@Caball009 Caball009 changed the title fix(ini): Remove superfluous call to INI::getNextTokenOrNull fix(ini): Remove superfluous call to INI::getNextTokenOrNull in GenericObjectCreationNugget::parseDebrisObjectNames Jun 28, 2026
@Caball009

Copy link
Copy Markdown
Author

I narrowed the scope of this PR.

@Caball009 Caball009 marked this pull request as ready for review June 28, 2026 23:04
@greptile-apps

greptile-apps Bot commented Jun 28, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a token-skipping bug in GenericObjectCreationNugget::parseDebrisObjectNames, where the INI parser advanced twice per loop iteration (once in the loop body, once in the for-increment), causing every second debris object name to be silently dropped. The fix wraps the redundant in-body getNextTokenOrNull() call in a #if RETAIL_COMPATIBLE_CRC guard to preserve the original behavior for CRC-compatible builds while correcting parsing in non-retail builds.

  • Bug fix: Removes the extra ini->getNextTokenOrNull() call inside the loop body so all tokens are consumed exactly once per iteration, restoring full debris name lists for non-retail builds.
  • Retail compatibility: The original (buggy) behavior is preserved under the RETAIL_COMPATIBLE_CRC macro to avoid breaking replay/CRC compatibility with the shipped retail game.
  • Both game directories affected: The identical fix is applied to both Generals/ and GeneralsMD/ (Zero Hour) copies of ObjectCreationList.cpp.

Confidence Score: 5/5

Safe to merge — the change is a minimal, well-scoped fix with no risk of unintended side effects outside the debris name parsing loop.

The fix removes exactly one redundant getNextTokenOrNull() call per loop iteration and correctly preserves the original double-advance under RETAIL_COMPATIBLE_CRC for CRC/replay compatibility. Both affected files receive the identical change. The loop logic before and after is easy to follow and the fix is demonstrably correct.

No files require special attention.

Important Files Changed

Filename Overview
Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp Wraps the superfluous in-body getNextTokenOrNull() in #if RETAIL_COMPATIBLE_CRC so non-retail builds parse all debris names correctly; change is minimal and correct.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp Identical fix applied to the Zero Hour copy of parseDebrisObjectNames; same correctness assessment as the Generals counterpart.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["for-init: token = getNextToken()"] --> B{token != null?}
    B -- No --> Z[End loop]
    B -- Yes --> C["push token to m_names"]
    C --> D{RETAIL_COMPATIBLE_CRC?}
    D -- Yes --> E["token = getNextTokenOrNull()\n(extra advance — skips one token)"]
    E --> F["for-increment: token = getNextTokenOrNull()"]
    D -- No --> F
    F --> B

    style E fill:#f9a,stroke:#c33
    style D fill:#adf,stroke:#36c
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["for-init: token = getNextToken()"] --> B{token != null?}
    B -- No --> Z[End loop]
    B -- Yes --> C["push token to m_names"]
    C --> D{RETAIL_COMPATIBLE_CRC?}
    D -- Yes --> E["token = getNextTokenOrNull()\n(extra advance — skips one token)"]
    E --> F["for-increment: token = getNextTokenOrNull()"]
    D -- No --> F
    F --> B

    style E fill:#f9a,stroke:#c33
    style D fill:#adf,stroke:#36c
Loading

Reviews (1): Last reviewed commit: "Removed superfluous call to 'getNextToke..." | Re-trigger Greptile

@Caball009 Caball009 requested a review from xezon June 29, 2026 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Fix Is fixing something, but is not user facing Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants