package action import ( "bytes" "fmt" "math" "mongo.games.com/game/machine/machinedoll" "mongo.games.com/game/protocol/machine" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/timer" "sync" "time" ) type ConnMessageQueue struct { queue chan []interface{} conn *machinedoll.Conn waitGroup *sync.WaitGroup } var connMessageQueues = make(map[*machinedoll.Conn]*ConnMessageQueue) func Process(conn *machinedoll.Conn, f1 []func(), f2 []func()) { // 获取或创建该 conn 对应的消息队列 queue, ok := connMessageQueues[conn] if !ok { queue = &ConnMessageQueue{ queue: make(chan []interface{}, 100), conn: conn, waitGroup: new(sync.WaitGroup), } connMessageQueues[conn] = queue go processConnMessageQueue(queue) } // 将消息添加到队列中 queue.queue <- []interface{}{f1, f2} } func processConnMessageQueue(queue *ConnMessageQueue) { for msg := range queue.queue { f1 := msg[0].([]func()) f2 := msg[1].([]func()) queue.waitGroup.Add(len(f1)) for _, f := range f1 { go func(f func()) { defer queue.waitGroup.Done() f() }(f) } queue.waitGroup.Wait() if len(f2) > 0 { queue.waitGroup.Add(1) go func() { defer queue.waitGroup.Done() timer.AfterTimer(func(h timer.TimerHandle, ud interface{}) bool { for _, f := range f2 { f() } return true }, nil, 200*time.Millisecond) }() } } } // 移动 1-前 2-后 3-左 4-右 5-投币 func SMDollMachinePerateHandler(session *netlib.Session, packetId int, data interface{}) error { fmt.Println("SMDollMachinePerateHandler %v", data) msg, ok := data.(*machine.SMDollMachineoPerate) if !ok { return nil } conn, ok := machinedoll.MachineMgr.ConnMap[int(msg.GetId())] if !ok || conn == nil { fmt.Println("移动,创建链接!!!!!!!!!!!!!") conn = machinedoll.MachineMgr.CreateConn(int(msg.GetId())) if conn == nil { return nil } } switch msg.Perate { case 1: //向后移动 f1 := []func(){ func() { machinedoll.Forward(conn) }, } f2 := []func(){ func() { machinedoll.ForwardStop(conn) }, } Process(conn, f1, f2) case 2: //向前移动 f1 := []func(){ func() { machinedoll.Backward(conn) }, } f2 := []func(){ func() { machinedoll.BackwardStop(conn) }, } Process(conn, f1, f2) case 3: //向右移动 f1 := []func(){ func() { machinedoll.Right(conn) }, } f2 := []func(){ func() { machinedoll.RightStop(conn) }, } Process(conn, f1, f2) case 4: //向左移动 f1 := []func(){ func() { machinedoll.Left(conn) }, } f2 := []func(){ func() { machinedoll.LeftStop(conn) }, } Process(conn, f1, f2) case 5: //投币 conn := machinedoll.MachineMgr.CreateConn(int(msg.GetId())) fmt.Println("===========玩家投币===========", conn) go DollMachineGrabResult(conn, msg.Snid, msg.GetId()) machinedoll.Coin(conn) } return nil } // 下抓 func SMDollMachineGrabHandler(session *netlib.Session, packetId int, data interface{}) error { fmt.Println("下抓SMDollMachineGrabHandler %v", data) msg, ok := data.(*machine.SMDollMachineGrab) if !ok { return nil } conn, ok := machinedoll.MachineMgr.ConnMap[int(msg.GetId())] if !ok || conn == nil { fmt.Println("下抓,创建链接!!!!!!!!!!!!!") conn = machinedoll.MachineMgr.CreateConn(int(msg.GetId())) if conn == nil { return nil } } switch msg.GetTypeId() { case 1: //弱抓 /* f1 := []func(){ func() { machinedoll.WeakGrab(conn) }, } f2 := []func(){} Process(conn, f1, f2)*/ machinedoll.WeakGrab(conn) case 2: //强力抓 /* f1 := []func(){ func() { machinedoll.Grab(conn) }, } f2 := []func(){} Process(conn, f1, f2)*/ machinedoll.Grab(conn) } return nil } // 监听抓取结果返回 func DollMachineGrabResult(conn *machinedoll.Conn, snid, id int32) { if conn == nil { return } num := int64(1) for { // 读取数据 //logger.Logger.Trace("监听抓取结果返回!") buf := make([]byte, 1024) n, err := conn.Read(buf) if err != nil { logger.Logger.Error("Failed to read response from client:", err) err := conn.Conn.Close() if err != nil { logger.Logger.Error("conn.Conn.Close():", err) return } return } // 将读取到的数据按照 221 进行分割 parts := bytes.Split(buf[:n], []byte{221}) //fmt.Println("获取到的返回值:", parts) instruction := []byte{0xAA, 0x05, 0x02, 0x50, 0x09, 0x00} instruction1 := []byte{0xAA, 0x05, 0x02, 0x50, 0x09, 0x01} // 遍历分割结果,打印出每个部分 for i, part := range parts { if len(part) > 0 { part = part[:len(part)-1] // 去除最后一个字节,该字节为分隔符 //fmt.Println("比较返回结果 part = ", part) if bytes.Contains(part, instruction) && num != 1 { //fmt.Printf("Part %d: %s\n", i+1, part) //回应数据 _, err = conn.Write([]byte{0xAA, 0x04, 0x01, 0x50, 0x09, 0x5c, 0xdd}) if err != nil { //fmt.Println("Failed to read response from server:", err) return } fmt.Println("没有抓到礼品!!!!!!!!snid = ", snid, "num = ", num) machinedoll.SendToGameServer(int(machine.DollMachinePacketID_PACKET_MSDollMachineoPerateResult), &machine.MSDollMachineoPerateResult{ Snid: snid, Id: id, Result: 0, TypeId: 2, }) //删除娃娃机链接 //delete(machinedoll.MachineMgr.ConnMap, conn.Id) err := conn.Conn.Close() if err != nil { return } fmt.Println("关闭与娃娃机链接") return } if bytes.Contains(part, instruction1) && num != 1 { fmt.Printf("Part %d: %s\n", i+1, part) //回应数据 _, err = conn.Write([]byte{0xAA, 0x04, 0x01, 0x50, 0x09, 0x5c, 0xdd}) if err != nil { fmt.Println("Failed to read response from server:", err) return } fmt.Println("抓到礼品了!!!!!!!!snid = ", snid, "num = ", num) machinedoll.SendToGameServer(int(machine.DollMachinePacketID_PACKET_MSDollMachineoPerateResult), &machine.MSDollMachineoPerateResult{ Snid: snid, Id: id, Result: 1, TypeId: 2, }) //删除娃娃机链接 //delete(machinedoll.MachineMgr.ConnMap, conn.Id) err := conn.Conn.Close() if err != nil { return } fmt.Println("关闭与娃娃机链接") return } //上分成功 coinData := []byte{0xAA, 0x04, 0x02, 0x03, 0x01} if bytes.Contains(part, coinData) { //返回消息 machinedoll.SendToGameServer(int(machine.DollMachinePacketID_PACKET_MSDollMachineoPerateResult), &machine.MSDollMachineoPerateResult{ Snid: snid, Id: id, Result: 1, TypeId: 1, }) fmt.Println("上分成功!!!!!!!!!!snid = ", snid, "num = ", num) } //上分失败 coinData = []byte{0xAA, 0x04, 0x02, 0x03, 0x00} if bytes.Contains(part, coinData) { //返回消息 machinedoll.SendToGameServer(int(machine.DollMachinePacketID_PACKET_MSDollMachineoPerateResult), &machine.MSDollMachineoPerateResult{ Snid: snid, Id: id, Result: 0, TypeId: 1, }) fmt.Println("上分失败!!!!!!!!!!snid = ", snid, "num = ", num) } } } num++ if num >= math.MaxInt64 { num = 2 } } } // 与游戏服务器连接成功,向游戏服务器推送所有娃娃机连接 func SMGameLinkSucceedHandler(session *netlib.Session, packetId int, data interface{}) error { fmt.Println("与游戏服务器连接成功") //开始向游戏服务器发送娃娃机连接信息 msg := &machine.MSDollMachineList{} for i, _ := range machinedoll.MachineMgr.ConnMap { info := &machine.DollMachine{} info.Id = int32(i) msg.Data = append(msg.Data, info) } session.Send(int(machine.DollMachinePacketID_PACKET_MSDollMachineList), msg) fmt.Println("向游戏服务器发送娃娃机连接信息:%v", msg) return nil } /* // 获取进入视频房间token func SMGetTokenHandler(session *netlib.Session, packetId int, data interface{}) error { logger.Logger.Tracef("SMGetTokenHandler %v", data) msg, ok := data.(*machine.SMGetToken) if !ok { return nil } // 请将 appId 修改为你的 appId,appid 为数字,从即构控制台获取 // 举例:1234567890 var appId uint32 = uint32(msg.GetAppId()) // 请修改为你的 serverSecret,serverSecret 为字符串,从即构控制台获取 // 举例: "fa94dd0f974cf2e293728a526b028271" serverSecret := msg.ServerSecret // 请将 userId 修改为用户的 user_id userId := msg.GetSnid() // token 的有效时长,单位:秒 var effectiveTimeInSeconds int64 = 3600 // token业务认证扩展,基础鉴权token此处填空字符串 var payload string = "" //生成token token, err := token04.GenerateToken04(appId, strconv.Itoa(int(userId)), serverSecret, effectiveTimeInSeconds, payload) if err != nil { logger.Logger.Error(err) return err } logger.Logger.Trace(token) info := &machine.MSSendToken{} info.Snid = msg.Snid info.Token = token info.Appid = msg.AppId info.StreamId = msg.StreamId session.Send(int(machine.DollMachinePacketID_PACKET_MSSendToken), info) fmt.Println("向游戏服务器发送娃娃机token:%v", info) return nil } */ func SMDollMachineHeartBeatHandler(session *netlib.Session, packetId int, data interface{}) error { //fmt.Println("收到返回的心跳包") return nil } func init() { netlib.Register(int(machine.DollMachinePacketID_PACKET_SMDollMachinePerate), &machine.SMDollMachineoPerate{}, SMDollMachinePerateHandler) netlib.Register(int(machine.DollMachinePacketID_PACKET_SMDollMachineGrab), &machine.SMDollMachineGrab{}, SMDollMachineGrabHandler) //链接成功 返回消息 netlib.Register(int(machine.DollMachinePacketID_PACKET_SMGameLinkSucceed), &machine.SMGameLinkSucceed{}, SMGameLinkSucceedHandler) netlib.Register(int(machine.DollMachinePacketID_Packet_SMDollMachineHeartBeat), &machine.SMDollMachineHeartBeat{}, SMDollMachineHeartBeatHandler) }