340 lines
9.5 KiB
Go
340 lines
9.5 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
|
|
|
|
}
|
|
}
|
|
{
|
|
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
|
|
}
|
|
}
|
|
params := map[string]string{
|
|
"c": "User",
|
|
"a": "info",
|
|
"account_id": msg.GetAccountId(),
|
|
"session_id": msg.GetSessionId(),
|
|
"target_id": msg.GetAccountId(),
|
|
}
|
|
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 := struct {
|
|
Errcode int `json:"errcode"`
|
|
Errmsg string `json:"errmsg"`
|
|
Info struct {
|
|
Activated string `json:"activated"`
|
|
RenameCount string `json:"rename_count"`
|
|
AccountID string `json:"account_id"`
|
|
Name string `json:"name"`
|
|
HeadId string `json:"head_id"`
|
|
HeroId string `json:"hero_id"`
|
|
HeadFrame string `json:"head_frame"`
|
|
} `json:"info"`
|
|
}{}
|
|
{
|
|
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 {
|
|
hum := new(player)
|
|
hum.init(pendingReq, rspObj.Info.Name, rspObj.Info.HeadId, rspObj.Info.HeroId, rspObj.Info.HeadFrame)
|
|
this.socketHash[pendingReq.hdr.GetSocket()] = hum
|
|
team := GetTeamMgr().CreateTeam(hum)
|
|
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)
|
|
} 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
|
|
}
|
|
if member != nil {
|
|
hum := member.(*player)
|
|
if hum.socket.IsValid() {
|
|
delete(this.socketHash, hum.socket)
|
|
}
|
|
hum.againInit(pendingReq,
|
|
rspObj.Info.Name,
|
|
rspObj.Info.HeadId,
|
|
rspObj.Info.HeroId,
|
|
rspObj.Info.HeadFrame)
|
|
this.socketHash[pendingReq.hdr.GetSocket()] = hum
|
|
} else {
|
|
hum := new(player)
|
|
hum.init(pendingReq,
|
|
rspObj.Info.Name,
|
|
rspObj.Info.HeadId,
|
|
rspObj.Info.HeroId,
|
|
rspObj.Info.HeadFrame)
|
|
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)
|
|
} 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()
|
|
}
|