mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2025-12-19 18:32:23 +08:00
机器人移动
This commit is contained in:
@@ -54,18 +54,23 @@ type Hk4e struct {
|
||||
|
||||
// Hk4eRobot 原神机器人
|
||||
type Hk4eRobot struct {
|
||||
RegionListUrl string `toml:"region_list_url"` // 一级dispatch地址
|
||||
RegionListParam string `toml:"region_list_param"` // 一级dispatch的url参数
|
||||
CurRegionUrl string `toml:"cur_region_url"` // 二级dispatch地址
|
||||
CurRegionParam string `toml:"cur_region_param"` // 二级dispatch的url参数
|
||||
KeyId string `toml:"key_id"` // 客户端密钥编号
|
||||
LoginSdkUrl string `toml:"login_sdk_url"` // sdk登录服务器地址
|
||||
Account string `toml:"account"` // 帐号
|
||||
Password string `toml:"password"` // base64编码的rsa公钥加密后的密码
|
||||
ClientVersion string `toml:"client_version"` // 客户端版本号
|
||||
DosEnable bool `toml:"dos_enable"` // 是否开启压力测试
|
||||
DosNum int32 `toml:"dos_num"` // 压力测试并发数量 帐号自动添加后缀编号
|
||||
DosLoopLogin bool `toml:"dos_loop_login"` // 压力测试是否循环登录退出
|
||||
RegionListUrl string `toml:"region_list_url"` // 一级dispatch地址
|
||||
RegionListParam string `toml:"region_list_param"` // 一级dispatch的url参数
|
||||
SelectRegionIndex int32 `toml:"select_region_index"` // 选择的二级dispatch索引
|
||||
CurRegionUrl string `toml:"cur_region_url"` // 二级dispatch地址 可强制指定 为空则使用一级dispatch获取的地址
|
||||
CurRegionParam string `toml:"cur_region_param"` // 二级dispatch的url参数
|
||||
KeyId string `toml:"key_id"` // 客户端密钥编号
|
||||
LoginSdkUrl string `toml:"login_sdk_url"` // sdk登录服务器地址
|
||||
Account string `toml:"account"` // 帐号
|
||||
Password string `toml:"password"` // base64编码的rsa公钥加密后的密码
|
||||
ClientVersion string `toml:"client_version"` // 客户端版本号
|
||||
DosEnable bool `toml:"dos_enable"` // 是否开启压力测试
|
||||
DosTotalNum int32 `toml:"dos_total_num"` // 压力测试总并发数量 帐号自动添加后缀编号
|
||||
DosBatchNum int32 `toml:"dos_batch_num"` // 压力测试每批登录并发数量
|
||||
DosLoopLogin bool `toml:"dos_loop_login"` // 压力测试是否循环登录退出
|
||||
ClientMoveEnable bool `toml:"client_move_enable"` // 是否开启客户端模拟移动
|
||||
ClientMoveSpeed int32 `toml:"client_move_speed"` // 客户端模拟移动速度
|
||||
ClientMoveRangeExt int32 `toml:"client_move_range_ext"` // 客户端模拟移动区域半径
|
||||
}
|
||||
|
||||
// MQ 消息队列
|
||||
|
||||
@@ -10,7 +10,8 @@ client_proto_proxy_enable = false
|
||||
[hk4e_robot]
|
||||
region_list_url = "https://hk4e.flswld.com" # 一级dispatch地址
|
||||
region_list_param = "" # 一级dispatch的url参数
|
||||
cur_region_url = "https://hk4e.flswld.com/query_cur_region" # 二级dispatch地址
|
||||
select_region_index = 0 # 选择的二级dispatch索引
|
||||
cur_region_url = "https://hk4e.flswld.com/query_cur_region" # 二级dispatch地址 可强制指定 为空则使用一级dispatch获取的地址
|
||||
cur_region_param = "?version=OSRELWin3.2.0&key_id=5" # 二级dispatch的url参数
|
||||
key_id = "5" # 客户端密钥编号
|
||||
login_sdk_url = "https://hk4e.flswld.com" # sdk登录服务器地址
|
||||
@@ -18,5 +19,9 @@ account = "flswld" # 帐号
|
||||
password = "" # base64编码的rsa公钥加密后的密码
|
||||
client_version = "CNRELWin3.2.0_R11611027_S11212885_D11793813" # 客户端版本号
|
||||
dos_enable = false # 是否开启压力测试
|
||||
dos_num = 1 # 压力测试并发数量 帐号自动添加后缀编号
|
||||
dos_total_num = 1 # 压力测试总并发数量 帐号自动添加后缀编号
|
||||
dos_batch_num = 1 # 压力测试每批登录并发数量
|
||||
dos_loop_login = false # 压力测试是否循环登录退出
|
||||
client_move_enable = false # 是否开启客户端模拟移动
|
||||
client_move_speed = 10 # 客户端模拟移动速度
|
||||
client_move_range_ext = 1024 # 客户端模拟移动区域半径
|
||||
|
||||
@@ -3,13 +3,18 @@ package main
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"math"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
pb "google.golang.org/protobuf/proto"
|
||||
"hk4e/pkg/endec"
|
||||
"hk4e/pkg/random"
|
||||
"hk4e/robot/net"
|
||||
|
||||
"hk4e/common/config"
|
||||
@@ -34,12 +39,27 @@ func main() {
|
||||
// engine.RunEngine([]int{0, 1, 2, 3}, 4, 1, "0.0.0.0")
|
||||
// time.Sleep(time.Second * 30)
|
||||
|
||||
dispatchInfo, err := login.GetDispatchInfo(config.GetConfig().Hk4eRobot.RegionListUrl,
|
||||
config.GetConfig().Hk4eRobot.RegionListParam,
|
||||
config.GetConfig().Hk4eRobot.CurRegionUrl,
|
||||
config.GetConfig().Hk4eRobot.CurRegionParam,
|
||||
config.GetConfig().Hk4eRobot.KeyId)
|
||||
if err != nil {
|
||||
logger.Error("get dispatch info error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if config.GetConfig().Hk4eRobot.DosEnable {
|
||||
for i := 0; i < int(config.GetConfig().Hk4eRobot.DosNum); i++ {
|
||||
go httpLogin(config.GetConfig().Hk4eRobot.Account + "_" + strconv.Itoa(i))
|
||||
for i := 0; i < int(config.GetConfig().Hk4eRobot.DosTotalNum); i++ {
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(int(config.GetConfig().Hk4eRobot.DosBatchNum))
|
||||
for j := 0; j < int(config.GetConfig().Hk4eRobot.DosBatchNum); j++ {
|
||||
go httpLogin(config.GetConfig().Hk4eRobot.Account+"_"+strconv.Itoa(i), dispatchInfo, wg)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
} else {
|
||||
httpLogin(config.GetConfig().Hk4eRobot.Account)
|
||||
httpLogin(config.GetConfig().Hk4eRobot.Account, dispatchInfo, nil)
|
||||
}
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
@@ -58,30 +78,28 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func httpLogin(account string) {
|
||||
func httpLogin(account string, dispatchInfo *login.DispatchInfo, wg *sync.WaitGroup) {
|
||||
defer func() {
|
||||
if config.GetConfig().Hk4eRobot.DosEnable {
|
||||
wg.Done()
|
||||
}
|
||||
}()
|
||||
logger.Info("robot start, account: %v", account)
|
||||
dispatchInfo, err := login.GetDispatchInfo(config.GetConfig().Hk4eRobot.RegionListUrl,
|
||||
config.GetConfig().Hk4eRobot.RegionListParam,
|
||||
config.GetConfig().Hk4eRobot.CurRegionUrl,
|
||||
config.GetConfig().Hk4eRobot.CurRegionParam,
|
||||
config.GetConfig().Hk4eRobot.KeyId)
|
||||
if err != nil {
|
||||
logger.Error("get dispatch info error: %v", err)
|
||||
return
|
||||
}
|
||||
accountInfo, err := login.AccountLogin(config.GetConfig().Hk4eRobot.LoginSdkUrl, account, config.GetConfig().Hk4eRobot.Password)
|
||||
if err != nil {
|
||||
logger.Error("account login error: %v", err)
|
||||
return
|
||||
}
|
||||
for {
|
||||
gateLogin(account, dispatchInfo, accountInfo)
|
||||
if !config.GetConfig().Hk4eRobot.DosLoopLogin {
|
||||
break
|
||||
go func() {
|
||||
for {
|
||||
gateLogin(account, dispatchInfo, accountInfo)
|
||||
if !config.GetConfig().Hk4eRobot.DosLoopLogin {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func gateLogin(account string, dispatchInfo *login.DispatchInfo, accountInfo *login.AccountInfo) {
|
||||
@@ -97,13 +115,14 @@ func gateLogin(account string, dispatchInfo *login.DispatchInfo, accountInfo *lo
|
||||
logger.Error("gen clientVersionHashData error: %v", err)
|
||||
return
|
||||
}
|
||||
checksumClientVersion := strings.Split(config.GetConfig().Hk4eRobot.ClientVersion, "_")[0]
|
||||
session.SendMsg(cmd.PlayerLoginReq, &proto.PlayerLoginReq{
|
||||
AccountType: 1,
|
||||
SubChannelId: 1,
|
||||
LanguageType: 2,
|
||||
PlatformType: 3,
|
||||
Checksum: "$008094416f86a051270e64eb0b405a38825",
|
||||
ChecksumClientVersion: "CNRELWin3.2.0",
|
||||
ChecksumClientVersion: checksumClientVersion,
|
||||
ClientDataVersion: 11793813,
|
||||
ClientVerisonHash: base64.StdEncoding.EncodeToString(clientVersionHashData),
|
||||
ClientVersion: config.GetConfig().Hk4eRobot.ClientVersion,
|
||||
@@ -116,10 +135,60 @@ func gateLogin(account string, dispatchInfo *login.DispatchInfo, accountInfo *lo
|
||||
|
||||
func clientLogic(account string, session *net.Session) {
|
||||
ticker := time.NewTicker(time.Second)
|
||||
tickCounter := uint64(0)
|
||||
pingSeq := uint32(0)
|
||||
enterSceneDone := false
|
||||
sceneBeginTime := uint32(0)
|
||||
bornPos := new(proto.Vector)
|
||||
currPos := new(proto.Vector)
|
||||
avatarEntityId := uint32(0)
|
||||
moveRot := random.GetRandomFloat32(0.0, 359.9)
|
||||
moveReliableSeq := uint32(0)
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
tickCounter++
|
||||
if config.GetConfig().Hk4eRobot.ClientMoveEnable {
|
||||
if enterSceneDone {
|
||||
currPos.X -= float32(float64(config.GetConfig().Hk4eRobot.ClientMoveSpeed) * math.Sin(float64(moveRot)))
|
||||
currPos.Z += float32(float64(config.GetConfig().Hk4eRobot.ClientMoveSpeed) * math.Cos(float64(moveRot)))
|
||||
if currPos.X > bornPos.X+float32(config.GetConfig().Hk4eRobot.ClientMoveRangeExt) ||
|
||||
currPos.Y > bornPos.Y+float32(config.GetConfig().Hk4eRobot.ClientMoveRangeExt) ||
|
||||
currPos.X < bornPos.X-float32(config.GetConfig().Hk4eRobot.ClientMoveRangeExt) ||
|
||||
currPos.Y < bornPos.Y-float32(config.GetConfig().Hk4eRobot.ClientMoveRangeExt) {
|
||||
moveRot = random.GetRandomFloat32(0.0, 359.9)
|
||||
}
|
||||
moveReliableSeq += 100
|
||||
entityMoveInfo := &proto.EntityMoveInfo{
|
||||
EntityId: avatarEntityId,
|
||||
MotionInfo: &proto.MotionInfo{
|
||||
Pos: currPos,
|
||||
Rot: &proto.Vector{X: 0.0, Y: moveRot, Z: 0.0},
|
||||
Speed: new(proto.Vector),
|
||||
State: proto.MotionState_MOTION_RUN,
|
||||
RefPos: new(proto.Vector),
|
||||
},
|
||||
SceneTime: uint32(time.Now().UnixMilli()) - sceneBeginTime,
|
||||
ReliableSeq: moveReliableSeq,
|
||||
IsReliable: true,
|
||||
}
|
||||
combatData, err := pb.Marshal(entityMoveInfo)
|
||||
if err != nil {
|
||||
logger.Error("marshal EntityMoveInfo error: %v, account: %v", err, account)
|
||||
continue
|
||||
}
|
||||
session.SendMsg(cmd.CombatInvocationsNotify, &proto.CombatInvocationsNotify{
|
||||
InvokeList: []*proto.CombatInvokeEntry{{
|
||||
CombatData: combatData,
|
||||
ForwardType: proto.ForwardType_FORWARD_TO_ALL_EXCEPT_CUR,
|
||||
ArgumentType: proto.CombatTypeArgument_ENTITY_MOVE,
|
||||
}},
|
||||
})
|
||||
}
|
||||
}
|
||||
if tickCounter%5 != 0 {
|
||||
continue
|
||||
}
|
||||
pingSeq++
|
||||
// 通过这个接口发消息给服务器
|
||||
session.SendMsg(cmd.PingReq, &proto.PingReq{
|
||||
@@ -128,11 +197,14 @@ func clientLogic(account string, session *net.Session) {
|
||||
})
|
||||
case protoMsg := <-session.RecvChan:
|
||||
// 从这个管道接收服务器发来的消息
|
||||
logger.Debug("recv protoMsg: %v", protoMsg)
|
||||
switch protoMsg.CmdId {
|
||||
case cmd.PlayerLoginRsp:
|
||||
rsp := protoMsg.PayloadMessage.(*proto.PlayerLoginRsp)
|
||||
logger.Info("login ok, rsp: %v", rsp)
|
||||
if rsp.Retcode != 0 {
|
||||
logger.Error("login fail, retCode: %v, account: %v", rsp.Retcode, account)
|
||||
return
|
||||
}
|
||||
logger.Info("login ok, account: %v", account)
|
||||
case cmd.DoSetPlayerBornDataNotify:
|
||||
session.SendMsg(cmd.SetPlayerBornDataReq, &proto.SetPlayerBornDataReq{
|
||||
AvatarId: 10000007,
|
||||
@@ -140,6 +212,8 @@ func clientLogic(account string, session *net.Session) {
|
||||
})
|
||||
case cmd.PlayerEnterSceneNotify:
|
||||
ntf := protoMsg.PayloadMessage.(*proto.PlayerEnterSceneNotify)
|
||||
bornPos.X, bornPos.Y, bornPos.Z = ntf.Pos.X, ntf.Pos.Y, ntf.Pos.Z
|
||||
currPos.X, currPos.Y, currPos.Z = ntf.Pos.X, ntf.Pos.Y, ntf.Pos.Z
|
||||
session.SendMsg(cmd.EnterSceneReadyReq, &proto.EnterSceneReadyReq{EnterSceneToken: ntf.EnterSceneToken})
|
||||
case cmd.EnterSceneReadyRsp:
|
||||
ntf := protoMsg.PayloadMessage.(*proto.EnterSceneReadyRsp)
|
||||
@@ -149,10 +223,20 @@ func clientLogic(account string, session *net.Session) {
|
||||
session.SendMsg(cmd.EnterSceneDoneReq, &proto.EnterSceneDoneReq{EnterSceneToken: ntf.EnterSceneToken})
|
||||
case cmd.EnterSceneDoneRsp:
|
||||
ntf := protoMsg.PayloadMessage.(*proto.EnterSceneDoneRsp)
|
||||
enterSceneDone = true
|
||||
sceneBeginTime = uint32(time.Now().UnixMilli())
|
||||
session.SendMsg(cmd.PostEnterSceneReq, &proto.PostEnterSceneReq{EnterSceneToken: ntf.EnterSceneToken})
|
||||
if config.GetConfig().Hk4eRobot.DosLoopLogin {
|
||||
return
|
||||
}
|
||||
case cmd.SceneEntityAppearNotify:
|
||||
ntf := protoMsg.PayloadMessage.(*proto.SceneEntityAppearNotify)
|
||||
for _, sceneEntityInfo := range ntf.EntityList {
|
||||
if sceneEntityInfo.EntityType != proto.ProtEntityType_PROT_ENTITY_AVATAR {
|
||||
continue
|
||||
}
|
||||
avatarEntityId = sceneEntityInfo.EntityId
|
||||
}
|
||||
}
|
||||
case <-session.DeadEvent:
|
||||
logger.Info("robot exit, account: %v", account)
|
||||
|
||||
@@ -61,8 +61,9 @@ func GateLogin(dispatchInfo *DispatchInfo, accountInfo *AccountInfo, keyId strin
|
||||
if protoMsg.CmdId != cmd.GetPlayerTokenRsp {
|
||||
return nil, errors.New("recv pkt is not GetPlayerTokenRsp")
|
||||
}
|
||||
// XOR密钥切换
|
||||
getPlayerTokenRsp := protoMsg.PayloadMessage.(*proto.GetPlayerTokenRsp)
|
||||
logger.Info("gate login ok, uid: %v", getPlayerTokenRsp.Uid)
|
||||
// XOR密钥切换
|
||||
seedEnc, err := base64.StdEncoding.DecodeString(getPlayerTokenRsp.ServerRandKey)
|
||||
if err != nil {
|
||||
logger.Error("base64 decode error: %v", err)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"hk4e/common/config"
|
||||
"hk4e/common/region"
|
||||
"hk4e/dispatch/api"
|
||||
"hk4e/pkg/endec"
|
||||
@@ -44,7 +45,7 @@ func GetDispatchInfo(regionListUrl string, regionListParam string, curRegionUrl
|
||||
return nil, errors.New("no region found")
|
||||
}
|
||||
if curRegionUrl == "" {
|
||||
selectRegion := queryRegionListHttpRsp.RegionList[0]
|
||||
selectRegion := queryRegionListHttpRsp.RegionList[int(config.GetConfig().Hk4eRobot.SelectRegionIndex)]
|
||||
logger.Info("select region: %v", selectRegion)
|
||||
curRegionUrl = selectRegion.DispatchUrl
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user