package main import ( "strconv" "strings" "time" "unicode/utf8" "mongo.games.com/goserver/core/basic" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/task" "mongo.games.com/game/common" "mongo.games.com/game/model" "mongo.games.com/game/proto" "mongo.games.com/game/protocol/friend" "mongo.games.com/game/srvdata" ) type CSFriendListPacketFactory struct { } type CSFriendListHandler struct { } func (this *CSFriendListPacketFactory) CreatePacket() interface{} { pack := &friend.CSFriendList{} return pack } func (this *CSFriendListHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFriendListHandler Process recv ", data) if msg, ok := data.(*friend.CSFriendList); ok { p := PlayerMgrSington.GetPlayer(sid) if p == nil { logger.Logger.Warn("CSFriendListHandler p == nil") return nil } platform := p.GetPlatform() if platform == nil { return nil } pack := &friend.SCFriendList{ ListType: proto.Int32(msg.GetListType()), OpRetCode: friend.OpResultCode_OPRC_Sucess, } switch msg.GetListType() { case ListType_Friend: dfl := FriendMgrSington.GetFriendList(p.Platform, p.GetSnId()) if dfl != nil { for _, bf := range dfl { if bf.SnId == p.SnId { continue } fi := &friend.FriendInfo{ SnId: proto.Int32(bf.SnId), Name: proto.String(bf.Name), Sex: proto.Int32(bf.Sex), Head: proto.Int32(bf.Head), HeadUrl: proto.String(bf.HeadUrl), CreateTs: proto.Int64(bf.CreateTime), LogoutTs: proto.Int64(bf.LogoutTime), LastChatTs: proto.Int64(bf.CreateTime), IsShield: proto.Bool(FriendMgrSington.IsShield(p.Platform, p.SnId, bf.SnId)), RoleId: bf.RoleId, } fi.Online = false bfp := PlayerMgrSington.GetPlayerBySnId(bf.SnId) if bfp != nil { fi.Online = bfp.IsOnLine() } chat := ChatMgrSington.GetChat(p.Platform, p.SnId, bf.SnId) if chat != nil { fi.LastChatTs = chat.LastChatTs } pack.FriendArr = append(pack.FriendArr, fi) } } proto.SetDefaults(pack) p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendList), pack) logger.Logger.Trace("SCFriendListHandler:", pack) case ListType_Apply: task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { ret, err := model.QueryFriendApplyBySnid(p.Platform, p.SnId) if err != nil { return nil } return ret }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if ret, ok := data.(*model.FriendApply); ok && ret != nil && ret.ApplySnids != nil { for _, as := range ret.ApplySnids { if as.SnId == p.SnId { continue } fi := &friend.FriendInfo{ SnId: proto.Int32(as.SnId), Name: proto.String(as.Name), Head: proto.Int32(as.Head), HeadUrl: proto.String(as.HeadUrl), CreateTs: proto.Int64(as.CreateTs), RoleId: as.RoleId, } fi.Online = false bfp := PlayerMgrSington.GetPlayerBySnId(as.SnId) if bfp != nil { fi.Online = bfp.IsOnLine() } pack.FriendArr = append(pack.FriendArr, fi) } } proto.SetDefaults(pack) p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendList), pack) logger.Logger.Trace("SCFriendListHandler: ", pack) })).Start() case ListType_Recommend: friends := PlayerMgrSington.RecommendFriendRule(p.Platform, p.SnId) for _, f := range friends { if f.Snid == p.SnId { continue } fi := &friend.FriendInfo{ SnId: proto.Int32(f.Snid), Name: proto.String(f.Name), Head: proto.Int32(f.Head), HeadUrl: proto.String(f.HeadUrl), RoleId: f.RoleId, } pack.FriendArr = append(pack.FriendArr, fi) } proto.SetDefaults(pack) p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendList), pack) logger.Logger.Trace("SCFriendListHandler: ", pack) } } return nil } type CSFriendOpPacketFactory struct { } type CSFriendOpHandler struct { } func (this *CSFriendOpPacketFactory) CreatePacket() interface{} { pack := &friend.CSFriendOp{} return pack } func (this *CSFriendOpHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFriendOpHandler Process recv ", data) if msg, ok := data.(*friend.CSFriendOp); ok { p := PlayerMgrSington.GetPlayer(sid) if p == nil { logger.Logger.Warn("CSFriendOpHandler p == nil") return nil } platform := p.GetPlatform() if platform == nil { return nil } destP := PlayerMgrSington.GetPlayerBySnId(msg.SnId) if destP != nil { roleId := common.DefaultRoleId if destP.Roles != nil { roleId = int(destP.Roles.ModId) } FriendMgrSington.FriendOp(msg.OpCode, p, &model.BindFriend{ SnId: destP.SnId, Platform: destP.Platform, Name: destP.Name, Head: destP.Head, HeadUrl: destP.HeadUrl, Sex: destP.Sex, LogoutTime: destP.LastLogoutTime.Unix(), CreateTime: time.Now().Unix(), RoleId: int32(roleId), }) } else { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { return model.GetPlayerBaseInfo(p.Platform, msg.SnId) }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if data == nil { pack := &friend.SCFriendOp{ OpCode: proto.Int32(msg.OpCode), SnId: proto.Int32(msg.SnId), OpRetCode: friend.OpResultCode_OPRC_Error, } p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack) return } if destPlayer, ok := data.(*model.PlayerBaseInfo); ok && destPlayer != nil { roleId := common.DefaultRoleId if destPlayer.Roles != nil { roleId = int(destPlayer.Roles.ModId) } FriendMgrSington.FriendOp(msg.OpCode, p, &model.BindFriend{ SnId: destPlayer.SnId, Platform: destPlayer.Platform, Name: destPlayer.Name, Head: destPlayer.Head, HeadUrl: destPlayer.HeadUrl, Sex: destPlayer.Sex, LogoutTime: destPlayer.LastLogoutTime.Unix(), CreateTime: time.Now().Unix(), RoleId: int32(roleId), }) } })).Start() } } return nil } type CSQueryPlayerGameLogPacketFactory struct { } type CSQueryPlayerGameLogHandler struct { } func (this *CSQueryPlayerGameLogPacketFactory) CreatePacket() interface{} { pack := &friend.CSQueryPlayerGameLog{} return pack } func (this *CSQueryPlayerGameLogHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSQueryPlayerGameLogHandler Process recv ", data) if msg, ok := data.(*friend.CSQueryPlayerGameLog); ok { p := PlayerMgrSington.GetPlayer(sid) if p == nil { logger.Logger.Warn("CSQueryPlayerGameLogHandler p == nil") return nil } snid := msg.GetSnid() gameId := msg.GetGameId() size := msg.GetSize() task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { ret := model.GetFriendRecordLogBySnid(p.Platform, snid, gameId, int(size)) return ret }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { pack := &friend.SCQueryPlayerGameLog{ Snid: snid, GameId: gameId, Size: size, } if ret, ok := data.([]*model.FriendRecord); ok && ret != nil { for _, gpl := range ret { gl := &friend.PlayerGameLog{ GameId: proto.Int32(gpl.GameId), BaseScore: proto.Int32(gpl.BaseScore), IsWin: proto.Int32(gpl.IsWin), Ts: proto.Int64(gpl.Ts), BillCoin: proto.Int64(gpl.BillCoin), MatchType: proto.Int32(int32(gpl.MatchType)), } pack.GameLogs = append(pack.GameLogs, gl) } } proto.SetDefaults(pack) p.SendToClient(int(friend.FriendPacketID_PACKET_SCQueryPlayerGameLog), pack) logger.Logger.Trace("SCQueryPlayerGameLogHandler: ", pack) })).Start() } return nil } type CSInviteFriendPacketFactory struct { } type CSInviteFriendHandler struct { } func (this *CSInviteFriendPacketFactory) CreatePacket() interface{} { pack := &friend.CSInviteFriend{} return pack } func (this *CSInviteFriendHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSInviteFriendHandler Process recv ", data) if msg, ok := data.(*friend.CSInviteFriend); ok { p := PlayerMgrSington.GetPlayer(sid) if p == nil { logger.Logger.Warn("CSInviteFriendHandler p == nil") return nil } platform := p.GetPlatform() if platform == nil { logger.Logger.Warn("CSInviteFriendHandler platform == nil") return nil } friendSnid := msg.GetToSnId() var opRetCode = friend.OpResultCode_OPRC_Sucess send := func(player *Player) { roleId := common.DefaultRoleId if p.Roles != nil { roleId = int(p.Roles.ModId) } pack := &friend.SCInviteFriend{ SrcSnId: proto.Int32(p.SnId), SrcName: proto.String(p.Name), SrcHead: proto.Int32(p.Head), SrcHeadUrl: proto.String(p.HeadUrl), OpRetCode: opRetCode, GameId: proto.Int(p.scene.gameId), RoomId: proto.Int(p.scene.sceneId), Pos: proto.Int32(msg.GetPos()), RoleId: int32(roleId), } proto.SetDefaults(pack) player.SendToClient(int(friend.FriendPacketID_PACKET_SCInviteFriend), pack) logger.Logger.Trace("SCInviteFriendHandler: ", pack) // 记录邀请记录 if opRetCode == friend.OpResultCode_OPRC_Sucess { if p.SnId != player.SnId { p.TaskInviteList[player.SnId] = p.scene.sceneId } } } //不能邀请自己 if p.SnId == friendSnid { logger.Logger.Warn("CSInviteFriendHandler invite self") opRetCode = friend.OpResultCode_OPRC_Friend_NotOpMyself send(p) return nil } //不是好友 if !FriendMgrSington.IsFriend(p.Platform, p.SnId, friendSnid) { logger.Logger.Warn("CSInviteFriendHandler not friend") opRetCode = friend.OpResultCode_OPRC_InviteFriend_NotFriend send(p) return nil } fp := PlayerMgrSington.GetPlayerBySnId(friendSnid) //不在线 if fp == nil || !fp.IsOnLine() { logger.Logger.Warn("CSInviteFriendHandler not online") opRetCode = friend.OpResultCode_OPRC_InviteFriend_NoOnline send(p) return nil } //CD if !FriendMgrSington.CanInvite(p.Platform, p.SnId, friendSnid) { logger.Logger.Warn("CSInviteFriendHandler in cd time") opRetCode = friend.OpResultCode_OPRC_Error send(p) return nil } //scene if p.scene == nil { logger.Logger.Warn("CSInviteFriendHandler scene is nil") opRetCode = friend.OpResultCode_OPRC_InviteFriend_SceneNotExist send(p) return nil } //私有房间 if p.scene.sceneMode != common.SceneMode_Private { logger.Logger.Warn("CSInviteFriendHandler scene is common.SceneMode_Private") opRetCode = friend.OpResultCode_OPRC_InviteFriend_RoomLimit send(p) return nil } //好友已在游戏中 if fp.scene != nil { logger.Logger.Warn("CSInviteFriendHandler scene is common.SceneMode_Private") opRetCode = friend.OpResultCode_OPRC_InviteFriend_Gaming send(p) return nil } pos := int(msg.GetPos()) if pos < 0 || pos >= p.scene.playerNum { logger.Logger.Trace("CSInviteFriendHandler pos is fail") opRetCode = friend.OpResultCode_OPRC_InviteFriend_PosIsError //座位不存在 send(p) return nil } if opRetCode == friend.OpResultCode_OPRC_Sucess { //成功都通知下 send(p) send(fp) } } return nil } type CSInviteFriendOpPacketFactory struct { } type CSInviteFriendOpHandler struct { } func (this *CSInviteFriendOpPacketFactory) CreatePacket() interface{} { pack := &friend.CSInviteFriendOp{} return pack } func (this *CSInviteFriendOpHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSInviteFriendOpHandler Process recv ", data) if msg, ok := data.(*friend.CSInviteFriendOp); ok { p := PlayerMgrSington.GetPlayer(sid) if p == nil { logger.Logger.Warn("CSInviteFriendOpHandler p == nil") return nil } platform := p.GetPlatform() if platform == nil { logger.Logger.Warn("CSInviteFriendOpHandler platform == nil") return nil } srcSnid := msg.GetSnId() opcode := msg.GetOpCode() var opRetCode = friend.OpResultCode_OPRC_Sucess send := func(player *Player) { pack := &friend.SCInviteFriendOp{ SnId: proto.Int32(p.SnId), Name: proto.String(p.Name), OpCode: proto.Int32(opcode), OpRetCode: opRetCode, Pos: proto.Int32(msg.GetPos()), } proto.SetDefaults(pack) isok := player.SendToClient(int(friend.FriendPacketID_PACKET_SCInviteFriendOp), pack) logger.Logger.Trace("SCInviteFriendOpHandler isok: ", isok, " pack: ", pack) } fp := PlayerMgrSington.GetPlayerBySnId(srcSnid) //不能操作自己 if p.SnId == srcSnid { logger.Logger.Warn("CSInviteFriendHandler invite self") opRetCode = friend.OpResultCode_OPRC_Friend_NotOpMyself send(p) return nil } //不在线 if fp == nil || !fp.IsOnLine() { logger.Logger.Warn("CSInviteFriendHandler not online") opRetCode = friend.OpResultCode_OPRC_InviteFriend_NoOnline send(p) return nil } //不是好友 if !FriendMgrSington.IsFriend(p.Platform, p.SnId, srcSnid) { logger.Logger.Warn("CSInviteFriendHandler not friend") opRetCode = friend.OpResultCode_OPRC_InviteFriend_NotFriend send(p) return nil } switch int(opcode) { case Invite_Agree: logger.Logger.Trace("同意邀请") if p.scene != nil { logger.Logger.Warn("CSInviteFriendHandler scene is not nil") opRetCode = friend.OpResultCode_OPRC_InviteFriend_HadInRoom //已在房间中 send(p) return nil } scene := fp.scene if scene == nil { logger.Logger.Warn("CSInviteFriendHandler scene is nil") opRetCode = friend.OpResultCode_OPRC_InviteFriend_SceneNotExist //场景不存在 send(p) return nil } //私有房间 if scene.sceneMode != common.SceneMode_Private { logger.Logger.Warn("CSInviteFriendHandler scene is common.SceneMode_Private") opRetCode = friend.OpResultCode_OPRC_InviteFriend_RoomLimit //只能进入私有房间 send(p) return nil } //进入房间 if scene.limitPlatform != nil { if scene.limitPlatform.Isolated && p.Platform != scene.limitPlatform.IdStr { logger.Logger.Warn("CSInviteFriendHandler scene room not find") opRetCode = friend.OpResultCode_OPRC_InviteFriend_RoomNotExist //房间不存在 send(p) return nil } } if scene.deleting { logger.Logger.Warn("CSInviteFriendHandler scene is deleting") opRetCode = friend.OpResultCode_OPRC_InviteFriend_SceneDeleting //场景正在删除 send(p) return nil } if scene.closed { logger.Logger.Warn("CSInviteFriendHandler scene is closed") opRetCode = friend.OpResultCode_OPRC_InviteFriend_SceneClosed //场景已关闭 send(p) return nil } dbGameFree := scene.dbGameFree if dbGameFree != nil { limitCoin := srvdata.CreateRoomMgrSington.GetLimitCoinByBaseScore(int32(scene.gameId), scene.dbGameFree.GetSceneType(), scene.BaseScore) if p.Coin < limitCoin { logger.Logger.Warn("CSInviteFriendHandler player limitCoin") opRetCode = friend.OpResultCode_OPRC_InviteFriend_CoinLimit //金币不足 send(p) return nil } } sp := GetScenePolicy(scene.gameId, scene.gameMode) if sp == nil { logger.Logger.Warn("CSInviteFriendHandler game not exist") opRetCode = friend.OpResultCode_OPRC_InviteFriend_GameNotExist //游戏不存在 send(p) return nil } if reason := sp.CanEnter(scene, p); reason != 0 { logger.Logger.Trace("CSInviteFriendHandler CanEnter reason ", reason) opRetCode = friend.OpResultCode_OPRC_InviteFriend_GameNotCanEnter //游戏已开始 send(p) return nil } if scene.IsFull() { logger.Logger.Trace("CSInviteFriendHandler sp is full") opRetCode = friend.OpResultCode_OPRC_InviteFriend_RoomFull //房间已满员 send(p) return nil } pos := int(msg.GetPos()) if pos < 0 || pos >= scene.playerNum { logger.Logger.Trace("CSInviteFriendHandler pos is fail") opRetCode = friend.OpResultCode_OPRC_InviteFriend_PosIsError //座位不存在 send(p) return nil } if !scene.PlayerEnter(p, pos, true) { logger.Logger.Trace("CSInviteFriendHandler EnterScene fail") opRetCode = friend.OpResultCode_OPRC_Error //进入房间失败 send(p) return nil } else { // 进入成功 for _, v := range scene.players { if v == nil || len(v.TaskInviteList) == 0 || v.SnId == p.SnId { continue } if v.TaskInviteList[p.SnId] == scene.sceneId { delete(v.TaskInviteList, p.SnId) TaskSubjectSingleton.Touch(common.TaskTypeInvitePlay, &TaskData{ SnId: v.SnId, GameID: scene.gameId, GameFreeID: scene.dbGameFree.GetId(), Num: 1, }) } } } case Invite_Refuse: logger.Logger.Trace("拒绝邀请") send(fp) //通知邀请者 } } return nil } type CSFuzzyQueryPlayerPacketFactory struct { } type CSFuzzyQueryPlayerHandler struct { } func (this *CSFuzzyQueryPlayerPacketFactory) CreatePacket() interface{} { pack := &friend.CSFuzzyQueryPlayer{} return pack } func (this *CSFuzzyQueryPlayerHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFuzzyQueryPlayerHandler Process recv ", data) if msg, ok := data.(*friend.CSFuzzyQueryPlayer); ok { p := PlayerMgrSington.GetPlayer(sid) if p == nil { logger.Logger.Warn("CSFuzzyQueryPlayerHandler p == nil") return nil } queryContent := msg.GetQueryContent() if utf8.RuneCountInString(queryContent) < 3 { return nil } pack := &friend.SCFuzzyQueryPlayer{ QueryContent: proto.String(queryContent), } // 优先搜索在线玩家 for _, player := range PlayerMgrSington.snidMap { if player != nil && player.IsOnLine() /*&& !player.IsRobot() && !FriendMgrSington.IsFriend(p.SnId, player.SnId)*/ { //在线 if !player.IsRob && player.Platform != p.Platform { //不同平台的真人不能匹配 continue } snidStr := strconv.FormatInt(int64(player.SnId), 10) if strings.Contains(player.Name, queryContent) || strings.Contains(snidStr, queryContent) { roleId := common.DefaultRoleId if player.Roles != nil { roleId = int(player.Roles.ModId) } pi := &friend.PlayerInfo{ SnId: proto.Int32(player.SnId), Name: proto.String(player.Name), Sex: proto.Int32(player.Sex), Head: proto.Int32(player.Head), HeadUrl: proto.String(player.HeadUrl), RoleId: int32(roleId), } pack.Players = append(pack.Players, pi) } } } if len(pack.Players) > 0 { p.SendToClient(int(friend.FriendPacketID_PACKET_SCFuzzyQueryPlayer), pack) logger.Logger.Tracef("CSFuzzyQueryPlayerHandler %v", pack) return nil } var err error var ls []*model.PlayerBaseInfo task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { snid, _ := strconv.Atoi(queryContent) ls = model.FindPlayerList(snid, "", queryContent, 0, 0, "", "", 0, 0, p.Platform, "", 10) return nil }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { if err != nil { logger.Logger.Errorf("CSFuzzyQueryPlayerHandler err:%v", err) } for _, v := range ls { roleId := common.DefaultRoleId if v.Roles != nil { roleId = int(v.Roles.ModId) } pi := &friend.PlayerInfo{ SnId: proto.Int32(v.SnId), Name: proto.String(v.Name), Sex: proto.Int32(v.Sex), Head: proto.Int32(v.Head), HeadUrl: proto.String(v.HeadUrl), RoleId: int32(roleId), } pack.Players = append(pack.Players, pi) } p.SendToClient(int(friend.FriendPacketID_PACKET_SCFuzzyQueryPlayer), pack) logger.Logger.Tracef("CSFuzzyQueryPlayerHandler %v", pack) })).Start() } return nil } func init() { //好友列表 申请列表 推荐列表 common.RegisterHandler(int(friend.FriendPacketID_PACKET_CSFriendList), &CSFriendListHandler{}) netlib.RegisterFactory(int(friend.FriendPacketID_PACKET_CSFriendList), &CSFriendListPacketFactory{}) //申请 同意 拒绝 删除 common.RegisterHandler(int(friend.FriendPacketID_PACKET_CSFriendOp), &CSFriendOpHandler{}) netlib.RegisterFactory(int(friend.FriendPacketID_PACKET_CSFriendOp), &CSFriendOpPacketFactory{}) //查看别人战绩 common.RegisterHandler(int(friend.FriendPacketID_PACKET_CSQueryPlayerGameLog), &CSQueryPlayerGameLogHandler{}) netlib.RegisterFactory(int(friend.FriendPacketID_PACKET_CSQueryPlayerGameLog), &CSQueryPlayerGameLogPacketFactory{}) //邀请好友对战 common.RegisterHandler(int(friend.FriendPacketID_PACKET_CSInviteFriend), &CSInviteFriendHandler{}) netlib.RegisterFactory(int(friend.FriendPacketID_PACKET_CSInviteFriend), &CSInviteFriendPacketFactory{}) //同意、拒绝好友邀请 common.RegisterHandler(int(friend.FriendPacketID_PACKET_CSInviteFriendOp), &CSInviteFriendOpHandler{}) netlib.RegisterFactory(int(friend.FriendPacketID_PACKET_CSInviteFriendOp), &CSInviteFriendOpPacketFactory{}) //根据id或者昵称查询玩家: common.RegisterHandler(int(friend.FriendPacketID_PACKET_CSFuzzyQueryPlayer), &CSFuzzyQueryPlayerHandler{}) netlib.RegisterFactory(int(friend.FriendPacketID_PACKET_CSFuzzyQueryPlayer), &CSFuzzyQueryPlayerPacketFactory{}) }