You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

batch.go 2.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
  2. // released under the MIT license
  3. package irc
  4. import (
  5. "strconv"
  6. "time"
  7. "github.com/goshuirc/irc-go/ircmsg"
  8. "github.com/oragono/oragono/irc/caps"
  9. )
  10. const (
  11. // maxBatchID is the maximum ID the batch counter can get to before it rotates.
  12. //
  13. // Batch IDs are made up of the current unix timestamp plus a rolling int ID that's
  14. // incremented for every new batch. It's an alright solution and will work unless we get
  15. // more than maxId batches per nanosecond. Later on when we have S2S linking, the batch
  16. // ID will also contain the server ID to ensure they stay unique.
  17. maxBatchID uint64 = 60000
  18. )
  19. // BatchManager helps generate new batches and new batch IDs.
  20. type BatchManager struct {
  21. idCounter uint64
  22. }
  23. // NewBatchManager returns a new Manager.
  24. func NewBatchManager() *BatchManager {
  25. return &BatchManager{}
  26. }
  27. // NewID returns a new batch ID that should be unique.
  28. func (bm *BatchManager) NewID() string {
  29. bm.idCounter++
  30. if maxBatchID < bm.idCounter {
  31. bm.idCounter = 0
  32. }
  33. return strconv.FormatInt(time.Now().UnixNano(), 36) + strconv.FormatUint(bm.idCounter, 36)
  34. }
  35. // Batch represents an IRCv3 batch.
  36. type Batch struct {
  37. ID string
  38. Type string
  39. Params []string
  40. }
  41. // New returns a new batch.
  42. func (bm *BatchManager) New(batchType string, params ...string) *Batch {
  43. newBatch := Batch{
  44. ID: bm.NewID(),
  45. Type: batchType,
  46. Params: params,
  47. }
  48. return &newBatch
  49. }
  50. // Start sends the batch start message to this client
  51. func (b *Batch) Start(client *Client, tags *map[string]ircmsg.TagValue) {
  52. if client.capabilities.Has(caps.Batch) {
  53. params := []string{"+" + b.ID, b.Type}
  54. for _, param := range b.Params {
  55. params = append(params, param)
  56. }
  57. client.Send(tags, client.server.name, "BATCH", params...)
  58. }
  59. }
  60. // End sends the batch end message to this client
  61. func (b *Batch) End(client *Client) {
  62. if client.capabilities.Has(caps.Batch) {
  63. client.Send(nil, client.server.name, "BATCH", "-"+b.ID)
  64. }
  65. }