using CommonAI.Zone; using CommonAI.Zone.Instance; using CommonAI.Zone.ZoneEditor; using CommonAIServer.Connector.Client; using CommonLang; using CommonLang.Concurrent; using CommonLang.Log; using CommonLang.Protocol; using CommonNetwork.Sockets; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using XmdsCommon.Plugin; using XmdsServerTestBots.Bot; namespace XmdsServerTestBots { public class BotRunner { public static BotRunner Instance { get; private set; } public static DirectoryInfo StartupPath { get; private set; } public static BotConfig Config { get; private set; } public static InstanceZoneFactory ZoneFactory { get; private set; } public static MessageFactoryGenerator MessageFactory { get; private set; } public static EditorTemplates Templates { get; private set; } private Logger log = LoggerFactory.GetLogger("BotRunner"); private Random random = new Random(); public bool IsRunning { get; private set; } public BotRunner(DirectoryInfo startup_path) { StartupPath = startup_path; log.Info("********************************************************"); log.Info("# 加载配置文件"); log.Info("********************************************************"); { Config = new BotConfig(); string path = new FileInfo(startup_path + "/bot_config.properties").FullName; Properties zone_server_config = Properties.LoadFromResource(path); log.Info("配置文件 : " + path); foreach (string key in zone_server_config.Keys) { log.Info(string.Format(" {0} = {1}", key, zone_server_config[key])); } zone_server_config.LoadFields(Config); EditorTemplates.DEFAULT_LOAD_FROM_BIN = true; log.Info("资源目录 : " + Config.GAME_DATA_ROOT_PATH); } log.Info("********************************************************"); log.Info("# 初始化战斗编辑器扩展"); log.Info("********************************************************"); { XmdsZoneFactoryBot.SaveMemory = true; ZoneFactory = new XmdsZoneFactoryBot(); TemplateManager.setFactory(ZoneFactory); log.Info(" 战斗编辑器插件 --> " + ZoneFactory); } log.Info("********************************************************"); log.Info("# 初始化消息编解码器"); log.Info("********************************************************"); { MessageFactory = TemplateManager.MessageCodec; log.Info("\r\n" + MessageFactory.ListAll(" ")); } log.Info("********************************************************"); log.Info("# 加载模板数据"); log.Info("********************************************************"); { Templates = new EditorTemplates(Config.GAME_DATA_ROOT_PATH, MessageFactory); Templates.LoadAllTemplates(); } log.Info("********************************************************"); log.Info("# 扫描测试数据"); log.Info("********************************************************"); { foreach (UnitInfo unit in Templates.Templates.getAllUnits()) { XmdsUnitProperties zu = unit.Properties as XmdsUnitProperties; if (zu.BotTestTemplate || unit.UType == UnitInfo.UnitType.TYPE_PLAYER) { test_player_templates.Add(unit); } } } Instance = this; } public void Start() { this.IsRunning = true; } public void Shutdown() { this.IsRunning = false; } //------------------------------------------------------------------------------------------------- private AtomicInteger test_player_indexer = new AtomicInteger(0); private List test_player_templates = new List(); private HashMap Bots = new HashMap(); public List BotsList { get { lock (Bots) { return new List(Bots.Values); } } } public int BotsCount { get { lock (Bots) { return Bots.Count; } } } public string BotsStatus { get { StringBuilder sb = new StringBuilder(); foreach (BotPlayer bot in BotsList) { sb.AppendLine(string.Format("Bot[{0}] IsRunning={1}", bot.Name, bot.IsRunning)); } return sb.ToString(); } } public BotPlayer AddBot(int force, List templates) { UnitInfo unit; if (templates == null) { unit = CUtils.GetRandomInArray(test_player_templates, random); } else { int templateID = CUtils.GetRandomInArray(templates, random); unit = Templates.Templates.getUnit(templateID); } if (unit == null) { log.Error("没有测试单位!"); return null; } string name = unit.Name + "_" + test_player_indexer.IncrementAndGet(); BotPlayer ret = null; lock (Bots) { if (Bots.ContainsKey(name)) { log.ErrorFormat("已包含单位[{0}]!", name); return null; } ret = new BotPlayer(name, "", unit, force, Templates, Config.TEST_SERVER_CONNECTION_STRING); Bots.Add(name, ret); log.InfoFormat("已添加单位: {0}", name); } ret.Start(); return ret; } public void AddBots(int count, int force, List templates = null) { for (int i = 0; i < count; i++) { AddBot(force, templates); } } public void CleanupBots() { foreach (BotPlayer bot in BotsList) { if (!bot.IsRunning) { lock (Bots) { Bots.Remove(bot.Name); } bot.Dispose(); } } } public void StopAllBots() { foreach (BotPlayer bot in BotsList) { bot.SendLeaveRoom(); } CleanupBots(); } public void StopBot(BotPlayer bot) { bot.SendLeaveRoom(); CleanupBots(); } } }