dict_warbot.go 2.9 KB

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