using Emgu.CV; using Emgu.CV.Structure; using RichCreator.Utility.Captures; using RichCreator.Utility.CV; using RichCreator.Utility.Structs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace RichCreator.StateMachines { /// /// 频道状态机 /// public class ChannelStateMachine { //默认状态 private ChannelStates currentState = ChannelStates.Start; //频道选择文字的位置 private ZTRectangle channelChoiceTextRect = ZTRectangle.Empty; //目前仅支持寂静城 private const Int32 channelIndex = 1;//0:时空之门,1:寂静城 //频道距离“频道选择文字”的偏移 private static ZTPoint[] channelOffsets = new ZTPoint[] { new ZTPoint(-279,246), new ZTPoint(-279,291) }; /// /// 开始工作 /// public ZTResult Work(ZTRectangle gameRect,bool isGroupMode,CancellationToken cancelToken,Int64 timeoutMillSecond) { if (timeoutMillSecond <= 0) { throw new ArgumentOutOfRangeException("过期时间不能小于等于0"); } DateTime timeoutTime = DateTime.Now.AddMilliseconds(timeoutMillSecond); while (true) { G.Instance.InfoWriter("states:" + currentState.ToString()); if (currentState == ChannelStates.Complete) { //完成 break; } if (cancelToken.IsCancellationRequested) { //取消 return ZTResult.Cancel; } if (DateTime.Now > timeoutTime) { //超时 return ZTResult.Timeout; } switch (currentState) { case ChannelStates.Start: //开始 currentState = ChannelStates.CheckSailiyaHouse; break; case ChannelStates.CheckSailiyaHouse: //检测是否赛丽亚的房间 if (DnfCVHelper.IsInSaiLiYaHouse(gameRect)) { //检测是否组队模式 currentState = ChannelStates.CheckGroupMode; } else { currentState = ChannelStates.IsChoiceRolePage; } break; case ChannelStates.IsChoiceRolePage: //检测是否角色选择界面 ZTRectangle startGameButtonRect = ZTRectangle.Empty; if (DnfCVHelper.IsSelectRoleWindow(out startGameButtonRect)) { currentState = ChannelStates.ConfirmAutoChange; } else { currentState = ChannelStates.CheckSailiyaHouse; Thread.Sleep(1000); } break; case ChannelStates.ConfirmAutoChange: //查找“确认”按钮并点击,并等待2秒 ZTRectangle confirmButtonRect = ZTRectangle.Empty; if (ChannelCVHelper.HasConnectionErrorInChoiceRole(out confirmButtonRect)) { G.Instance.InputControl.MoveToAndClick(confirmButtonRect.GetCenterPoint()); } currentState = ChannelStates.CheckSailiyaHouse; Thread.Sleep(2000); break; case ChannelStates.CheckGroupMode: //是否组队模式 if (isGroupMode) { currentState = ChannelStates.CheckChannel; } else { currentState = ChannelStates.CheckConnectIsValid; } break; case ChannelStates.CheckConnectIsValid: //是否有效网络连接 ZTPoint validButtonPoint = ZTPoint.Empty; if (ChannelCVHelper.HasConnectIsVaildWindow(out validButtonPoint, gameRect)) { G.Instance.InputControl.MoveToAndClick(validButtonPoint); currentState = ChannelStates.ChangeChannelPageIsOpen; Thread.Sleep(2000); } else { currentState = ChannelStates.CloseAllWindow; } break; case ChannelStates.CheckChannel: //是否指定频道 if (ChannelCVHelper.IsInJijingchengChannel(gameRect)) { currentState = ChannelStates.CheckConnectIsValid; } else { currentState = ChannelStates.ChangeChannelPageIsOpen; } break; case ChannelStates.ChangeChannelPageIsOpen: //切换频道界面是否打开 if (ChannelCVHelper.IsOpenChannelChoiceWindow(out channelChoiceTextRect, gameRect)) { currentState = ChannelStates.ChangeChannel; } else { currentState = ChannelStates.OpenChangeChannelPage; } break; case ChannelStates.ChangeChannel: //双击切换频道,等待两秒 ZTPoint textCenterPoint = channelChoiceTextRect.GetCenterPoint(); ZTPoint clickPoint = textCenterPoint.Add(channelOffsets[channelIndex]); G.Instance.InputControl.MoveToAndDClick(clickPoint); Thread.Sleep(2000); currentState = ChannelStates.CheckSailiyaHouse; break; case ChannelStates.OpenChangeChannelPage: //打开切换频道界面 G.Instance.InputControl.MoveToAndClick(new ZTPoint(gameRect.End.X - 136, gameRect.Start.Y + 9)); Thread.Sleep(2000); currentState = ChannelStates.ChangeChannelPageIsOpen; break; case ChannelStates.CloseAllWindow: //关闭所有窗口 CloseAllAlertWindow(cancelToken,gameRect); currentState = ChannelStates.Complete; break; default: return ZTResult.Failed; } } return ZTResult.Success; } /// /// 关闭所有弹出窗 /// /// /// /// private bool CloseAllAlertWindow(CancellationToken cancelToken, ZTRectangle gameRect) { while (!cancelToken.IsCancellationRequested) { G.Instance.InputControl.MoveTo(0, 0, false, false, false); Thread.Sleep(10); //截图 System.Drawing.Bitmap bitmap = ScreenCapture.Instance.CaptureScreen(); Image image = new Image(bitmap); ZTRectangle closeButtonRect = ZTRectangle.Empty; if (!DnfCVHelper.GetAlertWindow(out closeButtonRect, image, gameRect)) { return true; } G.Instance.InputControl.MoveToAndClick(closeButtonRect.GetCenterPoint()); Thread.Sleep(500); } return false; } /// /// 频道状态 /// public enum ChannelStates { Start,//开始 CheckSailiyaHouse,//检测是否赛丽亚的房间 IsChoiceRolePage,//检测是否角色选择界面 ConfirmAutoChange,//查找“确认”按钮并点击 CheckGroupMode,//是否组队模式 CheckConnectIsValid,//是否有效网络连接 CheckChannel,//是否指定频道 ChangeChannelPageIsOpen,//切换频道界面是否打开 ChangeChannel,//双击切换频道,等待两秒 OpenChangeChannelPage,//打开切换频道界面 CloseAllWindow,//关闭所有窗口 Complete//完成 } } }