540 lines
20 KiB
Lua
540 lines
20 KiB
Lua
local skynet = require "skynet"
|
||
local oo = require "Class"
|
||
local pb = require "pb"
|
||
local log = require "Log"
|
||
local json =require "json"
|
||
local errorInfo = require "ErrorInfo"
|
||
local dataType = require "DataType"
|
||
local redisKeyUrl = require "RedisKeyUrl"
|
||
local curServerId = tonumber(skynet.getenv "serverId")
|
||
|
||
local Group = oo.class()
|
||
Group.MaxQueryCount = 4 --最大查询数量
|
||
Group.MaxMapCount = 12 --最大地图数量
|
||
|
||
Group.RankStatus_Acc = 1 --累加状态
|
||
Group.RankStatus_Calc = 2 --结算状态
|
||
|
||
Group.PutType_House = 1 --放房间
|
||
Group.PutType_Bag = 2 --放背包
|
||
Group.PutType_Move = 3 --移动
|
||
Group.PutType_Operate = 4 --原地操作
|
||
|
||
Group.ArchType_House = 1 --房子
|
||
Group.ArchType_Garden = 2 --花园景观
|
||
|
||
Group.MaxMsgRecordToClient = 50 --发送给客户端最大的消息记录数量
|
||
|
||
Group.IdentityType_Leader = 1 --园长
|
||
Group.IdentityType_ViceLeader = 2 --副园长
|
||
Group.IdentityType_Member = 3 --成员
|
||
|
||
Group.ArchType_Park = 1 --公园
|
||
Group.ArchType_Market = 2 --集市
|
||
Group.ArchType_Library = 3 --图书馆
|
||
Group.ArchType_Dessert = 4 --甜品店
|
||
Group.ArchType_Road = 5 --路面
|
||
|
||
Group.ContributeType_Wood = 1 --木材
|
||
Group.ContributeType_Cement = 2 --水泥
|
||
Group.ContributeType_Rebar = 3 --钢筋
|
||
|
||
Group.GroupOpType_Create = 1 --创建
|
||
Group.GroupOpType_Update = 2 --更新
|
||
Group.GroupOpType_Dissolve = 3 --解散
|
||
|
||
Group.onlineGroupList = {}
|
||
|
||
--初始建筑
|
||
Group.InitArchs =
|
||
{
|
||
{ id = 62 , nowPos = { x = 0, y = 0 } , rotateType = 0 , isPutInFurniture = false , clickType = 1 },
|
||
{ id = 56 , nowPos = { x = -5.705, y = -3.18999958 } , rotateType = 0 , isPutInFurniture = false , clickType = 1 },
|
||
{ id = 57 , nowPos = { x = -3.36000013, y = -1.38999963 } , rotateType = 0 , isPutInFurniture = false , clickType = 1 }
|
||
}
|
||
|
||
--初始化地块
|
||
function Group:InitScenePlot( player , groupId , plotId , partnerId )
|
||
local myPartnerId = player.gameData.partner.id
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupPrivatePlot, groupId )
|
||
local plotInfo =
|
||
{
|
||
plotId = plotId ,
|
||
partnerId = partnerId ,
|
||
archs = skynet.server.common:DeepCopy( self.InitArchs )
|
||
}
|
||
|
||
--如果已经初始化了庭院,就用初始化后的庭院数据,只有自己才会同步 ,有可能是群主审核通过,player是群主的,后面考虑优化
|
||
local curHouse = player.gameData.house[ 11 ]
|
||
if myPartnerId == partnerId and curHouse and #curHouse.groupGarden.archs > 0 then
|
||
plotInfo.archs = curHouse.groupGarden.archs
|
||
end
|
||
|
||
skynet.server.redis:lset( redisKey , plotId - 1 , json:encode( plotInfo ))
|
||
end
|
||
|
||
--重置土地
|
||
function Group:ResetScenePlot( groupId , plotId )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupPrivatePlot, groupId )
|
||
local plotInfo = {}
|
||
plotInfo.plotId = plotId
|
||
plotInfo.partnerId = ""
|
||
plotInfo.archs = {}
|
||
skynet.server.redis:lset( redisKey , plotId - 1 , json:encode(plotInfo))
|
||
end
|
||
|
||
--是否存在家园
|
||
function Group:IsExistGroup( groupId )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
if not skynet.server.redis:exists( redisKey) then
|
||
return false
|
||
end
|
||
return true
|
||
end
|
||
|
||
--是否为园长
|
||
function Group:IsLeader( myPartnerId )
|
||
local curDetail = skynet.server.personal:GetDetail( myPartnerId )
|
||
if self.IdentityType_Leader == curDetail.groupIdentityType then
|
||
return true
|
||
else
|
||
return false
|
||
end
|
||
end
|
||
|
||
--是否为管理员
|
||
function Group:IsManage( myPartnerId )
|
||
local curDetail = skynet.server.personal:GetDetail( myPartnerId )
|
||
if self.IdentityType_Leader == curDetail.groupIdentityType or self.IdentityType_ViceLeader == curDetail.groupIdentityType then
|
||
return true
|
||
else
|
||
return false
|
||
end
|
||
end
|
||
|
||
--获取家园ID
|
||
function Group:GetGroupID( player )
|
||
local myPartnerId = player.gameData.partner.id
|
||
local curDetail = skynet.server.personal:GetDetail( myPartnerId )
|
||
if not curDetail then
|
||
return ""
|
||
end
|
||
return curDetail.groupId or ""
|
||
end
|
||
|
||
--获取家园
|
||
function Group:GetGroup( groupId )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
if not skynet.server.redis:exists( redisKey) then
|
||
return nil
|
||
end
|
||
|
||
local basicInfo = skynet.server.redis:hgetall(redisKey)
|
||
basicInfo = redisKeyUrl:CovertTable(basicInfo)
|
||
return basicInfo
|
||
end
|
||
|
||
--获取当前家园所有信息
|
||
function Group:GetGroupAllInfo( player )
|
||
local curPartner = player.gameData.partner
|
||
local partnerId = curPartner.id
|
||
local curDetail = skynet.server.personal:GetDetail( partnerId )
|
||
local groupId = curDetail.groupId
|
||
local groupInfo = {}
|
||
local curGroupInfo = self:GetGroup( groupId )
|
||
if curGroupInfo then
|
||
groupInfo = {}
|
||
groupInfo.id = curGroupInfo.id
|
||
groupInfo.name = curGroupInfo.name
|
||
groupInfo.level = curGroupInfo.communityLevel
|
||
groupInfo.exp = curGroupInfo.communityExp
|
||
groupInfo.declaration = curGroupInfo.declaration
|
||
groupInfo.badgeId = curGroupInfo.badgeId
|
||
groupInfo.myTotalScore = curDetail.groupContributeScore
|
||
groupInfo.signInType = curDetail.groupSignInType
|
||
groupInfo.joinType = curGroupInfo.joinType
|
||
groupInfo.minJoinLevel = curGroupInfo.minJoinLevel
|
||
groupInfo.member = self:GetMember( groupId , partnerId )
|
||
end
|
||
return groupInfo
|
||
end
|
||
|
||
--设置家园信息
|
||
function Group:SetGroupInfo( groupId , ... )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
skynet.server.redis:hmset( redisKey , ... )
|
||
end
|
||
|
||
--获取家园信息
|
||
function Group:GetGroupInfo( groupId , ... )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
return skynet.server.redis:hmget( redisKey , ... )
|
||
end
|
||
|
||
--累加家园信息数量
|
||
function Group:AccGroupInfo( groupId , param , count )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
skynet.server.redis:hincrby( redisKey , param , count )
|
||
end
|
||
|
||
function Group:GetMember( groupId , myPartnerId )
|
||
local member = {}
|
||
|
||
--获取所有的分数排行
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupContributionScoreZSet, groupId )
|
||
local memeberScore = skynet.server.redis:zrange( redisKey , 0 , -1 , "withscores")
|
||
memeberScore = redisKeyUrl:CovertTable(memeberScore)
|
||
|
||
--获取我的好友列表
|
||
local redisKey = string.format( redisKeyUrl.GameServerPartnerMyFriendZSet , myPartnerId )
|
||
local friendList = skynet.server.redis:zrange( redisKey , 0 , -1 )
|
||
|
||
--是否为好友
|
||
local function IsFriend( otherPartnerId )
|
||
for k, v in pairs( friendList ) do
|
||
if otherPartnerId == v then
|
||
return true
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
for partnerId, v in pairs( memeberScore ) do
|
||
--获取个人信息
|
||
local detail = skynet.server.personal:GetDetail( partnerId )
|
||
local medals = {}
|
||
table.insert( medals , detail.medals1)
|
||
table.insert( medals , detail.medals2)
|
||
table.insert( medals , detail.medals3)
|
||
|
||
--衣服数据
|
||
local clothesData = {}
|
||
table.insert( clothesData , detail.clothesData1 or 2 )
|
||
table.insert( clothesData , detail.clothesData2 or 3 )
|
||
table.insert( clothesData , detail.clothesData3 or 10 )
|
||
table.insert( clothesData , detail.clothesData4 or 14 )
|
||
table.insert( clothesData , detail.clothesData5 or 17 )
|
||
table.insert( clothesData , detail.clothesData6 or 16 )
|
||
table.insert( clothesData , detail.clothesData7 or 0 )
|
||
table.insert( clothesData , detail.clothesData8 or 0 )
|
||
table.insert( clothesData , detail.clothesData9 or 0 )
|
||
table.insert( clothesData , detail.clothesData10 or 0 )
|
||
|
||
--肤色
|
||
local colorData = {}
|
||
table.insert( colorData , detail.colorData1 or 1 )
|
||
table.insert( colorData , detail.colorData2 or 6 )
|
||
table.insert( colorData , detail.colorData3 or 26 )
|
||
|
||
--自定义头像处理
|
||
if detail.birthdayShow==false then
|
||
detail.birthdayDate=""
|
||
end
|
||
if detail.headId ==0 and detail.DIYHeadInfo ~=nil then
|
||
table.insert( member , {
|
||
partnerId = detail.partnerId ,
|
||
nickName = detail.nickName ,
|
||
level = detail.level ,
|
||
headId = detail.headId ,
|
||
headFrameId = detail.headFrameId ,
|
||
identityType = detail.groupIdentityType ,
|
||
contributionScore = v ,
|
||
joinTime = detail.groupJoinTime ,
|
||
isFriend = IsFriend( partnerId ) ,
|
||
title1 = detail.title1,
|
||
title2 = detail.title2,
|
||
medals = medals ,
|
||
clothesData = clothesData ,
|
||
colorData = colorData,
|
||
DIYHeadInfo = detail.DIYHeadInfo,
|
||
birthdayDate=detail.birthdayDate
|
||
})
|
||
else
|
||
table.insert( member , {
|
||
partnerId = detail.partnerId ,
|
||
nickName = detail.nickName ,
|
||
level = detail.level ,
|
||
headId = detail.headId ,
|
||
headFrameId = detail.headFrameId ,
|
||
identityType = detail.groupIdentityType ,
|
||
contributionScore = v ,
|
||
joinTime = detail.groupJoinTime ,
|
||
isFriend = IsFriend( partnerId ) ,
|
||
title1 = detail.title1,
|
||
title2 = detail.title2,
|
||
medals = medals ,
|
||
clothesData = clothesData ,
|
||
colorData = colorData,
|
||
birthdayDate=detail.birthdayDate
|
||
})
|
||
end
|
||
|
||
end
|
||
return member
|
||
end
|
||
|
||
--计算排行榜状态和时间
|
||
function Group:CalcRankStatusAndTime()
|
||
local curDay = skynet.server.common:GetDayInWeek()
|
||
local curTime = skynet.server.common:GetTableTime()
|
||
if 7 == curDay and curTime.hour >= 20 then --周天晚上8点进行结算
|
||
local nexRankStatusTime = skynet.server.common:GetAfterSomeDayTime(1)
|
||
return self.RankStatus_Calc,nexRankStatusTime
|
||
else
|
||
local nexRankStatusTime = skynet.server.common:GetAfterSomeDayTime( 7 - curDay , 20 )
|
||
return self.RankStatus_Acc,nexRankStatusTime
|
||
end
|
||
end
|
||
|
||
--计算福利结算时间
|
||
function Group:CalcContributeRewardTime()
|
||
local curDay = skynet.server.common:GetDayInWeek()
|
||
local curTime = skynet.server.common:GetTableTime()
|
||
if 7 == curDay and curTime.hour >= 12 then --周天中午12点进行结算
|
||
return skynet.server.common:GetAfterSomeDayTime( 7 , 12 )
|
||
else
|
||
return skynet.server.common:GetAfterSomeDayTime( 7 - curDay , 12 )
|
||
end
|
||
end
|
||
|
||
--是否有效地块
|
||
function Group:IsVaildMapId( mapId )
|
||
if mapId < 1 or mapId > self.MaxMapCount then
|
||
return false
|
||
else
|
||
return true
|
||
end
|
||
end
|
||
|
||
--家园合法参数检测
|
||
function Group:IsVaildParam( key , value )
|
||
if nil == key or nil == value then
|
||
return false
|
||
end
|
||
|
||
if "groupId" == key and 10 == #value then
|
||
return true
|
||
elseif "partnerId" == key and 12 == #value then
|
||
return true
|
||
elseif "groupName" == key and #value >= 1 and #value <= 30 then
|
||
return true
|
||
elseif "declaration" == key and #value <= 150 then
|
||
return true
|
||
elseif "badgeId" == key then --and tonumber(value) > 0 and tonumber(value) < 10 then
|
||
return true
|
||
elseif "joinType" == key and tonumber(value) >= self.JoinType_Freedom and tonumber(value) <= self.JoinType_Audit then
|
||
return true
|
||
elseif "minJoinLevel" == key and tonumber(value) > 0 and tonumber(value) < 100 then
|
||
return true
|
||
elseif "identityType" == key and tonumber(value) >= self.IdentityType_Leader and tonumber(value) <= self.IdentityType_Member then
|
||
return true
|
||
elseif "plotId" == key and tonumber(value) > 0 and tonumber(value) <= self.MaxMapCount then
|
||
return true
|
||
elseif "msgText" == key and #value >= 1 and #value < 90 then
|
||
return true
|
||
elseif "archType" == key and value >= self.ArchType_Park and value <= self.ArchType_Road then
|
||
return true
|
||
elseif "contributeType" == key and value >= self.ContributeType_Wood and value <= self.ContributeType_Rebar then
|
||
return true
|
||
end
|
||
log.warning("错误参数 ",key,value)
|
||
return false
|
||
end
|
||
|
||
--获取消息ID
|
||
function Group:GetLastMsgID( groupId )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupMsgID , groupId )
|
||
local msgId = skynet.server.redis:incr( redisKey )
|
||
return msgId,redisKey
|
||
end
|
||
|
||
--将群信息同步到其它游戏服
|
||
function Group:SyncOnlineGroupInfo( groupId , groupOpType , isSync )
|
||
if self.GroupOpType_Create == groupOpType then
|
||
--同步本地
|
||
local curInfo = self:GetGroup( groupId )
|
||
if curInfo then
|
||
table.insert( self.onlineGroupList , curInfo)
|
||
end
|
||
elseif self.GroupOpType_Update == groupOpType then
|
||
for k, v in pairs( self.onlineGroupList ) do
|
||
if groupId == v.id then
|
||
local curInfo = self:GetGroup( groupId )
|
||
if curInfo then
|
||
self.onlineGroupList[ k ] = curInfo
|
||
end
|
||
break
|
||
end
|
||
end
|
||
elseif self.GroupOpType_Dissolve == groupOpType then
|
||
--同步本地
|
||
for k, v in pairs( self.onlineGroupList ) do
|
||
if groupId == v.id then
|
||
self.onlineGroupList[ k ] = nil
|
||
break
|
||
end
|
||
end
|
||
end
|
||
|
||
if isSync then
|
||
--同步其它服
|
||
local c2sData = {}
|
||
c2sData.groupOpType = groupOpType
|
||
c2sData.groupId = groupId
|
||
|
||
local minGameId = skynet.server.clusterServer.gameServerMinID
|
||
local maxGameId = skynet.server.clusterServer.gameServerMaxID
|
||
local serverCmd = skynet.server.gameServer.GameToGame_SyncOnlineGroup
|
||
for k, v in pairs( skynet.server.gameServer.clusterInfo ) do
|
||
if curServerId ~= v.serverId and v.serverId >= minGameId and v.serverId <= maxGameId and skynet.server.clusterServer.Status_Running == v.status then
|
||
skynet.server.gameServer:SendMsgToServer( v.serverId , serverCmd, c2sData )
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
--是否为房屋ID
|
||
function Group:IsHouseID( player , houseId )
|
||
local cfgCurGarden = skynet.server.gameConfig:GetPlayerCurCfg( player, "Garden" , houseId )
|
||
if cfgCurGarden and 4 == cfgCurGarden.gardenType then
|
||
return true
|
||
end
|
||
return false
|
||
end
|
||
|
||
--排行榜排序
|
||
function Group:SortRank( rankList )
|
||
local sortRank = {}
|
||
for k, v in pairs( rankList ) do
|
||
table.insert( sortRank , { partnerId = k , score = v })
|
||
end
|
||
table.sort( sortRank , function (a , b)
|
||
return a.score > b.score
|
||
end)
|
||
return sortRank
|
||
end
|
||
|
||
--同步家园庭院数据
|
||
function Group:SyncGarden( player , groupId , plotId, allArchs )
|
||
if self:IsVaildParam( "groupId" , groupId ) then
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupPrivatePlot, groupId )
|
||
local plotInfo = skynet.server.redis:lindex( redisKey , plotId - 1 ) --获取家园信息
|
||
plotInfo = json:decode(plotInfo)
|
||
plotInfo.archs = allArchs
|
||
skynet.server.redis:lset( redisKey , plotId - 1 , json:encode(plotInfo))
|
||
end
|
||
end
|
||
|
||
--记录单个向往一日家园任务数据
|
||
function Group:SaveDreamLifeTask( player , taskId , finishTime )
|
||
local groupId = self:GetGroupID( player )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupDreamLifeTaskList , groupId)
|
||
--确保有家园 再保存任务数据
|
||
if self:GetGroup( groupId ) then
|
||
local taskInfo = {}
|
||
taskInfo.taskId = taskId
|
||
taskInfo.partnerId = player.gameData.partner.id
|
||
taskInfo.finishTime = finishTime
|
||
taskInfo.isCheck = 0 --该状态记录是否被检查过 0 否 1 是
|
||
skynet.server.redis:lpush( redisKey , json:encode(taskInfo) )
|
||
local redisKey1 = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
skynet.server.redis:hmset(redisKey1 , "dailyTaskTime" , skynet.GetTime() ) --dailyTaskTime 日常任务记录时间 ,后面可能有周任务记录时间
|
||
end
|
||
end
|
||
|
||
--检查家园中是否有完成的向往一日家园任务
|
||
function Group:CheckDreamLifeTask( player )
|
||
local groupId = self:GetGroupID( player )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupDreamLifeTaskList , groupId)
|
||
--确保有家园和对应任务数据
|
||
if self:GetGroup( groupId ) and skynet.server.redis:exists(redisKey) then
|
||
local allTaskInfo = skynet.server.redis:lrange(redisKey , 0 , -1)
|
||
for k , v in pairs(allTaskInfo) do
|
||
local taskInfo = json:decode( v )
|
||
--检查任务是否已经完成
|
||
if skynet.GetTime() >= taskInfo.finishTime and taskInfo.isCheck == 0 then
|
||
--修改对应任务数据
|
||
self:UpdateDreamLifeTask(player , dataType.GroupTaskType_DreamLife , taskInfo.taskId)
|
||
taskInfo.isCheck = 1
|
||
skynet.server.redis:lset(redisKey , k-1 , json:encode(taskInfo))
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
--获取玩家对应任务是否完成
|
||
function Group:GetDreamLifeTaskState(player , taskId)
|
||
local partnerId = player.gameData.partner.id
|
||
local groupId = self:GetGroupID( player )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupDreamLifeTaskList , groupId)
|
||
--确保有家园和对应任务数据
|
||
if self:GetGroup( groupId ) and skynet.server.redis:exists(redisKey) then
|
||
local allTaskInfo = skynet.server.redis:lrange(redisKey , 0 , -1)
|
||
for k , v in pairs(allTaskInfo) do
|
||
local taskInfo = json:decode( v )
|
||
if taskInfo.partnerId == partnerId and taskInfo.taskId == taskId then
|
||
if taskInfo.isCheck == 1 then
|
||
return true
|
||
else
|
||
return false
|
||
end
|
||
end
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
--更新任务
|
||
function Group:UpdateDreamLifeTask( player , taskType , taskId )
|
||
local groupId = self:GetGroupID( player )
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
--拼接对应的key 例如 DreamLifeTask_5
|
||
local stringKey = taskType .. "_" .. taskId
|
||
skynet.server.redis:hincrby( redisKey , stringKey , 1)
|
||
end
|
||
|
||
--获取任务次数
|
||
function Group:GetTaskCount( player , taskType , taskId )
|
||
local t = skynet.GetTime()
|
||
local groupId = self:GetGroupID( player )
|
||
local curGroup = self:GetGroup( groupId )
|
||
if not curGroup then
|
||
log.warning("家园 获取任务次数 未找到家园信息 ", player.gameData.partner.id ,groupId )
|
||
return 0
|
||
end
|
||
|
||
local redisKey = string.format( redisKeyUrl.GameServerGroupInfoHash , groupId )
|
||
local stringKey = taskType .. "_" .. taskId
|
||
local dailyTaskTime = curGroup.dailyTaskTime
|
||
if dailyTaskTime and not skynet.server.common:IsSameDay( t , dailyTaskTime ) then
|
||
--新的一天,初始化日常任务的数据
|
||
skynet.server.redis:hmset(redisKey , "dailyTaskTime" , t )
|
||
if taskType == dataType.GroupTaskType_DreamLife then
|
||
local cfgDreamLifeTask = skynet.server.gameConfig:GetPlayerAllCfg(player , taskType)
|
||
for k , v in pairs(cfgDreamLifeTask) do
|
||
if v.taskType == 2 then
|
||
local key = taskType .. "_" .. v.id
|
||
skynet.server.redis:hmset(redisKey , key , 0 )
|
||
end
|
||
end
|
||
end
|
||
--移除前一天的任务数据
|
||
local redisKey1 = string.format( redisKeyUrl.GameServerGroupDreamLifeTaskList , groupId)
|
||
skynet.server.redis:del(redisKey1)
|
||
curGroup[stringKey] = 0
|
||
end
|
||
|
||
return curGroup[stringKey] or 0
|
||
end
|
||
|
||
--清理所有的提示信息
|
||
function Group:ResetAllMsgTips( partnerId )
|
||
skynet.server.partner:SendMsgTips( partnerId , 38 , false )
|
||
skynet.server.partner:SendMsgTips( partnerId , 39 , false )
|
||
skynet.server.partner:SendMsgTips( partnerId , 60 , false )
|
||
skynet.server.partner:SendMsgTips( partnerId , 65 , false )
|
||
skynet.server.partner:SendMsgTips( partnerId , 66 , false )
|
||
end
|
||
|
||
skynet.server.group = Group
|
||
return Group |