dict_warbot.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // package dict_warbot -- потокобезопасный словарь ботов
  2. package dict_warbot
  3. import (
  4. "fmt"
  5. "log"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "wartank/pkg/alias"
  10. "wartank/pkg/types"
  11. "wartank/server/serv_bots/warbot"
  12. )
  13. const (
  14. strBotList = "/bots/list" // Константа путь к списку ботов в базе
  15. )
  16. // DictWarBot -- потокобезопасный словарь ботов
  17. type DictWarBot struct {
  18. server types.ИСервер
  19. store types.ИХранилище
  20. dict map[alias.БотНомер]types.ИБот
  21. block sync.RWMutex
  22. }
  23. // NewDictWarBot -- возвращает новый потокобезопасный словарь ботов
  24. func NewDictWarBot(server types.ИСервер) (*DictWarBot, error) {
  25. if server == nil {
  26. return nil, fmt.Errorf("NewDictWarBot(): IServer==nil")
  27. }
  28. log.Printf("NewDictWarBot()\n")
  29. сам := &DictWarBot{
  30. server: server,
  31. store: server.Хранилище(),
  32. dict: map[alias.БотНомер]types.ИБот{},
  33. }
  34. if err := сам.load(); err != nil {
  35. return nil, fmt.Errorf("NewDictBot(): in load list bots from store, err=%w", err)
  36. }
  37. return сам, nil
  38. }
  39. // ListBot -- возвращает список существующих ботов
  40. func (сам *DictWarBot) ListBot() []types.ИБот {
  41. сам.block.RLock()
  42. defer сам.block.RUnlock()
  43. lst := make([]types.ИБот, 0)
  44. for _, bot := range сам.dict {
  45. lst = append(lst, bot)
  46. }
  47. return lst
  48. }
  49. // Get -- возвращает бота по имени
  50. func (сам *DictWarBot) Get(botNumber alias.БотНомер) types.ИБот {
  51. сам.block.RLock()
  52. defer сам.block.RUnlock()
  53. bot := сам.dict[botNumber]
  54. return bot
  55. }
  56. // Add -- добавляет нового бота в словарь
  57. func (сам *DictWarBot) Add(bot types.ИБот) {
  58. сам.block.Lock()
  59. defer сам.block.Unlock()
  60. if bot == nil {
  61. return
  62. }
  63. сам.dict[bot.Номер()] = bot
  64. сам.save()
  65. }
  66. // Сохраняет словарь ботов в базе
  67. func (сам *DictWarBot) save() {
  68. strNumber := ""
  69. for botNumber := range сам.dict {
  70. strNumber += fmt.Sprint(botNumber) + ";"
  71. }
  72. strNumber = strNumber[:len(strNumber)-1]
  73. err := сам.store.Уст(strBotList, []byte(strNumber))
  74. if err != nil {
  75. сам.server.Отменить()
  76. }
  77. }
  78. // Загружает всех ботов с базы
  79. func (сам *DictWarBot) load() error {
  80. binNumber, err := сам.store.Получ(strBotList)
  81. if err != nil {
  82. if !strings.Contains(err.Error(), "not found") {
  83. return fmt.Errorf("DictWarBot.load(): in get list bot, err=\n\t%w", err)
  84. }
  85. }
  86. strNumbers := string(binNumber)
  87. if strNumbers == "" {
  88. return nil
  89. }
  90. lstNumbers := strings.Split(strNumbers, ";")
  91. for _, strNumber := range lstNumbers {
  92. if strNumber == "" {
  93. continue
  94. }
  95. iNumber, err := strconv.Atoi(strNumber)
  96. if err != nil {
  97. return fmt.Errorf("DictWarBot.load(): in conver number bot(%v), err=\n\t%w", strNumber, err)
  98. }
  99. number := alias.БотНомер(iNumber)
  100. _, isOk := сам.dict[number]
  101. if isOk {
  102. continue
  103. }
  104. bot, err := warbot.ЗагрузитьВарБот(сам.server, number)
  105. if err != nil {
  106. return fmt.Errorf("ServBots.load(): in create bot %q, err=\n\t%w", strNumber, err)
  107. }
  108. if bot.АвтоИграЕсли() {
  109. go bot.Пуск()
  110. }
  111. сам.dict[number] = bot
  112. }
  113. return nil
  114. }