HomeServer/Server/AllServer/GameServer/Partner.lua
2024-11-20 15:41:37 +08:00

1530 lines
65 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local skynet = require "skynet"
local oo = require "Class"
local pb = require "pb"
local log = require "Log"
local errorInfo = require "ErrorInfo"
local dataType = require "DataType"
local redisKeyUrl = require "RedisKeyUrl"
local sqlUrl = require "SqlUrl"
local json = require "json"
local serverId = tonumber(skynet.getenv "serverId")
local Partner = oo.class()
Partner.QueryType_ID = 1 --玩家ID查询
Partner.QueryType_NickName = 2 --玩家昵称查询
Partner.MaxQueryCount = 4 --最大查询数量
Partner.MaxResetQueryTime = 300 --最大还原查询时间
Partner.MsgType_Text = 1 --文本消息
Partner.MsgType_Gift = 2 --礼物
Partner.MsgType_InviteDoubleSpace = 3 --双人空间邀请
--双人空间购买房间邀请
Partner.MsgType_InviteDoubleSpaceBuyHouse = 4
--双人空间购买装修方案邀请
Partner.MsgType_InviteDoubleSpaceBuyHouseScheme = 5
--双人空间代购房间通知
Partner.MsgType_InviteDoubleSpaceBuyHouseNotice = 6
--双人空间代购装修方案通知
Partner.MsgType_InviteDoubleSpaceBuyHouseSchemeNotice = 7
Partner.MaxMsgRecordToClient = 50 --发送给客户端最大的消息记录数量
Partner.MaxMsgRecord = 2000 --好友消息记录最大数量
Partner.MaxFriendCount = 30 --最大好友数量
Partner.HouseDetailMaxOutTime = 3600 --好友房子过期时间
Partner.MaxGetOnlineCount = 200 --最大获取在线用户数量
Partner.RefreshOnlineInterval = 120 --刷新在线用户间隔
--邀请状态
Partner.InviteStatus_Inviting = 1 --正在邀请中
Partner.InviteStatus_Agree = 2 --已同意邀请
Partner.InviteStatus_Refuse = 3 --已拒绝邀请
Partner.InviteStatus_OutOfTime = 4 --已过期
function Partner:Init()
self.onlineUserList = {} --在线用户列表
skynet.server.timer:Add( dataType.Timer_SyncOnlineUser , self.RefreshOnlineInterval , self["SyncOnlineList"] , self )
end
--好友列表
function Partner:MyList( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerMyList", c2sData.data ))
local data = {}
data.infos = self:GetFriendList( player )
skynet.server.msgTips:ReduceAll( player , 53 )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerMyList")
s2cData.data = assert(pb.encode("S2CPartnerMyList", data))
end
--获取好友列表
function Partner:GetFriendList( player )
local data = {}
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
local myPlayerId = player.gameData.partner.id
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
local friendList = skynet.server.redis:zrange( redisKey , 0 , -1 )
--检查下我有不有新的朋友
local myDetail = skynet.server.personal:GetDetail( myPlayerId )
if not myDetail then
return data
end
if myDetail.newFriendCount and myDetail.newFriendCount > 0 then
--有条件才触发任务
skynet.server.levelTask:Modify( player , 73 , myDetail.newFriendCount )
skynet.server.taskListEvent:Modify( player , 73 , myDetail.newFriendCount )
skynet.server.personal:SetDetail( myPlayerId ,"newFriendCount", 0)
end
--遍历好友列表
for k, otherPartnerId in pairs( friendList ) do
local curDetail = skynet.server.personal:GetDetail( otherPartnerId )
if curDetail then
--获取我和该玩家的未读消息数量
local redisKey = string.format( redisKeyUrl.GameServerPartnerUnreadMsgIndexZSet , myPlayerId )
local minIndex = tonumber(skynet.server.redis:zscore( redisKey , otherPartnerId ))
if not minIndex then
skynet.server.redis:zadd( redisKey , 0 , otherPartnerId)
end
--最新消息数量
redisKey = self:GetMsgKey( myPlayerId , otherPartnerId )
local msgList = skynet.server.redis:zrangebyscore( redisKey , (minIndex or 0 ) + 1 , "+inf" )
local count = 0
for i = 1, #msgList, 1 do
local tmp = json:decode(msgList[i])
if myPlayerId ~= tmp.sendPartnerId and tmp.isShowMsg then
count = count + 1
end
end
curDetail.unReadCount = count
--是否与好友是双人空间
local myInfoKey = skynet.server.doubleSpace:GetMyInfoKey( myPlayerId , otherPartnerId )
if skynet.server.redis:exists( myInfoKey ) then
curDetail.isDoubleSpace = true
skynet.server.levelTask:Modify( player , 74 , 1 )
skynet.server.taskListEvent:Modify( player , 74 , 1 )
else
curDetail.isDoubleSpace = false
end
--检查下好友的数量达到没有
local doubleSpaceCount = tonumber(curDetail.doubleSpaceCount) or 0
if doubleSpaceCount >= cfgSValue.coupleHouseLimit then
curDetail.isInviteDoubleBtn = false
else
curDetail.isInviteDoubleBtn = true
end
--是否离线
if not curDetail.isOnline then
curDetail.offlineTime=curDetail.updateTime
end
table.insert( data , curDetail )
end
end
return data
end
--好友推荐
function Partner:Recommend( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerRecommend", c2sData.data ))
local data = {}
data.querys = {}
local myPlayerId = player.gameData.partner.id
local tmpPartner = player.tmpData.partner
local firstQuery = true --第一次查询
--把我的好友先添加进去
local function AddMyFriend()
tmpPartner.alreadyQueryUser = {}
table.insert( tmpPartner.alreadyQueryUser , myPlayerId) --自己加进去
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
local friendList = skynet.server.redis:zrange( redisKey , 0 , -1 )
for k, v in pairs( friendList ) do
table.insert( tmpPartner.alreadyQueryUser , v) --我的好友加进去
end
end
--是否存在好友
local function IsExistFriend( partnerId )
for k, v in pairs( tmpPartner.alreadyQueryUser ) do
if partnerId == v then
return true
end
end
return false
end
--查询在线用户
local function QuerynlineUser()
if 0 == #tmpPartner.alreadyQueryUser or #tmpPartner.alreadyQueryUser >= 50 then
AddMyFriend()
end
local count = 0
local isEnough = false
for k, v in pairs( self.onlineUserList ) do
if not IsExistFriend( v.partnerId ) then
table.insert( tmpPartner.alreadyQueryUser , v.partnerId)
table.insert( data.querys , { info = v , isApply = self:IsApply( player , v.partnerId )})
count = count + 1
end
if count >= self.MaxQueryCount then
isEnough = true
break
end
end
if not isEnough and firstQuery then
firstQuery = false
--找出来数量不够就清空重新找
tmpPartner.alreadyQueryUser = {}
data.querys = {}
QuerynlineUser()
end
end
QuerynlineUser()
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerRecommend")
s2cData.data = assert(pb.encode("S2CPartnerRecommend", data))
end
--好友查询
function Partner:Query( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerQuery", c2sData.data ))
local data = {}
data.querys = {}
local queryType = c2sData.data.queryType
local queyValue = c2sData.data.queyValue
if not queryType then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local myPlayerId = player.gameData.partner.id
local queryAll = {}
if self.QueryType_ID == queryType and queyValue and myPlayerId ~= queyValue then
table.insert(queryAll , queyValue )
elseif self.QueryType_NickName == queryType and queyValue then
--[[暂时不用
local redisKey = redisKeyUrl.GameServerPartneNickNameZSet
local tmpQueryData = skynet.server.redis:zscan( redisKey ,0,"match" , string.format("*%s*",queyValue)) --根据关键字模糊查询相关昵称
for k, v in pairs( tmpQueryData[2] ) do
if 2 == k and myPlayerId ~= v then
table.insert(queryAll , v )
end
end
]]
else
if myPlayerId == queyValue then
s2cData.code = errorInfo.ErrorCode.NoQueryMySelf
else
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
end
end
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
local friendList = skynet.server.redis:zrange( redisKey , 0 , -1 )
--根据找到的数据获取详情
for k1, v1 in pairs( queryAll ) do
local curDetail = skynet.server.personal:GetDetail( v1 )
if curDetail then
if not curDetail.birthdayShow then
curDetail.birthdayDate = ""
end
data.partnerDetail = curDetail
data.isApply = self:IsApply( player , v1 )
data.isFriend = false
data.birthdayDate=curDetail.birthdayDate
--看看是不是我的好友
for k2, v2 in pairs( friendList ) do
if v1 == v2 then
data.isFriend = true
break
end
end
end
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerQuery")
s2cData.data = assert(pb.encode("S2CPartnerQuery", data))
end
--好友添加
function Partner:Add( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerAdd", c2sData.data ))
local data = {}
data.query = {}
local myPlayerId = player.gameData.partner.id
local partnerId = c2sData.data.partnerId
if not partnerId or myPlayerId == partnerId then --不能加自己
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
if not self:IsAddFriend( myPlayerId ) then
s2cData.code = errorInfo.ErrorCode.MyFriendMaxLimit
elseif self:IsOtherApply( myPlayerId , partnerId ) then --看看别人申请了我没有,别人申请了就不用再申请了。
s2cData.code = errorInfo.ErrorCode.OtherFriendApplyFriendForMe
else
--先要检查下存不存在
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
local basicInfo = skynet.server.personal:GetDetail( partnerId )
if not basicInfo then
s2cData.code = errorInfo.ErrorCode.NoExistUser
elseif basicInfo.level < cfgSValue.partnerUnlockLvl then
s2cData.code = errorInfo.ErrorCode.NoFriendFunc
else
local isApply = self:IsApply( player , partnerId )
data.query.info = basicInfo
if not isApply then
--加入到我的申请列表
local myPlayerId = player.gameData.partner.id
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyApplyOtherZSet , myPlayerId )
skynet.server.redis:zadd( redisKey , skynet.GetTime() , partnerId )
--加入到别人的申请列表
redisKey = string.format( redisKeyUrl.GameServerPartnerOtherApplyMyZSet , partnerId )
skynet.server.redis:zadd( redisKey , skynet.GetTime() , myPlayerId )
self:SendMsgTips( partnerId , 54 , true )
log.debug(string.format("玩家 %d 好友 向 %s 发出添加好友邀请", player.userId , partnerId ))
else
log.debug(string.format("玩家 %d 好友 已经向 %s 发出添加好友邀请", player.userId , partnerId ))
end
data.query.isApply = true
end
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerAdd")
s2cData.data = assert(pb.encode("S2CPartnerAdd", data))
end
--好友删除
function Partner:Delete( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerDelete", c2sData.data ))
local data = {}
local otherPartnerId = c2sData.data.partnerId
if not otherPartnerId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
--友谊小船说翻就翻 好友互删
local myPartnerId = player.gameData.partner.id
local redisKey = nil
redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPartnerId )
skynet.server.redis:zrem( redisKey , otherPartnerId )
redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , otherPartnerId )
skynet.server.redis:zrem( redisKey , myPartnerId )
--清空聊天记录
redisKey = self:GetMsgKey( myPartnerId , otherPartnerId )
skynet.server.redis:del( redisKey )
--清空消息ID
local _,redisKey = self:GetLastMsgID( myPartnerId , otherPartnerId )
skynet.server.redis:del( redisKey )
--删除好友空间
redisKey = skynet.server.doubleSpace:GetMyInfoKey( myPartnerId , otherPartnerId )
if skynet.server.redis:exists( redisKey ) then
skynet.server.doubleSpace:RemovePutFurniture(player, myPartnerId, otherPartnerId )
skynet.server.redis:del( redisKey )
skynet.server.personal:AccDetail( myPartnerId ,"doubleSpaceCount", -1) --减少双人空间数量
skynet.server.personal:AccDetail( otherPartnerId ,"doubleSpaceCount", -1) --减少双人空间数量
end
data.infos = self:GetFriendList( player )
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerDelete")
s2cData.data = assert(pb.encode("S2CPartnerDelete", data))
end
--好友申请列表
function Partner:ApplyList( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerApplyList", c2sData.data ))
local data = {}
data.infos = self:GetApplyList( player )
skynet.server.msgTips:ReduceAll( player , 54 )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerApplyList")
s2cData.data = assert(pb.encode("S2CPartnerApplyList", data))
end
--好友申请回应
function Partner:ApplyRespond( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerApplyRespond", c2sData.data ))
local data = {}
data.infos = {}
local partnerId = c2sData.data.partnerId
local isAgree = c2sData.data.isAgree
if not partnerId or 0 == #partnerId or nil == isAgree then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local myPlayerId = player.gameData.partner.id
local function DeleteApplyFriend()
--从该玩家的申请列表中删除我
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyApplyOtherZSet , partnerId )
skynet.server.redis:zrem( redisKey , myPlayerId )
--从别人加我的申请列表中删除该玩家
redisKey = string.format( redisKeyUrl.GameServerPartnerOtherApplyMyZSet , myPlayerId )
skynet.server.redis:zrem( redisKey , partnerId)
end
local isAdd1 = self:IsAddFriend( myPlayerId )
local isAdd2 = self:IsAddFriend( partnerId )
if isAdd1 and isAdd2 and isAgree then
--将该玩家加入到我的好友列表中
DeleteApplyFriend()
local t = skynet.GetTime()
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
skynet.server.redis:zadd( redisKey , t , partnerId )
--将我也加入到该玩家的好友列表中
redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , partnerId )
skynet.server.redis:zadd( redisKey , t , myPlayerId )
skynet.server.personal:AccDetail( partnerId ,"newFriendCount", 1)
skynet.server.levelTask:Modify( player , 73 , 1 )
skynet.server.taskListEvent:Modify( player , 73 , 1 )
--发送下最新的好友列表
local friendData = {}
friendData.infos = self:GetFriendList( player )
skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_PartnerMyList" , friendData )
log.debug(string.format("玩家 %d 好友 成功加入好友 %s", player.userId , partnerId ))
else
if isAgree then
if not isAdd1 then
s2cData.code = errorInfo.ErrorCode.MyFriendMaxLimit
end
if not isAdd2 then
s2cData.code = errorInfo.ErrorCode.OtherFriendMaxLimit
end
log.warning(string.format("玩家 %d 好友 好友数量已满,无法加入 %s %s", player.userId , myPlayerId , partnerId ))
else
DeleteApplyFriend()
end
end
data.infos = self:GetApplyList( player )
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerApplyRespond")
s2cData.data = assert(pb.encode("S2CPartnerApplyRespond", data))
end
--好友聊天记录
function Partner:HistoryMsg( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerHistoryMsg", c2sData.data ))
local data = {}
local otherPartnerId = c2sData.data.partnerId
local earliestMsgId = c2sData.data.earliestMsgId
if not otherPartnerId or not earliestMsgId or earliestMsgId < 0 then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
data.partnerId = otherPartnerId
data.msgs = {}
local myPartnerId = player.gameData.partner.id
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
local msgList = nil
if 0 == earliestMsgId then
--清理过期消息
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
local outOfTime = ( cfgSValue.friendChatSave ) * 3600 --好友聊天内容有效期
self:ClearOutOfTimeMsg( myPartnerId , otherPartnerId , outOfTime )
--传0就发送最近指定数目的消息
msgList = skynet.server.redis:zrevrange( msgKey , 0 , self.MaxMsgRecordToClient - 1 )
else
local max = earliestMsgId - 1
local min = earliestMsgId - self.MaxMsgRecordToClient
msgList = skynet.server.redis:zrevrangebyscore( msgKey , max < 0 and 0 or max , min < 0 and 0 or min )
end
local lastMsgId = 0
local msgData = nil
for k, v in pairs( msgList ) do
msgData = json:decode(v)
if nil == msgData.isShowMsg then
--兼容线上数据,可能没有这值
msgData.isShowMsg = true
end
table.insert( data.msgs , msgData)
--获取最新的消息ID
if lastMsgId < msgData.msgId then
lastMsgId = msgData.msgId
end
end
if 0 == earliestMsgId then
--如果获取最新的消息那就把查看最新消息的索引设置为最新的消息ID
local redisKey = string.format( redisKeyUrl.GameServerPartnerUnreadMsgIndexZSet , myPartnerId )
skynet.server.redis:zadd( redisKey , lastMsgId , otherPartnerId )
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerHistoryMsg")
s2cData.data = assert(pb.encode("S2CPartnerHistoryMsg", data))
end
--好友发送消息
function Partner:SendMsg( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerSendMsg", c2sData.data ))
local data = {}
local otherPartnerId = c2sData.data.partnerId
local msgType = c2sData.data.msgType
local msgText = c2sData.data.msgText
if not otherPartnerId or not msgType or not msgText then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
elseif skynet.server.common:IsMaskWords( msgText ) then
s2cData.code = errorInfo.ErrorCode.ExistMaskWords
else
local myPartnerId = player.gameData.partner.id
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
local maxCount = skynet.server.redis:zcard( msgKey )
if maxCount >= self.MaxMsgRecord then
--玩家的消息记录过多
s2cData.code = errorInfo.ErrorCode.MaxLimit
else
local redisBanChatKey = string.format( redisKeyUrl.ChatManageBanChatTimeString, myPartnerId )
local unbanChatTime = tonumber(skynet.server.redis:get( redisBanChatKey )) or 0 --获取玩家解禁的时间
local isShowMsg = ( 0 == unbanChatTime ) and true or false --是否显示消息
--将消息转化为json保存到消息列表中
local msgData,lastMsgId = self:InitMsg( myPartnerId , otherPartnerId , self.MsgType_Text , isShowMsg )
msgData.msgText = msgText
skynet.server.redis:zadd( msgKey , lastMsgId , json:encode(msgData) )
data.partnerId = otherPartnerId --将好友的ID发送给自己
data.lastMsg = msgData
if isShowMsg then
self:SendMsgToFriend( myPartnerId , otherPartnerId , msgData )
end
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerSendMsg")
s2cData.data = assert(pb.encode("S2CPartnerSendMsg", data))
end
--好友礼物背包
function Partner:GiftBag( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerGiftBag", c2sData.data ))
local data = {}
local npcId = c2sData.data.npcId
if not npcId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerGiftBag")
s2cData.data = assert(pb.encode("S2CPartnerGiftBag", data))
end
--好友赠送礼物
function Partner:GiftGive( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerGiftGive", c2sData.data ))
local data = {}
local partnerId = c2sData.data.partnerId
local goodsInfo = c2sData.data.goodsInfo
if not skynet.server.bag:IsValidGoodsType( goodsInfo.goodsType ) or goodsInfo.goodsId <= 0 or goodsInfo.goodsCount <= 0 then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
elseif dataType.GoodsType_CuisineMaterial ~= goodsInfo.goodsType and dataType.GoodsType_Seed ~= goodsInfo.goodsType then --赠送食材原材料和种子
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
--给好友赠送礼物次数
local partnerGiftCount = player.gameData.todayGain.partnerGiftCount
if not partnerGiftCount[ partnerId ] then
partnerGiftCount[ partnerId ] = 0
end
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
if partnerGiftCount[ partnerId ] >= cfgSValue.friendGiftLimit then
--超过最大限制
s2cData.code = errorInfo.ErrorCode.TodayMaxLimit
else
local myPlayerId = player.gameData.partner.id
local msgKey = self:GetMsgKey( myPlayerId , partnerId )
--判断赠送的道具是否合规
local canSend = self:CanSendGoods(player , partnerId , goodsInfo.goodsType , goodsInfo.goodsId)
if canSend then
if not skynet.server.bag:RemoveGoods( player , goodsInfo.goodsType , goodsInfo.goodsId , goodsInfo.goodsCount ) then
s2cData.code = errorInfo.ErrorCode.NoEnoughGoods
else
--将消息转化为json保存到消息列表中
local msgData,lastMsgId = self:InitMsg( myPlayerId , partnerId , self.MsgType_Gift , true )
msgData.gift.info = goodsInfo
msgData.gift.status = dataType.GiftStatus_NoGain
skynet.server.redis:zadd( msgKey , lastMsgId , json:encode(msgData))
data.lastMsg = msgData
partnerGiftCount[ partnerId ] = partnerGiftCount[ partnerId ] + 1
skynet.server.levelTask:Modify( player , 65 , goodsInfo.goodsCount)
skynet.server.achieveTask:Modify( player , 65 , goodsInfo.goodsCount)
skynet.server.taskListEvent:Modify( player , 65 , goodsInfo.goodsCount)
if dataType.GoodsType_CuisineMaterial == goodsInfo.goodsType then
skynet.server.levelTask:Modify( player , 80 , goodsInfo.goodsCount)
skynet.server.taskListEvent:Modify( player , 80 , goodsInfo.goodsCount)
end
self:SendMsgToFriend( myPlayerId , partnerId , msgData )
end
else
s2cData.code = errorInfo.ErrorCode.NoGiveGoodsToPlayer
end
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerGiftGive")
s2cData.data = assert(pb.encode("S2CPartnerGiftGive", data))
end
--好友获取礼物
function Partner:GiftGet( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerGiftGet", c2sData.data ))
local data = {}
local partnerId = c2sData.data.partnerId
local msgId = c2sData.data.msgId
if not partnerId or not msgId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local myPlayerId = player.gameData.partner.id
local msgKey = self:GetMsgKey( myPlayerId , partnerId )
local msgData = skynet.server.redis:zrangebyscore( msgKey , msgId , msgId)
msgData = json:decode( msgData[1] )
if self.MsgType_Gift ~= msgData.msgType then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
elseif dataType.GiftStatus_AlreadyGain == msgData.gift.status then
s2cData.code = errorInfo.ErrorCode.AlreadyGet
else
--发货
msgData.gift.status = dataType.GiftStatus_AlreadyGain
--事务流程替换原数据
skynet.server.redis:zremrangebyscore( msgKey , msgId , msgId)
skynet.server.redis:zadd( msgKey , msgId , json:encode(msgData))
local goodsInfo = msgData.gift.info
skynet.server.bag:AddGoodsNoExp( player , goodsInfo.goodsType , goodsInfo.goodsId , goodsInfo.goodsCount )
--根据赠送的礼物 判断是否需要刷新相关数据
if dataType.GoodsType_Fish == goodsInfo.goodsType then
skynet.server.fishShop:FishRefreshRedDot(player, goodsInfo.goodsId )
elseif dataType.GoodsType_Coffee == goodsInfo.goodsType then
--skynet.server.coffeeShop:GainCoffee(player, goodsInfo.goodsId )
elseif dataType.GoodsType_CuisineMenu == goodsInfo.goodsType then
skynet.server.cuisineShop:RefreshData(player, goodsInfo.goodsId )
end
data.partnerId = partnerId
data.msg = msgData
self:SendMsgToFriend( myPlayerId , partnerId , msgData )
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerGiftGet")
s2cData.data = assert(pb.encode("S2CPartnerGiftGet", data))
end
--好友详情
function Partner:Detail( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerDetail", c2sData.data ))
local data = {}
local partnerId = c2sData.data.partnerId
if not partnerId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local basicInfo = skynet.server.personal:GetDetail( partnerId )
if basicInfo then
data.partner = basicInfo
else
s2cData.code = errorInfo.ErrorCode.NoExistUser
end
data.partner.birthdayDate=basicInfo.birthdayDate or ""
if basicInfo.birthdayShow==false then
data.partner.birthdayDate=""
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerDetail")
s2cData.data = assert(pb.encode("S2CPartnerDetail", data))
end
--获取好友房间信息
function Partner:ShowFriendHouse( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerShowFriendHouse", c2sData.data ))
local data = {}
local partnerId = c2sData.data.partnerId
local houseId = c2sData.data.houseId
if not partnerId or not houseId or houseId < 0 then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local houseDetail = {}
local redisKey = string.format( redisKeyUrl.GameServerHouseDetailHash , partnerId )
if not skynet.server.redis:exists( redisKey) then
--没有玩家的缓存数据需要从DB中加载
local detail = skynet.server.personal:GetDetail( partnerId )
if not detail then
s2cData.code = errorInfo.ErrorCode.NoExistUser
else
local dbIndex = detail.dbIndex
local userId = detail.userId
--从DB中获取玩家数据
local sql = string.format(sqlUrl.queryAccountFromPlayer , userId )
local queryData = skynet.server.db:QueryPlayer( dbIndex , sql )
--local queryData = skynet.server.mongo[ "player".. dbIndex ]:findOne({ _id = userId } , { GameData = 1 } )
if not queryData then
s2cData.code = errorInfo.ErrorCode.NoExistHouse
else
queryData = queryData[1]
local gameData = json:decode(queryData.GameData)
houseDetail.curHouseId = gameData.curHouseID --当前房间ID
houseDetail.flowerpot = gameData.flowerpot --花盆信息
houseDetail.houseList = {}
--由于房间数据过大分批次保存到redis
for k, v in pairs( gameData.house ) do
if skynet.server.house.Status_AlreadyBuy == v.status or skynet.server.house.Status_Live == v.status then
skynet.server.redis:hset( redisKey , "houseData_"..k , json:encode(v) )
table.insert( houseDetail.houseList, k )
if gameData.curHouseID == k then
houseDetail.curHouseData = v --当前房间信息
end
end
end
--将一些信息保存到redis中
skynet.server.redis:hmset( redisKey ,
"curHouseId" , gameData.curHouseID ,
"flowerpot" , json:encode(gameData.flowerpot) ,
"houseList" , json:encode(houseDetail.houseList))
end
end
else
--从redis中读取数据
local tmpData = skynet.server.redis:hmget( redisKey , "curHouseId", "flowerpot" , "houseList")
houseDetail.curHouseId = tonumber( tmpData[1])
houseDetail.flowerpot = json:decode(tmpData[2])
houseDetail.houseList = json:decode(tmpData[3])
--如果为0查询默认房间数据 非0根据玩家发送的houseId查询房间数据
if 0 ~= houseId then
houseDetail.curHouseId = houseId
end
houseDetail.curHouseData = skynet.server.redis:hget( redisKey , "houseData_"..houseDetail.curHouseId)
houseDetail.curHouseData = json:decode(houseDetail.curHouseData)
end
skynet.server.levelTask:Modify( player , 76 , 1 , nil , partnerId )
skynet.server.taskListEvent:Modify( player , 76 , 1 )
skynet.server.redis:expire( redisKey , self.HouseDetailMaxOutTime ) --设置过期时间为1小时
data = self:GetFriendHouseData( partnerId , houseDetail )
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerShowFriendHouse")
s2cData.data = assert(pb.encode("S2CPartnerShowFriendHouse", data))
end
--好友消除红点
function Partner:ClearRedDot( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerClearRedDot", c2sData.data ))
local data = {}
local partnerId = c2sData.data.partnerId
if not partnerId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
data.partnerId = partnerId
local myPlayerId = player.gameData.partner.id
local msgKey = self:GetMsgKey( myPlayerId , partnerId )
local msgList = skynet.server.redis:zrange( msgKey , -1 , -1 )
local lastMsgId = 0
local tmpData = nil
for k, v in pairs( msgList ) do
tmpData = json:decode(v)
local redisKey = string.format( redisKeyUrl.GameServerPartnerUnreadMsgIndexZSet , myPlayerId )
skynet.server.redis:zadd( redisKey , tmpData.msgId , partnerId )
break
end
skynet.server.msgTips:ReduceAll( player , 53 )
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerClearRedDot")
s2cData.data = assert(pb.encode("S2CPartnerClearRedDot", data))
end
--好友组建双人空间请求
function Partner:DoubleSpaceRequest( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerDoubleSpaceRequest", c2sData.data ))
local data = {}
local otherPartnerId = c2sData.data.partnerId
if "" == otherPartnerId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local t1 = skynet.GetTime()
local myPartnerId = player.gameData.partner.id
local msgData = self:GetMsgDataForType( myPartnerId , otherPartnerId , self.MsgType_InviteDoubleSpace )
if msgData and ( t1 - msgData.updateTime ) <= dataType.OneDaySec then --如果小于1天就不允许再发送消息
s2cData.code = errorInfo.ErrorCode.AlreadyApplyDoubleSpace --已经申请
else
--走到这里,表示消息已经过期,如果还是邀请状态就改为过期状态
if msgData and self.InviteStatus_Inviting == msgData.doubleSpace.inviteStatus then
msgData.doubleSpace.inviteStatus = self.InviteStatus_OutOfTime
self:SetMsgData( myPartnerId , otherPartnerId , msgData.msgId , msgData )
end
local myCount = skynet.server.personal:GetCurDetail( myPartnerId , "doubleSpaceCount" )
local otherCount = skynet.server.personal:GetCurDetail( otherPartnerId , "doubleSpaceCount" )
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
if nil == myCount then
s2cData.code = errorInfo.ErrorCode.MyNoEnoughLevel --自己等级未达到
elseif nil == otherCount then
s2cData.code = errorInfo.ErrorCode.OtherNoEnoughLevel --对方等级未达到
elseif myCount >= cfgSValue.coupleHouseLimit then
s2cData.code = errorInfo.ErrorCode.MyDoubleSpaceNoCount --我的空间数量已达上限
elseif otherCount >= cfgSValue.coupleHouseLimit then
s2cData.code = errorInfo.ErrorCode.OtherDoubleSpaceNoCount --对方空间数量已达上限
elseif skynet.server.doubleSpace:IsExist( myPartnerId , otherPartnerId ) then
s2cData.code = errorInfo.ErrorCode.AlreadyExistDoubleSpace --双方已经建立了空间
else
--发送邀请好友消息
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
local msgData,lastMsgId = self:InitMsg( myPartnerId , otherPartnerId , self.MsgType_InviteDoubleSpace , true )
msgData.doubleSpace.inviteStatus = self.InviteStatus_Inviting
skynet.server.redis:zadd( msgKey , lastMsgId , json:encode(msgData))
--好友在线,也将该消息给他
self:SendMsgToFriend( myPartnerId , otherPartnerId , msgData )
data.lastMsg = msgData
end
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerDoubleSpaceRequest")
s2cData.data = assert(pb.encode("S2CPartnerDoubleSpaceRequest", data))
end
--好友组建双人空间回应
function Partner:DoubleSpaceResponse( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerDoubleSpaceResponse", c2sData.data ))
local data = {}
local otherPartnerId = c2sData.data.partnerId
local msgId = c2sData.data.msgId
local isAgree = c2sData.data.isAgree
local myPartnerId = player.gameData.partner.id
if not otherPartnerId or not msgId or nil == isAgree then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
local msgData = skynet.server.redis:zrangebyscore( msgKey , msgId , msgId)
msgData = json:decode( msgData[1] )
--不是邀请双人空间消息或者 状态不是邀请中都报异常
if self.MsgType_InviteDoubleSpace ~= msgData.msgType or self.InviteStatus_Inviting ~= msgData.doubleSpace.inviteStatus then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
msgData.doubleSpace.inviteStatus = self.InviteStatus_Refuse
if true == isAgree then
--如果同意了,再检查下自己和别人是否数量已达上限
local myCount = skynet.server.personal:GetCurDetail( myPartnerId , "doubleSpaceCount" )
local otherCount = skynet.server.personal:GetCurDetail( otherPartnerId , "doubleSpaceCount" )
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
if myCount >= cfgSValue.coupleHouseLimit then --我的已经达到上限
s2cData.code = errorInfo.ErrorCode.MyDoubleSpaceNoCount
elseif otherCount >= cfgSValue.coupleHouseLimit then --对方已经达上线
s2cData.code = errorInfo.ErrorCode.OtherDoubleSpaceNoCount
else
msgData.doubleSpace.inviteStatus = self.InviteStatus_Agree
--创建双人空间
skynet.server.doubleSpace:Cretate( player , msgData.sendPartnerId )
end
end
--替换原数据
skynet.server.redis:zremrangebyscore( msgKey , msgId , msgId)
skynet.server.redis:zadd( msgKey , msgId , json:encode(msgData))
self:SendMsgToFriend( myPartnerId , otherPartnerId , msgData )
data.partnerId = otherPartnerId
data.msg = msgData
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerDoubleSpaceResponse")
s2cData.data = assert(pb.encode("S2CPartnerDoubleSpaceResponse", data))
end
--好友一键申请回应
function Partner:AllApplyRespond( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SPartnerAllApplyRespond", c2sData.data ))
local data = {}
data.infos = {}
local isAgree = c2sData.data.isAgree
if nil == isAgree then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
local myPlayerId = player.gameData.partner.id
local redisKey = string.format( redisKeyUrl.GameServerPartnerOtherApplyMyZSet , myPlayerId )
local applyPartnerIds = skynet.server.redis:zrange( redisKey , 0 , -1 ) --获取申请加我的人
redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
local myFriendCount = skynet.server.redis:zcard( redisKey ) --我的好友数量
if isAgree and myFriendCount + #applyPartnerIds > self.MaxFriendCount then
--如果我的好友数量+申请人的数量 大于最大值就不能加成功
s2cData.code = errorInfo.ErrorCode.MyFriendMaxLimit
else
for k, partnerId in pairs( applyPartnerIds ) do
local function DeleteApplyFriend()
--从该玩家的申请列表中删除我
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyApplyOtherZSet , partnerId )
skynet.server.redis:zrem( redisKey , myPlayerId )
--从别人加我的申请列表中删除该玩家
redisKey = string.format( redisKeyUrl.GameServerPartnerOtherApplyMyZSet , myPlayerId )
skynet.server.redis:zrem( redisKey , partnerId)
end
local isAdd = self:IsAddFriend( partnerId )
if isAdd and isAgree then
DeleteApplyFriend()
--如果能加该好友,并且同意,将该玩家加入到我的好友列表中
local t = skynet.GetTime()
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
skynet.server.redis:zadd( redisKey , t , partnerId )
--将我也加入到该玩家的好友列表中
redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , partnerId )
skynet.server.redis:zadd( redisKey , t , myPlayerId )
skynet.server.personal:AccDetail( partnerId ,"newFriendCount", 1)
skynet.server.levelTask:Modify( player , 73 , 1 )
skynet.server.taskListEvent:Modify( player , 73 , 1 )
log.debug(string.format("玩家 %d 好友 一键成功加入好友 %s", player.userId , partnerId ))
else
if isAgree then
if not isAdd then
s2cData.code = errorInfo.ErrorCode.OtherFriendMaxLimit
end
log.warning(string.format("玩家 %d 好友 一键好友数量已满,无法加入 %s %s", player.userId , myPlayerId , partnerId ))
else
DeleteApplyFriend()
end
end
end
--发送下最新的好友列表
local friendData = {}
friendData.infos = self:GetFriendList( player )
skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_PartnerMyList" , friendData )
end
data.infos = self:GetApplyList( player )
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_PartnerAllApplyRespond")
s2cData.data = assert(pb.encode("S2CPartnerAllApplyRespond", data))
end
--初始化消息
function Partner:InitMsg( myPartnerId , otherPartnerId , msgType , isShowMsg )
local lastMsgId = self:GetLastMsgID( myPartnerId , otherPartnerId )
local msgData = {}
msgData.msgId = lastMsgId
msgData.sendPartnerId = myPartnerId
msgData.updateTime = skynet.GetTime()
msgData.msgType = msgType
msgData.msgText = ""
msgData.gift = {}
msgData.doubleSpace = {}
msgData.isShowMsg = isShowMsg
return msgData,lastMsgId
end
--获取好友房间数据
function Partner:GetFriendHouseData( partnerId , houseDetail )
local data = {}
local curHouseId = houseDetail.curHouseId
local curSchemeId = houseDetail.curHouseData.curSchemeId --当前场景ID
--组装数据
data.partnerId = partnerId
data.houseId = curHouseId
data.houseIdList = houseDetail.houseList
data.furnitureInfo = self:GetCurSchemeFurniture( curHouseId , curSchemeId , houseDetail )
data.decorateInfo = self:GetCurSchemeDecorate( curHouseId , curSchemeId , houseDetail )
--当前已经解锁的区域ID
data.areaId = {}
for areaId, v in pairs( houseDetail.curHouseData.unlockAreaList ) do
if true == v then
table.insert( data.areaId , areaId )
end
end
return data
end
--获取当前房间当前方案所有花盆信息
function Partner:GetFlowerpot( curHouseId , curSchemeId, flowerpotInfo )
local furnitureInfo = nil
local isExist = false
for k, v in pairs( flowerpotInfo.nowPos ) do
--当前房间和当前方案下的花盆位置
if curHouseId == v.houseId and curSchemeId == v.schemeId then
furnitureInfo = {}
--将当前花盆的基本信息拷贝过来
for k, v in pairs( flowerpotInfo ) do
furnitureInfo[ k ] = v
end
furnitureInfo.furnitureInfo = nil --这个值不传客户端去
furnitureInfo.nowPos = {}
furnitureInfo.nowPos.x = v.x
furnitureInfo.nowPos.y = v.y
furnitureInfo.isPutInFurniture = v.isPutInFurniture or false
break
end
end
return furnitureInfo
end
--获取当前方案
function Partner:GetCurScheme( curSchemeId , houseDetail )
for k, v in pairs( houseDetail.curHouseData.scheme ) do
if curSchemeId == v.id then
return v
end
end
return nil
end
--获取当前方案下的家具和花盆
function Partner:GetCurSchemeFurniture( curHouseId , curSchemeId , houseDetail )
local furnitureInfo = {}
local curScheme = self:GetCurScheme( curSchemeId , houseDetail )
--将家具和花盆打包在一起发给客户端
for k, v in pairs( curScheme.furniture ) do
table.insert( furnitureInfo , v )
end
for k, v in pairs( houseDetail.flowerpot ) do
--从花盆列表中找到当前方案下的位置信息
local flowerpotInfo = self:GetFlowerpot( curHouseId , curSchemeId , v )
if flowerpotInfo then
table.insert( furnitureInfo , flowerpotInfo )
end
end
return furnitureInfo
end
--获取当前方案下的装修
function Partner:GetCurSchemeDecorate( curHouseId , curSchemeId , houseDetail )
local furnitureInfo = {}
for k1, v1 in pairs( houseDetail.curHouseData.scheme ) do
if curSchemeId == v1.id then
return v1.decorate
end
end
return furnitureInfo
end
--是否添加好友
function Partner:IsAddFriend( partnerId )
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , partnerId )
local addCount = skynet.server.redis:zcard( redisKey )
if addCount < self.MaxFriendCount then
return true
end
return false
end
--别人是否申请了我的好友
function Partner:IsOtherApply( myPartnerId , otherPartnerId )
local redisKey = string.format( redisKeyUrl.GameServerPartnerOtherApplyMyZSet , otherPartnerId )
local applyPartnerIds = skynet.server.redis:zrange( redisKey , 0 , -1 ) --获取申请加我的人
for k, partnerId in pairs( applyPartnerIds ) do
if myPartnerId == partnerId then
return true
end
end
return false
end
--是否已申请好友
function Partner:IsApply( player , addPlayerId )
local myPlayerId = player.gameData.partner.id
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyApplyOtherZSet , myPlayerId )
local isApply = skynet.server.redis:zrank( redisKey , addPlayerId )
if isApply then
return true
end
redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
isApply = skynet.server.redis:zrank( redisKey , addPlayerId )
if isApply then
return true
end
return false
end
--获取最新的申请列表
function Partner:GetApplyList( player )
local data = {}
local myPlayerId = player.gameData.partner.id
local redisKey = string.format( redisKeyUrl.GameServerPartnerOtherApplyMyZSet , myPlayerId )
local applyList= skynet.server.redis:zrevrange( redisKey , 0 , -1 , "withscores") --获取所有加我的人
applyList = redisKeyUrl:CovertTable( applyList )
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
local outOfTime = ( cfgSValue.friendApplyTimeLimit ) * 3600 --超时
for otherPartnerId , applyTime in pairs( applyList ) do
if skynet.GetTime() >= applyTime + outOfTime then
--skynet.server.redis:multi()
--从该玩家的申请列表中删除我
redisKey = string.format( redisKeyUrl.GameServerPartnerMyApplyOtherZSet , otherPartnerId )
skynet.server.redis:zrem( redisKey , myPlayerId )
--从别人加我的列表中删除玩家
redisKey = string.format( redisKeyUrl.GameServerPartnerOtherApplyMyZSet , myPlayerId )
skynet.server.redis:zrem( redisKey , otherPartnerId )
--skynet.server.redis:exec()
else
local basicInfo = skynet.server.personal:GetDetail( otherPartnerId )
if basicInfo then
table.insert( data , basicInfo )
end
end
end
return data
end
--获取消息的Key
function Partner:GetMsgKey( myPlayerId , otherPlayerId )
local key = ""
--谁的ID大就谁在前面
if myPlayerId > otherPlayerId then
key = string.format("%s-%s" , myPlayerId , otherPlayerId )
else
key = string.format("%s-%s" , otherPlayerId , myPlayerId )
end
local redisKey = string.format( redisKeyUrl.GameServerPartnerMsgRecordZSet , key )
return redisKey
end
--获取最新的消息ID
function Partner:GetLastMsgID( myPlayerId , otherPlayerId )
local key = ""
--谁的ID大就谁在前面
if myPlayerId > otherPlayerId then
key = string.format("%s-%s" , myPlayerId , otherPlayerId )
else
key = string.format("%s-%s" , otherPlayerId , myPlayerId )
end
local redisKey = string.format( redisKeyUrl.GameServerPartnerMsgID , key )
local msgId = skynet.server.redis:incr( redisKey )
return msgId,redisKey
end
--同步在线玩家数据
function Partner:SyncOnlineList()
self.onlineUserList = {}
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( nil , "SValue")
local redisKey = redisKeyUrl.GameServerPartnerAllUserZSet
local queryData = skynet.server.redis:zrevrange( redisKey , 0, self.MaxGetOnlineCount -1 )
--根据找到的数据获取详情
for k, v in pairs( queryData ) do
local curDetail = skynet.server.personal:GetDetail( v )
if curDetail and curDetail.partnerId and curDetail.level >= cfgSValue.partnerUnlockLvl and self:IsAddFriend( v ) then
table.insert( self.onlineUserList , curDetail )
end
end
end
--发送消息到好友
function Partner:SendMsgToFriend( sendPartnerId , toPartnerId , msgData )
local playerDetail = skynet.server.personal:GetDetail( toPartnerId ) --获取个人详情
if not playerDetail then
return
end
local tmpData = {}
tmpData.partnerId = sendPartnerId
tmpData.lastMsg = msgData
local cmd = "CMD_S2C_PartnerSendMsg"
local returnValue = skynet.server.playerCenter:IsSameServer( toPartnerId )
if nil == returnValue then
return
elseif true ==returnValue then
--在同一服务器
skynet.server.gameServer:SendMsgToUser( playerDetail.userId , cmd , tmpData )
local player = skynet.server.playerCenter:GetPlayer( playerDetail.userId )
if player then
--发送红点信息
skynet.server.msgTips:Add( player , 53 )
end
elseif false ==returnValue then
--不在同一服务器,将聊天消息推到玩家所在的游戏服
local sendData = {}
sendData.userId = playerDetail.userId
sendData.cmd = cmd
sendData.data = tmpData
local serverCmd = skynet.server.gameServer.GameToGame_NetMsg
skynet.server.gameServer:SendMsgToServer( playerDetail.gameServerId , serverCmd, sendData )
end
end
--发送消息到好友
function Partner:SendMsgTips( toPartnerId , tipsId , isSend )
local playerDetail = skynet.server.personal:GetDetail( toPartnerId ) --获取个人详情
if not playerDetail then
return
end
local returnValue = skynet.server.playerCenter:IsSameServer( toPartnerId )
if nil == returnValue then
return
elseif true ==returnValue then
local player = skynet.server.playerCenter:GetPlayer( playerDetail.userId )
if player then
--发送红点信息
if isSend then
skynet.server.msgTips:Add( player , tipsId )
else
skynet.server.msgTips:ReduceAll( player , tipsId )
end
end
elseif false ==returnValue then
--不在同一服务器,将聊天消息推到玩家所在的游戏服
local sendData = {}
sendData.userId = playerDetail.userId
sendData.cmd = "CMD_Temp_TipsMsg"
sendData.isSend = isSend
sendData.data = tipsId
local serverCmd = skynet.server.gameServer.GameToGame_NetMsg
skynet.server.gameServer:SendMsgToServer( playerDetail.gameServerId , serverCmd, sendData )
end
end
--取消Tips消息
function Partner:ReduceAllMsgTips( toPartnerId , tipsId )
local playerDetail = skynet.server.personal:GetDetail( toPartnerId ) --获取个人详情
if not playerDetail then
return
end
local returnValue = skynet.server.playerCenter:IsSameServer( toPartnerId )
if nil == returnValue then
return
elseif true ==returnValue then
local player = skynet.server.playerCenter:GetPlayer( playerDetail.userId )
if player then
--发送红点信息
skynet.server.msgTips:ReduceAll( player , tipsId )
end
elseif false ==returnValue then
--不在同一服务器,将聊天消息推到玩家所在的游戏服
local sendData = {}
sendData.userId = playerDetail.userId
sendData.cmd = "CMD_Temp_TipsMsg"
sendData.isSend = false
sendData.data = tipsId
local serverCmd = skynet.server.gameServer.GameToGame_NetMsg
skynet.server.gameServer:SendMsgToServer( playerDetail.gameServerId , serverCmd, sendData )
end
end
--判断赠送的道具是否合规
function Partner:CanSendGoods(player , partnerId , goodsType , goodsId)
local basicInfo = skynet.server.personal:GetDetail(partnerId)
local cfgCuisineMenu = skynet.server.gameConfig:GetPlayerAllCfg( player , "CuisineMenu")
local cfgCuisineMaterial = skynet.server.gameConfig:GetPlayerAllCfg( player , "CuisineMaterial")
local cfgFishType = skynet.server.gameConfig:GetPlayerAllCfg( player , "FishType")
if dataType.GoodsType_CuisineMenu == goodsType then
--如果赠送的道具是料理店相关的 判断该玩家是否可以接受
local sendCuisineLevel = cfgCuisineMenu[goodsId].menuLevel --解锁菜的菜单等级
local cuisineLevel = basicInfo.cuisineLevel --该玩家的菜单等级
local unlockCondition = skynet.server.map:GetUnlockCondition( player , 6 ) --判断玩家等级是否达到料理店解锁等级
--如果不满足相关条件 则不可赠送
if cuisineLevel and unlockCondition and basicInfo.level >= unlockCondition[ 2 ] and sendCuisineLevel <= cuisineLevel then
return true
else
return false
end
elseif dataType.GoodsType_CuisineMaterial == goodsType then
--如果赠送的道具是料理店相关的 判断该玩家是否可以接受
local materialLevel = cfgCuisineMaterial[goodsId].menuLevel --解锁材料的菜单等级
local cuisineLevel = basicInfo.cuisineLevel --该玩家的菜单等级
local unlockCondition = skynet.server.map:GetUnlockCondition( player , 6 ) --判断玩家等级是否达到料理店解锁等级
--如果不满足相关条件 则不可赠送
if cuisineLevel and unlockCondition and basicInfo.level >= unlockCondition[ 2 ] and materialLevel <= cuisineLevel then
return true
else
return false
end
elseif dataType.GoodsType_Fish == goodsType then
--如果赠送的道具是鱼 判断该玩家是否可以接受
local sendFishLevel = cfgFishType[goodsId].fishType --该鱼的等级
local fishLevel = basicInfo.fishLevel --该玩家可获取鱼的最高等级
local unlockCondition = skynet.server.map:GetUnlockCondition( player , 5 ) --判断玩家等级是否达到渔店解锁等级
--如果不满足相关条件 则不可赠送
if fishLevel and unlockCondition and basicInfo.level >= unlockCondition[ 2 ] and sendFishLevel <= fishLevel then
return true
else
return false
end
else
--其他的物品不做限制
return true
end
end
--清理过期消息
function Partner:ClearOutOfTimeMsg( myPartnerId , otherPartnerId , outOfTime )
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
local msgList = skynet.server.redis:zrange( msgKey , 0 , -1 ) --将我与该好友的消息全部取出
local msgData = nil
local startPos,endPos = 0,0 --过期消息的开始位置和结束位置
for k, v in pairs( msgList ) do
msgData = json:decode( v )
--只清理文档过期消息
if self.MsgType_Gift ~= tonumber( msgData.msgType ) and skynet.GetTime() >= tonumber( msgData.updateTime ) + outOfTime then
if 0 == startPos then
--记录开始和结束位置
startPos = msgData.msgId
endPos = msgData.msgId
elseif 0 ~= startPos then
--记录结束位置
endPos = msgData.msgId
end
--双人空间消息如果还是邀请状态并且过期了就改为过期状态
if self.MsgType_InviteDoubleSpace == tonumber( msgData.msgType ) and self.InviteStatus_Inviting == msgData.doubleSpace.inviteStatus then
local diffTime = skynet.GetTime() - msgData.updateTime
if diffTime > dataType.OneDaySec then
msgData.doubleSpace.inviteStatus = self.InviteStatus_OutOfTime
self:SetMsgData( myPartnerId , otherPartnerId , msgData.msgId , msgData )
end
end
end
end
if 0 ~= startPos then
--删除所有过期数据
skynet.server.redis:zremrangebyscore( msgKey , startPos , endPos)
end
end
--[[
--清理过期消息
function Partner:ClearOutOfTimeMsg( player , myPlayerId )
--清空我与其它玩家的过期消息
local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue")
local outOfTime = ( cfgSValue.friendChatSave ) * 3600 --好友聊天内容有效期
--获取我所有的好友
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPlayerId )
local friendList = skynet.server.redis:zrange( redisKey , 0 , -1 )
for k, otherPlayerId in pairs( friendList ) do
local msgKey = self:GetMsgKey( myPlayerId , otherPlayerId )
local msgList = skynet.server.redis:zrange( msgKey , 0 , -1 ) --将我与该好友的消息全部取出
local tmpMsg = nil
local startPos,endPos = 0,0 --过期消息的开始位置和结束位置
for k, v in pairs( msgList ) do
tmpMsg = json:decode( v )
--只清理文档过期消息
if self.MsgType_Gift ~= tonumber(tmpMsg.msgType) and os.time() >= tonumber(tmpMsg.updateTime) + outOfTime then
if 0 == startPos then
--记录开始和结束位置
startPos = tmpMsg.msgId
endPos = tmpMsg.msgId
elseif 0 ~= startPos then
--记录结束位置
endPos = tmpMsg.msgId
end
end
end
if 0 ~= startPos then
--删除所有过期数据
skynet.server.redis:zremrangebyscore( msgKey , startPos , endPos)
end
end
end
]]
--根据类型获取消息数据(只获取没有过期的消息)
function Partner:GetMsgDataForType( myParentId , otherParentId , msgType )
local msgKey = self:GetMsgKey( myParentId , otherParentId )
local msgList = skynet.server.redis:zrange( msgKey , 0 , -1 ) --将我与该好友的消息全部取出
local tmpMsg = nil
for k, v in pairs( msgList ) do
tmpMsg = json:decode( v )
--只有正在邀请的才会获取
if msgType == tonumber( tmpMsg.msgType ) and self.InviteStatus_Inviting == tmpMsg.doubleSpace.inviteStatus then
return tmpMsg
end
end
return nil
end
--获取消息数据
function Partner:GetMsgData( myPartnerId , otherPartnerId , msgId )
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
local msgData = skynet.server.redis:zrangebyscore( msgKey , msgId , msgId)
msgData = json:decode( msgData[1] )
return msgData
end
--设置消息数据
function Partner:SetMsgData( myPartnerId , otherPartnerId , msgId , newMsgData )
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
skynet.server.redis:zremrangebyscore( msgKey , msgId , msgId)
skynet.server.redis:zadd( msgKey , msgId , json:encode( newMsgData ))
end
--好友双人空间购买房屋邀请
function Partner:DoubleSpaceBuyInvite( player , otherPartnerId,msgType,houseId,schemeId )
if "" == otherPartnerId then
return
end
local t1 = skynet.GetTime()
local myPartnerId = player.gameData.partner.id
local msgData = self:GetMsgDataForTypeAndId( myPartnerId , otherPartnerId , msgType ,houseId ,schemeId)
if msgData and ( t1 - msgData.updateTime ) <= dataType.OneDaySec then --如果小于1天就不允许再发送消息
log.info("双人空间购买房间邀请 重复申请")
return --已经申请
end
--走到这里,表示消息已经过期,如果还是邀请状态就改为过期状态
if msgData and self.InviteStatus_Inviting == msgData.doubleSpace.inviteStatus then
msgData.doubleSpace.inviteStatus = self.InviteStatus_OutOfTime
self:SetMsgData( myPartnerId , otherPartnerId , msgData.msgId , msgData )
end
--发送邀请好友消息
local msgKey = self:GetMsgKey( myPartnerId , otherPartnerId )
local msgData,lastMsgId = self:InitMsg( myPartnerId , otherPartnerId , msgType , true )
msgData.doubleSpace.inviteStatus = self.InviteStatus_Inviting
msgData.doubleSpace.houseID = houseId
msgData.doubleSpace.schemeID = schemeId
skynet.server.redis:zadd( msgKey , lastMsgId , json:encode(msgData))
--好友在线,也将该消息给他
self:SendMsgToFriend( myPartnerId , otherPartnerId , msgData )
--推送给自己
self:SendMsgToFriend( otherPartnerId , myPartnerId , msgData )
end
--好友双人空间购买房屋回应
function Partner:DoubleSpaceBuyInviteRespond( player , otherParentId,msgType,houseId,schemeId )
local myPartnerId = player.gameData.partner.id
local msgKey = self:GetMsgKey( myPartnerId , otherParentId )
local msgList = skynet.server.redis:zrange( msgKey , 0 , -1 ) --将我与该好友的消息全部取出
local tmpMsg = nil
for k, v in pairs( msgList ) do
tmpMsg = json:decode( v )
--只有正在邀请的才会获取
if msgType == tonumber( tmpMsg.msgType )
and self.InviteStatus_Inviting == tmpMsg.doubleSpace.inviteStatus
and tonumber(tmpMsg.doubleSpace.houseID) == houseId
and tonumber(tmpMsg.doubleSpace.schemeID) == schemeId then
local msgId = tmpMsg.msgId
--设置已同意
tmpMsg.doubleSpace.inviteStatus=self.InviteStatus_Agree
--替换原数据
skynet.server.redis:zremrangebyscore( msgKey , msgId , msgId)
skynet.server.redis:zadd( msgKey , msgId , json:encode(tmpMsg))
--好友在线,也将该消息给他
self:SendMsgToFriend( myPartnerId , otherParentId , tmpMsg )
--推送给自己
self:SendMsgToFriend( otherParentId , myPartnerId , tmpMsg )
end
end
end
--根据类型获取消息数据(只获取没有过期的消息)
function Partner:GetMsgDataForTypeAndId( myParentId , otherParentId , msgType , houseId , schemeId )
local msgKey = self:GetMsgKey( myParentId , otherParentId )
local msgList = skynet.server.redis:zrange( msgKey , 0 , -1 ) --将我与该好友的消息全部取出
local tmpMsg = nil
for k, v in pairs( msgList ) do
tmpMsg = json:decode( v )
--只有正在邀请的才会获取
if msgType == tonumber( tmpMsg.msgType )
and tmpMsg.sendPartnerId == myParentId
and self.InviteStatus_Inviting == tmpMsg.doubleSpace.inviteStatus
and tonumber(tmpMsg.doubleSpace.houseID) == houseId
and tonumber(tmpMsg.doubleSpace.schemeID) == schemeId then
return tmpMsg
end
end
return nil
end
skynet.server.partner = Partner
return Partner