dict_warbot.go 3.6 KB

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