926 lines
26 KiB
Go
926 lines
26 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
"mongo.games.com/goserver/core/basic"
|
|
"mongo.games.com/goserver/core/logger"
|
|
"mongo.games.com/goserver/core/module"
|
|
"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/worldsrv/internal"
|
|
)
|
|
|
|
const (
|
|
ListType_Friend int32 = iota // 0.好友列表
|
|
ListType_Apply // 1.申请列表
|
|
ListType_Recommend // 2.推荐列表
|
|
)
|
|
|
|
const (
|
|
OpType_Apply int32 = iota // 0.申请
|
|
OpType_Agree // 1.同意
|
|
OpType_Refuse // 2.拒绝
|
|
OpType_Delete // 3.删除
|
|
)
|
|
|
|
const (
|
|
Invite_Agree int = iota // 0.同意
|
|
Invite_Refuse // 1.拒绝
|
|
)
|
|
|
|
const FriendMaxNum = 200
|
|
const ShieldMaxNum = 10000
|
|
const FriendApplyMaxNum = 1000 //好友申请上限
|
|
const FriendWrite = "FriendWrite"
|
|
|
|
var FriendMgrSington = &FriendMgr{
|
|
FriendList: make(map[string]map[int32]*model.Friend),
|
|
TsInviteCd: make(map[string]map[string]int64),
|
|
}
|
|
|
|
type FriendMgr struct {
|
|
FriendList map[string]map[int32]*model.Friend // 平台id:snid:好友信息
|
|
TsInviteCd map[string]map[string]int64 // 平台id:snid:邀请cd时间
|
|
}
|
|
|
|
func (this *FriendMgr) ModuleName() string {
|
|
return "FriendMgr"
|
|
}
|
|
|
|
func (this *FriendMgr) Init() {
|
|
}
|
|
|
|
// Add 缓存玩家信息
|
|
func (this *FriendMgr) Add(platform string, snid int32) {
|
|
logger.Logger.Trace("(this *FriendMgr) Add ", snid)
|
|
if this.FriendList[platform] == nil {
|
|
this.FriendList[platform] = make(map[int32]*model.Friend)
|
|
}
|
|
if _, exist := this.FriendList[platform][snid]; !exist {
|
|
p := PlayerMgrSington.GetPlayerBySnId(snid)
|
|
if p != nil {
|
|
this.FriendList[platform][snid] = model.NewFriend(p.Platform, p.SnId)
|
|
this.UpdateInfo(p.Platform, p.SnId)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Del 删除玩家缓存
|
|
func (this *FriendMgr) Del(platform string, snid int32) {
|
|
if this.FriendList[platform] == nil {
|
|
return
|
|
}
|
|
if _, exist := this.FriendList[platform][snid]; exist {
|
|
delete(this.FriendList[platform], snid)
|
|
}
|
|
}
|
|
|
|
// CanInvite 是否可以邀请,邀请冷却
|
|
func (this *FriendMgr) CanInvite(platform string, snid, fsnid int32) bool {
|
|
if this.TsInviteCd[platform] == nil {
|
|
this.TsInviteCd[platform] = make(map[string]int64)
|
|
}
|
|
strSnid := strconv.FormatInt(int64(snid), 10) + "_" + strconv.FormatInt(int64(fsnid), 10)
|
|
if _, exist := this.TsInviteCd[platform][strSnid]; !exist {
|
|
this.TsInviteCd[platform][strSnid] = time.Now().Unix()
|
|
return true
|
|
}
|
|
if this.TsInviteCd[platform][strSnid] == 0 {
|
|
this.TsInviteCd[platform][strSnid] = time.Now().Unix()
|
|
return true
|
|
}
|
|
if time.Now().Unix()-this.TsInviteCd[platform][strSnid] > 30 {
|
|
this.TsInviteCd[platform][strSnid] = time.Now().Unix()
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// AgreeApply 同意好友申请
|
|
func (this *FriendMgr) AgreeApply(platform string, snid int32, bf *model.BindFriend) friend.OpResultCode {
|
|
logger.Logger.Trace("(this *FriendMgr) AgreeApply ", snid, " BindFriend: ", bf)
|
|
if bf == nil || bf.Platform != platform {
|
|
return friend.OpResultCode_OPRC_Friend_NoPlayer
|
|
}
|
|
if this.FriendList[platform] == nil {
|
|
this.FriendList[platform] = make(map[int32]*model.Friend)
|
|
}
|
|
|
|
// 是否为好友
|
|
if this.IsFriend(platform, snid, bf.SnId) {
|
|
return friend.OpResultCode_OPRC_Friend_AlreadyAdd
|
|
}
|
|
|
|
// 检查好友数量
|
|
dflDest := this.GetFriendList(platform, snid)
|
|
if dflDest != nil {
|
|
if len(dflDest) >= FriendMaxNum {
|
|
return friend.OpResultCode_OPRC_Friend_DestFriendMax
|
|
}
|
|
}
|
|
dfl := this.GetFriendList(platform, bf.SnId)
|
|
if dfl != nil {
|
|
if len(dfl) >= FriendMaxNum {
|
|
return friend.OpResultCode_OPRC_Friend_FriendMax
|
|
}
|
|
}
|
|
|
|
bf.CreateTime = time.Now().Unix()
|
|
this.FriendList[platform][snid].BindFriend = append(this.FriendList[platform][snid].BindFriend, bf)
|
|
this.FriendList[platform][snid].Dirty = true
|
|
return friend.OpResultCode_OPRC_Sucess
|
|
}
|
|
|
|
// RemoveFriend 删除好友
|
|
func (this *FriendMgr) RemoveFriend(platform string, snid, destSnid int32) bool {
|
|
logger.Logger.Trace("(this *FriendMgr) RemoveFriend ", snid, " destSnid: ", destSnid)
|
|
if this.FriendList[platform] == nil {
|
|
return false
|
|
}
|
|
if fl, exist := this.FriendList[platform][snid]; exist {
|
|
for i, f := range fl.BindFriend {
|
|
if f.SnId == destSnid {
|
|
fl.BindFriend = append(fl.BindFriend[:i], fl.BindFriend[i+1:]...)
|
|
fl.Dirty = true
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (this *FriendMgr) UpdateInfo(platform string, snid int32) {
|
|
logger.Logger.Trace("(this *FriendMgr) UpdateInfo ", snid)
|
|
if this.FriendList[platform] == nil {
|
|
return
|
|
}
|
|
|
|
p := PlayerMgrSington.GetPlayerBySnId(snid)
|
|
if p == nil {
|
|
return
|
|
}
|
|
|
|
info, ok := this.FriendList[platform][snid]
|
|
if !ok {
|
|
return
|
|
}
|
|
info.Name = p.Name
|
|
info.Head = p.Head
|
|
info.HeadUrl = p.HeadUrl
|
|
info.Sex = p.Sex
|
|
info.Coin = p.Coin
|
|
info.Diamond = p.Diamond
|
|
item := BagMgrSingleton.GetItem(p.SnId, VCard)
|
|
if item != nil {
|
|
info.VCard = item.ItemNum
|
|
}
|
|
info.Roles = p.Roles.ModUnlock
|
|
info.Pets = p.Pets.ModUnlock
|
|
info.Age = p.Age
|
|
info.Signature = p.Signature
|
|
info.GameID = p.GameID
|
|
info.UpdateTime = time.Now().Unix()
|
|
info.Dirty = true
|
|
|
|
for _, v := range info.BindFriend {
|
|
if v == nil {
|
|
continue
|
|
}
|
|
in := this.FriendList[platform][v.SnId]
|
|
if in == nil {
|
|
continue
|
|
}
|
|
for _, vv := range in.BindFriend {
|
|
if vv != nil && vv.SnId == snid {
|
|
vv.Name = p.Name
|
|
vv.Head = p.Head
|
|
vv.HeadUrl = p.HeadUrl
|
|
vv.Sex = p.Sex
|
|
vv.LogoutTime = p.LastLogoutTime.Unix()
|
|
vv.RoleId = p.Roles.ModId
|
|
in.Dirty = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetPlayer 获取玩家信息
|
|
func (this *FriendMgr) GetPlayer(platform string, snid int32) *model.Friend {
|
|
if this.FriendList[platform] == nil {
|
|
return nil
|
|
}
|
|
if fi, exist := this.FriendList[platform][snid]; exist {
|
|
this.UpdateInfo(platform, snid)
|
|
return fi
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetFriendList 获取好友列表
|
|
func (this *FriendMgr) GetFriendList(platform string, snid int32) []*model.BindFriend {
|
|
var allFriend []*model.BindFriend
|
|
if this.FriendList[platform] == nil {
|
|
return nil
|
|
}
|
|
if f, exist := this.FriendList[platform][snid]; exist {
|
|
if f != nil && f.BindFriend != nil {
|
|
for _, bindFriend := range f.BindFriend {
|
|
allFriend = append(allFriend, bindFriend)
|
|
}
|
|
}
|
|
}
|
|
return allFriend
|
|
}
|
|
|
|
// IsFriend 是否好友关系
|
|
func (this *FriendMgr) IsFriend(platform string, snid, destSnid int32) bool {
|
|
logger.Logger.Trace("(this *FriendMgr) IsFriend ", snid, " -> ", destSnid)
|
|
dfl := this.GetFriendList(platform, snid)
|
|
if dfl != nil && len(dfl) != 0 {
|
|
for _, df := range dfl {
|
|
if df.SnId == destSnid {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ApplyList 查询好友申请列表
|
|
func (this *FriendMgr) ApplyList(platform string, snid int32) {
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
ret, err := model.QueryFriendApplyBySnid(platform, 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 {
|
|
if ret.ApplySnids != nil {
|
|
pack := &friend.SCFriendApplyData{}
|
|
for _, as := range ret.ApplySnids {
|
|
fa := &friend.FriendApply{
|
|
Snid: proto.Int32(as.SnId),
|
|
Name: proto.String(as.Name),
|
|
CreateTs: proto.Int64(as.CreateTs),
|
|
}
|
|
pack.FriendApplys = append(pack.FriendApplys, fa)
|
|
}
|
|
if len(pack.FriendApplys) > 0 {
|
|
proto.SetDefaults(pack)
|
|
p := PlayerMgrSington.GetPlayerBySnId(snid)
|
|
if p != nil {
|
|
p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendApplyData), pack)
|
|
logger.Logger.Trace("SCFriendApplyData: 好友申请列表 pack: ", pack)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})).StartByFixExecutor("QueryFriendApplyBySnid")
|
|
}
|
|
|
|
// AddShield 屏蔽好友消息
|
|
func (this *FriendMgr) AddShield(platform string, snid, ssnid int32) {
|
|
if this.FriendList[platform] == nil {
|
|
return
|
|
}
|
|
if fl, exist := this.FriendList[platform][snid]; exist {
|
|
if fl.Shield == nil {
|
|
fl.Shield = []int32{}
|
|
}
|
|
if len(fl.Shield) > ShieldMaxNum {
|
|
return
|
|
}
|
|
fl.Shield = append(fl.Shield, ssnid)
|
|
fl.Dirty = true
|
|
}
|
|
}
|
|
|
|
// DelShield 解除消息屏蔽
|
|
func (this *FriendMgr) DelShield(platform string, snid, ssnid int32) {
|
|
if this.FriendList[platform] == nil {
|
|
return
|
|
}
|
|
if fl, exist := this.FriendList[platform][snid]; exist {
|
|
if fl.Shield == nil {
|
|
return
|
|
}
|
|
if len(fl.Shield) == 0 {
|
|
return
|
|
}
|
|
fl.Shield = common.DelSliceInt32(fl.Shield, ssnid)
|
|
fl.Dirty = true
|
|
}
|
|
}
|
|
|
|
// IsShield 是否屏蔽消息
|
|
// snid的玩屏蔽ssnid的消息
|
|
func (this *FriendMgr) IsShield(platform string, snid, ssnid int32) bool {
|
|
if this.FriendList[platform] == nil {
|
|
return false
|
|
}
|
|
if fl, exist := this.FriendList[platform][snid]; exist {
|
|
if fl.Shield == nil {
|
|
return false
|
|
}
|
|
if len(fl.Shield) == 0 {
|
|
return false
|
|
}
|
|
return common.InSliceInt32(fl.Shield, ssnid)
|
|
}
|
|
return false
|
|
}
|
|
|
|
// UpdateLogoutTime 更新玩家下线时间
|
|
func (this *FriendMgr) UpdateLogoutTime(platform string, snid int32) {
|
|
if this.FriendList[platform] == nil {
|
|
return
|
|
}
|
|
if fl, exist := this.FriendList[platform][snid]; exist {
|
|
fl.LogoutTime = time.Now().Unix()
|
|
fl.Dirty = true
|
|
if fl.BindFriend != nil {
|
|
for _, bf := range fl.BindFriend {
|
|
if this.FriendList[bf.Platform] != nil {
|
|
if data, ok := this.FriendList[bf.Platform][bf.SnId]; ok {
|
|
if data.BindFriend != nil {
|
|
for _, bindFriend := range data.BindFriend {
|
|
if bindFriend.SnId == snid {
|
|
bindFriend.LogoutTime = time.Now().Unix()
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *FriendMgr) FriendOp(opcode int32, p *Player, destP *model.BindFriend) {
|
|
switch opcode {
|
|
case OpType_Apply:
|
|
logger.Logger.Trace("@Apply friend", p.SnId, " -> ", destP.SnId)
|
|
this.FriendApply(p, destP)
|
|
case OpType_Agree:
|
|
logger.Logger.Trace("@AgreeApply friend", p.SnId, " -> ", destP.SnId)
|
|
this.FriendAgree(p, destP)
|
|
case OpType_Refuse:
|
|
logger.Logger.Trace("@Refuse friend", p.SnId, " -> ", destP.SnId)
|
|
this.FriendRefuse(p, destP)
|
|
case OpType_Delete:
|
|
logger.Logger.Trace("@Delete friend", p.SnId, " -> ", destP.SnId)
|
|
this.FriendDelete(p, destP)
|
|
}
|
|
}
|
|
|
|
// FriendApply 好友申请
|
|
// 记录在数据库
|
|
func (this *FriendMgr) FriendApply(p *Player, destP *model.BindFriend) {
|
|
SendToClick := func(retCode friend.OpResultCode, self ...bool) {
|
|
pack := &friend.SCFriendOp{
|
|
OpCode: proto.Int32(OpType_Apply),
|
|
SnId: proto.Int32(destP.SnId),
|
|
OpRetCode: retCode,
|
|
}
|
|
if len(self) == 0 {
|
|
p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
} else {
|
|
destPs := PlayerMgrSington.GetPlayerBySnId(destP.SnId)
|
|
if destPs != nil && destPs.IsOnLine() {
|
|
roleId := common.DefaultRoleId
|
|
if p.Roles != nil {
|
|
roleId = int(p.Roles.ModId)
|
|
}
|
|
pack.Friend = &friend.FriendInfo{
|
|
SnId: proto.Int32(p.SnId),
|
|
Name: proto.String(p.Name),
|
|
Sex: proto.Int32(p.Sex),
|
|
Head: proto.Int32(p.Head),
|
|
HeadUrl: proto.String(p.HeadUrl),
|
|
CreateTs: proto.Int64(time.Now().Unix()),
|
|
LogoutTs: proto.Int64(p.LastLogoutTime.Unix()),
|
|
RoleId: int32(roleId),
|
|
}
|
|
destPs.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
}
|
|
}
|
|
logger.Logger.Tracef(">>FriendApply %d -> %d, %v", p.SnId, destP.SnId, pack)
|
|
}
|
|
if FriendMgrSington.IsFriend(p.Platform, p.SnId, destP.SnId) {
|
|
SendToClick(friend.OpResultCode_OPRC_Friend_AlreadyAdd)
|
|
return
|
|
}
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
ret, err := model.QueryFriendApplyBySnid(p.Platform, destP.SnId)
|
|
if err != nil {
|
|
return friend.OpResultCode_OPRC_Error
|
|
}
|
|
if ret != nil {
|
|
//在申请列表
|
|
if ret.ApplySnids != nil {
|
|
if len(ret.ApplySnids) > FriendApplyMaxNum {
|
|
return friend.OpResultCode_OPRC_Friend_DestApplyFriendMax //对方好友申请已达上限
|
|
}
|
|
for _, as := range ret.ApplySnids {
|
|
if as.SnId == p.SnId {
|
|
return friend.OpResultCode_OPRC_Friend_AlreadyApply //已经申请过好友
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
//不在申请列表 新增
|
|
ret = model.NewFriendApply(destP.SnId)
|
|
}
|
|
roleId := common.DefaultRoleId
|
|
if p.Roles != nil {
|
|
roleId = int(p.Roles.ModId)
|
|
}
|
|
ret.ApplySnids = append(ret.ApplySnids, &model.FriendApplySnid{
|
|
SnId: p.SnId,
|
|
Name: p.Name,
|
|
Head: p.Head,
|
|
HeadUrl: p.HeadUrl,
|
|
CreateTs: time.Now().Unix(),
|
|
RoleId: int32(roleId),
|
|
})
|
|
model.UpsertFriendApply(p.Platform, destP.SnId, ret)
|
|
return friend.OpResultCode_OPRC_Sucess
|
|
}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess, false) // 对方
|
|
SendToClick(data.(friend.OpResultCode)) // 自己
|
|
})).StartByFixExecutor(FriendWrite)
|
|
}
|
|
|
|
// FriendAgree 同意好友申请
|
|
func (this *FriendMgr) FriendAgree(p *Player, destP *model.BindFriend) {
|
|
SendToClick := func(retCode friend.OpResultCode, self ...bool) {
|
|
pack := &friend.SCFriendOp{
|
|
OpCode: proto.Int32(OpType_Agree),
|
|
SnId: proto.Int32(destP.SnId),
|
|
OpRetCode: retCode,
|
|
}
|
|
if len(self) == 0 {
|
|
roleId := common.DefaultRoleId
|
|
if destP.RoleId != 0 {
|
|
roleId = int(destP.RoleId)
|
|
}
|
|
pack.Friend = &friend.FriendInfo{
|
|
SnId: proto.Int32(destP.SnId),
|
|
Name: proto.String(destP.Name),
|
|
Sex: proto.Int32(destP.Sex),
|
|
Head: proto.Int32(destP.Head),
|
|
HeadUrl: proto.String(destP.HeadUrl),
|
|
CreateTs: proto.Int64(time.Now().Unix()),
|
|
LogoutTs: proto.Int64(destP.LogoutTime),
|
|
RoleId: int32(roleId),
|
|
}
|
|
p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
} else {
|
|
destPs := PlayerMgrSington.GetPlayerBySnId(destP.SnId)
|
|
if destPs != nil && destPs.IsOnLine() {
|
|
roleId := common.DefaultRoleId
|
|
if p.Roles != nil {
|
|
roleId = int(p.Roles.ModId)
|
|
}
|
|
pack.Friend = &friend.FriendInfo{
|
|
SnId: proto.Int32(p.SnId),
|
|
Name: proto.String(p.Name),
|
|
Sex: proto.Int32(p.Sex),
|
|
Head: proto.Int32(p.Head),
|
|
HeadUrl: proto.String(p.HeadUrl),
|
|
CreateTs: proto.Int64(time.Now().Unix()),
|
|
LogoutTs: proto.Int64(p.LastLogoutTime.Unix()),
|
|
RoleId: int32(roleId),
|
|
}
|
|
destPs.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
}
|
|
}
|
|
logger.Logger.Tracef(">>FriendAgree %d -> %d, %v", p.SnId, destP.SnId, pack)
|
|
}
|
|
me := FriendMgrSington.GetPlayer(p.Platform, p.SnId)
|
|
if me == nil {
|
|
SendToClick(friend.OpResultCode_OPRC_Error)
|
|
return
|
|
}
|
|
if FriendMgrSington.IsFriend(p.Platform, p.SnId, destP.SnId) { //已经是好友了
|
|
SendToClick(friend.OpResultCode_OPRC_Friend_AlreadyAdd)
|
|
return
|
|
}
|
|
//验证自己
|
|
if len(me.BindFriend) >= FriendMaxNum {
|
|
SendToClick(friend.OpResultCode_OPRC_Friend_FriendMax)
|
|
return
|
|
}
|
|
|
|
destPFriend := FriendMgrSington.GetPlayer(destP.Platform, destP.SnId)
|
|
if destPFriend != nil {
|
|
if len(destPFriend.BindFriend) >= FriendMaxNum {
|
|
SendToClick(friend.OpResultCode_OPRC_Friend_DestFriendMax)
|
|
return
|
|
}
|
|
}
|
|
|
|
var friendDB *model.Friend
|
|
var err error
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
if destPFriend == nil {
|
|
// 不在线
|
|
friendDB, err = model.QueryFriendBySnid(destP.Platform, destP.SnId)
|
|
if err != nil {
|
|
logger.Logger.Error("QueryFriendBySnid:", err, destP.SnId)
|
|
return friend.OpResultCode_OPRC_Error
|
|
}
|
|
if friendDB == nil || friendDB.SnId != destP.SnId {
|
|
friendDB = model.NewFriend(destP.Platform, destP.SnId)
|
|
}
|
|
|
|
if len(friendDB.BindFriend) >= FriendMaxNum {
|
|
return friend.OpResultCode_OPRC_Friend_FriendMax
|
|
}
|
|
|
|
for _, v := range friendDB.BindFriend {
|
|
if v.SnId == p.SnId {
|
|
return friend.OpResultCode_OPRC_Friend_AlreadyAdd
|
|
}
|
|
}
|
|
}
|
|
|
|
ret, err := model.QueryFriendApplyBySnid(p.Platform, p.SnId)
|
|
if err != nil {
|
|
return friend.OpResultCode_OPRC_Error
|
|
}
|
|
//查看是否在申请列表
|
|
if ret != nil {
|
|
if ret.ApplySnids != nil {
|
|
for i, as := range ret.ApplySnids {
|
|
if as.SnId == destP.SnId {
|
|
//在申请列表 删除
|
|
ret.ApplySnids = append(ret.ApplySnids[:i], ret.ApplySnids[i+1:]...)
|
|
model.UpsertFriendApply(p.Platform, p.SnId, ret)
|
|
// 保存好友关系
|
|
if friendDB != nil {
|
|
friendDB.BindFriend = append(friendDB.BindFriend, &model.BindFriend{
|
|
SnId: p.SnId,
|
|
CreateTime: time.Now().Unix(),
|
|
})
|
|
model.UpsertFriend(friendDB)
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return friend.OpResultCode_OPRC_Error
|
|
}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
|
|
if data != nil {
|
|
logger.Logger.Error("FriendAgree data:", data)
|
|
SendToClick(data.(friend.OpResultCode))
|
|
return
|
|
}
|
|
|
|
//同意者加入到被同意者好友里
|
|
if destPlayer := FriendMgrSington.GetPlayer(destP.Platform, destP.SnId); destPlayer != nil {
|
|
roleId := common.DefaultRoleId
|
|
if p.Roles != nil {
|
|
roleId = int(p.Roles.ModId)
|
|
}
|
|
result := FriendMgrSington.AgreeApply(destP.Platform, destP.SnId, &model.BindFriend{
|
|
SnId: p.SnId,
|
|
CreateTime: time.Now().Unix(),
|
|
Platform: p.Platform,
|
|
Name: p.Name,
|
|
Head: p.Head,
|
|
HeadUrl: p.HeadUrl,
|
|
Sex: p.Sex,
|
|
LogoutTime: p.LastLogoutTime.Unix(),
|
|
RoleId: int32(roleId),
|
|
})
|
|
if result != friend.OpResultCode_OPRC_Sucess && result != friend.OpResultCode_OPRC_Friend_AlreadyAdd {
|
|
logger.Logger.Warn("AgreeApply error: ", result)
|
|
SendToClick(result)
|
|
return
|
|
}
|
|
}
|
|
|
|
// 被同意者加入到同意者好友里
|
|
result := FriendMgrSington.AgreeApply(p.Platform, p.SnId, destP)
|
|
if result != friend.OpResultCode_OPRC_Sucess {
|
|
SendToClick(result, false)
|
|
SendToClick(result)
|
|
return
|
|
}
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess, false)
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess)
|
|
})).StartByFixExecutor(FriendWrite)
|
|
}
|
|
|
|
func (this *FriendMgr) FriendRefuse(p *Player, destP *model.BindFriend) {
|
|
SendToClick := func(retCode friend.OpResultCode, self ...bool) {
|
|
pack := &friend.SCFriendOp{
|
|
OpCode: proto.Int32(OpType_Refuse),
|
|
SnId: proto.Int32(destP.SnId),
|
|
OpRetCode: retCode,
|
|
}
|
|
if len(self) == 0 {
|
|
p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
} else {
|
|
destPs := PlayerMgrSington.GetPlayerBySnId(destP.SnId)
|
|
if destPs != nil && destPs.IsOnLine() {
|
|
destPs.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
}
|
|
}
|
|
logger.Logger.Tracef(">>FriendRefuse %d -> %d, %v", p.SnId, destP.SnId, pack)
|
|
}
|
|
if FriendMgrSington.IsFriend(p.Platform, p.SnId, destP.SnId) {
|
|
SendToClick(friend.OpResultCode_OPRC_Friend_AlreadyAdd)
|
|
return
|
|
}
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
ret, _ := model.QueryFriendApplyBySnid(p.Platform, p.SnId)
|
|
if ret != nil {
|
|
if ret.ApplySnids != nil {
|
|
for i, as := range ret.ApplySnids {
|
|
if as.SnId == destP.SnId {
|
|
ret.ApplySnids = append(ret.ApplySnids[:i], ret.ApplySnids[i+1:]...)
|
|
model.UpsertFriendApply(p.Platform, p.SnId, ret)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return errors.New("not in apply")
|
|
}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
|
|
//拒绝了不提醒
|
|
if data != nil {
|
|
logger.Logger.Error("FriendRefuse data:", data)
|
|
SendToClick(friend.OpResultCode_OPRC_Error)
|
|
return
|
|
}
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess)
|
|
})).StartByFixExecutor(FriendWrite)
|
|
}
|
|
|
|
func (this *FriendMgr) FriendDelete(p *Player, destP *model.BindFriend) {
|
|
SendToClick := func(retCode friend.OpResultCode, self ...bool) {
|
|
pack := &friend.SCFriendOp{
|
|
OpCode: proto.Int32(OpType_Delete),
|
|
SnId: proto.Int32(destP.SnId),
|
|
OpRetCode: retCode,
|
|
}
|
|
if len(self) == 0 {
|
|
pack.SnId = destP.SnId
|
|
p.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
logger.Logger.Tracef(">>FriendDelete %d -> %d, %v", p.SnId, destP.SnId, pack)
|
|
} else {
|
|
destPs := PlayerMgrSington.GetPlayerBySnId(destP.SnId)
|
|
if destPs != nil && destPs.IsOnLine() {
|
|
pack.SnId = p.SnId
|
|
destPs.SendToClient(int(friend.FriendPacketID_PACKET_SCFriendOp), pack)
|
|
logger.Logger.Tracef(">>FriendDelete dest %d -> %d, %v", p.SnId, destP.SnId, pack)
|
|
}
|
|
}
|
|
}
|
|
f := FriendMgrSington.GetPlayer(p.Platform, destP.SnId)
|
|
if f != nil {
|
|
//发起者删除被删除者
|
|
isok1 := FriendMgrSington.RemoveFriend(p.Platform, p.SnId, f.SnId)
|
|
if !isok1 {
|
|
logger.Logger.Warn("RemoveFriend error: ", p.SnId, " del friend:", f.SnId)
|
|
SendToClick(friend.OpResultCode_OPRC_Error)
|
|
return
|
|
}
|
|
//被删除者删除发起者
|
|
isok2 := FriendMgrSington.RemoveFriend(f.Platform, f.SnId, p.SnId)
|
|
if !isok2 {
|
|
logger.Logger.Warn("RemoveFriend error: ", f.SnId, " del friend:", p.SnId)
|
|
//删除失败不用通知
|
|
} else {
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess, false)
|
|
}
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess)
|
|
ChatMgrSington.DelChat(p.Platform, p.SnId, f.SnId)
|
|
} else {
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
ret, _ := model.QueryFriendBySnid(p.Platform, destP.SnId)
|
|
if ret != nil {
|
|
//被删除者删除发起者
|
|
if ret.BindFriend != nil {
|
|
for i, bindFriend := range ret.BindFriend {
|
|
if bindFriend.SnId == p.SnId {
|
|
ret.BindFriend = append(ret.BindFriend[:i], ret.BindFriend[i+1:]...)
|
|
model.UpsertFriend(ret)
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess, false)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return errors.New("not in apply")
|
|
}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
|
|
if data != nil {
|
|
logger.Logger.Error("FriendDelete data:", data)
|
|
SendToClick(friend.OpResultCode_OPRC_Error)
|
|
return
|
|
} else {
|
|
//发起者删除被删除者
|
|
isok1 := FriendMgrSington.RemoveFriend(p.Platform, p.SnId, destP.SnId)
|
|
if !isok1 {
|
|
logger.Logger.Warn("RemoveFriend error: ", p.SnId, " del friend:", destP.SnId)
|
|
//SendToClick(friend.OpResultCode_OPRC_Error)
|
|
//return
|
|
}
|
|
SendToClick(friend.OpResultCode_OPRC_Sucess)
|
|
}
|
|
ChatMgrSington.DelChat(p.Platform, p.SnId, destP.SnId)
|
|
})).StartByFixExecutor(FriendWrite)
|
|
}
|
|
}
|
|
|
|
func (this *FriendMgr) Update() {
|
|
}
|
|
|
|
func (this *FriendMgr) Shutdown() {
|
|
module.UnregisteModule(this)
|
|
}
|
|
|
|
func (this *FriendMgr) UpdateName(snId int32, name string) {
|
|
p := PlayerMgrSington.GetPlayerBySnId(snId)
|
|
if p != nil {
|
|
this.UpdateInfo(p.Platform, p.SnId)
|
|
}
|
|
}
|
|
|
|
func (this *FriendMgr) UpdateHead(snId, head int32) {
|
|
p := PlayerMgrSington.GetPlayerBySnId(snId)
|
|
if p != nil {
|
|
this.UpdateInfo(p.Platform, p.SnId)
|
|
}
|
|
}
|
|
|
|
//========================implement IPlayerLoad ==============================
|
|
|
|
func (this *FriendMgr) Load(platform string, snid int32, player any) *internal.PlayerLoadReplay {
|
|
return nil
|
|
}
|
|
|
|
func (this *FriendMgr) Callback(player any, ret *internal.PlayerLoadReplay) {
|
|
}
|
|
|
|
func (this *FriendMgr) LoadAfter(platform string, snid int32) *internal.PlayerLoadReplay {
|
|
ret := &internal.PlayerLoadReplay{
|
|
Platform: platform,
|
|
Snid: snid,
|
|
}
|
|
|
|
friendDB, err := model.QueryFriendBySnid(platform, snid)
|
|
if err != nil {
|
|
logger.Logger.Error("QueryFriendBySnid:", err, snid)
|
|
ret.Err = err
|
|
return ret
|
|
}
|
|
|
|
if friendDB == nil {
|
|
return ret
|
|
}
|
|
|
|
var offSnID []int32
|
|
for _, v := range friendDB.BindFriend {
|
|
roleId := common.DefaultRoleId
|
|
if v.RoleId != 0 {
|
|
roleId = int(v.RoleId)
|
|
}
|
|
p := PlayerMgrSington.GetPlayerBySnId(v.SnId)
|
|
if p != nil {
|
|
v.Platform = p.Platform
|
|
v.Name = p.Name
|
|
v.Head = p.Head
|
|
v.HeadUrl = p.HeadUrl
|
|
v.Sex = p.Sex
|
|
if !p.IsOnLine() {
|
|
v.LogoutTime = p.LastLogoutTime.Unix()
|
|
}
|
|
v.RoleId = int32(roleId)
|
|
} else {
|
|
offSnID = append(offSnID, v.SnId)
|
|
}
|
|
}
|
|
|
|
if len(offSnID) > 0 {
|
|
offFriends, err := model.QueryFriendsBySnids(platform, offSnID)
|
|
if err != nil {
|
|
logger.Logger.Error("QueryFriendsBySnids is err:", err)
|
|
ret.Err = err
|
|
return ret
|
|
}
|
|
for _, offFriend := range offFriends {
|
|
for _, v := range friendDB.BindFriend {
|
|
roleId := common.DefaultRoleId
|
|
if v.RoleId != 0 {
|
|
roleId = int(v.RoleId)
|
|
}
|
|
if v.SnId == offFriend.SnId {
|
|
v.Platform = offFriend.Platform
|
|
v.Name = offFriend.Name
|
|
v.Head = offFriend.Head
|
|
v.HeadUrl = offFriend.HeadUrl
|
|
v.Sex = offFriend.Sex
|
|
v.LogoutTime = offFriend.LogoutTime
|
|
v.RoleId = int32(roleId)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ret.Data = friendDB
|
|
|
|
return ret
|
|
}
|
|
|
|
func (this *FriendMgr) CallbackAfter(ret *internal.PlayerLoadReplay) {
|
|
if ret == nil || ret.Platform == "" || ret.Snid <= 0 {
|
|
return
|
|
}
|
|
|
|
if ret.Err != nil {
|
|
logger.Logger.Error("(this *FriendMgr) CallbackAfter err:", ret.Err)
|
|
return
|
|
}
|
|
if ret.Data == nil {
|
|
this.Add(ret.Platform, ret.Snid)
|
|
logger.Logger.Infof("(this *FriendMgr) LoadFriendData New: %+v", *this.GetPlayer(ret.Platform, ret.Snid))
|
|
return
|
|
}
|
|
|
|
data, ok := ret.Data.(*model.Friend)
|
|
if !ok {
|
|
logger.Logger.Error("bug")
|
|
return
|
|
}
|
|
|
|
if this.FriendList[ret.Platform] == nil {
|
|
this.FriendList[ret.Platform] = make(map[int32]*model.Friend)
|
|
}
|
|
|
|
this.FriendList[ret.Platform][ret.Snid] = data
|
|
logger.Logger.Infof("(this *FriendMgr) LoadFriendData db: %+v", *data)
|
|
p := PlayerMgrSington.GetPlayerBySnId(ret.Snid)
|
|
if p != nil {
|
|
this.UpdateInfo(ret.Platform, ret.Snid)
|
|
}
|
|
FriendUnreadMgrSington.LoadFriendUnreadData(ret.Platform, ret.Snid)
|
|
this.ApplyList(ret.Platform, ret.Snid)
|
|
}
|
|
|
|
func (this *FriendMgr) Save(platform string, snid int32, isSync, force bool) {
|
|
logger.Logger.Trace("(this *FriendMgr) SaveFriendData ", snid)
|
|
ret := this.GetPlayer(platform, snid)
|
|
if ret == nil || (!ret.Dirty && !force) {
|
|
return
|
|
}
|
|
|
|
var res bool
|
|
f := func() {
|
|
res = model.UpsertFriend(ret) != nil
|
|
}
|
|
cf := func() {
|
|
if res {
|
|
ret.Dirty = false
|
|
}
|
|
}
|
|
|
|
if isSync {
|
|
f()
|
|
cf()
|
|
return
|
|
}
|
|
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
f()
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
cf()
|
|
})).StartByFixExecutor(fmt.Sprintf("player%v", ret.SnId))
|
|
}
|
|
|
|
func (this *FriendMgr) Release(platform string, snid int32) {
|
|
this.Del(platform, snid)
|
|
}
|
|
|
|
func init() {
|
|
module.RegisteModule(FriendMgrSington, time.Hour, 0)
|
|
internal.RegisterPlayerLoad(FriendMgrSington)
|
|
}
|