256 lines
5.5 KiB
Go
256 lines
5.5 KiB
Go
package machinedoll
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"mongo.games.com/goserver/core/timer"
|
||
"os/signal"
|
||
"syscall"
|
||
|
||
"mongo.games.com/game/protocol/machine"
|
||
"mongo.games.com/goserver/core/logger"
|
||
"mongo.games.com/goserver/core/netlib"
|
||
"mongo.games.com/goserver/srvlib"
|
||
"net"
|
||
"os"
|
||
"path/filepath"
|
||
"time"
|
||
)
|
||
|
||
var GameConn *netlib.Session
|
||
var ConnMap = make(map[int]net.Conn)
|
||
|
||
type MachineManager struct {
|
||
DelConnMap map[int]string
|
||
}
|
||
|
||
var MachineMgr = &MachineManager{
|
||
DelConnMap: make(map[int]string),
|
||
}
|
||
|
||
func (this *MachineManager) ModuleName() string {
|
||
return "MachineManager"
|
||
}
|
||
|
||
// 心跳间隔时间(秒)
|
||
const heartbeatInterval = 1
|
||
|
||
func (this *MachineManager) Init() {
|
||
var serverAddrs []string
|
||
programDir, err := os.Getwd()
|
||
if err != nil {
|
||
fmt.Println("Error getting working directory:", err)
|
||
return
|
||
}
|
||
configFile := filepath.Join(programDir, "machineIPConfig.json")
|
||
fmt.Println("构建配置文件的路径", configFile)
|
||
fileData, err := os.ReadFile(configFile)
|
||
if err != nil {
|
||
logger.Logger.Error("Read robot account file error:", err)
|
||
return
|
||
} else {
|
||
if err = json.Unmarshal(fileData, &serverAddrs); err != nil {
|
||
logger.Logger.Error("Unmarshal robot account data error:", err)
|
||
return
|
||
}
|
||
}
|
||
//与娃娃机创建连接
|
||
// 遍历每个服务器地址,建立连接
|
||
for i, addr := range serverAddrs {
|
||
conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
|
||
if err != nil {
|
||
fmt.Println("Failed to connect to server:", err)
|
||
continue
|
||
}
|
||
ConnMap[i+1] = conn
|
||
go this.StartHeartbeat(i+1, &conn, addr)
|
||
}
|
||
fmt.Println("Connected to server:\n", ConnMap[1].RemoteAddr())
|
||
fmt.Println("投币请按Q!!!!")
|
||
fmt.Println("w向前s向后a向左d向右 j强力抓取k弱力抓取!")
|
||
// 监听 WASD 按键事件
|
||
/* go listenKeyboardEvents(ConnMap[1])
|
||
|
||
// 监听中断信号,等待用户退出
|
||
waitForUserExit()*/
|
||
}
|
||
func (this *MachineManager) StartHeartbeat(id int, conn *net.Conn, addr string) {
|
||
// 定期发送心跳包
|
||
ticker := time.NewTicker(heartbeatInterval * time.Second)
|
||
defer ticker.Stop()
|
||
|
||
for {
|
||
select {
|
||
case <-ticker.C:
|
||
// 发送心跳包
|
||
_, err := (*conn).Write([]byte("heartbeat"))
|
||
if err != nil {
|
||
fmt.Println("Failed to send heartbeat:", err)
|
||
delete(ConnMap, id)
|
||
this.DelConnMap[id] = addr
|
||
//通知游戏服
|
||
this.UpdateToGameServer()
|
||
fmt.Println("删除链接!!!!!!addr = ", addr)
|
||
go timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool {
|
||
this.ReConnect()
|
||
return true
|
||
}), nil, time.Duration(5)*time.Second, 100)
|
||
return
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 重连
|
||
func (this *MachineManager) ReConnect() bool {
|
||
fmt.Println("================重连============")
|
||
delIds := []int{}
|
||
status := false
|
||
for id, addr := range this.DelConnMap {
|
||
conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
ConnMap[id] = conn
|
||
delIds = append(delIds, id)
|
||
status = true
|
||
}
|
||
for _, id := range delIds {
|
||
delete(this.DelConnMap, id)
|
||
fmt.Println("重新链接成功!!!!!!id = ", id)
|
||
}
|
||
if status {
|
||
this.UpdateToGameServer()
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (this *MachineManager) UpdateToGameServer() {
|
||
msg := &machine.MSDollMachineList{}
|
||
for i, _ := range ConnMap {
|
||
info := &machine.DollMachine{}
|
||
info.Id = int32(i)
|
||
info.VideoAddr = "www.baidu.com"
|
||
msg.Data = append(msg.Data, info)
|
||
}
|
||
SendToGameServer(int(machine.DollMachinePacketID_PACKET_MSDollMachineList), msg)
|
||
}
|
||
|
||
func SendToGameServer(pid int, msg interface{}) {
|
||
if GameConn == nil {
|
||
GameConn = srvlib.ServerSessionMgrSington.GetSession(1, 7, 701)
|
||
}
|
||
if GameConn != nil {
|
||
GameConn.Send(pid, msg)
|
||
} else {
|
||
logger.Logger.Error("GameConn is nil !")
|
||
}
|
||
}
|
||
|
||
func init() {
|
||
MachineMgr.Init()
|
||
}
|
||
|
||
func listenKeyboardEvents(conn net.Conn) {
|
||
for {
|
||
// 读取键盘事件
|
||
key := readKeyboardEvent()
|
||
switch key {
|
||
case "w":
|
||
Backward(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
BackwardStop(conn)
|
||
case "W":
|
||
Backward(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
BackwardStop(conn)
|
||
case "a":
|
||
Left(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
LeftStop(conn)
|
||
case "A":
|
||
Left(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
LeftStop(conn)
|
||
case "s":
|
||
Forward(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
ForwardStop(conn)
|
||
case "S":
|
||
Forward(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
ForwardStop(conn)
|
||
case "d":
|
||
Right(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
RightStop(conn)
|
||
case "D":
|
||
Right(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
RightStop(conn)
|
||
case "j":
|
||
Grab(conn)
|
||
case "J":
|
||
SetPower(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
Grab(conn)
|
||
|
||
case "k":
|
||
WeakGrab(conn)
|
||
case "K":
|
||
WeakGrab(conn)
|
||
|
||
case "q":
|
||
Coin(conn)
|
||
Backward(conn)
|
||
time.Sleep(200 * time.Millisecond)
|
||
BackwardStop(conn)
|
||
case "Q":
|
||
Coin(conn)
|
||
Backward(conn)
|
||
time.Sleep(150 * time.Millisecond)
|
||
BackwardStop(conn)
|
||
case "1":
|
||
RestoreFactorySettings(conn)
|
||
case "2":
|
||
OpenMusic(conn)
|
||
case "3":
|
||
Reboot(conn)
|
||
case "4":
|
||
StopServer(conn)
|
||
case "5":
|
||
StartServer(conn)
|
||
case "6":
|
||
ClearRemainingGames(conn)
|
||
case "7":
|
||
SetPower(conn)
|
||
case "8":
|
||
CloseMusic(conn)
|
||
}
|
||
}
|
||
}
|
||
|
||
func readKeyboardEvent() string {
|
||
var b [1]byte
|
||
var done uint32
|
||
err := syscall.ReadFile(syscall.Stdin, b[:], &done, nil)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
return string(b[:])
|
||
}
|
||
|
||
func waitForUserExit() {
|
||
// 创建一个信号通道
|
||
signalChan := make(chan os.Signal, 1)
|
||
|
||
// 监听中断信号
|
||
signal.Notify(signalChan, os.Interrupt)
|
||
|
||
// 等待用户按下 Ctrl+C 退出
|
||
<-signalChan
|
||
fmt.Println("退出程序...")
|
||
}
|