asmrobot
2019-10-14 730fe7ea65bcadbe235e40bb54b2410d14495267
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
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
{
    /// <summary>
    /// 频道状态机
    /// </summary>
    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)
            };
 
        /// <summary>
        /// 开始工作
        /// </summary>
        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;
        }
 
 
        /// <summary>
        /// 关闭所有弹出窗
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <param name="gameRect"></param>
        /// <returns></returns>
        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<Rgb, byte> image = new Image<Rgb, byte>(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;
        }
 
 
        /// <summary>
        /// 频道状态
        /// </summary>
        public enum ChannelStates
        {
            Start,//开始
            CheckSailiyaHouse,//检测是否赛丽亚的房间
            IsChoiceRolePage,//检测是否角色选择界面
            ConfirmAutoChange,//查找“确认”按钮并点击
            CheckGroupMode,//是否组队模式
            CheckConnectIsValid,//是否有效网络连接
            CheckChannel,//是否指定频道
            ChangeChannelPageIsOpen,//切换频道界面是否打开
            ChangeChannel,//双击切换频道,等待两秒
            OpenChangeChannelPage,//打开切换频道界面
            CloseAllWindow,//关闭所有窗口
            Complete//完成
        }
    }
}