mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 14:22:26 +08:00
添加客户端机器人
This commit is contained in:
5
robot/cmd/application.toml
Normal file
5
robot/cmd/application.toml
Normal file
@@ -0,0 +1,5 @@
|
||||
[logger]
|
||||
level = "DEBUG"
|
||||
mode = "CONSOLE"
|
||||
track = true
|
||||
max_size = 10485760
|
||||
67
robot/cmd/main.go
Normal file
67
robot/cmd/main.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"hk4e/common/config"
|
||||
hk4egatenet "hk4e/gate/net"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/protocol/cmd"
|
||||
"hk4e/protocol/proto"
|
||||
"hk4e/robot/net"
|
||||
|
||||
"github.com/FlourishingWorld/dpdk-go/engine"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config.InitConfig("application.toml")
|
||||
logger.InitLogger("robot")
|
||||
|
||||
err := engine.InitEngine("00:0C:29:3E:3E:DF", "192.168.199.199", "255.255.255.0", "192.168.199.1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
engine.RunEngine([]int{0, 1, 2, 3}, 1, "0.0.0.0")
|
||||
|
||||
time.Sleep(time.Second * 30)
|
||||
|
||||
session := net.NewSession("192.168.199.233:22222", []byte{0x00})
|
||||
go func() {
|
||||
protoMsg := <-session.RecvChan
|
||||
logger.Debug("%v", protoMsg)
|
||||
}()
|
||||
go func() {
|
||||
session.SendChan <- &hk4egatenet.ProtoMsg{
|
||||
ConvId: 0,
|
||||
CmdId: cmd.GetPlayerTokenReq,
|
||||
HeadMessage: &proto.PacketHead{
|
||||
ClientSequenceId: 1,
|
||||
SentMs: uint64(time.Now().UnixMilli()),
|
||||
},
|
||||
PayloadMessage: &proto.GetPlayerTokenReq{
|
||||
AccountToken: "xxxxxx",
|
||||
AccountUid: "10001",
|
||||
KeyId: 0,
|
||||
ClientRandKey: "",
|
||||
},
|
||||
}
|
||||
}()
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||
for {
|
||||
s := <-c
|
||||
switch s {
|
||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||
engine.StopEngine()
|
||||
time.Sleep(time.Second)
|
||||
return
|
||||
case syscall.SIGHUP:
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
109
robot/net/session.go
Normal file
109
robot/net/session.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
hk4egatenet "hk4e/gate/net"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/pkg/random"
|
||||
"hk4e/protocol/cmd"
|
||||
|
||||
"github.com/FlourishingWorld/dpdk-go/protocol/kcp"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
SendChan chan *hk4egatenet.ProtoMsg
|
||||
RecvChan chan *hk4egatenet.ProtoMsg
|
||||
conn *kcp.UDPSession
|
||||
seed uint64 // TODO 密钥交换后收到的服务器生成的seed
|
||||
xorKey []byte
|
||||
changeXorKeyFin bool
|
||||
useMagicSeed bool
|
||||
}
|
||||
|
||||
func NewSession(gateAddr string, dispatchKey []byte) (r *Session) {
|
||||
conn, err := kcp.DialWithOptions(gateAddr, "0.0.0.0:30000")
|
||||
if err != nil {
|
||||
logger.Error("kcp client conn to server error: %v", err)
|
||||
return
|
||||
}
|
||||
conn.SetACKNoDelay(true)
|
||||
conn.SetWriteDelay(false)
|
||||
sendChan := make(chan *hk4egatenet.ProtoMsg, 1000)
|
||||
recvChan := make(chan *hk4egatenet.ProtoMsg, 1000)
|
||||
r = &Session{
|
||||
SendChan: sendChan,
|
||||
RecvChan: recvChan,
|
||||
conn: conn,
|
||||
seed: 0,
|
||||
xorKey: dispatchKey,
|
||||
changeXorKeyFin: false,
|
||||
useMagicSeed: true,
|
||||
}
|
||||
go r.recvHandle()
|
||||
go r.sendHandle()
|
||||
return r
|
||||
}
|
||||
|
||||
func (s *Session) recvHandle() {
|
||||
logger.Info("recv handle start")
|
||||
conn := s.conn
|
||||
convId := conn.GetConv()
|
||||
recvBuf := make([]byte, hk4egatenet.PacketMaxLen)
|
||||
dataBuf := make([]byte, 0, 1500)
|
||||
for {
|
||||
_ = conn.SetReadDeadline(time.Now().Add(time.Second * hk4egatenet.ConnRecvTimeout))
|
||||
recvLen, err := conn.Read(recvBuf)
|
||||
if err != nil {
|
||||
logger.Error("exit recv loop, conn read err: %v, convId: %v", err, convId)
|
||||
_ = conn.Close()
|
||||
break
|
||||
}
|
||||
recvData := recvBuf[:recvLen]
|
||||
kcpMsgList := make([]*hk4egatenet.KcpMsg, 0)
|
||||
hk4egatenet.DecodeBinToPayload(recvData, &dataBuf, convId, &kcpMsgList, s.xorKey)
|
||||
for _, v := range kcpMsgList {
|
||||
protoMsgList := hk4egatenet.ProtoDecode(v, nil, nil)
|
||||
for _, vv := range protoMsgList {
|
||||
s.RecvChan <- vv
|
||||
if s.changeXorKeyFin == false && vv.CmdId == cmd.GetPlayerTokenRsp {
|
||||
// XOR密钥切换
|
||||
logger.Info("change session xor key, convId: %v", convId)
|
||||
s.changeXorKeyFin = true
|
||||
keyBlock := random.NewKeyBlock(s.seed, s.useMagicSeed)
|
||||
xorKey := keyBlock.XorKey()
|
||||
key := make([]byte, 4096)
|
||||
copy(key, xorKey[:])
|
||||
s.xorKey = key
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) sendHandle() {
|
||||
logger.Info("send handle start")
|
||||
conn := s.conn
|
||||
convId := conn.GetConv()
|
||||
for {
|
||||
protoMsg, ok := <-s.SendChan
|
||||
if !ok {
|
||||
logger.Error("exit send loop, send chan close, convId: %v", convId)
|
||||
_ = conn.Close()
|
||||
break
|
||||
}
|
||||
kcpMsg := hk4egatenet.ProtoEncode(protoMsg, nil, nil)
|
||||
if kcpMsg == nil {
|
||||
logger.Error("decode kcp msg is nil, convId: %v", convId)
|
||||
continue
|
||||
}
|
||||
bin := hk4egatenet.EncodePayloadToBin(kcpMsg, s.xorKey)
|
||||
_ = conn.SetWriteDeadline(time.Now().Add(time.Second * hk4egatenet.ConnSendTimeout))
|
||||
_, err := conn.Write(bin)
|
||||
if err != nil {
|
||||
logger.Error("exit send loop, conn write err: %v, convId: %v", err, convId)
|
||||
_ = conn.Close()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user