Skip to content

Commit 25499cf

Browse files
Zayn995claude
andcommitted
Release v1.19.2: no network code, and no archive inside the exe
Two structural changes, both aimed at the antivirus false positives that are blocking the Nexus page. The exe was 90% embedded archive. --onedir in 1.19.0 only moved the DLLs into _internal; the Python code stayed inside S2Tweaker.exe as a zlib-compressed blob: 2,857,284 of 3,175,748 bytes, entropy 7.999 of a possible 8.0. That is the exact shape analysts use to identify PyInstaller malware, and the CI guard did not catch it because 3.17 MB passed an 8 MB limit. With --debug noarchive the modules ship as plain .pyc in _internal: the launcher is 345,705 bytes with entropy 6.823. --noupx pins the packer off, since the generated spec sets upx=True and only a missing UPX on PATH kept it dormant. The guard is now 1 MB and additionally counts .pyc files, so it tests the invariant it claims to test. The update check is gone, along with every trace of networking. Nexus' file submission guidelines prohibit executables that connect to the internet "unless where it is crucial" and state that "'auto update' functionality does not qualify as crucial". The tool now contains no urllib, no sockets and no HTTP client at all, and tests/test_no_network.py walks the AST of every module to keep it that way. That claim is worth more than the button was: a moderator can verify it with one grep. Also removed with it: the Updater badge, the wizard's fourth page and the FAQ entry that advertised update.bat. Page 3 no longer names update.bat as a landmark either - it has not been in the download since 1.19.1, and the wizard must never point at a file the user does not have. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent c1c270f commit 25499cf

12 files changed

Lines changed: 198 additions & 332 deletions

File tree

.github/workflows/build.yml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,22 @@ jobs:
7474
throw "Versions-Ressource unvollstaendig: $f ist leer"
7575
}
7676
}
77-
# Der Starter darf kein eingebettetes Archiv mehr sein.
78-
if ((Get-Item $exe).Length -gt 8MB) {
77+
# Der Starter darf kein eingebettetes Archiv mehr sein. Die alte
78+
# Schranke von 8 MB hat das NICHT geprueft: 1.19.1 kam mit
79+
# 3,17 MB durch und bestand zu 90 % aus genau dem Archiv, das
80+
# hier ausgeschlossen sein sollte. Mit --debug noarchive liegt
81+
# der Starter bei ~345 KB; 1 MB laesst Luft und schlaegt an,
82+
# sobald der Klumpen zurueckkehrt.
83+
if ((Get-Item $exe).Length -gt 1MB) {
7984
throw "Starter ist $((Get-Item $exe).Length) Bytes gross - steckt wieder ein Archiv drin?"
8085
}
86+
# Gegenprobe am Inhalt statt nur an der Groesse: die Module
87+
# muessen als .pyc in _internal liegen.
88+
$pyc = (Get-ChildItem "dist/S2Tweaker/_internal" -Recurse -Filter *.pyc | Measure-Object).Count
89+
"Module als .pyc : $pyc"
90+
if ($pyc -lt 100) {
91+
throw "Nur $pyc .pyc-Dateien - steckt der Python-Code wieder in der EXE?"
92+
}
8193
8294
- name: Programmordner als Artefakt
8395
# Genau dieses Artefakt bekommt spaeter die SignPath-Signatur.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ built lazily when you expand a category, so startup stays fast.
5757

5858
| Layer | Details |
5959
|---|---|
60+
| Network | **None.** Since 1.19.2 the program contains no networking code at all — no `urllib`, no sockets, no HTTP client — and the bundled repak is compiled without its HTTP/TLS stack. Both are enforced on every build ([tests/test_no_network.py](tests/test_no_network.py), [tests/test_no_download.py](tests/test_no_download.py)) and can be verified with one `grep` of this repository. The update check was removed with 1.19.2: Nexus' file submission guidelines prohibit internet-connecting executables "unless where it is crucial" and say "'auto update' functionality does not qualify as crucial". Updating is a manual file swap. |
6061
| Vanilla data | `repak unpack` of `pakchunk0-Windows.pak` (only the 29 needed GameData files), then `.cfg.bin` → text via the vendored decoder ([s2tweaker/vendor_bin2cfg.py](s2tweaker/vendor_bin2cfg.py)). Cached in `cache/vanilla-<pakSize>-s<schema>/`; a game update changes the fingerprint → automatic re-extraction. |
6162
| Oodle | The game's config archives are Oodle-compressed, so reading them needs the proprietary `oo2core_9_win64.dll`. The game does **not** ship it (Oodle is linked into the game executable), and **S2Tweaker never downloads it**: a program that pulls a library off the internet and then runs it looks exactly like a dropper, which is one reason scanners flag tools like this. The user places the file once; the tool looks in the usual local spots, always verifies the SHA-256, and says so at startup with a link and a target folder if it is missing. The bundled repak cannot fetch it either - it is built from source with the download function and its HTTP/TLS stack removed ([tools/build_repak.py](tools/build_repak.py)). Packing never needs Oodle. |
6263
| Parsing | [cfgparse.py](s2tweaker/cfgparse.py) parses GSC's cfg text format (`Name : struct.begin {refkey=...}``struct.end`) into a tree; `refkey` inheritance chains are resolved to get effective vanilla values. |

docs/CODE_SIGNING_POLICY.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,25 @@ source, and both are stated openly:
5050
## Privacy
5151

5252
S2Tweaker collects nothing. There is no telemetry, no analytics, no account
53-
and no usage reporting. It makes exactly two kinds of outbound request, both
54-
of which the user triggers:
55-
56-
1. **"Check for updates"** (a button, never in the background): one request
57-
to `api.github.com` asking for the latest release tag.
58-
2. **Oodle library**: one download from the public OodleUE mirror on GitHub,
59-
once, if the library is not already present on the machine.
53+
and no usage reporting.
54+
55+
Since 1.19.2 it makes **no outbound requests at all**. There is no networking
56+
code left in the program: no `urllib`, no sockets, no HTTP client. The
57+
bundled `repak.exe` is compiled from source with its download function and
58+
its entire HTTP/TLS stack removed, so it cannot make a request either. Both
59+
claims are enforced by [tests/test_no_network.py](../tests/test_no_network.py)
60+
and [tests/test_no_download.py](../tests/test_no_download.py) on every build,
61+
and anyone can verify them by grepping this repository.
62+
63+
Two earlier network paths were removed deliberately:
64+
65+
1. **"Check for updates"** — dropped in 1.19.2. Nexus Mods' file submission
66+
guidelines prohibit executables that connect to the internet "unless where
67+
it is crucial", and state that "'auto update' functionality does not
68+
qualify as crucial". Updating is now a manual file swap.
69+
2. **Oodle library download** — dropped in 1.19.1. A program that fetches a
70+
library and then loads it is dropper-shaped, and it caused antivirus false
71+
positives. The user places that file once, guided by a setup window.
6072

6173
Everything else — settings, presets, cache, generated mods — stays in the
6274
tool's own folder on the user's machine.

s2tweaker/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
Haltbarkeit, Mutanten usw.) eine Mod-Pak-Datei fuer den ~mods-Ordner.
55
"""
66

7-
__version__ = "1.19.1"
7+
__version__ = "1.19.2"
88

99

s2tweaker/faq.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -615,19 +615,17 @@
615615
},
616616
{
617617
"q": "Does S2Tweaker download anything? What is the Oodle file?",
618-
"a": "No, nothing - not the tool and not the repak it bundles. "
619-
"Reading your game's packed configs needs Oodle's "
620-
"oo2core_9_win64.dll, which is proprietary and may not be "
621-
"shipped with the tool. Older versions fetched it "
618+
"a": "No. Since 1.19.2 there is no networking code in the tool at "
619+
"all - not in it, not in the repak it bundles. Check the "
620+
"public source yourself. Reading your game's packed configs "
621+
"needs Oodle's oo2core_9_win64.dll, which is proprietary and "
622+
"may not be shipped with the tool. Older versions fetched it "
622623
"automatically; that was dropped, because a program that "
623624
"downloads a library and then runs it is exactly what "
624-
"malware does and it made scanners flag this tool. Now you "
625+
"malware does, and it made scanners flag this tool. Now you "
625626
"place the file once yourself: if it is missing, S2Tweaker "
626-
"says so at startup and gives you the link and the folder. "
627-
"Every Unreal Engine install has the file, as do some other "
628-
"S.T.A.L.K.E.R. 2 tools. Building a pak never needs it. The "
629-
"only network request left is the update check, and only "
630-
"when you click it.",
627+
"says so at startup and shows the link and the folder. "
628+
"Building a pak never needs it.",
631629
"k": "internet network download dll oodle offline privacy "
632630
"telemetry connection firewall blocked",
633631
},
@@ -787,16 +785,16 @@
787785
},
788786
{
789787
"q": "How do I update the tool? Is there an auto-update?",
790-
"a": "Click '⟳ Check for updates' (top right): the tool asks "
791-
"github.com once whether a newer release exists - never in "
792-
"the background. If there is one it opens the download "
793-
"page. There is also an optional helper, update.bat, that "
794-
"does the swap for you and keeps your old files as .bak. It "
795-
"is deliberately NOT in the download: a file that fetches "
796-
"something and replaces programs is what scanners dislike. "
797-
"The 'Updater' button shows whether you have it and offers "
798-
"the link. Settings, presets, output and cache always stay "
799-
"where they are.",
788+
"a": "By hand, and on purpose. Download the new version from "
789+
"where you got this one, then replace S2Tweaker.exe and the "
790+
"_internal folder next to it. Your settings, presets, "
791+
"output and cache stay where they are - nothing else has to "
792+
"be touched. There is no update check and no auto-update "
793+
"any more: a tool that talks to a server to fetch and "
794+
"replace program files is the pattern antivirus scanners "
795+
"and mod sites object to, and this one had enough trouble "
796+
"with false positives already. The version you are running "
797+
"is in the window title.",
800798
"k": "update autoupdate upgrade new version release download "
801799
"github check latest newer patch tool bat updater",
802800
},

0 commit comments

Comments
 (0)