using CommonAI.Zone; using CommonAI.Zone.Helper; using CommonAI.Zone.ZoneEditor; using CommonAI.ZoneClient.Agent; using CommonLang; using CommonLang.Concurrent; using CommonLang.Log; using CommonLang.Property; using CommonLang.Vector; using pomelo.area; using pomelo.chat; using pomelo.connector; using Pomelo.DotNetClient; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; using XmdsBattleClient.Client; using XmdsBattleClientBot.Bot; using XmdsBattleClientBot.XmdsBot; namespace XmdsBotTest.Runner { public class BotRunner : IDisposable { protected readonly ListLogger events; protected readonly BotClient bot; protected readonly AddBotConfig add; protected readonly int index; protected XmdsNetClient client { get { return bot.Client; } } protected readonly AtomicReference status = new AtomicReference(""); private HashMap modules = new HashMap(); public BotClient Bot { get { return bot; } } public string RoleName { get { return bot.RoleName; } } public string SceneName { get { return bot.SceneName; } } public Pomelo.DotNetClient.NetWorkState NetState { get { return bot.NetState; } } public string Status { get { return status.Value; } } public BotRunner() { } public BotRunner(BotClient bot, int index, AddBotConfig add) { this.events = new ListLogger("event bot[" + bot.Account + "]"); this.add = add; this.index = index; this.bot = bot; this.bot.event_OnStart += on_start; this.bot.event_OnStop += on_stop; this.bot.event_OnUpdate += on_update; this.bot.event_OnBattleUpdate += on_bs_update; this.bot.Client.GameSocket.IsSaveResponse = true; this.bot.Client.OnBeginEnterScene += on_gs_begin_enter_scene; this.bot.Client.OnBattlePlayerReady += on_bs_actor_ready; this.bot.Client.GameSocket.NetWorkStateChangedEvent += GameSocket_NetWorkStateChangedEvent; //this.bot.Client.LoginHandler.AddIpMapping(bot.Config.GetIpMapping()); foreach (var mt in RunnerModule.GetSubTypes()) { RunnerModule _module = ReflectionUtil.CreateInstance(mt, this) as RunnerModule; modules.Add(mt, _module); } } public void Start() { bot.Start(); } public void Stop() { bot.Stop(); } public void Dispose() { bot.Dispose(); modules.Clear(); } public override string ToString() { return bot.Account; } public void PopLogs(List list) { events.PopLogs(list); } //-------------------------------------------------------------------------------------------------------- private void test_entry(EntryRequest request, Action cb, object option) { // var _socket = client.GateSocket; // MemoryStream ms = new MemoryStream(); // _socket.Serializer.Serialize(ms, request); // var req = new byte[ms.Length]; // Array.Copy(ms.GetBuffer(), req, ms.Length); // var route = EventTypes.GetRequestKey(typeof(EntryRequest)); // _socket.onRequestStart(route, option); // _socket.request_binary(route, req, (err, rsp) => // { // MemoryStream rs = new MemoryStream(rsp); // var rsp_type = EventTypes.GetResponseType(route); // var response = _socket.Serializer.Deserialize(rs, null, rsp_type); // _socket.onRequestEnd(route, err, response, option); // cb(err, response as EntryResponse); // }); } private void GameSocket_NetWorkStateChangedEvent(NetWorkState obj) { //if (obj == NetWorkState.DISCONNECTED) //{ // new Thread(() => // { // Thread.Sleep(5000); // events.Info("waiting 5 sec reconnect..."); // //if (!bot.Client.GameSocket.IsConnected) // { // reconnect(); // } // }).Start(); //} } public void reconnect() { new Thread(() => { bot.QueueTask(() => { bot.Stop(); }); int wait = bot.Random.Next(100, 3000); events.Info("waiting " + wait + "ms..."); Thread.Sleep(wait); bot.QueueTask(() => { bot.connect(()=> { on_start(bot); }); }); }).Start(); } public void connect() { if (bot.NetState != NetWorkState.CONNECTED) { status.Value = "重连中...."; new Thread(() => { bot.QueueTask(() => { bot.Stop(); }); bot.QueueTask(() => { bot.connect(() => { status.Value = "连接成功..."; on_start(bot); }); }); }).Start(); } else { MessageBox.Show("该客户端已经连接,无需再连"); } } /// /// 离开副本 /// public void leaveScene() { bot.Client.GameSocket.fightLevelHandler.leaveDungeonRequest((err, res)=>{ if(err != null) { MessageBox.Show("该场景不是副本,无法离开"); } }); } //-------------------------------------------------------------------------------------------------------- protected virtual void on_start(BotClient obj) { events.Info("Bot started"); obj.login(start_enter_server, (err)=> { obj.register(start_enter_server, on_error); }); } protected virtual void on_stop(BotClient obj) { events.Info("Bot stoped"); } protected virtual void on_update(BotClient obj) { foreach (var m in modules.Values) { m.OnUpdate(); } } protected virtual void on_bs_update(CommonAI.ZoneClient.ZoneActor obj) { } protected virtual void on_error(Exception err) { events.Error(err.Message, err); //将错误信息显示到当前状态 status.Value = err.Message; } public virtual void log_response(string info, Exception err, dynamic r) { if (err != null) events.Error(info + " : " + err.Message); else if (r != null) events.Log(info + " : " + r.s2c_code + " : " + r.s2c_msg); } public CommonAI.Data.XmdsUnitPro LastSelectUnitPro { get; private set; } protected virtual void start_enter_server() { bot.gate_EnterServer(on_gate_enter_server, (err) => { events.Error(err.Message); if (err is PomeloException) { var pe = err as PomeloException; if (pe.Code == 500) { reconnect(); return; } } }); } protected virtual void start_re_enter_server() { events.Log("gate re enter server"); bot.gate_ReEnterServer((e)=> { if (e.s2c_players.Count > 0) { events.Log("gate bind player"); bot.gate_BindPlayer(e.s2c_players[0].id, on_gate_bind_player, on_error); } }, (err) => { events.Error(err.Message); if (err is PomeloException) { var pe = err as PomeloException; if (pe.Code == 500) { reconnect(); return; } } }); } protected virtual void on_gate_enter_server(EntryResponse e) { events.Log("gate enter server done : player count = " + e.s2c_players.Count); bot.QueueTask((System.Action)(() => { if (e.s2c_players.Count > 0) { events.Log("gate bind player"); bot.gate_BindPlayer(e.s2c_players[0].id, this.on_gate_bind_player, this.on_error); } else { //this.LastSelectUnitPro = global::CommonAI.Data.XmdsUnitPro.None; this.LastSelectUnitPro = CUtils.RandomEnumValue(bot.Random); if (LastSelectUnitPro == global::CommonAI.Data.XmdsUnitPro.None) { LastSelectUnitPro = global::CommonAI.Data.XmdsUnitPro.Sword; } string name = CUtils.GetRandomInArray(add.RoleNameFormat, bot.Random); if (add.RandomRoleName || name == null) { events.Log("gate get random name"); bot.gate_GetRandomName((int)LastSelectUnitPro, this.on_gate_get_random_name, this.on_error); } else { if (name.Contains("{0}")) name = string.Format(name, index.ToString(add.digit_format)); events.Log("gate create role : " + name); bot.gate_CreateRole((int)LastSelectUnitPro, name, this.on_gate_create_role, (err) => { on_error(err); events.Log("gate get random name"); bot.gate_GetRandomName((int)LastSelectUnitPro, this.on_gate_get_random_name, this.on_error); }); } } })); } protected virtual void on_gate_get_random_name(GetRandomNameResponse e) { events.Log("gate get random name done"); bot.QueueTask(() => { if (string.IsNullOrEmpty(e.s2c_name)) { events.Log("gate get random name"); bot.gate_GetRandomName((int)LastSelectUnitPro, on_gate_get_random_name, on_error); } else { events.Log("gate create role : " + e.s2c_name); bot.gate_CreateRole((int)LastSelectUnitPro, e.s2c_name, on_gate_create_role, (err) => { on_error(err); events.Log("gate get random name"); bot.gate_GetRandomName((int)LastSelectUnitPro, on_gate_get_random_name, on_error); }); } }); } protected virtual void on_gate_create_role(CreatePlayerResponse e) { events.Log("gate create role done : " + e.s2c_player.name); bot.QueueTask(() => { events.Log("gate bind player : " + e.s2c_player.name); bot.gate_BindPlayer(e.s2c_player.id, on_gate_bind_player, on_error); }); } protected virtual void on_gate_bind_player(BindPlayerResponse e) { events.Log("gate bind player done : " + e.s2c_player.name); foreach (var m in modules.Values) { m.OnGateBindPlayer(e); } } //-------------------------------------------------------------------------------------------------------- protected virtual void on_gs_begin_enter_scene(XmdsBattleClient.Battle.XmdsBattleClient obj) { this.CurrentMoveAgent = null; this.CurrentRandomMoveTarget = null; events.Log("gs begin enter scene done"); if (bot.Client.BattleClient != null) { bot.Client.BattleClient.Layer.ActorAdded += on_bs_actor_added; } bot.gs_EnterScene(on_gs_enter_scene, on_error); } protected virtual void on_gs_enter_scene(EnterSceneResponse response) { events.Log("bs enter scene done : " + response.s2c_instanceId); bot.LineIndex = response.s2c_areaIndex; bot.SendUnitGuard(true); foreach (var m in modules.Values) { m.OnGameEnterScene(response); } } private void on_bs_actor_ready(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneActor actor) { foreach (var m in modules.Values) { m.OnBattleActorReady(layer, actor); } } private void on_bs_actor_added(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneActor actor) { actor.OnDoEvent += on_bs_actor_do_event; layer.AddTimePeriodicMS(5000, (t) => { check_move(); }); } private void on_bs_actor_do_event(CommonAI.ZoneClient.ZoneObject obj, CommonAI.Zone.ObjectEvent e) { if (e is UnitDeadEvent) { if (e.object_id == bot.CurrentZoneActor.ObjectID) { on_actor_dead(bot.CurrentZoneActor, e as UnitDeadEvent); } } } private void on_actor_dead(CommonAI.ZoneClient.ZoneActor actor, UnitDeadEvent e) { do_relive(2); foreach (var m in modules.Values) { m.OnBattleActorDead(actor, e); } } //-------------------------------------------------------------------------------------------------------- public virtual void do_relive(int type) { bot.Client.GameSocket.playerHandler.reliveRequest(type, (e, r) => { log_response("reliveRequest done : ", e, r); }); } //-------------------------------------------------------------------------------------------------------- #region GM private void sendCMD(string cmd, Action cb) { //bot.Client.GameSocket.chatHandler.sendChatRequest(1, cmd, "", "", cb); } public virtual void do_gm_add_exp(int exp) { sendCMD("@gm add exp " + exp, (e, r) => { log_response("do_gm_add_exp done : ", e, r); }); } public virtual void do_gm_add_upexp(int exp) { sendCMD("@gm add upexp " + exp, (e, r) => { log_response("do_gm_add_upexp done : ", e, r); }); } public virtual void do_gm_add_diamond(int exp) { sendCMD("@gm add diamond " + exp, (e, r) => { log_response("do_gm_add_diamond done : ", e, r); }); } public virtual void do_gm_add_gold(int exp) { sendCMD("@gm add gold " + exp, (e, r) => { log_response("do_gm_add_gold done : ", e, r); }); } public virtual void do_gm_finish_task(int taskTemplateID) { sendCMD("@gm finishTask " + taskTemplateID, (e, r) => { log_response("do_gm_finish_task done : ", e, r); }); } public virtual void do_gm_unlock_bag(int num) { sendCMD("@gm unlock " + num, (e, r) => { log_response("do_gm_unlock_bag done : ", e, r); }); } /************************************************************************/ /* 模拟充值成功回调 */ /************************************************************************/ public virtual void do_gm_pay_success(String orderId) { sendCMD("@gm paySuccess " + orderId, (e, r) => { log_response("do_gm_pay_success done : ", e, r); }); } public virtual void do_gm_open_func() { sendCMD("@gm openFunc", (e, r) => { log_response("do_gm_open_func done : ", e, r); }); } public virtual void do_gm_add_skin() { sendCMD("@gm allSkin",(e,r) => { log_response("do_gm_add_skin done : ", e, r); }); } public virtual void do_gm_add_item(string code, int num) { sendCMD("@gm add " + code + " " + num, (e, r) => { log_response("do_gm_add_item done : ", e, r); }); } public virtual void do_gm_add_item() { //sendCMD("@gm add lclot1-test 1", (e, r) => //{ // log_response("do_gm_add_item done : ", e, r); //}); //sendCMD("@gm add lweap1-test 1", (e, r) => //{ // log_response("do_gm_add_item done : ", e, r); //}); } #endregion //-------------------------------------------------------------------------------------------------------- #region Task public virtual BotClient.QuestData do_seek_task(int questID, BotClient.QuestData.SeekAction action) { var quest = bot.CurrentQuestManager.GetQuest(questID); if (quest != null) { events.Log("do_seek_task : " + quest); quest.Seek(action); } return quest; } public virtual BotClient.QuestData do_seek_expect_task(BotClient.QuestData.QuestStatus expect, BotClient.QuestData.SeekAction action, bool random = false) { BotClient.QuestData q = null; if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.TRUNK, expect, action, random)) != null) { events.Log("do_seek_expect_task : " + q); return q; } if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.INVALID, expect, action, random)) != null) { events.Log("do_seek_expect_task : " + q); return q; } return q; } public virtual BotClient.QuestData do_seek_random_task(BotClient.QuestData.SeekAction action, bool random = false) { BotClient.QuestData q = null; if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.TRUNK, BotClient.QuestData.QuestStatus.CAN_FINISH, action, random)) != null) { events.Log("do_seek_random_task : " + q); return q; } if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.TRUNK, BotClient.QuestData.QuestStatus.IN_PROGRESS, action, random)) != null) { events.Log("do_seek_random_task : " + q); return q; } if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.TRUNK, BotClient.QuestData.QuestStatus.NEW, action, random)) != null) { events.Log("do_seek_random_task : " + q); return q; } if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.INVALID, BotClient.QuestData.QuestStatus.CAN_FINISH, action, random)) != null) { events.Log("do_seek_random_task : " + q); return q; } if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.INVALID, BotClient.QuestData.QuestStatus.IN_PROGRESS, action, random)) != null) { events.Log("do_seek_random_task : " + q); return q; } if ((q = bot.CurrentQuestManager.SeekExpectTask(BotClient.QuestData.QuestType.INVALID, BotClient.QuestData.QuestStatus.NEW, action, random)) != null) { events.Log("do_seek_random_task : " + q); return q; } return q; } public virtual void do_update_quest_status(BotClient.QuestData quest) { events.Log("do_update_quest_status : " + quest + " : " + quest.State); bot.Client.GameSocket.taskHandler.updateTaskStatusRequest(quest.TemplateID, (int)quest.Kind, (err, msg) => { if (err != null) events.Error("updateTaskStatusRequest error : " + err.Message); else events.Log("updateTaskStatusRequest done : " + msg.s2c_code + " : " + msg.s2c_msg); }); } public virtual void do_accept_quest(BotClient.QuestData quest, Action error = null) { if (client.BattleActor != null) { events.Log("do_accept_quest : " + quest + " : " + quest.State); client.GameSocket.taskHandler.acceptTaskRequest(quest.TemplateID, (int)quest.Kind, client.BattleActor.ObjectID.ToString(), (err, msg) => { if (err != null) { events.Error("acceptTaskRequest error : " + err.Message); if (error != null) error(err); } else { events.Log("acceptTaskRequest done : " + msg.s2c_code + " : " + msg.s2c_msg); } }); } } public virtual void do_submit_task(BotClient.QuestData quest, Action error = null) { if (client.BattleActor != null) { events.Log("do_submit_task : " + quest + " : " + quest.State); client.GameSocket.taskHandler.submitTaskRequest(quest.TemplateID, (int)quest.Kind, 0, client.BattleActor.ObjectID.ToString(), (err, msg) => { if (err != null) { events.Error("submitTaskRequest error : " + err.Message); if (error != null) error(err); } else { events.Log("submitTaskRequest done : " + msg.s2c_code + " : " + msg.s2c_msg); } }); } } #endregion //-------------------------------------------------------------------------------------------------------- #region Move public ActorMoveAgent CurrentMoveAgent { get; private set; } public SceneObjectData CurrentRandomMoveTarget { get; private set; } private Vector2 mLastPos = new Vector2(); private void check_move() { float min_step = client.DataRoot.Templates.CFG.OBJECT_MOVE_TO_MIN_STEP_SEC; bool not_move = MathVector.getDistance(mLastPos.X, mLastPos.Y, bot.CurrentZoneActor.X, bot.CurrentZoneActor.Y) < min_step; mLastPos.SetX(bot.CurrentZoneActor.X); mLastPos.SetY(bot.CurrentZoneActor.Y); if (not_move) { CurrentRandomMoveTarget = null; if (CurrentMoveAgent != null) CurrentMoveAgent.Stop(); CurrentMoveAgent = null; } } private SceneObjectData do_bs_actor_random_move_regions(List list, bool attack, float min_distance) where R : SceneObjectData { var player = bot.CurrentZoneActor; var layer = bot.CurrentZoneLayer; if (player != null && layer.IsLoaded) { try { bot.SendUnitGuard(attack); if (CurrentRandomMoveTarget == null || MathVector.getDistance(player.X, player.Y, CurrentRandomMoveTarget.X, CurrentRandomMoveTarget.Y) <= min_distance || layer.FindPath(player.X, player.Y, CurrentRandomMoveTarget.X, CurrentRandomMoveTarget.Y) == null) { CUtils.RandomList(bot.Random, list); foreach (var rg in list) { if (player.Parent.FindPath(player.X, player.Y, rg.X, rg.Y) != null) { events.Log("do_bs_actor_random_move_region : " + rg.Name); if (!attack) { do_start_move_agent(rg.X, rg.Y, min_distance); } else { player.SendUnitAttackMoveTo(rg.X, rg.Y, attack); } CurrentRandomMoveTarget = rg; return rg; } } } else if (bot.CurrentZoneActor.CurrentState == UnitActionStatus.Idle) { if (!attack) { do_start_move_agent(CurrentRandomMoveTarget.X, CurrentRandomMoveTarget.Y, min_distance); } else { player.SendUnitAttackMoveTo(CurrentRandomMoveTarget.X, CurrentRandomMoveTarget.Y, attack); } return CurrentRandomMoveTarget; } } catch (Exception err) { events.Error(err.Message, err); } } return null; } public virtual SceneObjectData do_bs_actor_random_move_region(bool attack = true, float min_distance = 0.1f) { return do_bs_actor_random_move_regions(bot.CurrentRegionManager.AllRegions(), attack, min_distance); } public virtual SceneObjectData do_bs_actor_random_move_transport(bool attack = true, float min_distance = 0.1f) { return do_bs_actor_random_move_regions(bot.CurrentRegionManager.AllTransports(), attack, min_distance); } public virtual ActorMoveAgent do_start_move_agent(float x, float y, float distance, bool force_trans = false) { if (CurrentMoveAgent != null) { CurrentMoveAgent.Stop(); } CurrentMoveAgent = new ActorMoveAgent(x, y, distance); bot.CurrentZoneActor.AddAgent(CurrentMoveAgent); bot.SendUnitGuard(false); if (CurrentMoveAgent.Result == CommonAI.RTS.Manhattan.AstarManhattan.FindPathResult.Destination) { bot.CurrentRegionManager.CheckTrans(1, force_trans); } else if (CurrentMoveAgent.IsEnd) { bot.CurrentZoneActor.SendUnitAttackMoveTo(x, y, false); } return CurrentMoveAgent; } #endregion //-------------------------------------------------------------------------------------------------------- #region Pick public virtual CommonAI.ZoneClient.ZoneItem do_try_pick_nearest_item(out Vector2 move_to) { move_to = null; if (bot.CurrentZoneActor.CurrentState != UnitActionStatus.Pick) { var item = bot.CurrentZoneLayer.GetNearPickableItem(bot.CurrentZoneActor); if (item != null) { events.Log("try pick nearest item : " + item.Info.Name); if (MathVector.getDistance(bot.CurrentZoneActor.X, bot.CurrentZoneActor.Y, item.X, item.Y) < item.RadiusSize) { bot.CurrentZoneActor.SendUnitPickObject(item.ObjectID); return item; } else { move_to = new Vector2(item.X, item.Y); } } } return null; } public virtual CommonAI.ZoneClient.ZoneItem do_start_pick_any_item() { if (bot.CurrentZoneActor.CurrentState != UnitActionStatus.Pick) { var item = bot.CurrentZoneLayer.GetNearPickableItem(bot.CurrentZoneActor); if (item != null) { events.Log("do pick item : " + item.Info.Name); bot.CurrentZoneActor.SendUnitPickObject(item.ObjectID); return item; } } return null; } #endregion #region BagAndEquip #endregion //-------------------------------------------------------------------------------------------------------- public abstract class RunnerModule { public string module_name = "模块名"; private static HashMap s_SubModules = new HashMap(); public static List GetSubTypes() { var ret = new List(); foreach (var mt in typeof(RunnerModule).Assembly.GetTypes()) { if (mt.IsSubclassOf(typeof(RunnerModule)) && !mt.IsAbstract) { ret.Add(mt); } } return ret; } /// /// 获取类中的属性值 /// /// /// /// public string GetModelValue(string FieldName, object obj) { try { Type Ts = obj.GetType(); object o = Ts.GetProperty(FieldName).GetValue(obj, null); string Value = Convert.ToString(o); if (string.IsNullOrEmpty(Value)) return null; return Value; } catch { return null; } } public static void SetModuleEnable(Type type, bool value) { s_SubModules[type] = value; } public static bool GetModuleEnable(Type type) { bool enable = false; if (s_SubModules.TryGetValue(type, out enable)) { return enable; } return false; } static RunnerModule() { foreach (var mt in GetSubTypes()) { s_SubModules.Add(mt, true); } } private bool m_Enable; protected BotClient bot { get; private set; } protected BotRunner runner { get; private set; } protected XmdsNetClient client { get; private set; } protected Logger log { get; private set; } public bool Enable { get { return m_Enable; } } public void autoJoinTeam() { if(IsCanJoin) { autoJoinTeamRequest(); } } public virtual void autoJoinTeamRequest() { } protected virtual int rand() { return 20; } public bool IsCanJoin { get { return Enable && bot.IsFree && (runner.CurrentMoveAgent == null) && bot.Random.Next(100) < rand(); } } public RunnerModule() { } public RunnerModule(BotRunner r) { this.runner = r; this.bot = r.Bot; this.client = bot.Client; this.log = r.events; this.m_Enable = GetModuleEnable(GetType()); } public void SetStatus(string st) { runner.status.Value = st; } internal void OnUpdate() { bool enable = GetModuleEnable(GetType()); if (m_Enable != enable) { m_Enable = enable; OnEnableChanged(enable); } } protected virtual void OnEnableChanged(bool enable) { } protected internal virtual void OnGateBindPlayer(BindPlayerResponse e) { } protected internal virtual void OnGameEnterScene(EnterSceneResponse response) { } protected internal virtual void OnBattleActorReady(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneActor actor) { } protected internal virtual void OnBattleActorDead(CommonAI.ZoneClient.ZoneActor actor, UnitDeadEvent e) { } } } }