Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.12.2
1.12.3
2 changes: 1 addition & 1 deletion client/docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Generated from `internal/apispec` by `cmd/apidocgen`. Do not edit by hand.

**Client version:** `1.12.2`
**Client version:** `1.12.3`

The Client is a local HTTP server (default port **62485**) that bridges Blendkit DCC add-ons (Blender, Godot, and embedders such as Maya and Rhino) with the Blendkit web service.

Expand Down
2 changes: 1 addition & 1 deletion client/docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "GPL-2.0-or-later"
},
"title": "Blendkit-Client API",
"version": "1.12.2"
"version": "1.12.3"
},
"openapi": "3.1.0",
"paths": {
Expand Down
5 changes: 5 additions & 0 deletions client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,17 @@ func main() {
systemIDOverride := flag.String("system_id", "", "stable machine ID (15 digits) persisted by the add-on; overrides the MAC-derived ID so telemetry survives MAC randomization")
flag.Parse()

// Machine ID precedence: --system_id from the spawning add-on, then the ID the
// add-on persisted (a standalone Client gets no flag but must report the same
// machine), and only then the MAC-derived fallback set in init().
if *systemIDOverride != "" {
if validSystemID(*systemIDOverride) {
SystemID = systemIDOverride
} else {
BKLog.Printf("Ignoring invalid --system_id %q, keeping MAC-derived ID", *systemIDOverride)
}
} else if persisted := persistedSystemID(); persisted != "" {
SystemID = &persisted
}

// A standalone Client is one a user started directly — no add-on passed its
Expand Down
36 changes: 36 additions & 0 deletions client/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,42 @@ func validSystemID(s string) bool {
return true
}

// systemIDFilePath mirrors the add-on's paths.get_system_id_filepath().
func systemIDFilePath() string {
home := os.Getenv("XDG_DATA_HOME")
if home == "" {
var err error
home, err = os.UserHomeDir()
if err != nil {
return ""
}
}
return filepath.Join(home, "blenderkit_data", "system_id")
}

// persistedSystemID returns the machine ID the add-on stored, or "" when absent.
//
// The add-on passes the same value via --system_id when it spawns the Client, but
// a Client started standalone (or by another software's add-on) gets no flag, and
// must not fall back to a MAC-derived ID the add-on no longer uses: the two would
// then report different machines for the same user. The file is the shared source
// of truth; the Client only ever reads it.
func persistedSystemID() string {
path := systemIDFilePath()
if path == "" {
return ""
}
content, err := os.ReadFile(path)
if err != nil {
return ""
}
id := strings.TrimSpace(string(content))
if !validSystemID(id) {
return ""
}
return id
}

func StringToAddonVersion(s string) (*AddonVersionStruct, error) {
adVer := &AddonVersionStruct{}
if s == "" {
Expand Down
29 changes: 29 additions & 0 deletions client/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ package main

import (
"fmt"
"os"
"path/filepath"
"reflect"
"regexp"
"strings"
Expand Down Expand Up @@ -205,3 +207,30 @@ func TestValidSystemID(t *testing.T) {
}
}
}

func TestPersistedSystemID(t *testing.T) {
dir := t.TempDir()
t.Setenv("XDG_DATA_HOME", dir)
if err := os.MkdirAll(filepath.Join(dir, "blenderkit_data"), 0o755); err != nil {
t.Fatal(err)
}
path := filepath.Join(dir, "blenderkit_data", "system_id")

if got := persistedSystemID(); got != "" {
t.Errorf("missing file: got %q; want empty", got)
}

if err := os.WriteFile(path, []byte("000000000000123\n"), 0o644); err != nil {
t.Fatal(err)
}
if got := persistedSystemID(); got != "000000000000123" {
t.Errorf("valid file: got %q; want 000000000000123", got)
}

if err := os.WriteFile(path, []byte("not-an-id"), 0o644); err != nil {
t.Fatal(err)
}
if got := persistedSystemID(); got != "" {
t.Errorf("garbage file: got %q; want empty (falls back to MAC)", got)
}
}
Loading