Get T5 products from the hub's catalogs
CI / build (push) Successful in 25s

The proxy keeps the person's library in a cache folder (hub-products in its data folder), one pack per
product, served like any other pack: the hub says which revision to load and which catalogs host it, each file
comes from a catalog and is checked against the hub's sha256 (files are kept by hash, so a new revision only
downloads what changed), and adult files are fetched with the hub's access token. Products someone wears in a
room that aren't here yet are fetched too, and put on them when they arrive.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-29 18:56:26 -07:00
1 parent 93fa2f5d90
commit c281fb572c
6 files changed
+579 -3

No files matched your search

+29 -1
View File
@@ -48,10 +48,38 @@ type Products struct {
// chats it's in (the hub client).
Observer Observer
// Want, if set, is asked for products someone in a room wears that aren't here (the fetcher gets hub products).
Want func(id string)
roomMu sync.Mutex
room room
}
// Ready is told a product arrived (the fetcher wrote it): it's served from now on, and given to the client for
// anyone in a room who wears it.
func (p *Products) Ready(id string) {
p.refresh(true)
p.roomMu.Lock()
p.room.init()
var chats []string
for chat, avatars := range p.room.last {
for _, a := range avatars {
for _, it := range a.Items {
if it.ID == id {
chats = append(chats, chat)
}
}
}
}
p.roomMu.Unlock()
for _, chat := range chats {
p.roomMu.Lock()
avatars := p.room.last[chat]
p.roomMu.Unlock()
p.Others(chat, avatars)
}
}
// Observer hears about the client's IMVU account, its community outfit, and the chats it's in.
type Observer interface {
Session(imvuID int64)
@@ -120,7 +148,7 @@ func (p *Products) refresh(force bool) {
}
for _, e := range entries {
dir := filepath.Join(root, e.Name())
if !e.IsDir() {
if !e.IsDir() || strings.HasPrefix(e.Name(), ".") { // hidden: the fetcher's work in progress
continue
}
if _, err := os.Stat(filepath.Join(dir, "t5de-product.json")); err != nil {