Skip to content

Match HACKList writes to official TSLPatcher LongInt behavior - #349

Closed
arrenkaetris wants to merge 1 commit into
OpenKotOR:masterfrom
arrenkaetris:fix/hacklist-tslpatcher-longint
Closed

arrenkaetris wants to merge 1 commit into
OpenKotOR:masterfrom
arrenkaetris:fix/hacklist-tslpatcher-longint

Conversation

@arrenkaetris

Copy link
Copy Markdown

Description

Unprefixed [HACKList] values now follow official TSLPatcher. Delphi writes a 32-bit LongInt at the given offset. It only reverses those four bytes when the target filename ends in ncs.

The previous HoloPatcher path wrote a 2-byte big-endian word for the same INI line. That is a different width, not just a different endianness. 8=1234 on a .ncs file used to overwrite bytes [8,9] with 04 D2. Official TSLPatcher overwrites bytes [8,9,10,11] with 00 00 04 D2.

Most real [HACKList] mods were written and tested against TSLPatcher.exe. This change makes HoloPatcher produce the same bytes.

Official source in KotORPublicDomain/TSLPatcher:

iValue  : LongInt;
...
iValue  := StrToInt(sVal);
sExt := lowercase(copy(l_dlgopen.FileName, Length(l_dlgopen.FileName) - 2, 3));
if (lowercase(sExt) = 'ncs') then begin
    iValue := (((iValue and longint($FF000000)) shr 24)
            or ((iValue and longint($00FF0000)) shr 8)
            or ((iValue and longint($0000FF00)) shl 8)
            or ((iValue and longint($000000FF)) shl 24));
end;
theFile.seek(iOffset, soFromBeginning);
theFile.write(iValue, sizeof(iValue));

Optional u8: and u16: prefixes still select the narrower HoloPatcher widths.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test addition or update
  • Build system or CI changes
  • Code style changes (formatting, renaming, etc.)

The break is only for INI lines that relied on HoloPatcher's unofficial 2-byte default. Mods written for official TSLPatcher now match.

Package(s) Affected

  • PyKotor (core library)
  • One or more tools under Tools/
  • Documentation
  • CI/CD
  • Other: ___________

HoloPatcher consumes this library. The standalone OpenKotOR/HoloPatcher repo has no HACKList writer of its own.

Changes Made

Unprefixed HACKList values parse as 32-bit integers. .ncs targets are written big-endian. Other extensions stay little-endian, matching Delphi's native write() plus the NCS swap. The INI writer now emits u8: and u16: when those explicit widths are serialized, so a later read does not treat them as LongInts.

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this manually
  • I have tested on multiple Python versions (3.8+)
  • I have tested on multiple operating systems (if applicable)

Test Results

Libraries/PyKotor/tests/tslpatcher/test_hacklist.py and Libraries/PyKotor/tests/tslpatcher/parity/test_parity_harness.py passed locally (12 tests). The 8=1234 fixture now expects 000004d2. An explicit u16:1234 fixture still expects 04d2.

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Related Issues

Related to HoloPatcher install compatibility with official TSLPatcher [HACKList] mods.

Additional Notes

This pull request is against PyKotor because that is where [HACKList] is implemented. A pull request to OpenKotOR/HoloPatcher cannot change these bytes. HoloPatcher will pick up the fix when it uses a PyKotor build that includes this commit.

Official TSLPatcher always writes a LongInt and only byte-swaps that value for .ncs files. Matching that width keeps existing mods working when they were authored against TSLPatcher.exe.
@github-actions

Copy link
Copy Markdown
Contributor

Message that will be displayed on users' first pull request

@arrenkaetris

Copy link
Copy Markdown
Author

Testing this against a mod or 2 that implements [HACKList] is recommended first.

@github-actions github-actions Bot added package: holopatcher Related to HoloPatcher package: pykotor Related to PyKotor core labels Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: holopatcher Related to HoloPatcher package: pykotor Related to PyKotor core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants