Refresh the inventory on the user's queue, which the client joins by connecting
CI / build (push) Successful in 25s

The client never subscribes to its user queue; the proxy now follows every IMQ connection and the signed-in
account (from the login answer), and delivers the refresh event on /user/<id>. Checked live: removing a product
from the library on the hub reloads the client's inventory.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-29 19:16:30 -07:00
1 parent ca7a86ce89
commit 5b4e44c4e7
5 files changed
+34 -11

No files matched your search

+23 -11
View File
@@ -31,7 +31,7 @@ type room struct {
userIDs map[int64]string // user -> the gateway's user_id for them, as last seen
missing map[string]bool // products others wear that aren't in the packs (logged once)
last map[string][]hub.Avatar // chat -> what the hub last said about the others in it
users map[*proxy.IMQConn]string // each connection's user queue ("/user/<id>")
conns map[*proxy.IMQConn]bool // the client's IMQ connections
}
func (r *room) init() {
@@ -42,7 +42,7 @@ func (r *room) init() {
r.userIDs = map[int64]string{}
r.missing = map[string]bool{}
r.last = map[string][]hub.Avatar{}
r.users = map[*proxy.IMQConn]string{}
r.conns = map[*proxy.IMQConn]bool{}
}
}
@@ -72,9 +72,6 @@ func (p *Products) Subscribed(c *proxy.IMQConn, queues []string) {
var joined []string
var rooms []string
for _, q := range queues {
if strings.HasPrefix(q, "/user/") {
p.room.users[c] = q
}
chat := chatOf(q)
if chat == "" {
continue
@@ -129,7 +126,7 @@ func (p *Products) Closed(c *proxy.IMQConn) {
p.Unsubscribed(c, queues)
p.roomMu.Lock()
delete(p.room.subs, c)
delete(p.room.users, c)
delete(p.room.conns, c)
p.roomMu.Unlock()
}
@@ -365,17 +362,32 @@ func (p *Products) interceptParticipant(x *proxy.Exchange) error {
return nil
}
// Opened implements proxy.IMQWatcher.
func (p *Products) Opened(c *proxy.IMQConn) {
p.roomMu.Lock()
defer p.roomMu.Unlock()
p.room.init()
p.room.conns[c] = true
}
// RefreshInventory has the client load its inventory again (after the library changed), with the server event
// IMVU sends after a purchase: "refreshInventory {}" on the user queue's web_msg mount.
// IMVU sends after a purchase: "refreshInventory {}" on the user queue's ("/user/<id>") web_msg mount.
func (p *Products) RefreshInventory() {
p.mu.Lock()
user := p.user
p.mu.Unlock()
if user == "" {
return
}
p.roomMu.Lock()
p.room.init()
users := make(map[*proxy.IMQConn]string, len(p.room.users))
for c, q := range p.room.users {
users[c] = q
var conns []*proxy.IMQConn
for c := range p.room.conns {
conns = append(conns, c)
}
p.roomMu.Unlock()
for c, q := range users {
q := "/user/" + user
for _, c := range conns {
if err := c.Deliver(imq.Delivered{UserID: "0", Queue: q, Mount: "web_msg", Message: []byte("refreshInventory {}")}); err != nil {
p.logf("products: refreshing the inventory: %v", err)
}