mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-07 05:13:44 +00:00
fix(ugc): served player models keep the client's own collision
With ugc_manifest_models the world left made models out of the LXFML it sends when a property loads, so the client never built them and had no HKX: the UGC server makes no physics, and the HKX request got a 404, so served models had no collision. Now every model's LXFML is sent and the client builds each one (NIF and HKX). For the models whose mesh the UGC server made, once the client has loaded and 3 seconds after, the world sends it the served NIF's checksum and NotifyClientUGCModelReady: the client drops what it cached for the model and asks again, downloads the served mesh (its own NIF no longer matches) and keeps its own HKX (still matching). An HKX request is answered with the LXFML too, followed by the same switch, at most 3 times per client and model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -401,14 +401,19 @@ What the 1.10.64 client does with a placed player model (LOT 14, spawned with `b
|
||||
With `ugc_manifest=1` and `ugc_manifest_models=1` (`sharedconfig.ini`, default 0; the dashboard shows it under UGC
|
||||
serving), the worlds:
|
||||
|
||||
* **Property load**: send the LXFML (one `BlueprintSaveResponse`) only for the models whose mesh the UGC server hasn't
|
||||
made (no `model.nif` in `ugc_file_checksums`: pending, failed, empty or the UGC server not running). Made ones are
|
||||
left out; the client asks for their files.
|
||||
* **Property load**: send the LXFML of every model (one `BlueprintSaveResponse`): the client builds each model's NIF
|
||||
and HKX (its collision; the UGC server makes no physics). For the models whose mesh the UGC server made (a
|
||||
`model.nif` in `ugc_file_checksums`), once the client has loaded (`PlayerLoaded`) and 3 seconds after, the world
|
||||
sends it the served NIF's checksum and `NotifyClientUGCModelReady` for each placed copy. The client drops what it
|
||||
cached for the model and asks again: its cache now has the served NIF's checksum, which its own file doesn't match,
|
||||
so it downloads the served mesh, and still has its own HKX's, so it keeps the collision it built. The model shows
|
||||
as the client built it for those few seconds.
|
||||
* **NIF** of a made model: the UGC server's checksum; the client downloads `<id>.nif.sd0` from the UGC server.
|
||||
* **LXFML** of a made model: the MD5 and size of the stored LXFML inflated (what the UGC server serves as
|
||||
`<id>.lxfml.sd0`), worked out once per model and kept.
|
||||
* **HKX** of a made model: valid 0. The UGC server makes no physics: a client that built the model itself before keeps
|
||||
using its HKX; others ask the UGC server, get 404 (not a logout) and have no collision for that model.
|
||||
* **HKX** of any model: the model's LXFML (the UGC server makes no physics), and for a made model the same switch to
|
||||
the served mesh afterwards. At most 3 switches per client and model, so a client that keeps asking isn't switched
|
||||
back and forth for ever.
|
||||
* **Any model file of a model that isn't made** (e.g. a model someone else just placed, or `ugc_manifest_models=0`):
|
||||
the model's LXFML to that client (once per 10 seconds for the three requests), which builds it itself, so a model is
|
||||
never left waiting. A blueprint that isn't a player model gets valid 0.
|
||||
|
||||
Reference in New Issue
Block a user