aozhiwei 1f58f81f28 1
2024-03-19 19:24:37 +08:00

343 lines
9.8 KiB
Go

package player
import (
"cs"
"encoding/json"
"f5"
"fmt"
"github.com/golang/protobuf/proto"
"main/common"
"main/constant"
. "main/global"
"mt"
"net"
"q5"
"ss"
)
type pendingLoginRequest struct {
hdr *f5.MsgHdr
msg *cs.CMLogin
addTick int64
reqId int64
}
type playerMgr struct {
cs.MsgHandlerImpl
socketHash map[f5.WspCliConn]*player
pendingLoginHash map[string]*pendingLoginRequest
currReqId int64
}
func (this *playerMgr) Init() {
this.socketHash = make(map[f5.WspCliConn]*player)
this.pendingLoginHash = make(map[string]*pendingLoginRequest)
f5.GetTimer().SetInterval(
1000,
func(e int32, args *q5.Args) {
if e == q5.TIMER_EXEC_EVENT {
mt.Table.MasterCluster.Traverse(
func(meta *mt.MasterCluster) bool {
this.reportServerState(meta.GetIp(), meta.GetListenPort())
return true
})
}
})
f5.GetApp().RegisterIMMsgHandle(
constant.IM_WSP_CLOSE,
func(args q5.Args) {
conn := args[0].(net.Conn)
deletedPlayers := make(map[f5.WspCliConn]*player)
for socket, hum := range this.socketHash {
if conn == socket.Conn {
deletedPlayers[socket] = hum
}
}
for socket, _ := range deletedPlayers {
this.onSocketClose(socket)
}
})
}
func (this *playerMgr) UnInit() {
}
func (this *playerMgr) CMLogin(hdr *f5.MsgHdr, msg *cs.CMLogin) {
{
if msg.GetCreateTeamParam() == nil &&
msg.GetJoinTeamParam() == nil {
rspMsg := cs.SMLogin{}
rspMsg.Errcode = proto.Int32(1)
rspMsg.Errmsg = proto.String("params error")
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, &rspMsg)
return
}
if msg.GetZoneId() < 1 || msg.GetZoneId() > 100 ||
msg.GetNodeId() < 1 || msg.GetNodeId() > 10 {
rspMsg := cs.SMLogin{}
rspMsg.Errcode = proto.Int32(3)
rspMsg.Errmsg = proto.String("zone_id or node_id error")
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, &rspMsg)
return
}
}
{
oldHum := this.internalGetPlayerBySocket(hdr.GetSocket())
if oldHum != nil {
rspMsg := cs.SMLogin{}
rspMsg.Errcode = proto.Int32(0)
rspMsg.Errmsg = proto.String("")
rspMsg.ServerInfo = proto.String(mt.Table.MatchCluster.GetServerInfo())
rspMsg.TeamUuid = proto.String(oldHum.GetTeam().GetTeamUuid())
oldHum.reBind(hdr.GetSocket())
oldHum.SendMsg(&rspMsg)
return
}
}
reqId := this.genSeqId()
pendingReq := this.getPendingRequest(msg.GetAccountId())
if pendingReq == nil {
this.pendingLoginHash[msg.GetAccountId()] = &pendingLoginRequest{
hdr: hdr,
msg: msg,
addTick: q5.GetTickCount(),
reqId: reqId,
}
} else {
if pendingReq.msg.GetAccountId() == msg.GetAccountId() &&
pendingReq.msg.GetSessionId() == msg.GetSessionId() {
pendingReq.hdr = hdr
pendingReq.msg = msg
return
} else {
pendingReq.hdr = hdr
pendingReq.msg = msg
pendingReq.reqId = reqId
}
}
mapId := msg.GetCreateTeamParam().GetMapId()
params := map[string]string{
"c": "User",
"a": "getBattleInfo",
"account_id": msg.GetAccountId(),
"session_id": msg.GetSessionId(),
"map_id": q5.ToString(mapId),
}
url := fmt.Sprintf("%s/webapp/index.php", mt.Table.Config.GetById(0).GetGameapiUrl())
f5.GetHttpCliMgr().SendJsStyleRequest(
url,
params,
func(rsp f5.HttpCliResponse) {
this.apiAuthCb(hdr, msg, rsp, reqId)
})
}
func (this *playerMgr) apiAuthCb(hdr *f5.MsgHdr, msg *cs.CMLogin, rsp f5.HttpCliResponse, reqId int64) {
pendingReq := this.getPendingRequest(msg.GetAccountId())
if pendingReq == nil || pendingReq.reqId != reqId {
return
}
defer delete(this.pendingLoginHash, msg.GetAccountId())
rspMsg := cs.SMLogin{}
if rsp.GetErr() != nil {
rspMsg.Errcode = proto.Int32(2)
rspMsg.Errmsg = proto.String("server internal error")
GetWspListener().SendProxyMsg(pendingReq.hdr.Conn, pendingReq.hdr.SocketHandle, &rspMsg)
return
}
rspObj := common.LoginRsp{}
{
f5.GetSysLog().Info("getBattleinfo:%s", rsp.GetRawData())
err := json.Unmarshal([]byte(rsp.GetRawData()), &rspObj)
if err != nil {
rspMsg.Errcode = proto.Int32(1)
rspMsg.Errmsg = proto.String("invalid session_id")
GetWspListener().SendProxyMsg(pendingReq.hdr.Conn, pendingReq.hdr.SocketHandle, &rspMsg)
f5.GetSysLog().Warning("game2006api parse error:%s", err)
return
}
}
if rspObj.Errcode != 0 {
rspMsg.Errcode = proto.Int32(1)
rspMsg.Errmsg = proto.String("invalid session_id")
GetWspListener().SendProxyMsg(pendingReq.hdr.Conn, pendingReq.hdr.SocketHandle, &rspMsg)
f5.GetSysLog().Warning("game2006api login auth errcode:%d", rspObj.Errcode)
return
}
if msg.GetCreateTeamParam() != nil {
if rspObj.Info.MapInfo.MapId == 0 {
rspMsg.Errcode = proto.Int32(2)
rspMsg.Errmsg = proto.String("invalid map_id")
GetWspListener().SendProxyMsg(pendingReq.hdr.Conn, pendingReq.hdr.SocketHandle, &rspMsg)
f5.GetSysLog().Warning("game2006api login auth map_id:%d", rspObj.Info.MapInfo.MapId)
return
}
hum := newPlayer()
hum.init(pendingReq, &rspObj)
this.socketHash[pendingReq.hdr.GetSocket()] = hum
team := GetTeamMgr().CreateTeam(hum, msg, &rspObj.Info.MapInfo)
if team == nil {
rspMsg.Errcode = proto.Int32(102)
rspMsg.Errmsg = proto.String("create team error")
GetWspListener().SendProxyMsg(pendingReq.hdr.Conn, pendingReq.hdr.SocketHandle, &rspMsg)
return
}
rspMsg.TeamUuid = proto.String(team.GetTeamUuid())
rspMsg.ServerInfo = proto.String(mt.Table.MatchCluster.GetServerInfo())
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, &rspMsg)
team.SendUpdateNotify()
GetTeamMgr().OnEnterNewUser(hum)
} else if msg.GetJoinTeamParam() != nil {
team := GetTeamMgr().GetTeamByUuid(msg.GetJoinTeamParam().GetTeamUuid())
if team == nil {
rspMsg.Errcode = proto.Int32(101)
rspMsg.Errmsg = proto.String("join team error team not found")
GetWspListener().SendProxyMsg(pendingReq.hdr.Conn, pendingReq.hdr.SocketHandle, &rspMsg)
return
}
member := team.GetMemberByAccountId(msg.GetAccountId())
if !team.CanJoin(msg.GetAccountId()) {
rspMsg.Errcode = proto.Int32(103)
rspMsg.Errmsg = proto.String("join team error")
GetWspListener().SendProxyMsg(pendingReq.hdr.Conn, pendingReq.hdr.SocketHandle, &rspMsg)
return
}
var hum *player
if member != nil {
hum = member.(*player)
if hum.socket.IsValid() {
delete(this.socketHash, hum.socket)
}
hum.againInit(pendingReq, &rspObj)
this.socketHash[pendingReq.hdr.GetSocket()] = hum
} else {
hum = newPlayer()
hum.init(pendingReq, &rspObj)
this.socketHash[pendingReq.hdr.GetSocket()] = hum
team.Join(hum)
}
rspMsg.TeamUuid = proto.String(team.GetTeamUuid())
rspMsg.ServerInfo = proto.String(mt.Table.MatchCluster.GetServerInfo())
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, &rspMsg)
team.SendUpdateNotify()
GetTeamMgr().OnEnterNewUser(hum)
} else {
panic("CMLogin Param error")
}
}
func (this *playerMgr) reportServerState(masterIp string, masterPort int32) {
params := map[string]string{
"node_id": q5.ToString(f5.GetApp().GetNodeId()),
"instance_id": q5.ToString(f5.GetApp().GetInstanceId()),
"ip": mt.Table.MatchCluster.GetIp(),
"port": q5.ToString(mt.Table.MatchCluster.GetListenPort()),
"online_num": q5.ToString(0),
"room_num": q5.ToString(0),
"channel": q5.ToString(0),
"alive_count": q5.ToString(0),
"servicing": q5.ToString(1),
}
f5.GetHttpCliMgr().SendQuickChannelJsStyleRequest(
fmt.Sprintf("http://%s:%d/webapp/index.php?c=GS&a=report&", masterIp, masterPort),
params,
func(rsp f5.HttpCliResponse) {
//f5.GetSysLog().Info(rsp.GetRawData())
})
}
func (this *playerMgr) GetPlayerBySocket(socket f5.WspCliConn) common.Player {
hum := this.internalGetPlayerBySocket(socket)
if hum != nil {
return hum
} else {
return nil
}
}
func (this *playerMgr) internalGetPlayerBySocket(socket f5.WspCliConn) *player {
player, ok := this.socketHash[socket]
if ok {
return player
}
return nil
}
func (this *playerMgr) ProcessCMMsg(handler *cs.CsNetMsgHandler, hdr *f5.MsgHdr) {
switch handler.HandlerId {
case constant.PLAYER_MGR_HANDLER_ID:
cs.DispatchMsg(handler, hdr, this)
case constant.PLAYER_HANDLER_ID:
hum := this.internalGetPlayerBySocket(hdr.GetSocket())
if hum != nil {
cs.DispatchMsg(handler, hdr, hum)
}
}
}
func (this *playerMgr) getPendingRequest(accountId string) *pendingLoginRequest {
req, ok := this.pendingLoginHash[accountId]
if ok {
return req
}
return nil
}
func (this *playerMgr) genSeqId() int64 {
this.currReqId++
reqId := this.currReqId
return reqId
}
func (this *playerMgr) SS_WSP_SocketDisconnect(hdr *f5.MsgHdr, msg *ss.SS_WSP_SocketDisconnect) {
this.onSocketClose(hdr.GetSocket())
}
func (this *playerMgr) CMReconnect(hdr *f5.MsgHdr, msg *cs.CMReconnect) {
hum := this.internalGetPlayerBySocket(hdr.GetSocket())
rspMsg := &cs.SMReconnect{}
if hum != nil {
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, rspMsg)
return
}
team := GetTeamMgr().GetTeamByUuid(msg.GetTeamUuid())
if team == nil {
rspMsg.Errcode = proto.Int32(1)
rspMsg.Errmsg = proto.String("team already disband")
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, rspMsg)
return
}
member := team.GetMemberByAccountId(msg.GetAccountId())
if member == nil {
rspMsg.Errcode = proto.Int32(1)
rspMsg.Errmsg = proto.String("team already disband")
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, rspMsg)
return
}
hum = member.(*player)
if hum.GetSessionId() != msg.GetSessionId() {
rspMsg.Errcode = proto.Int32(2)
rspMsg.Errmsg = proto.String("invalid session_id")
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, rspMsg)
return
}
hum.reBind(hdr.GetSocket())
GetWspListener().SendProxyMsg(hdr.Conn, hdr.SocketHandle, rspMsg)
}
func (this *playerMgr) onSocketClose(conn f5.WspCliConn) {
hum := this.internalGetPlayerBySocket(conn)
if hum == nil {
return
}
delete(this.socketHash, conn)
hum.onOffline()
}