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//完成
|
}
|
}
|
}
|