Skip to content

feat: make connection and version problems diagnosable, add compose - #60

Draft
ofmiceandcam98-eng wants to merge 1 commit into
tiltedphoques:mainfrom
ofmiceandcam98-eng:feat/diagnostics-and-compose
Draft

feat: make connection and version problems diagnosable, add compose#60
ofmiceandcam98-eng wants to merge 1 commit into
tiltedphoques:mainfrom
ofmiceandcam98-eng:feat/diagnostics-and-compose

Conversation

@ofmiceandcam98-eng

Copy link
Copy Markdown

Four small changes, each from time lost to a failure that produced no useful output. Happy to split if you'd prefer.

1. Game version check

Log the game version at load, and warn when it isn't the tested one.

On an unsupported patch the mod currently fails as a wall of script validation errors:

Missing native function 'GetNetworkWorldSystem' in native class 'GameInstance'
Native class 'IGameSystem' has declared base class 'IScriptable' that is different than current one 'gameIGameSystem'
Native class 'Event' has declared base class 'IScriptable' that is different than current one 'redEvent'

Nothing there says "wrong game version." It cost me hours before I worked that out. Now:

Game version 2.31.0
CyberpunkMP was tested against game 2.31 - you are on 2.4.
If the game refuses to start with script validation errors, this mismatch is the likely cause.

It warns rather than refuses — a later patch may work fine, and hard-blocking would be presumptuous. The supported version is a single constexpr in Main.cpp.

2. Client connection diagnostics

Log the resolved address and the dialled address, and say when the launch arguments weren't parsed:

Server address: 100.109.102.127:11778 (ip from launch args, port from launch args)
Connecting to 100.109.102.127:11778

The game's parser only populates these for the --key=value form. Writing -ip 1.2.3.4 leaves the value list empty, so settings.ip silently stays 127.0.0.1 and the client times out against the player's own machine. From the outside that is indistinguishable from a dead server — two of us lost an evening to it, with a correct-looking IP sitting in the launch script the whole time.

Server address: 127.0.0.1:11778 (ip DEFAULT - --ip= was not parsed, port ...)

3. Server connection observability

OnConnection / OnDisconnection logged at debug, which isn't emitted by default:

spdlog::debug("Connection received {:x}", aHandle);

So a server operator cannot distinguish a client that never reached them from one that reached them and failed later — which is exactly the question you need answered when someone says "I can't connect." Now logged at info, with the peer address:

Connection received from 100.80.238.91:52134 (id 3f2a1b)
Connection 3f2a1b ended (reason 2)

4. Docker Compose

A compose file over the existing Dockerfile, so hosting is one command:

  • Requires the admin credentials the server refuses to start without (fails fast with a clear message instead of a SecurityException at runtime)
  • Publishes UDP (game) and TCP (web API)
  • Persists config/, plugins/, logs/ on the host so settings survive a rebuild
  • Sets tty: truewithout a console attached the server crashes on startup, because Swan doesn't register its ConsoleLogger and WebApi's Logger.UnregisterLogger<ConsoleLogger>() throws "The logger is not registered". That one is non-obvious and worth encoding in the compose file.

.env is gitignored so credentials aren't committed; .env.example documents what's needed.

Verification

Client and server both build. Tested on game 2.31 with two clients connecting over a VPN — the address logging is what finally identified a malformed --ip= argument on the remote machine.

Related: #56 (build), #57 (loads on 2.31), #58 (remote players), #59 (SdkGenerator).

Every one of these came from time lost to a failure that produced no
useful output.

Game version check (client/Main.cpp)
-----------------------------------
Log the game version at load, and warn when it isn't the one this build
was tested against. On an unsupported patch the mod currently fails as a
wall of script validation errors ("Missing native function ...",
"declared base class ... different than current one ...") that give no
hint the game version is the cause. Warn rather than refuse: a later
patch may work fine, and blocking it would be presumptuous.

Connection diagnostics (client/Settings.cpp, NetworkWorldSystem.cpp)
-------------------------------------------------------------------
Log the address we resolve and the address we dial, and say explicitly
when --ip= / --port= were not parsed and the defaults are in use.

The game's parser only fills these in for the --key=value form. Writing
"-ip 1.2.3.4" leaves the value list empty, so settings.ip silently stays
127.0.0.1 and the client times out against the player's own machine -
indistinguishable, from the outside, from a dead server.

Server connection observability (server/GameServer.cpp)
-------------------------------------------------------
OnConnection/OnDisconnection logged at debug, which is not emitted by
default, so a server operator could not tell a client that never reached
them from one that reached them and failed later. Log at info, and
include the peer address on connect.

Docker Compose (docker-compose.yml, .env.example)
-------------------------------------------------
Compose file over the existing Dockerfile so hosting is one command.
Requires the admin credentials the server refuses to start without,
publishes UDP (game) and TCP (web api), persists config/plugins/logs on
the host, and sets tty: true - without a console attached, Swan does not
register its ConsoleLogger and WebApi's UnregisterLogger<ConsoleLogger>()
throws on startup. .env is gitignored so credentials are not committed.
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.

2 participants