dict_warbot.go 3.6 KB

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