Conversation
There was a problem hiding this comment.
Pull request overview
Adds an initial native (non-Docker) implementation for Dofus 3 Unity bundle/image/i18n unpacking to avoid Docker Desktop UID/GID issues on Windows (fixes #114), while keeping a Docker backend available via DODUDA_UNITY_BACKEND.
Changes:
- Introduce Unity unpack backend abstraction with
nativeas default anddockeras opt-in. - Implement native Unity bundle decoding, imagebundle extraction, and i18n
.binparsing (plus a native i18n test). - Add a mapping-time normalization step to rewrite
ridfields to strings for Unity JSON inputs.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| update.go | Switch Unity bundle/image unpacking to backend selection; image pulls now via backend Prepare. |
| unity_backend.go | Adds backend selection via DODUDA_UNITY_BACKEND (default native). |
| unity_backend_native.go | Native backend adapter wiring into new native unpackers. |
| unity_backend_docker.go | Docker backend moved here (container-based bundle/image unpack + image pulling). |
| unity_bundle_native.go | Native UnityFS bundle reader + type tree decoding into JSON. |
| unity_imagebundle_native.go | Native .imagebundle sprite/texture extraction and PNG writing. |
| unity_i18n_native.go | Native localization .bin to JSON converter. |
| unity_i18n_native_test.go | Test covering native i18n conversion using an on-repo fixture. |
| mapping.go | Adds RID normalization pass over Unity raw JSON files prior to parsing. |
| images.go | Adds fallback logic for directory layout differences between backends. |
| README.md | Updates docs to reflect native Dofus 3 unpacking and Docker being optional/legacy. |
| go.mod / go.sum | Adds deps required for native Unity decoding/decompression and texture handling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| feedbacks := make(chan string) | ||
|
|
||
| var feedbackWg sync.WaitGroup | ||
| if !muteSpinner { | ||
| feedbackWg.Add(1) |
There was a problem hiding this comment.
PullImages creates an unbuffered feedbacks channel and only starts a consumer goroutine when muteSpinner is false. If muteSpinner is true, any send to feedbacks later in the function will block forever. Consider buffering the channel, always consuming it, or guarding sends when muteSpinner is true.
| _, err = io.ReadAll(imageHandle) | ||
| if err != nil { | ||
| log.Fatalf("Error finishing image handler: %v", err) | ||
| } |
There was a problem hiding this comment.
PullImages returns an error in its signature, but io.ReadAll errors currently call log.Fatalf which terminates the process and skips caller error handling. Prefer returning the error (wrapped with context) instead of exiting.
| feedbackWg.Wait() | ||
|
|
||
| return nil | ||
| return unpackUnityI18nNative(inputPath, outputPath) |
There was a problem hiding this comment.
UnpackUnityI18n bypasses the selected Unity backend and always uses the native implementation, even when DODUDA_UNITY_BACKEND=docker is set. If users force the Docker backend for consistency/workarounds, this behavior is surprising; consider routing i18n unpacking through the backend selection as well (e.g., add it to UnityUnpackBackend).
| errorChan <- err | ||
| } | ||
| } else if errors.Is(err, os.ErrNotExist) { | ||
| if _, toErr := os.Stat(toPath); toErr != nil { |
There was a problem hiding this comment.
This fallback branch triggers on any error from os.Stat(toPath), not just "not exists". For example, permission or transient IO errors would incorrectly send the code down the native-backend fallback path. Consider checking errors.Is(toErr, os.ErrNotExist) explicitly (and returning other errors).
| if err := os.WriteFile(filePath, rewritten, os.ModePerm); err != nil { | ||
| return fmt.Errorf("write %s: %w", entry.Name(), err) |
There was a problem hiding this comment.
normalizeUnityRIDTypes rewrites the original raw JSON files in-place (and re-serializes them without preserving formatting). This is a potentially surprising/destructive side effect for a "map" operation. Consider normalizing during parsing, writing normalized copies to a temp/work directory, or scoping the rewrite to files known to require RID normalization.
| return append([]byte(nil), out...), nil | ||
| } | ||
|
|
||
| func unityCropSpriteImage(src image.Image, sprite *uni.Sprite) image.Image { |
There was a problem hiding this comment.
unityCropSpriteImage is currently unused. If sprites need to be cropped to TextureRect (which this helper suggests), the current export likely writes full textures instead of per-sprite images. Either wire this into the sprite decode/export path or remove the dead code to avoid confusion.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@copilot apply changes based on the comments in this thread |
…g, stat check, in-place normalization, dead code Agent-Logs-Url: https://github.com/dofusdude/doduda/sessions/e8c76188-9498-45ba-a041-9bc8b48959f6 Co-authored-by: stelzo <40026170+stelzo@users.noreply.github.com>
Applied all changes from the review thread in commit 554dbd0:
|
fixes #114