HomeServer/Server/AllServer/GameServer/Partner.lua

1530 lines
65 KiB
Lua
Raw Permalink Normal View History

2024-11-20 15:41:09 +08:00
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