HomeServer/Server/AllServer/GameServer/Group/Group.lua

540 lines
20 KiB
Lua
Raw 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 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