dict_warbot.go 3.7 KB

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