Saving an outfit (POST /api/outfits.php) sent its community products to IMVU. They're now taken out (any ID in the community range, known or not), the request re-signed, and the products remembered under the outfit's ID, then added back when the client loads its saved outfits (marked AP if one is adult). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
400831bf3c
commit
6506c641f0
3 files changed
+159
-2
No files matched your search
@@ -47,6 +47,8 @@ func (p *Products) Intercept(x *proxy.Exchange) error {
|
||||
return p.interceptBaseLook(x)
|
||||
case "/api/service/inventory/inventory_delete.php":
|
||||
return p.interceptHide(x)
|
||||
case "/api/outfits.php":
|
||||
return p.interceptOutfits(x)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -576,3 +578,102 @@ func (p *Products) interceptHide(x *proxy.Exchange) error {
|
||||
x.Response = localResponse(200, "application/json", []byte(`{"success": true}`))
|
||||
return nil
|
||||
}
|
||||
|
||||
// interceptOutfits keeps community products out of saved outfits IMVU stores (POST /api/outfits.php, JSON with
|
||||
// "products": "1,2,3"), remembering them under the outfit's ID, and adds them back when the client loads saved
|
||||
// outfits (GET /api/outfits.php?batch=... or ?outfit_id=...: {"result": [{"user_outfits_id", "pids", ...}]}).
|
||||
func (p *Products) interceptOutfits(x *proxy.Exchange) error {
|
||||
if len(x.Body) > 0 {
|
||||
var save map[string]json.RawMessage
|
||||
if json.Unmarshal(x.Body, &save) != nil {
|
||||
return nil
|
||||
}
|
||||
var products string
|
||||
if json.Unmarshal(save["products"], &products) != nil {
|
||||
return nil // not a save (e.g. set_default_outfit_id)
|
||||
}
|
||||
var kept []string
|
||||
var community []string
|
||||
stripped := 0
|
||||
for _, f := range strings.Split(products, ",") {
|
||||
id, err := strconv.ParseInt(strings.TrimSpace(f), 10, 64)
|
||||
if err == nil && IsCommunity(id) {
|
||||
stripped++ // always kept from IMVU, even if its product isn't known anymore
|
||||
if pid, ok := p.state.productID(id); ok {
|
||||
community = append(community, pid)
|
||||
}
|
||||
continue
|
||||
}
|
||||
kept = append(kept, f)
|
||||
}
|
||||
if stripped == 0 {
|
||||
return nil
|
||||
}
|
||||
save["products"], _ = json.Marshal(strings.Join(kept, ","))
|
||||
body, _ := json.Marshal(save)
|
||||
if !p.keys.resign(x.Request.Header, x.Body, x.URL.RawQuery, body, x.URL.RawQuery) {
|
||||
return errNoKey
|
||||
}
|
||||
x.Body = body
|
||||
p.logf("products: kept %d community products out of an outfit saved to IMVU", stripped)
|
||||
x.ModifyResponse = func(resp *http.Response, b []byte) ([]byte, error) {
|
||||
var r struct {
|
||||
Result struct {
|
||||
OutfitID json.Number `json:"outfit_id"`
|
||||
} `json:"result"`
|
||||
}
|
||||
if json.Unmarshal(b, &r) == nil && r.Result.OutfitID != "" {
|
||||
if err := p.state.setOutfit(r.Result.OutfitID.String(), community); err != nil {
|
||||
p.logf("products: remembering an outfit: %v", err)
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
x.ModifyResponse = func(resp *http.Response, b []byte) ([]byte, error) {
|
||||
var r map[string]json.RawMessage
|
||||
if json.Unmarshal(b, &r) != nil {
|
||||
return b, nil
|
||||
}
|
||||
var outfits []map[string]json.RawMessage
|
||||
if json.Unmarshal(r["result"], &outfits) != nil {
|
||||
return b, nil
|
||||
}
|
||||
changed := false
|
||||
for _, o := range outfits {
|
||||
var id json.Number
|
||||
if json.Unmarshal(o["user_outfits_id"], &id) != nil {
|
||||
continue
|
||||
}
|
||||
products := p.state.outfit(id.String())
|
||||
if len(products) == 0 {
|
||||
continue
|
||||
}
|
||||
var pids []json.RawMessage
|
||||
json.Unmarshal(o["pids"], &pids)
|
||||
adult := false
|
||||
for _, pid := range products {
|
||||
if s := p.byProductID(pid); s != nil {
|
||||
pids = append(pids, json.RawMessage(strconv.FormatInt(s.local, 10)))
|
||||
adult = adult || s.pack.Manifest.Rating == "adult"
|
||||
}
|
||||
}
|
||||
o["pids"], _ = json.Marshal(pids)
|
||||
if adult {
|
||||
var restricted string
|
||||
json.Unmarshal(o["restricted"], &restricted)
|
||||
if restricted == "" || restricted == "0" {
|
||||
o["restricted"], _ = json.Marshal("1")
|
||||
}
|
||||
}
|
||||
changed = true
|
||||
}
|
||||
if !changed {
|
||||
return b, nil
|
||||
}
|
||||
r["result"], _ = json.Marshal(outfits)
|
||||
return json.Marshal(r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user