local skynet = require "skynet" local oo = require "Class" local log = require "Log" local pb = require "pb" local dataType = require "DataType" local errorInfo = require "ErrorInfo" local json = require "json" local sqlUrl = require "SqlUrl" local redisKeyUrl = require "RedisKeyUrl" local clusterServer = require "ClusterServer" local activity = require "Activity" local serverId = tonumber(skynet.getenv "serverId") local Gm = oo.class() function Gm:Init() end -- 获取Web消息 function Gm:WebMsg(c2sData) local player = {} if "GMModifyTime" ~= c2sData.gameMessage and "GMCopyData" ~= c2sData.gameMessage and "GMModifyTask" ~= c2sData.gameMessage then player = skynet.server.playerCenter:GetPlayerForAccount(c2sData.playerId) if not player then return end c2sData.commandField = json:decode(c2sData.commandField) end if "GMCmd" == c2sData.gameMessage then self:WebCmd(player, c2sData) elseif "GMAddGoods" == c2sData.gameMessage then self:WebGoods(player, c2sData) elseif "GMModifyTime" == c2sData.gameMessage then self:WebModifyTime(player, c2sData) elseif "GMCopyData" == c2sData.gameMessage then self:GMCopyData(player, c2sData ) elseif "GMModifyTask" == c2sData.gameMessage then player = skynet.server.playerCenter:GetPlayerForAccount(c2sData.playerId) if not player then return end self:GMModifyTask(player, c2sData) end end -- 获取该商品的配置 function Gm:WebCmd(player, c2sData) local data = {} for k, v in pairs(c2sData.commandField) do local key = v.articlesName local value = v.articlesNumber log.info(string.format("玩家 %d GM增加 %s 数量 %d", player.userId, key, value)) if "coin" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_27") player:MoneyChange(dataType.MoneyType_Coin, value, eventId) elseif "clovers" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_27") player:MoneyChange(dataType.MoneyType_Map, value, eventId) elseif "volute" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_27") player:MoneyChange(dataType.MoneyType_Volute, value, eventId) elseif "contributeCoin" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_27") player:MoneyChange(dataType.MoneyType_ContributeCoin, value, eventId) elseif "exp" == key then player:AddExpCount(value) elseif "level" == key then self:Level(player, value) elseif "咖啡豆" == key then player.gameData.shop[dataType.ShopType_Coffee].currency[1] = player.gameData.shop[dataType.ShopType_Coffee].currency[1] + value elseif "糖" == key then player.gameData.shop[dataType.ShopType_Coffee].currency[2] = player.gameData.shop[dataType.ShopType_Coffee].currency[2] + value elseif "牛奶" == key then player.gameData.shop[dataType.ShopType_Coffee].currency[3] = player.gameData.shop[dataType.ShopType_Coffee].currency[3] + value elseif "卷发棒" == key then player.gameData.shop[dataType.ShopType_Style].money.resource1 = player.gameData.shop[dataType.ShopType_Style].money.resource1 + value elseif "化妆刷" == key then player.gameData.shop[dataType.ShopType_Style].money.resource2 = player.gameData.shop[dataType.ShopType_Style].money.resource2 + value elseif "梳子" == key then player.gameData.shop[dataType.ShopType_Style].money.resource3 = player.gameData.shop[dataType.ShopType_Style].money.resource3 + value elseif "Head" == v.articlesType then local cfgOneHead = skynet.server.gameConfig:GetPlayerCurCfg( player , "Head" , v.articlesId) if cfgOneHead.type == dataType.HeadType_Head then -- 判断改玩家是否拥有该头像 local own = false for k1, v1 in pairs(player.gameData.personal.ownHeadIds) do if v.articlesId == v1 then own = true break end end -- 将玩家头像设置为当前头像 -- player.gameData.personal.headId = v.articlesId -- 判断当前头像是否是玩家没有的头像 if not own then skynet.server.personal:ChangeGainInfo(player , dataType.GoodsType_HeadAndHeadFrame , v.articlesId , dataType.HeadType_Head , skynet.server.personal.AddGoods) end elseif cfgOneHead.type == dataType.HeadType_Frame then -- 判断改玩家是否拥有该头像框 local own = false for k1, v1 in pairs(player.gameData.personal.ownHeadFrameIds) do if v.articlesId == v1 then own = true break end end if not own then skynet.server.personal:ChangeGainInfo(player , dataType.GoodsType_HeadAndHeadFrame , v.articlesId , dataType.HeadType_Frame , skynet.server.personal.AddGoods) end end elseif "Title" == v.articlesType then local cfgTitle = skynet.server.gameConfig:GetPlayerAllCfg(player, "Title") for k1, v1 in pairs(cfgTitle) do -- 判断改玩家是否拥有该头衔 if v1.id == v.articlesId and 1 == v1.type then -- 形容头衔 local own = false for k2, v2 in pairs(player.gameData.personal.ownTitle1s) do if v.articlesId == v2 then own = true break end end -- 将玩家头衔设置为当前头衔 -- player.gameData.personal.title1 = v.articlesId -- 判断当前头衔是否是玩家没有的头衔 if not own then table.insert(player.gameData.personal.ownTitle1s, v.articlesId) end break elseif v1.id == v.articlesId and 2 == v1.type then -- 名称头衔 local own = false for k2, v2 in pairs(player.gameData.personal.ownTitle2s) do if v.articlesId == v2 then own = true break end end -- 将玩家头衔设置为当前头衔 -- player.gameData.personal.title2 = v.articlesId -- 判断当前头衔是否是玩家没有的头衔 if not own then table.insert(player.gameData.personal.ownTitle2s, v.articlesId) end break end end elseif "Badge" == v.articlesType then -- 判断改玩家是否拥有该勋章 local own = false for k1, v1 in pairs(player.gameData.personal.ownMedals) do if v.articlesId == v1 then own = true break end end -- 判断当前头衔是否是玩家没有的头衔 if not own then table.insert(player.gameData.personal.ownMedals, v.articlesId) end -- 将玩家勋章设置为当前勋章 -- if #player.gameData.personal.medals < 3 then -- table.insert(player.gameData.personal.medals , v.articlesId) -- elseif 3 == #player.gameData.personal.medals then -- --判断当前勋章中包含该勋章没 -- local hava = false -- for k1 , v1 in pairs(player.gameData.personal.medals) do -- if v1 == v.articlesId then -- hava = true -- break -- end -- end -- if not hava then -- player.gameData.personal.medals[1] = v.articlesId -- end -- end elseif "NPC" == v.articlesType then -- 增加指定NPC好感度 local curNpc = player.gameData.friend[v.articlesId] if curNpc then skynet.server.friend:AddFavorability(player, curNpc, value) end end end -- end end -- 获取该商品的配置 function Gm:WebGoods(player, c2sData) local isAllGoods = c2sData.cmdType for k, v in pairs(c2sData.commandField) do local id = v.articlesId local count = v.articlesNumber local goodsType = v.articlesType local cfgAll = nil if "Furniture" == goodsType then goodsType = dataType.GoodsType_Furniture cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Furniture") elseif "Decoration" == goodsType then goodsType = dataType.GoodsType_Decorate cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Decoration") elseif "Flowerpot" == goodsType then goodsType = dataType.GoodsType_Flowerpot cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Flowerpot") elseif "Seed" == goodsType then goodsType = dataType.GoodsType_Seed cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Seed") elseif "Plant" == goodsType then goodsType = dataType.GoodsType_Plant cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Plant") elseif "Clothes" == goodsType then goodsType = dataType.GoodsType_Clothes cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Clothes") elseif "Ticket" == goodsType then goodsType = dataType.GoodsType_Prop cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Ticket") elseif "FishType" == goodsType then goodsType = dataType.GoodsType_Fish cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "FishType") elseif "CuisineMenu" == goodsType then goodsType = dataType.GoodsType_CuisineMenu cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "CuisineMenu") elseif "CuisineMaterial" == goodsType then goodsType = dataType.GoodsType_CuisineMaterial cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "CuisineMaterial") elseif "CoffeeType" == goodsType then goodsType = dataType.GoodsType_Coffee cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "CoffeeType") elseif "PetClothes" == goodsType then goodsType = dataType.GoodsType_PetClothes cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "PetClothes") elseif "Garden" == goodsType then goodsType = dataType.GoodsType_Garden cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Garden") elseif "Reward" == goodsType then goodsType = dataType.GoodsType_RewardId cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Reward") elseif "ClothesSuit" == goodsType then --衣服套装物品单独逻辑发放 cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "ClothesSuit") if isAllGoods then for k1 , v1 in pairs(cfgAll) do if v1.type == 1 then --人物套装 local cfgAllClothes = skynet.server.gameConfig:GetPlayerAllCfg(player, "Clothes") for k2 , v2 in pairs(cfgAllClothes) do if v2.suitId == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_Clothes, v2.id, count) end end elseif v1.type == 2 then --宠物套装 local cfgAllClothes = skynet.server.gameConfig:GetPlayerAllCfg(player, "PetClothes") for k2 , v2 in pairs(cfgAllClothes) do if v2.suitId == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_PetClothes, v2.id, count) end end end end else for k1 , v1 in pairs(cfgAll) do if v1.id == id and v1.type == 1 then --人物套装 local cfgAllClothes = skynet.server.gameConfig:GetPlayerAllCfg(player, "Clothes") for k2 , v2 in pairs(cfgAllClothes) do if v2.suitId == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_Clothes, v2.id, count) end end break elseif v1.id == id and v1.type == 2 then --宠物套装 local cfgAllClothes = skynet.server.gameConfig:GetPlayerAllCfg(player, "PetClothes") for k2 , v2 in pairs(cfgAllClothes) do if v2.suitId == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_PetClothes, v2.id, count) end end break end end end elseif "Suit" == goodsType then --家具套装物品单独逻辑发放 cfgAll = skynet.server.gameConfig:GetPlayerAllCfg(player, "Suit") if isAllGoods then for k1 , v1 in pairs(cfgAll) do --家具套装 local cfgAllFur = skynet.server.gameConfig:GetPlayerAllCfg(player, "Furniture") for k2 , v2 in pairs(cfgAllFur) do if v2.suitType == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_Furniture, v2.id, count) end end --装修套装 local cfgAllDec = skynet.server.gameConfig:GetPlayerAllCfg(player, "Decoration") for k2 , v2 in pairs(cfgAllDec) do if v2.suitType == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_Decorate, v2.id, count) end end end else for k1 , v1 in pairs(cfgAll) do if v1.id == id then --家具套装 local cfgAllFur = skynet.server.gameConfig:GetPlayerAllCfg(player, "Furniture") for k2 , v2 in pairs(cfgAllFur) do if v2.suitType == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_Furniture, v2.id, count) end end --装修套装 local cfgAllDec = skynet.server.gameConfig:GetPlayerAllCfg(player, "Decoration") for k2 , v2 in pairs(cfgAllDec) do if v2.suitType == v1.id then skynet.server.bag:AddGoods(player, dataType.GoodsType_Decorate, v2.id, count) end end break end end end elseif "Points" == goodsType then if id == dataType.PointsType_Store then player.gameData.storePack.rechargeAmount = player.gameData.storePack.rechargeAmount + count local myPlayerId = player.gameData.partner.id if myPlayerId then --充值时更新下最新的充值记录 skynet.server.personal:SetDetail( myPlayerId , "rechargeAmount" , player.gameData.storePack.rechargeAmount ) end elseif id == dataType.PointsType_Time then --限时累充积分修改 -- local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue" ) -- if next(player.gameData.design.timeCardPoolInfo) ~= nil then -- for k1 , v1 in pairs(player.gameData.design.timeCardPoints) do -- if v1.raffleId == player.gameData.design.timeCardPoolInfo.id then -- v1.points = v1.points + count * cfgSValue.valueAccumulatePoint -- break -- end -- end -- end --添加累计积分 skynet.server.activityLimitedAccum:AddPoints(player,count) end end if isAllGoods and type(goodsType) == "number" then -- GM发送所有疝 --GM添加咖啡 解锁图鉴 if dataType.GoodsType_Coffee == goodsType then for k1, v1 in pairs(cfgAll) do skynet.server.bag:AddGoods(player, goodsType, v1.id, count) skynet.server.coffeeShop:GainCoffee( player , v1.id ) end elseif dataType.GoodsType_RewardId == goodsType then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_27") for k1, v1 in pairs(cfgAll) do player:GiveReward(v1.id,eventId) end else for k1, v1 in pairs(cfgAll) do if dataType.GoodsType_Clothes == goodsType and v1.suitId >= 0 then skynet.server.bag:AddGoods(player, goodsType, v1.id, count) elseif dataType.GoodsType_Clothes ~= goodsType then skynet.server.bag:AddGoods(player, goodsType, v1.id, count) end end end log.info(string.format("玩家 %d GM增加 商品类型 %s 所有道具", player.userId, v.articlesType)) elseif type(goodsType) == "number" then log.info(string.format("玩家 %d GM增加 商品类型 %s ID %d 数量 %d", player.userId, v.articlesType, id, count)) if dataType.GoodsType_RewardId == goodsType then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_27") player:GiveReward(id,eventId) else skynet.server.bag:AddGoods(player, goodsType, id, count) end --GM添加咖啡 解锁图鉴 if dataType.GoodsType_Coffee == goodsType then skynet.server.coffeeShop:GainCoffee( player , id ) end end end end -- 修改时间 function Gm:WebModifyTime(player, c2sData) if not skynet.server.gameConfig:IsOnline() or skynet.server.gameConfig:IsTest() then if 1 == c2sData.cmdType then -- 还原 skynet.AddTime = 0 skynet.server.activity.UpdateTime = 0 log.info("时间还原 最新时间 ", skynet.server.common:GetStrTime(skynet:GetTime())) elseif 2 == c2sData.cmdType then -- 修改 local addTime = math.floor(c2sData.changeTime / 1000) - skynet.GetTime() if addTime > 0 then skynet.AddTime = skynet.AddTime + addTime log.info("修改时间 最新时间 ", skynet.server.common:GetStrTime(skynet:GetTime())) else log.info("时间错误") end end if clusterServer:IsGameServer( serverId ) then skynet.server.activityDecoWeek:SyncHotDesignList() end end end -- 复制玩家数据 function Gm:GMCopyData(player, c2sData ) if not skynet.server.gameConfig:IsOnline() then -- 从redis中获取玩家数据库索引和玩家id -- 被复制的玩家 local userDBInfo1 = skynet.server.redisCenter:GetRedisDBInfo( c2sData.fromPlayerAccount ) local dbIndex1 =userDBInfo1.DBIndex local userId1 = userDBInfo1.UserID ---- 复制的玩家 local userDBInfo2 = skynet.server.redisCenter:GetRedisDBInfo( c2sData.toPlayerAccount ) local dbIndex2 =userDBInfo2.DBIndex local userId2 = userDBInfo2.UserID -- 判断是否存在玩家 if not userId1 then log.info(string.format("复制数据失败 被复制的玩家 %s 不存在", c2sData.fromPlayerAccount)) return true elseif not userId2 then log.info(string.format("复制数据失败 复制的玩家 %s 不存在", c2sData.toPlayerAccount)) return true end -- 从数据库中获取玩家具体数据 local sql1 = string.format(sqlUrl.queryAccountFromPlayer, userId1) local fromData = skynet.server.db:QueryPlayer(dbIndex1, sql1) fromData = fromData[1] local sql2 = string.format(sqlUrl.queryAccountFromPlayer, userId2) local toData = skynet.server.db:QueryPlayer(dbIndex2, sql2) toData = toData[1] --开始复制数据 local basicInfo1 = json:decode(fromData.BasicInfo) local gameData1 = json:decode(fromData.GameData) local basicInfo2 = json:decode(toData.BasicInfo) local gameData2 = json:decode(toData.GameData) local basicInfo = {} local gameData = {} basicInfo = basicInfo2 gameData = gameData1 basicInfo.isNewPlayer = basicInfo1.isNewPlayer -- 特定数据不能复制 gameData.partner = gameData2.partner --保存该玩家数据 local sql = string.format(sqlUrl.saveAccountToPlayer, json:encode(basicInfo), json:encode(gameData), userId2) skynet.server.db:QueryPlayer(dbIndex2, sql) log.info(string.format("成功将玩家 %s 的数据复制到 玩家 %s", c2sData.fromPlayerAccount , c2sData.toPlayerAccount)) end end -- 修改玩家任务数据 function Gm:GMModifyTask(player, c2sData) -- 任务类型 1 等级任务 2 npc任务 3 通行证任务 4 成就任务 5 嘉年华任务 local taskType = c2sData.cmdType if taskType == 1 then for k, v in pairs(player.gameData.levelTask) do if v.id < c2sData.taskId then v.status = skynet.server.task.TaskStatus_AlreadyGet elseif v.id == c2sData.taskId then v.status = skynet.server.task.TaskStatus_NoComplete v.progress = c2sData.taskProgress --elseif v.id > c2sData.taskId then -- v.status = skynet.server.task.TaskStatus_NoComplete end end elseif taskType == 2 then for k, v in pairs(player.gameData.npcTask) do if v.id < c2sData.taskId then v.status = skynet.server.task.TaskStatus_AlreadyGet elseif v.id == c2sData.taskId then v.status = skynet.server.task.TaskStatus_NoComplete v.progress = c2sData.taskProgress --elseif v.id > c2sData.taskId and then --and v.status = skynet.server.task.TaskStatus_NoComplete end end elseif taskType == 3 then for k, v in pairs(player.gameData.passCheck.tasks) do if v.id < c2sData.taskId then v.status = skynet.server.task.TaskStatus_AlreadyGet elseif v.id == c2sData.taskId then v.status = skynet.server.task.TaskStatus_NoComplete v.progress = c2sData.taskProgress --elseif v.id > c2sData.taskId then -- v.status = skynet.server.task.TaskStatus_NoComplete end end elseif taskType == 4 then for k, v in pairs(player.gameData.achieveTask) do if v.id < c2sData.taskId then v.status = skynet.server.task.TaskStatus_AlreadyGet elseif v.id == c2sData.taskId then v.status = skynet.server.task.TaskStatus_NoComplete v.progress = c2sData.taskProgress --elseif v.id > c2sData.taskId then -- v.status = skynet.server.task.TaskStatus_NoComplete end end elseif taskType == 5 then for k, v in pairs(player.gameData.activity[dataType.ActivityType_Carnival].Carnival.tasks) do if v.id < c2sData.taskId then v.status = skynet.server.task.TaskStatus_AlreadyGet elseif v.id == c2sData.taskId then v.status = skynet.server.task.TaskStatus_NoComplete v.progress = c2sData.taskProgress --elseif v.id > c2sData.taskId then -- v.status = skynet.server.task.TaskStatus_NoComplete end end --寻味之旅 elseif taskType == 6 then skynet.server.activitySeekTreasure:ChangeTask(player,c2sData.taskId,c2sData.taskProgress) end log.info(string.format("玩家 %d GM修改任务类型 %s 任务id %d 任务进度 %d", player.userId, taskType, c2sData.taskId, c2sData.taskProgress)) end -- 获取该商品的配置 function Gm:Cmd(player, c2sData, s2cData) c2sData.data = assert(pb.decode("C2SGMCmd", c2sData.data)) local data = {} local key = c2sData.data.key local value = c2sData.data.value if not key or not value then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else --if not skynet.server.gameConfig:IsOnline() then local isSuc = false if "coin" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_27") isSuc = player:MoneyChange(dataType.MoneyType_Coin, value, eventId) elseif "clovers" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_28") isSuc = player:MoneyChange(dataType.MoneyType_Map, value, eventId) elseif "volute" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_29") isSuc = player:MoneyChange(dataType.MoneyType_Volute, value, eventId) elseif "contributeCoin" == key then local eventId = pb.enum("EnumMoneyChangeEventID", "EventID_30") isSuc = player:MoneyChange(dataType.MoneyType_ContributeCoin, value, eventId) elseif "exp" == key then isSuc = player:AddExpCount(value) end if not isSuc then s2cData.code = errorInfo.ErrorCode.GMCmdFailed end --end end s2cData.cmd = pb.enum("MsgType", "CMD_S2C_GMCmd") s2cData.data = assert(pb.encode("S2CGMCmd", data)) end -- 获取该商品的配置 function Gm:AddGoods(player, c2sData, s2cData) c2sData.data = assert(pb.decode("C2SGMAddGoods", c2sData.data)) local data = {} local type = c2sData.data.type local id = c2sData.data.id local count = c2sData.data.count if not type or not id or not count then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else --if not skynet.server.gameConfig:IsOnline() then local isSuc = skynet.server.bag:AddGoods(player, type, id, count) if not isSuc then s2cData.code = errorInfo.ErrorCode.GMCmdFailed end --end end s2cData.cmd = pb.enum("MsgType", "CMD_S2C_GMAddGoods") s2cData.data = assert(pb.encode("S2CGMAddGoods", data)) end function Gm:Level(player, value) local level = player.gameData.level player.gameData.exp = 0 if not value or level > value then return end --[[ if value > player.maxLevelLimt then value = player.maxLevelLimt - level else value = value - level end ]] for i = level , value - 1, 1 do local cfgLevel = skynet.server.gameConfig:GetPlayerCurCfg( player , "Level" , i ) if cfgLevel then player:AddExpCount(cfgLevel.requireExp, true, true) end end end skynet.server.gm = Gm return Gm