FormBotTest.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. 
  2. using DeepCore;
  3. using DeepCore.Reflection;
  4. using DeepCore.Xml;
  5. using DeepEditor.Common.G2D;
  6. using DeepMMO.Client.BotTest.Runner;
  7. using DeepMMO.Client.Win32.Battle;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.ComponentModel;
  11. using System.Drawing;
  12. using System.Text;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. using System.Windows.Forms;
  16. namespace DeepMMO.Client.BotTest
  17. {
  18. public partial class FormBotTest : Form
  19. {
  20. private static bool first_start = true;
  21. private int lastIndex = 0;
  22. private long last_update_time;
  23. private BotConfig config;
  24. private bool started = false;
  25. public FormBotTest(BotConfig cfg)
  26. {
  27. this.config = cfg;
  28. InitializeComponent();
  29. InitBotModules();
  30. }
  31. public BotListViewItem SelectedBotItem
  32. {
  33. get
  34. {
  35. if (list_Bots.SelectedItems.Count > 0)
  36. {
  37. return list_Bots.SelectedItems[0] as BotListViewItem;
  38. }
  39. return null;
  40. }
  41. }
  42. public BotListViewItem[] SelectedBotItems
  43. {
  44. get
  45. {
  46. return list_Bots.SelectedItems.ToArray<BotListViewItem>();
  47. }
  48. }
  49. private void FormBotTest_Load(object sender, EventArgs e)
  50. {
  51. if (BotLauncher.NoBattleView)
  52. {
  53. splitContainer2.Panel1Collapsed = true;
  54. }
  55. }
  56. private void FormBotTest_Shown(object sender, EventArgs e)
  57. {
  58. if (BotLauncher.IsAuto && first_start)
  59. {
  60. first_start = false;
  61. StartBots(BotLauncher.DefaultBotPrefix, BotLauncher.DefaultBotCount);
  62. }
  63. }
  64. private void FormBotTest_FormClosing(object sender, FormClosingEventArgs e)
  65. {
  66. foreach (BotListViewItem item in list_Bots.Items)
  67. {
  68. try
  69. {
  70. item.Runner.Dispose();
  71. }
  72. catch (Exception err)
  73. {
  74. Console.WriteLine(err.Message);
  75. }
  76. }
  77. }
  78. private void btn_GC_Click(object sender, EventArgs e)
  79. {
  80. System.GC.Collect();
  81. }
  82. private void timer_30_Tick(object sender, EventArgs e)
  83. {
  84. if (base.Visible)
  85. {
  86. long curTime = DeepCore.CUtils.CurrentTimeMS;
  87. if (last_update_time == 0)
  88. {
  89. last_update_time = curTime;
  90. }
  91. int intervalMS = (int)(curTime - last_update_time);
  92. last_update_time = curTime;
  93. intervalMS = Math.Min(intervalMS, timer_30.Interval * 2);
  94. foreach (BotListViewItem item in list_Bots.Items)
  95. {
  96. item.Update(intervalMS);
  97. }
  98. }
  99. var selected = SelectedBotItem;
  100. if (text_Events.Tag != selected)
  101. {
  102. text_Events.Tag = selected;
  103. text_Events.Clear();
  104. }
  105. if (selected != null)
  106. {
  107. if (text_Events.TextLength < selected.Events.Length)
  108. {
  109. char[] copyto = new char[selected.Events.Length - text_Events.TextLength];
  110. selected.Events.CopyTo(text_Events.TextLength, copyto, 0, copyto.Length);
  111. text_Events.AppendText(new string(copyto));
  112. }
  113. if (text_Events.TextLength > selected.Events.Length)
  114. {
  115. text_Events.Clear();
  116. }
  117. }
  118. }
  119. private void timer_3000_Tick(object sender, EventArgs e)
  120. {
  121. long totalRecvBytes = 0;
  122. long totalSentBytes = 0;
  123. foreach (var item in list_Bots.Items.ToArray<BotListViewItem>())
  124. {
  125. item.Refresh();
  126. totalRecvBytes += item.Client.GameClient.TotalRecvBytes;
  127. totalSentBytes += item.Client.GameClient.TotalSentBytes;
  128. if (config.KeepBotCount > 0)
  129. {
  130. if (item.Runner.IsDisposed)
  131. {
  132. try { list_Bots.Items.Remove(item); } catch { }
  133. }
  134. else if (item.Runner.Client.IsGameDisconnected)
  135. {
  136. try { item.Runner.Dispose(); } catch { }
  137. }
  138. }
  139. }
  140. if (started && config.KeepBotCount > 0 && list_Bots.Items.Count < config.KeepBotCount)
  141. {
  142. StartBots(BotLauncher.DefaultBotPrefix, config.KeepBotCount - list_Bots.Items.Count, true);
  143. }
  144. this.lbl_NetStatus.Text = string.Format("TotalRecv={0} TotalSent={1}",
  145. CUtils.ToBytesSizeString(totalRecvBytes),
  146. CUtils.ToBytesSizeString(totalSentBytes));
  147. this.Text = "BotTest : (" + list_Bots.Items.Count + ")";
  148. }
  149. private void btn_AddBots_Click(object sender, EventArgs e)
  150. {
  151. StartBots();
  152. }
  153. private void btn_StopAll_Click(object sender, EventArgs e)
  154. {
  155. foreach (BotListViewItem item in list_Bots.Items)
  156. {
  157. try
  158. {
  159. item.Runner.Stop();
  160. }
  161. catch (Exception err)
  162. {
  163. Console.WriteLine(err.Message);
  164. }
  165. }
  166. }
  167. private void btn_CleanBots_Click(object sender, EventArgs e)
  168. {
  169. for (int i = list_Bots.Items.Count - 1; i >= 0; --i)
  170. {
  171. try
  172. {
  173. BotListViewItem item = list_Bots.Items[i] as BotListViewItem;
  174. if (item.Client.IsGameDisconnected)
  175. {
  176. list_Bots.Items.RemoveAt(i);
  177. try { item.Runner.Dispose(); } catch { }
  178. }
  179. }
  180. catch (Exception err)
  181. {
  182. Console.WriteLine(err.Message);
  183. }
  184. }
  185. }
  186. private void btn_ClearConsole_Click(object sender, EventArgs e)
  187. {
  188. text_Events.Clear();
  189. var selected = SelectedBotItem;
  190. if (selected != null)
  191. {
  192. selected.Events.Clear();
  193. }
  194. }
  195. private void btn_ClearAllConsole_Click(object sender, EventArgs e)
  196. {
  197. text_Events.Clear();
  198. foreach (BotListViewItem item in list_Bots.Items)
  199. {
  200. item.Events.Clear();
  201. }
  202. }
  203. private void list_Bots_SelectedIndexChanged(object sender, EventArgs e)
  204. {
  205. splitContainer2.Panel1.Controls.Clear();
  206. var selected = SelectedBotItem;
  207. if (selected != null && selected.BattleView != null)
  208. {
  209. splitContainer2.Panel1.Controls.Add(selected.BattleView);
  210. }
  211. }
  212. private void moduleItem_CheckedChanged(object sender, EventArgs e)
  213. {
  214. var item = sender as ToolStripMenuItem;
  215. var mt = item.Tag as Type;
  216. BotModule.SetModuleEnable(mt, item.Checked);
  217. SaveBotModules();
  218. }
  219. private void group_Module_Click(object sender, EventArgs e)
  220. {
  221. }
  222. private void menu_BotItem_Opening(object sender, CancelEventArgs e)
  223. {
  224. var menu = sender as ContextMenuStrip;
  225. if (menu != null)
  226. {
  227. var mp = menu.PointToScreen(new Point(0, 0));
  228. var lp = list_Bots.PointToClient(mp);
  229. var item = list_Bots.GetItemAt(lp.X, lp.Y);
  230. if (item != null)
  231. {
  232. item.Selected = true;
  233. var selected = SelectedBotItem;
  234. if (selected == null)
  235. {
  236. e.Cancel = true;
  237. }
  238. }
  239. else
  240. {
  241. e.Cancel = true;
  242. }
  243. }
  244. }
  245. private void btn_BotReconnect_Click(object sender, EventArgs e)
  246. {
  247. foreach (var bot in SelectedBotItems)
  248. {
  249. bot.Runner.Reconnect();
  250. }
  251. }
  252. private void btn_BotStart_Click(object sender, EventArgs e)
  253. {
  254. foreach (var bot in SelectedBotItems)
  255. {
  256. bot.Runner.Start();
  257. }
  258. }
  259. private void btn_BotStop_Click(object sender, EventArgs e)
  260. {
  261. foreach (var bot in SelectedBotItems)
  262. {
  263. bot.Runner.Stop();
  264. }
  265. }
  266. private void btn_EmuDisconnect_Click(object sender, EventArgs e)
  267. {
  268. foreach (var bot in SelectedBotItems)
  269. {
  270. bot.Runner.Disconnect();
  271. }
  272. }
  273. //-------------------------------------------------------------------------------------------------------------
  274. #region OP
  275. private void StartBots(string name_prefix = null, int count = 1, bool keep = false)
  276. {
  277. var add = AddBotConfig.TryLoadAddConfig();
  278. if (name_prefix != null)
  279. {
  280. add.name_format = name_prefix;
  281. add.count = count;
  282. add.index = lastIndex;
  283. }
  284. else
  285. {
  286. var servers = RPGClientTemplateManager.Instance.GetAllServers();
  287. var servers_optionals = new DeepEditor.Common.G2D.DataGrid.OptionalList();
  288. servers_optionals.AddRange(servers);
  289. servers_optionals.Converter = new Func<System.Reflection.MemberInfo, object, object>((field, value) =>
  290. {
  291. var server = value as Data.ServerInfo;
  292. return server.id;
  293. });
  294. add.index = lastIndex;
  295. if (keep == false)
  296. {
  297. var dialog = new G2DPropertyDialog<AddBotConfig>(add);
  298. {
  299. dialog.Text = "1";
  300. dialog.PropertyGrid.SelectedDescriptorObject.AppendOptionals(nameof(AddBotConfig.serverID), servers_optionals);
  301. var res = dialog.ShowDialog();
  302. if (res == System.Windows.Forms.DialogResult.OK)
  303. {
  304. add = dialog.SelectedObject;
  305. }
  306. else
  307. {
  308. return;
  309. }
  310. }
  311. }
  312. else
  313. {
  314. add.count = count;
  315. }
  316. // add = G2DPropertyDialog<AddBotConfig>.Show("1", add);
  317. }
  318. if (add != null)
  319. {
  320. try
  321. {
  322. if (add.name_format.Contains("{0}") && !string.IsNullOrEmpty(add.digit_format))
  323. {
  324. var starting = new List<BotListViewItem>();
  325. for (int i = 0; i < add.count; i++)
  326. {
  327. var id = add.index + i;
  328. var name = string.Format(add.name_format, id.ToString(add.digit_format));
  329. var item = new BotListViewItem(name, id, add, config);
  330. list_Bots.Items.Add(item);
  331. starting.Add(item);
  332. }
  333. Task.Run(async () =>
  334. {
  335. foreach (var e in starting)
  336. {
  337. if (config.AddBotIntervalMS > 0)
  338. {
  339. await Task.Delay(config.AddBotIntervalMS);
  340. }
  341. e.Runner.Start();
  342. }
  343. }).ConfigureAwait(true);
  344. }
  345. else
  346. {
  347. var name = add.name_format;
  348. var item = new BotListViewItem(name, lastIndex, add, config);
  349. list_Bots.Items.Add(item);
  350. item.Runner.Start();
  351. }
  352. }
  353. catch (Exception err)
  354. {
  355. MessageBox.Show(err.Message);
  356. }
  357. this.started = true;
  358. this.lastIndex = add.index + add.count;
  359. if (keep == false)
  360. {
  361. AddBotConfig.TrySaveAddConfig(add);
  362. }
  363. }
  364. }
  365. private void InitBotModules()
  366. {
  367. try
  368. {
  369. var saved = XmlUtil.LoadXML(Application.StartupPath + "/bot_modules.save");
  370. if (saved != null)
  371. {
  372. var cfg = XmlUtil.XmlToObject<BotModuleConfig>(saved);
  373. foreach (var me in cfg.Modules)
  374. {
  375. var mt = ReflectionUtil.GetType(me.Key);
  376. if (mt != null)
  377. {
  378. BotModule.SetModuleEnable(mt, me.Value);
  379. }
  380. }
  381. }
  382. }
  383. catch (Exception err)
  384. {
  385. MessageBox.Show(err.Message);
  386. }
  387. foreach (var mt in BotFactory.Instance.GetModuleTypes())
  388. {
  389. var enable = BotModule.GetModuleEnable(mt);
  390. var item = new ToolStripMenuItem();
  391. item.CheckOnClick = true;
  392. item.Size = new System.Drawing.Size(152, 22);
  393. item.Text = "模块:" + mt.Name;
  394. item.Tag = mt;
  395. item.Checked = enable;
  396. item.CheckedChanged += moduleItem_CheckedChanged;
  397. group_Module.DropDownItems.Add(item);
  398. }
  399. }
  400. private void SaveBotModules()
  401. {
  402. BotModuleConfig cfg = new BotModuleConfig();
  403. foreach (var mt in BotFactory.Instance.GetModuleTypes())
  404. {
  405. cfg.Modules.Add(mt.FullName, BotModule.GetModuleEnable(mt));
  406. }
  407. var save = XmlUtil.ObjectToXml(cfg);
  408. XmlUtil.SaveXML(Application.StartupPath + "/bot_modules.save", save);
  409. }
  410. #endregion
  411. }
  412. public class BotGamePanelContainer : GamePanelContainer
  413. {
  414. private readonly BotRunner bot;
  415. public BotGamePanelContainer(BotRunner bot)
  416. {
  417. this.bot = bot;
  418. }
  419. protected override void Client_OnErrorResponse(Protocol.Response rsp, Exception err = null)
  420. {
  421. var prefix = (rsp != null) ? (rsp.GetType().Name + " : " + rsp + Environment.NewLine) : "";
  422. var suffix = (err != null) ? (err.Message + Environment.NewLine + err.StackTrace) : "";
  423. bot.LogEvents.Error(prefix + suffix);
  424. }
  425. protected override void Client_OnError(Exception err)
  426. {
  427. bot.LogEvents.Error(err.Message + Environment.NewLine + err.StackTrace);
  428. }
  429. }
  430. public class BotListViewItem : ListViewItem
  431. {
  432. public RPGClient Client { get; private set; }
  433. public BotRunner Runner { get; private set; }
  434. public StringBuilder Events { get; private set; }
  435. public GamePanelContainer BattleView { get; private set; }
  436. public BotListViewItem(string name, int index, AddBotConfig add, BotConfig cfg)
  437. : base(name)
  438. {
  439. var bot = BotFactory.Instance.CreateBotRunner(cfg, add, name);
  440. this.Client = bot.Client;
  441. this.Runner = bot;
  442. this.Events = new StringBuilder();
  443. if (BotLauncher.NoBattleView == false)
  444. {
  445. this.Runner.Client.IsAutoUpdateBattle = false;
  446. this.BattleView = new BotGamePanelContainer(bot);
  447. this.BattleView.Init(this.Client);
  448. this.BattleView.Dock = DockStyle.Fill;
  449. }
  450. else
  451. {
  452. this.Runner.Client.IsAutoUpdateBattle = true;
  453. }
  454. this.Tag = bot;
  455. var colums = bot.Columns;
  456. for (int i = 1; i < colums.Length; i++)
  457. {
  458. this.SubItems.Add(colums[i]);
  459. }
  460. }
  461. public void Update(int intervalMS)
  462. {
  463. if (BattleView != null)
  464. {
  465. Runner.Update(intervalMS);
  466. BattleView.UpdateBattle(intervalMS);
  467. }
  468. else
  469. {
  470. Runner.Update(intervalMS);
  471. }
  472. }
  473. public void Refresh()
  474. {
  475. if (Events.Length > 10000)
  476. {
  477. Events.Clear();
  478. }
  479. using (var list = CollectionObjectPool<string>.AllocList())
  480. {
  481. this.Runner.PopLogs(list);
  482. foreach (var e in list)
  483. {
  484. Events.AppendLine(e);
  485. }
  486. }
  487. var colums = Runner.Columns;
  488. for (int i = 1; i < colums.Length; i++)
  489. {
  490. if (this.SubItems[i].Text != colums[i])
  491. this.SubItems[i].Text = colums[i];
  492. }
  493. if (Client.GameClient.IsConnected == false)
  494. {
  495. this.ForeColor = Color.Gray;
  496. }
  497. else
  498. {
  499. this.ForeColor = Color.Black;
  500. }
  501. }
  502. }
  503. }