dict_bot.go 3.7 KB

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