81 lines
2.3 KiB
Go
81 lines
2.3 KiB
Go
package products
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
"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
|
|
}
|
|
|
|
// 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, err := strconv.ParseInt(f, 10, 64)
|
|
if err == nil && id == bodyProduct && fields[0] == "*use" {
|
|
r.outfit = true
|
|
}
|
|
if err == nil && isCommunity(id) {
|
|
r.products = append(r.products, id)
|
|
continue
|
|
}
|
|
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
|
|
}
|