dict_warbot.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. sf := &DictWarBot{
  28. server: server,
  29. store: server.Store(),
  30. dict: map[string]types.ИБот{},
  31. }
  32. if err := sf.load(); err != nil {
  33. return nil, fmt.Errorf("NewDictBot(): in load list bots from store, err=%w", err)
  34. }
  35. return sf, nil
  36. }
  37. // ListBot -- возвращает список существующих ботов
  38. func (sf *DictWarBot) ListBot() []types.ИБот {
  39. lst := make([]types.ИБот, 0)
  40. for _, bot := range sf.dict {
  41. lst = append(lst, bot)
  42. }
  43. return lst
  44. }
  45. // Get -- возвращает бота по имени
  46. func (sf *DictWarBot) Get(botName string) types.ИБот {
  47. sf.block.RLock()
  48. defer sf.block.RUnlock()
  49. bot := sf.dict[botName]
  50. return bot
  51. }
  52. // Add -- добавляет нового бота в словарь
  53. func (sf *DictWarBot) Add(bot types.ИБот) {
  54. sf.block.Lock()
  55. defer sf.block.Unlock()
  56. if bot == nil {
  57. return
  58. }
  59. sf.dict[bot.Имя()] = bot
  60. sf.save()
  61. }
  62. // Сохраняет словарь ботов в базе
  63. func (sf *DictWarBot) save() {
  64. strName := ""
  65. for name := range sf.dict {
  66. strName += name + ";"
  67. }
  68. strName = strName[:len(strName)-1]
  69. err := sf.store.Put(strBotList, strName)
  70. if err != nil {
  71. sf.server.CancelApp()
  72. }
  73. }
  74. // Загружает всех ботов с базы
  75. func (sf *DictWarBot) load() error {
  76. strName, err := sf.store.Get(strBotList)
  77. if err != nil {
  78. if !strings.Contains(err.Error(), "not found") {
  79. return fmt.Errorf("DictWarBot.load(): in get list bot, err=\n\t%w", err)
  80. }
  81. }
  82. if strName == "" {
  83. return nil
  84. }
  85. lstName := strings.Split(strName, ";")
  86. for _, name := range lstName {
  87. if name == "" {
  88. continue
  89. }
  90. _, isOk := sf.dict[name]
  91. if isOk {
  92. continue
  93. }
  94. bot, err := warbot.ЗагрузитьВарБот(sf.server, name)
  95. if err != nil {
  96. return fmt.Errorf("ServBots.load(): in create bot %q, err=\n\t%w", name, err)
  97. }
  98. if bot.АвтоИграЕсли() {
  99. go bot.Пуск()
  100. }
  101. sf.dict[name] = bot
  102. }
  103. return nil
  104. }