4
0

chat.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package state
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/url"
  6. "time"
  7. "github.com/mk6i/retro-aim-server/wire"
  8. "github.com/google/uuid"
  9. )
  10. const (
  11. // PrivateExchange is the ID of the exchange that hosts non-public created
  12. // by users.
  13. PrivateExchange uint16 = 4
  14. // PublicExchange is the ID of the exchange that hosts public chat rooms
  15. // created by the server operator exclusively.
  16. PublicExchange uint16 = 5
  17. )
  18. // ErrChatRoomNotFound indicates that a chat room lookup failed.
  19. var (
  20. ErrChatRoomNotFound = errors.New("chat room not found")
  21. ErrDupChatRoom = errors.New("chat room already exists")
  22. )
  23. // ChatRoom is the representation of a chat room's metadata.
  24. type ChatRoom struct {
  25. // Cookie is the unique chat room identifier.
  26. Cookie string
  27. // CreateTime indicates when the chat room was created.
  28. CreateTime time.Time
  29. // Creator is the screen name of the user who created the chat room.
  30. Creator IdentScreenName
  31. // DetailLevel is the detail level of the chat room. Unclear what this value means.
  32. DetailLevel uint8
  33. // Exchange indicates which exchange the chatroom belongs to. Typically, a canned value.
  34. Exchange uint16
  35. // InstanceNumber indicates which instance chatroom exists in. Typically, a canned value.
  36. InstanceNumber uint16
  37. // Name is the name of the chat room.
  38. Name string
  39. }
  40. // URL creates a URL that can be used to join a chat room.
  41. func (c ChatRoom) URL() *url.URL {
  42. v := url.Values{}
  43. v.Set("roomname", c.Name)
  44. v.Set("exchange", fmt.Sprintf("%d", c.Exchange))
  45. return &url.URL{
  46. Scheme: "aim",
  47. Opaque: "gochat?" + v.Encode(),
  48. }
  49. }
  50. // TLVList returns a TLV list of chat room metadata.
  51. func (c ChatRoom) TLVList() []wire.TLV {
  52. return []wire.TLV{
  53. // From protocols/oscar/family_chatnav.c in lib purple, these are the
  54. // room creation flags:
  55. // - 1 Evilable
  56. // - 2 Nav Only
  57. // - 4 Instancing Allowed
  58. // - 8 Occupant Peek Allowed
  59. // It's unclear what effect they actually have.
  60. wire.NewTLV(wire.ChatRoomTLVFlags, uint16(15)),
  61. wire.NewTLV(wire.ChatRoomTLVCreateTime, uint32(c.CreateTime.Unix())),
  62. wire.NewTLV(wire.ChatRoomTLVMaxMsgLen, uint16(1024)),
  63. wire.NewTLV(wire.ChatRoomTLVMaxOccupancy, uint16(100)),
  64. // From protocols/oscar/family_chatnav.c in lib purple, these are the
  65. // room creation permission values:
  66. // - 0 creation not allowed
  67. // - 1 room creation allowed
  68. // - 2 exchange creation allowed
  69. // It's unclear what effect they actually have.
  70. wire.NewTLV(wire.ChatRoomTLVNavCreatePerms, uint8(2)),
  71. wire.NewTLV(wire.ChatRoomTLVFullyQualifiedName, c.Name),
  72. wire.NewTLV(wire.ChatRoomTLVRoomName, c.Name),
  73. }
  74. }
  75. // NewChatRoom creates new state.ChatRoom objects
  76. func NewChatRoom() ChatRoom {
  77. return ChatRoom{
  78. Cookie: uuid.New().String(),
  79. CreateTime: time.Now().UTC(),
  80. }
  81. }