package machinedoll import ( "encoding/json" "fmt" "net" "os" "os/signal" "path/filepath" "syscall" "time" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/module" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/srvlib" "mongo.games.com/game/protocol/machine" ) var GameConn *netlib.Session var MachineMgr = &MachineManager{ ConnMap: map[int]*Conn{}, DelConnMap: make(map[int]string), } type Conn struct { Id int net.Conn Addr string } type MachineManager struct { ConnMap map[int]*Conn DelConnMap map[int]string } func (this *MachineManager) ModuleName() string { return "MachineManager" } func (this *MachineManager) Init() { var serverAddrs []string programDir, err := os.Getwd() if err != nil { logger.Logger.Error("Error getting working directory:", err) return } configFile := filepath.Join(programDir, "machineIPConfig.json") logger.Logger.Trace("构建配置文件的路径", 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 { logger.Logger.Error("Failed to connect to server:", err) continue } this.ConnMap[i+1] = &Conn{ Id: i + 1, Conn: conn, Addr: addr, } SetBaseParam(conn) logger.Logger.Trace("设置每台娃娃机基础配置!") } /* fmt.Println("Connected to server:\n", this.ConnMap[1].RemoteAddr()) fmt.Println("投币请按Q!!!!") fmt.Println("w向前s向后a向左d向右 j强力抓取k弱力抓取!") // 监听 WASD 按键事件 go listenKeyboardEvents(this.ConnMap[1]) // 监听中断信号,等待用户退出 waitForUserExit()*/ } // 创建娃娃机链接 func (this *MachineManager) CreateConn(key int) *Conn { fmt.Println("新建与娃娃机链接") var serverAddrs []string programDir, err := os.Getwd() if err != nil { logger.Logger.Error("Error getting working directory:", err) return nil } configFile := filepath.Join(programDir, "machineIPConfig.json") logger.Logger.Trace("构建配置文件的路径", configFile) fileData, err := os.ReadFile(configFile) if err != nil { logger.Logger.Error("Read robot account file error:", err) return nil } else { if err = json.Unmarshal(fileData, &serverAddrs); err != nil { logger.Logger.Error("Unmarshal robot account data error:", err) return nil } } //与娃娃机创建连接 // 遍历每个服务器地址,建立连接 for i, addr := range serverAddrs { if i+1 == key { conn, err := net.DialTimeout("tcp", addr, 5*time.Second) if err != nil { logger.Logger.Error("Failed to connect to server:", err) continue } this.ConnMap[i+1] = &Conn{ Id: i + 1, Conn: conn, Addr: addr, } return this.ConnMap[i+1] } } return nil } func (this *MachineManager) Update() { //向游戏服发送心跳包 pack := &machine.MSDollMachineHeartBeat{} SendToGameServer(int(machine.DollMachinePacketID_Packet_MSDollMachineHeartBeat), pack) /* var delConn []*Conn task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { for _, v := range this.ConnMap { _, err := v.Write([]byte("heartbeat")) if err != nil { delConn = append(delConn, v) v.Close() fmt.Println("断开连接:%v", v.Addr) this.UpdateToGameServer(v, 0) } } return nil }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { for _, v := range delConn { delete(this.ConnMap, v.Id) this.DelConnMap[v.Id] = v.Addr } // 重连 var delIds []*Conn task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { for id, addr := range this.DelConnMap { conn, err := net.DialTimeout("tcp", addr, 5*time.Second) if err != nil { continue } fmt.Println("娃娃机重连成功!addr = %v", addr) delIds = append(delIds, &Conn{ Id: id, Conn: conn, Addr: addr, }) } return nil }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { for _, v := range delIds { this.ConnMap[v.Id] = v delete(this.DelConnMap, v.Id) this.UpdateToGameServer(v, 1) } })).StartByFixExecutor(this.ModuleName()) })).StartByFixExecutor(this.ModuleName())*/ } func (this *MachineManager) Shutdown() { for _, v := range this.ConnMap { v.Close() this.UpdateToGameServer(v, 0) } module.UnregisteModule(this) } func (this *MachineManager) UpdateToGameServer(conn *Conn, status int32) { msg := &machine.MSUpdateDollMachineStatus{} msg.Id = int32(conn.Id) msg.Status = status msg.VideoAddr = conn.Addr SendToGameServer(int(machine.DollMachinePacketID_PACKET_MSUpdateDollMachineStatus), msg) } func SendToGameServer(pid int, msg interface{}) { GameConn = srvlib.ServerSessionMgrSington.GetSession(1, 7, 777) if GameConn != nil { GameConn.Send(pid, msg) } else { logger.Logger.Error("GameConn is nil !") } } func init() { module.RegisteModule(MachineMgr, time.Second, 0) } 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": 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) case "9": queryBaseParam(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("退出程序...") }