game_sync/machine/action/action_server.go

345 lines
9.8 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 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)
}()
}
}
}
// 移动
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.Backward(conn) },
}
f2 := []func(){
func() { machinedoll.BackwardStop(conn) },
}
Process(conn, f1, f2)
case 2:
//向后移动
f1 := []func(){
func() { machinedoll.Forward(conn) },
}
f2 := []func(){
func() { machinedoll.ForwardStop(conn) },
}
Process(conn, f1, f2)
case 3:
//向左移动
f1 := []func(){
func() { machinedoll.Left(conn) },
}
f2 := []func(){
func() { machinedoll.LeftStop(conn) },
}
Process(conn, f1, f2)
case 4:
//向右移动
f1 := []func(){
func() { machinedoll.Right(conn) },
}
f2 := []func(){
func() { machinedoll.RightStop(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 {
logger.Logger.Tracef("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) {
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)
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 修改为你的 appIdappid 为数字,从即构控制台获取
// 举例1234567890
var appId uint32 = uint32(msg.GetAppId())
// 请修改为你的 serverSecretserverSecret 为字符串,从即构控制台获取
// 举例: "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)
}