package products import ( "encoding/json" "strings" ) // outfitCommands are the chat commands whose arguments are product IDs: putting products on and taking them off. var outfitCommands = map[string]bool{ "*use": true, "*putOn": true, "*putOnOutfit": true, "*remove": true, "*takeOff": true, } // bodyProduct is the avatar body every full outfit starts from; a *use list with it is a whole outfit (the client // re-sends its outfit that way every 30 s or so). const bodyProduct = 80 // strippedCommand is a chat line with community products taken out of its outfit command. type strippedCommand struct { text string // the line to send instead changed bool // products were taken out empty bool // nothing is left to send outfit bool // the line was a whole outfit (*use with the body) products []int64 // the community products it named kept []int64 // the other products it named } // stripCommand takes products for which isCommunity is true out of an outfit command's arguments. func stripCommand(text string, isCommunity func(int64) bool) strippedCommand { fields := strings.Fields(text) if len(fields) == 0 || !outfitCommands[fields[0]] { return strippedCommand{text: text} } r := strippedCommand{text: text} kept := []string{fields[0]} for _, f := range fields[1:] { id, ok := parseID(f) if ok && id == bodyProduct && fields[0] == "*use" { r.outfit = true } if ok && isCommunity(id) { r.products = append(r.products, id) continue } if ok { r.kept = append(r.kept, id) } kept = append(kept, f) } if len(r.products) == 0 { return r } r.changed = true r.empty = len(kept) == 1 r.text = strings.Join(kept, " ") return r } // chatMessage is the JSON the client sends on a chat queue's "messages" mount. type chatMessage struct { fields map[string]json.RawMessage text string userID int64 } func parseChatMessage(b []byte) (*chatMessage, bool) { var fields map[string]json.RawMessage if json.Unmarshal(b, &fields) != nil { return nil, false } m := &chatMessage{fields: fields} if json.Unmarshal(fields["message"], &m.text) != nil { return nil, false } json.Unmarshal(fields["userId"], &m.userID) return m, true } func (m *chatMessage) withText(text string) []byte { b, _ := json.Marshal(text) m.fields["message"] = b out, _ := json.Marshal(m.fields) return out }