Room channel: other T5DE users' community products on their avatars
CI / build (push) Successful in 28s
CI / build (push) Successful in 28s
The proxy follows the client's IMQ chat subscriptions and tells the hub which chats it's in (and the room, from chat.getOrMakeChat). For the other T5DE users the hub says are in a chat, it gives the client the community products it has packs for, as *use and *remove lines from them, and adds them to the whole outfits they send. It also takes community products out of the outfit the client posts to IMVU's chat participant endpoint, which had been sending them to IMVU. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
e394f1dc24
commit
93fa2f5d90
11 files changed
+858
-12
No files matched your search
@@ -5,7 +5,10 @@ import "errors"
|
||||
// Message types the proxy reads or writes.
|
||||
const (
|
||||
C2gSendMessage = 1304
|
||||
C2gUnsubscribe = 1308
|
||||
C2gSubscribe = 1309
|
||||
G2cResult = 3102
|
||||
G2cSendMessage = 3104
|
||||
)
|
||||
|
||||
// SendMessage is a C2gSendMessage: a message the client sends to a queue's mount.
|
||||
@@ -118,3 +121,84 @@ func appendBytesField(b []byte, num uint64, v []byte) []byte {
|
||||
b = appendVarint(appendVarint(b, num<<3|2), uint64(len(v)))
|
||||
return append(b, v...)
|
||||
}
|
||||
|
||||
// ParseSubscription reads a C2gSubscribe's or C2gUnsubscribe's data: the queues (listed plainly, or with an op ID
|
||||
// for a result).
|
||||
func ParseSubscription(data []byte) ([]string, error) {
|
||||
fs, err := fields(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var queues []string
|
||||
for _, f := range fs {
|
||||
switch {
|
||||
case f.num == 1 && f.isLen:
|
||||
queues = append(queues, string(f.bytes))
|
||||
case f.num == 2 && f.isLen:
|
||||
sub, err := fields(f.bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, sf := range sub {
|
||||
if sf.num == 1 && sf.isLen {
|
||||
queues = append(queues, string(sf.bytes))
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("imq: unexpected field in a subscription")
|
||||
}
|
||||
}
|
||||
return queues, nil
|
||||
}
|
||||
|
||||
// Delivered is a G2cSendMessage: a message the gateway delivers to the client, from a user (user_id).
|
||||
type Delivered struct {
|
||||
UserID string
|
||||
Queue string
|
||||
Mount string
|
||||
Message []byte
|
||||
Sequence uint64 // 0: none (the client only tracks sequences it's given)
|
||||
}
|
||||
|
||||
// ParseDelivered reads a G2cSendMessage's data.
|
||||
func ParseDelivered(data []byte) (Delivered, error) {
|
||||
fs, err := fields(data)
|
||||
if err != nil {
|
||||
return Delivered{}, err
|
||||
}
|
||||
var m Delivered
|
||||
seen := 0
|
||||
for _, f := range fs {
|
||||
switch {
|
||||
case f.num == 1 && f.isLen:
|
||||
m.UserID, seen = string(f.bytes), seen|1
|
||||
case f.num == 2 && f.isLen:
|
||||
m.Queue, seen = string(f.bytes), seen|2
|
||||
case f.num == 3 && f.isLen:
|
||||
m.Mount, seen = string(f.bytes), seen|4
|
||||
case f.num == 4 && f.isLen:
|
||||
m.Message, seen = f.bytes, seen|8
|
||||
case f.num == 5 && !f.isLen:
|
||||
m.Sequence = f.varint
|
||||
default:
|
||||
return Delivered{}, errors.New("imq: unexpected field in G2cSendMessage")
|
||||
}
|
||||
}
|
||||
if seen != 15 {
|
||||
return Delivered{}, errors.New("imq: G2cSendMessage is missing fields")
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Marshal encodes the message's data, fields in the gateway's order.
|
||||
func (m Delivered) Marshal() []byte {
|
||||
var b []byte
|
||||
b = appendBytesField(b, 1, []byte(m.UserID))
|
||||
b = appendBytesField(b, 2, []byte(m.Queue))
|
||||
b = appendBytesField(b, 3, []byte(m.Mount))
|
||||
b = appendBytesField(b, 4, m.Message)
|
||||
if m.Sequence != 0 {
|
||||
b = appendVarintField(b, 5, m.Sequence)
|
||||
}
|
||||
return b
|
||||
}
|
||||
Reference in new issue
Block a user