| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- package state
- import (
- "errors"
- "fmt"
- "net/url"
- "time"
- "github.com/mk6i/open-oscar-server/wire"
- )
- const (
- // PrivateExchange is the ID of the exchange that hosts non-public created
- // by users.
- PrivateExchange uint16 = 4
- // PublicExchange is the ID of the exchange that hosts public chat rooms
- // created by the server operator exclusively.
- PublicExchange uint16 = 5
- )
- // ErrChatRoomNotFound indicates that a chat room lookup failed.
- var (
- ErrChatRoomNotFound = errors.New("chat room not found")
- ErrDupChatRoom = errors.New("chat room already exists")
- )
- // NewChatRoom creates a new ChatRoom instance.
- func NewChatRoom(name string, creator IdentScreenName, exchange uint16) ChatRoom {
- return ChatRoom{
- name: name,
- creator: creator,
- exchange: exchange,
- }
- }
- // ChatRoom represents of a chat room.
- type ChatRoom struct {
- createTime time.Time
- creator IdentScreenName
- exchange uint16
- name string
- }
- // Creator returns the screen name of the user who created the chat room.
- func (c ChatRoom) Creator() IdentScreenName {
- return c.creator
- }
- // Exchange returns which exchange the chat room belongs to.
- func (c ChatRoom) Exchange() uint16 {
- return c.exchange
- }
- // Name returns the chat room name.
- func (c ChatRoom) Name() string {
- return c.name
- }
- // InstanceNumber returns which instance chatroom exists in. Overflow chat
- // rooms do not exist yet, so all chats happen in the same instance.
- func (c ChatRoom) InstanceNumber() uint16 {
- return 0
- }
- // CreateTime returns when the chat room was inserted in the database.
- func (c ChatRoom) CreateTime() time.Time {
- return c.createTime
- }
- // DetailLevel returns the detail level of the chat room (whatever that means).
- func (c ChatRoom) DetailLevel() uint8 {
- return 0x02 // Pidgin 2.13.0 expects value 0x02
- }
- // Cookie returns the chat room unique identifier.
- func (c ChatRoom) Cookie() string {
- // According to Pidgin, the chat cookie is a 3-part identifier. The third
- // segment is the chat name, which is shown explicitly in the Pidgin code.
- // We can assume that the first two parts were the exchange and instance
- // number. As of now, Pidgin is the only client that cares about the cookie
- // format, and it only cares about the chat name segment.
- return fmt.Sprintf("%d-%d-%s", c.exchange, c.InstanceNumber(), c.name)
- }
- // URL creates a URL that can be used to join a chat room.
- func (c ChatRoom) URL() *url.URL {
- // macOS client v4.0.9 requires the `roomname` param to precede `exchange`
- // param. Create the path using string concatenation rather than url.Values
- // because url.Values sorts the params alphabetically.
- opaque := fmt.Sprintf("gochat?roomname=%s&exchange=%d", url.QueryEscape(c.name), c.exchange)
- return &url.URL{
- Scheme: "aim",
- Opaque: opaque,
- }
- }
- // TLVList returns a TLV list of chat room metadata.
- func (c ChatRoom) TLVList() []wire.TLV {
- return []wire.TLV{
- // From protocols/oscar/family_chatnav.c in lib purple, these are the
- // room creation flags:
- // - 1 Evilable
- // - 2 Nav Only
- // - 4 Instancing Allowed
- // - 8 Occupant Peek Allowed
- // It's unclear what effect they actually have.
- wire.NewTLVBE(wire.ChatRoomTLVFlags, uint16(15)),
- wire.NewTLVBE(wire.ChatRoomTLVCreateTime, uint32(c.createTime.Unix())),
- wire.NewTLVBE(wire.ChatRoomTLVMaxMsgLen, uint16(1024)),
- wire.NewTLVBE(wire.ChatRoomTLVMaxOccupancy, uint16(100)),
- // From protocols/oscar/family_chatnav.c in lib purple, these are the
- // room creation permission values:
- // - 0 creation not allowed
- // - 1 room creation allowed
- // - 2 exchange creation allowed
- // It's unclear what effect they actually have.
- wire.NewTLVBE(wire.ChatRoomTLVNavCreatePerms, uint8(2)),
- wire.NewTLVBE(wire.ChatRoomTLVFullyQualifiedName, c.name),
- wire.NewTLVBE(wire.ChatRoomTLVRoomName, c.name),
- wire.NewTLVBE(wire.ChatRoomTLVMaxMsgVisLen, uint16(1024)),
- }
- }
|