package game import ( "fmt" "server/conf" baseCfg "server/conf/base" friendCfg "server/conf/friend" "server/db" "server/game/mod/activity" "server/game/mod/friend" "server/game/mod/item" MsqMod "server/game/mod/msg" GoUtil "server/game_util" "server/msg" "strconv" "google.golang.org/protobuf/proto" ) func ReqFriendRecommend(player *Player, buf []byte) error { FriendMod := player.PlayMod.getFriendMod() RecommendList := make([]*msg.ResPlayerSimple, 0) FriendNum := FriendMod.GetFriendNum() err := FriendMod.AddDailyRecommend() if err != nil { player.SendErrClienRes(&msg.ResFriendRecommend{}) return err } var n int if FriendNum < 10 { n = 3 } else { Active := 0 for k := range FriendMod.GetFriendList() { PlayerSimpleData := G_GameLogicPtr.GetSimplePlayerByUid(k) if PlayerSimpleData == nil { continue } if PlayerSimpleData.Login > GoUtil.Now()-86400 { Active++ } } n = max(0, 3-(Active/10)) } PlayerList := GetRecommendPlayer(player, n) for _, v := range PlayerList { PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(v) RecommendList = append(RecommendList, PlayerSimpleData) } player.PushClientRes(&msg.ResFriendRecommend{ List: RecommendList, }) player.PlayMod.save() return nil } // 搜索用户 func ReqSearchPlayer(player *Player, buf []byte) error { req := &msg.ReqSearchPlayer{} err := proto.Unmarshal(buf, req) if err != nil { return err } Uid, err := strconv.Atoi(req.Uid) list := make([]*msg.ResPlayerSimple, 0) if err == nil { SearchPlayer := G_GameLogicPtr.GetResSimplePlayerByUid(Uid) if SearchPlayer != nil && SearchPlayer.Level != 0 { list = append(list, SearchPlayer) } } data, err := db.SearchPlayer(req.Uid) if err != nil { player.SendErrClienRes(&msg.ResSearchPlayer{ Code: 0, }) } for _, v := range data { if player.M_DwUin == v.DwUin { continue } SearchPlayer := G_GameLogicPtr.GetResSimplePlayerByUid(int(v.DwUin)) list = append(list, SearchPlayer) } // list 列表去重 l := make(map[int]*msg.ResPlayerSimple) for _, v := range list { if _, ok := l[int(v.Uid)]; !ok { l[int(v.Uid)] = v } } l2 := make([]*msg.ResPlayerSimple, 0) for _, v := range l { l2 = append(l2, v) } player.PushClientRes(&msg.ResSearchPlayer{ List: l2, }) return nil } // 申请好友 func ReqApplyFriend(player *Player, buf []byte) error { req := &msg.ReqApplyFriend{} err := proto.Unmarshal(buf, req) if err != nil { return err } Uid := int(req.Uid) FriendMod := player.PlayMod.getFriendMod() if Uid == int(player.M_DwUin) { player.SendErrClienRes(&msg.ResApplyFriend{ Code: msg.RES_CODE_FAIL, Msg: "cannot apply yourself", }) return fmt.Errorf("cannot apply yourself") } if FriendMod.CheckFriend(Uid) { player.SendErrClienRes(&msg.ResApplyFriend{ Code: msg.RES_CODE_FAIL, Msg: "already friend", }) return fmt.Errorf("already friend") } // 好友人数到达上限(2000人)时,玩家将无法再发送好友申请 if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() { player.SendErrClienRes(&msg.ResApplyFriend{ Code: msg.RES_CODE_FAIL, Msg: "friend list full", }) return fmt.Errorf("friend list full") } // 对于任何玩家而言,向自己在24小时内已从任意途径发送过好友申请的玩家再次发送好友申请时,该次申请不会被发出 sendApplyTime := FriendMod.GetSendApplyTime(Uid) if sendApplyTime != 0 && GoUtil.Now()-sendApplyTime < oneday { player.PushClientRes(&msg.ResApplyFriend{ Code: msg.RES_CODE_FAIL, Uid: req.Uid, Msg: "already applied", }) return fmt.Errorf("already applied") } FriendMod.AddSendApply(Uid) now := GoUtil.Now() if req.Type == 1 { Items, err := FriendMod.GetSponsorReward() if err != nil { player.SendErrClienRes(&msg.ResApplyFriend{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } BaseMod := player.PlayMod.getBaseMod() BaseMod.GetEnergyByAD() err = player.HandleItem(Items, msg.ITEM_POP_LABEL_ApplyFriendSponsor.String()) if err != nil { player.SendErrClienRes(&msg.ResApplyFriend{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } player.AddLog(int(req.Uid), friend.LOG_TYPE_FRIEND_SPONSOR, "", now) FriendMgrSend(&MsqMod.Msg{ Type: MsqMod.HANDLE_TYPE_FRIEND_SPONSOER, From: int(player.M_DwUin), To: Uid, SendT: now, End: now + sevendays, }) player.PushClientRes(BaseMod.BackData()) player.TeLog("friend_invite_reward", map[string]interface{}{ "item_list": Items, }) } m := &MsqMod.Msg{ Type: MsqMod.HANDLE_TYPE_APPLY, From: int(player.M_DwUin), To: Uid, SendT: now, End: now + sevendays, Extra: map[string]interface{}{ "type": req.Type, }, } FriendMgrSend(m) player.PushClientRes(&msg.ResApplyFriend{ Code: msg.RES_CODE_SUCCESS, Uid: req.Uid, }) return nil } // 同意申请 func ReqAgreeFriend(player *Player, buf []byte) error { req := &msg.ReqAgreeFriend{} err := proto.Unmarshal(buf, req) if err != nil { return err } Uid := int(req.Uid) FriendMod := player.PlayMod.getFriendMod() if !FriendMod.CheckApply(Uid) { player.SendErrClienRes(&msg.ResAgreeFriend{ Code: msg.RES_CODE_FAIL, Msg: "apply uid not exist", }) return fmt.Errorf("apply uid not exist") } // 好友人数到达上限(2000人)时,玩家将无法再同意好友申请 if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() { player.SendErrClienRes(&msg.ResAgreeFriend{ Code: msg.RES_CODE_FAIL, Msg: "friend list full", }) return fmt.Errorf("friend list full") } // 新好友才可以打招呼 if !FriendMod.CheckGreeting(Uid) { FriendMod.AddReplyInfo(Uid, friend.REPLY_TYPE_GREETING, "", GoUtil.Now()+oneday, nil) } FriendMod.AddFriend(Uid) player.PushClientRes(&msg.ResAgreeFriend{ Code: msg.RES_CODE_SUCCESS, Uid: req.Uid, Player: G_GameLogicPtr.GetResSimplePlayerByUid(int(req.Uid)), }) player.TeLog("friend_add", map[string]interface{}{ "player_id": Uid, "add_type": "接受申请", }) player.AddLog(Uid, friend.LOG_TYPE_FRIEND_BECOME, "", GoUtil.Now()) m := &MsqMod.Msg{ Type: MsqMod.HADNLE_TYPE_AGREE, From: int(player.M_DwUin), To: Uid, SendT: GoUtil.Now(), } FriendMgrSend(m) player.FriendApplyBackData() player.FriendLogBackData() player.PlayMod.save() return nil } // 删除好友 func ReqDelFriend(player *Player, buf []byte) error { req := &msg.ReqDelFriend{} err := proto.Unmarshal(buf, req) if err != nil { return err } Uid := int(req.Uid) m := &MsqMod.Msg{ Type: MsqMod.HANDLE_TYPE_DEL, From: int(player.M_DwUin), To: Uid, SendT: GoUtil.Now(), } FriendMgrSend(m) FriendMod := player.PlayMod.getFriendMod() FriendMod.DelFriend(Uid) player.PlayMod.save() player.PushClientRes(&msg.ResDelFriend{ Code: msg.RES_CODE_SUCCESS, Uid: req.Uid, }) player.AddLog(Uid, friend.LOG_TYPE_FRIEND_DELETE, "", GoUtil.Now()) player.FriendListBackData() player.TeLog("friend_delete", map[string]interface{}{ "player_id": Uid, }) return nil } // 拒绝申请 func ReqRefuseFriend(player *Player, buf []byte) error { req := &msg.ReqRefuseFriend{} err := proto.Unmarshal(buf, req) if err != nil { return err } Uid := int(req.Uid) FriendMod := player.PlayMod.getFriendMod() FriendMod.RefuseApply(Uid) player.PlayMod.save() player.PushClientRes(&msg.ResRefuseFriend{ Code: msg.RES_CODE_SUCCESS, Uid: req.Uid, }) now := GoUtil.Now() m := &MsqMod.Msg{ Type: MsqMod.HANDLE_TYPE_REFUSE, From: int(player.M_DwUin), To: Uid, SendT: now, End: now + 86400*7, } FriendMgrSend(m) player.FriendApplyBackData() return nil } func ReqFriendList(player *Player, buf []byte) error { player.FriendListBackData() return nil } func ReqFriendApply(player *Player, buf []byte) error { player.FriendApplyBackData() return nil } func ReqFriendCardMsg(player *Player, buf []byte) error { player.FriendCardBackData() return nil } func ReqFriendTimeLine(player *Player, buf []byte) error { player.FriendLogBackData() return nil } func ReqFriendTLUpvote(player *Player, buf []byte) error { req := &msg.ReqFriendTLUpvote{} err := proto.Unmarshal(buf, req) if err != nil { return err } FriendMod := player.PlayMod.getFriendMod() Items, FUid, err := FriendMod.Upvote(int(req.Id)) if err != nil { player.SendErrClienRes(&msg.ResFriendTLUpvote{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } err = player.HandleItem(Items, msg.ITEM_POP_LABEL_TLUpvote.String()) if err != nil { player.SendErrClienRes(&msg.ResFriendTLUpvote{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } now := GoUtil.Now() // 添加时间线 m := &MsqMod.Msg{ Type: MsqMod.HANDLE_TYPE_HANDBOOK_UPVOTE, From: int(player.M_DwUin), To: int(FUid), SendT: now, End: now + sevendays, } FriendMod.AddActLog(friend.ACT_LOG_TYPE_VISIT_UPVOTE, "") player.UpdateUserInfo() FriendMgrSend(m) player.PlayMod.save() player.PushClientRes(&msg.ResFriendTLUpvote{ Code: msg.RES_CODE_SUCCESS, Id: req.Id, }) player.TeLog("friend_upvote", map[string]interface{}{ "player_id": int(req.Id), }) return nil } func ReqFriendTReward(player *Player, buf []byte) error { req := &msg.ReqFriendTReward{} err := proto.Unmarshal(buf, req) if err != nil { return err } FriendMod := player.PlayMod.getFriendMod() Items, err := FriendMod.GetReward(int(req.Id)) if err != nil { player.SendErrClienRes(&msg.ResFriendTReward{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } err = player.HandleItem(Items, msg.ITEM_POP_LABEL_FriendTReward.String()) if err != nil { player.SendErrClienRes(&msg.ResFriendTReward{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } player.PlayMod.save() player.PushClientRes(&msg.ResFriendTReward{ Code: msg.RES_CODE_SUCCESS, Id: req.Id, }) return nil } func ReqFriendReplyHandle(player *Player, buf []byte) error { req := &msg.ReqFriendReplyHandle{} err := proto.Unmarshal(buf, req) if err != nil { return err } FriendMod := player.PlayMod.getFriendMod() ReplyInfo := FriendMod.ReplyFriend(int(req.LogId)) if ReplyInfo == nil { player.SendErrClienRes(&msg.ResFriendReplyHandle{ Code: msg.RES_CODE_FAIL, Msg: "reply info not exist", }) return fmt.Errorf("reply info not exist") } ErrType := msg.FRIEND_REPLY_HANDLE_ERR_TYPE_NONE now := GoUtil.Now() items := make([]*item.Item, 0) if req.Type == 1 && ReplyInfo.Uid > 10000 { switch ReplyInfo.Type { case friend.REPLY_TYPE_GREETING: ReplyData := friend.ReplyInfo{ Uid: int(player.M_DwUin), Type: friend.REPLY_TYPE_GREETING_Get, Param: req.Param, } FriendMgrSend(&MsqMod.Msg{ From: int(player.M_DwUin), To: int(ReplyInfo.Uid), Type: MsqMod.HANDLE_TYPE_FRIEND_GREETING_REPLY, SendT: now, End: now + sevendays, Extra: ReplyData, }) FriendMod.GreetingFriend(int(ReplyInfo.Uid)) case friend.REPLY_TYPE_GREETING_Get: reply_items := baseCfg.GetFriendReplyReward() items = append(items, reply_items...) case friend.REPLY_TYPE_CATNIP: // 猫草大作战同意邀请 GameId := GoUtil.Int(ReplyInfo.Param) activityInfo := player.GetActivityInfo(player.GetActivityId(activity.ACT_TYPE_CATNIP)) if activityInfo == nil { break } err := player.SetCatnipPartner(GameId, ReplyInfo.Uid, activityInfo.EndT) if err == nil { CatnipMod := player.PlayMod.getCatnipMod() ActivityId := player.GetActivityId(activity.ACT_TYPE_CATNIP) UserList, _ := CatnipMod.Agree(GameId, ReplyInfo.Uid) player.TeLog("catnip_agree", map[string]interface{}{ "Id": int(GameId), }) FriendMgrSend(&MsqMod.Msg{ From: int(player.M_DwUin), To: int(ReplyInfo.Uid), Type: MsqMod.HANDLE_TYPE_CATNIP_AGREE, Extra: map[string]interface{}{ "ActivityId": ActivityId, "GameId": int(GameId), }, SendT: now, End: now + sevendays, }) for _, v := range UserList { FriendMgrSend(&MsqMod.Msg{ From: int(player.M_DwUin), To: int(v), Type: MsqMod.HANDLE_TYPE_CATNIP_AGREE, Extra: map[string]interface{}{ "ActivityId": ActivityId, "GameId": int(GameId), }, SendT: now, End: now + sevendays, }) } player.CatnipBackData() } else { ErrType = msg.FRIEND_REPLY_HANDLE_ERR_TYPE_CATNIP } } } if len(items) > 0 { err = player.HandleItem(items, msg.ITEM_POP_LABEL_FriendReplyHandle.String()) if err != nil { player.SendErrClienRes(&msg.ResFriendReplyHandle{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } } player.FriendLogBackData() player.PushClientRes(&msg.ResFriendReplyHandle{ Code: msg.RES_CODE_SUCCESS, LogId: req.LogId, Type: req.Type, ErrType: ErrType, }) return nil } func ReqFriendByCode(player *Player, buf []byte) error { req := &msg.ReqFriendByCode{} err := proto.Unmarshal(buf, req) if err != nil { return err } if req.Code == "" { player.SendErrClienRes(&msg.ResFriendByCode{ Code: msg.RES_CODE_FAIL, Msg: "code is empty", }) return fmt.Errorf("code is empty") } CodeNum := GoUtil.ParseUniqueStringToInt(req.Code) if CodeNum <= 0 { player.SendErrClienRes(&msg.ResFriendByCode{ Code: msg.RES_CODE_FAIL, Msg: "code is invalid", }) return fmt.Errorf("code is invalid") } Uid := int64(CodeNum) + int64(100000) + int64(conf.Server.AppID*100000000) if Uid == player.M_DwUin { player.SendErrClienRes(&msg.ResFriendByCode{ Code: msg.RES_CODE_FAIL, Msg: "can not add yourself", }) return fmt.Errorf("can not add yourself") } PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(int(Uid)) if PlayerSimpleData == nil { player.SendErrClienRes(&msg.ResFriendByCode{ Code: msg.RES_CODE_FAIL, Msg: "player not exist", }) return fmt.Errorf("player not exist") } player.PushClientRes(&msg.ResFriendByCode{ Code: msg.RES_CODE_SUCCESS, Player: PlayerSimpleData, }) return nil } func ReqAddNpc(player *Player, buf []byte) error { req := &msg.ReqAddNpc{} err := proto.Unmarshal(buf, req) if err != nil { return err } FriendMod := player.PlayMod.getFriendMod() err = FriendMod.SetNpc(int(req.NpcId)) if err != nil { player.SendErrClienRes(&msg.ResAddNpc{ Code: msg.RES_CODE_FAIL, Msg: err.Error(), }) return err } if len(FriendMod.Npc) == 1 { // 首次添加NPC 视为邀请好友成功 InviteMod := player.PlayMod.getInviteMod() InviteMod.AddInvite(int(req.NpcId)) } player.PlayMod.save() player.FriendListBackData() player.TeLog("add_npc", map[string]interface{}{ "NpcId": int(req.NpcId), }) FriendMod.AddReplyInfo(int(req.NpcId), friend.REPLY_TYPE_GREETING, "", GoUtil.Now()+oneday, nil) FriendMod.AddReplyInfo(int(req.NpcId), friend.REPLY_TYPE_GREETING_Get, "", GoUtil.Now()+oneday, nil) player.AddLog(int(req.NpcId), friend.LOG_TYPE_FRIEND_BECOME_NPC, GoUtil.String(req.NpcId), GoUtil.Now()) player.PushClientRes(&msg.ResAddNpc{ Code: msg.RES_CODE_SUCCESS, NpcId: req.NpcId, }) return nil }