game_sync/machine/machinedoll/machinemgr.go

256 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("退出程序...")
}