Skip to content

Fix reconnect crash (EOCD) and building-placement NullReferenceException#195

Open
chrizZzt wants to merge 1 commit into
thomaswp:masterfrom
chrizZzt:fix/reconnect-and-placement-crashes
Open

Fix reconnect crash (EOCD) and building-placement NullReferenceException#195
chrizZzt wants to merge 1 commit into
thomaswp:masterfrom
chrizZzt:fix/reconnect-and-placement-crashes

Conversation

@chrizZzt

Copy link
Copy Markdown

Fixes two independent crashes observed on Timberborn 1.0.13.1 / BeaverBuddies 1.7.1.

Fixes #193
Fixes #194

1. Reconnect crash — "End of Central Directory record could not be found" (#193)

After the host connection drops (SocketException: Connection refused), the client receives a short non-map payload (e.g. 213 bytes; real maps are ~420–460 KB) as its "first message". ClientConnectionService.LoadMap writes those bytes into a save and loads them, so ZipArchive throws during scene load (outside LoadMap, so a local try/catch can't catch it) and the game crashes.

Fix: validate the received bytes before loading — a Timberborn save is a ZIP, so it must start with the local-file-header magic PK\x03\x04 and have a minimum length. If the data isn't a valid save, show the existing connection-failed dialog (ShowError(null)) instead of loading a bogus save.

2. NullReferenceException in ReplayEvent.GetEntityID (#194)

When placing/duplicating a building, GetEntityID(DuplicationSource) calls component.GetComponent<EntityComponent>(), which throws internally in ComponentCache.GetIndex<T>() when the component isn't registered as an entity yet. The existing ?. only guards a null component, not an exception thrown inside GetComponent.

Fix: catch the exception and return null; callers already treat a null entity ID as "not an entity" and fall back to the base behaviour.

Notes

  • Both changes are minimal and defensive; no protocol changes, so a patched client stays compatible with an unpatched host (and vice-versa).
  • Verified the project builds against Timberborn 1.0.13.1 (Release Steam). I was not able to run an extensive multi-machine co-op session, so a second pair of eyes on the reconnect path is welcome.
  • Diagnosed from five Error reports/*.zip crash dumps; details and logs are in the linked issues.

Co-authored with assistance from Claude Code.

Two independent crashes observed on Timberborn 1.0.13.1 / BeaverBuddies 1.7.1:

1. Client reconnect crash "End of Central Directory record could not be
   found". After the host connection drops (SocketException: Connection
   refused), the client receives a short non-map payload (e.g. 213 bytes;
   real maps are ~420-460 KB) and ClientConnectionService.LoadMap writes it
   to a save and loads it, so ZipArchive throws during scene load and the
   game crashes. LoadMap now validates the data (ZIP local-header magic +
   minimum length) and shows the connection-failed dialog instead of
   loading a bogus save.

2. NullReferenceException in ReplayEvent.GetEntityID when placing or
   duplicating a building. GetComponent<EntityComponent>() throws internally
   (ComponentCache) on a component that isn't registered as an entity yet
   (e.g. a duplication source while a tool is mid-use); the existing ?. only
   guards a null component. GetEntityID now catches that and returns null,
   which callers already handle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thomaswp

Copy link
Copy Markdown
Owner

Thanks for the issues and the PR. I'm traveling and won't be able to look at it until next week, but I'll get back to you then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants