StoreAction.lua 11.3 KB
local _M = {}

local serverId = tonumber(skynet.getenv("servId"))
local md5 = require "md5"

local function makeOrder(roleId, rechargeId)
	local orderId = redisproxy:hincrby("autoincrement_set", "order", 1)
	local partnerOrderId = string.format("%d_%d_%d", serverId, roleId, orderId)
	local orderKey = string.format("order:%d:%d", roleId, orderId)
	redisproxy:del(orderKey)
	local order = require("models.Order").new({ 
		key = orderKey, 
		order = partnerOrderId, 
		rechargeId = rechargeId, 
	})
	order:create()
	redisproxy:sadd(string.format("role:%d:orders", roleId), partnerOrderId)
	return partnerOrderId
end

-- 入口在正式服关闭  -- mock 充值
function _M.rechargeRpc(agent , data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local dataSet = csvdb["shop_rechargeCsv"][id]
	if not dataSet then return end
	local roleId = role:getProperty("id")
	
	--创建订单号
	local partnerOrderId = makeOrder(roleId, id)
	SendPacket(actionCodes.Store_rechargeRpc, MsgPack.pack({ order = partnerOrderId }))


	-- 测试的 直接发奖励了
	skynet.timeout(10, function ()
		role:handlePurchase({
			order = partnerOrderId,
			amount = dataSet.rmb,
			game_money = dataSet.diamond,
			product_id = dataSet.productId,
			pay_time = skynet.timex(),
			transactionId = "onlyTest",
		})
	end)
	
	return true
end

local function table_keys( t )
    local keys = {}
    for k, _ in pairs( t ) do
        keys[#keys + 1] = k
    end
    return keys
end

local function signPms(params, secret_key)
    local keys = table_keys(params)
    table.sort(keys)
    local urlCode = ""
    for index, key in ipairs(keys) do
		urlCode = urlCode .. params[key]
	end
	return md5.sumhexa(urlCode .. secret_key):lower()
end


-- google 充值 入口
function _M.googleRechargeRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local dataSet = csvdb["shop_rechargeCsv"][id]
	if not dataSet then return end
	local roleId = role:getProperty("id")

	role.ignoreHeartbeat = true
	--创建订单号
	local partnerOrderId = makeOrder(roleId, id)
	-- 签名
	local secret_key = "b7657fa7ccd44c16a35e3f454ac7a075"
	local need = {
		out_trade_no = partnerOrderId,
		money = dataSet.rmb * 100,
		game_money = dataSet.diamond,
		product_id = dataSet.productId,
		notify_url = msg.notifyUrl
	}
	local sign = signPms(need, secret_key)

	SendPacket(actionCodes.Store_googleRechargeRpc, MsgPack.pack({ order = partnerOrderId, sign = sign}))
	return true
end

-- mycard 充值 入口
function _M.myCardRechargeRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local dataSet = csvdb["shop_rechargeCsv"][id]
	if not dataSet then return end
	local roleId = role:getProperty("id")

	role.ignoreHeartbeat = true
	--创建订单号
	local partnerOrderId = makeOrder(roleId, id)
	-- 签名
	local secret_key = "48759e07540f46d9af17ec82669b4272"
	local need = {
		out_trade_no = partnerOrderId,
		money = dataSet.rmb * 100,
		game_money = dataSet.diamond,
		notify_url = msg.notifyUrl
	}
	local sign = signPms(need, secret_key)

	SendPacket(actionCodes.Store_myCardRechargeRpc, MsgPack.pack({ order = partnerOrderId, sign = sign}))
	return true
end

-- mycard 充值 入口
function _M.iosRechargeRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local dataSet = csvdb["shop_rechargeCsv"][id]
	if not dataSet then return end
	local roleId = role:getProperty("id")

	role.ignoreHeartbeat = true
	--创建订单号
	local partnerOrderId = makeOrder(roleId, id)
	-- 签名
	local secret_key = "9647d2efe1074c73b9ac19af4337a70e"
	local need = {
		out_trade_no = partnerOrderId,
		money = dataSet.rmb * 100,
		game_money = dataSet.diamond,
		product_id = dataSet.iap_product_id,
		notify_url = msg.notifyUrl
	}
	local sign = signPms(need, secret_key)

	SendPacket(actionCodes.Store_iosRechargeRpc, MsgPack.pack({ order = partnerOrderId, sign = sign}))
	return true
end

function _M.purchaseOrderResult(agent, data)
	local role = agent.role

	local roleId = role:getProperty("id")
	local msg = MsgPack.unpack(data)

	role.ignoreHeartbeat = false

	local partnerOrderStr = msg.order
	local _, _, orderId = string.match(partnerOrderStr, "(.+)_(.+)_(.+)")
	local orderObject = require("models.Order").new({ key = string.format("order:%d:%d", roleId, orderId) })
	if not orderObject:load() then
		-- 订单不存在
		skynet.error("cancelPurchaseRpc", string.format("order %s not exist", partnerOrderStr))
		return true
	end

	if msg.status == "success" then
		orderObject:setProperty("transactionId", msg.platformOrder or "")
		local rechargeId = orderObject:getProperty("rechargeId")
		local dataSet = csvdb["shop_rechargeCsv"][rechargeId]
		
		role:log("setOrder", {
			order_status = 100, -- "订单状态:100 - 开始下单(玩家还未开始付费行为记录)200 - 支付完成并发货(SDK通知可以发货时记录),300 - 订单被取消,1000 - 其他"
			item_id = rechargeId, -- 道具id
			item_type = dataSet.type, -- 购买的道具类型,具体见"onItems"方法中道具类型枚举表
			item_name = dataSet.title, -- 购买的道具名
			item_number = 1, -- 购买的道具数量
			item_level = 1, -- 购买的道具等级
			order_cost = dataSet.rmb * 100, -- 此次消费的现金金额(单位:分),如 51800即未518元,对应客户端SDK传入的'total_fee'
			order_currency = "CNY", -- 货币类型,默认为"CNY"(人民币),遵循ISO 4217规范
			order_type = self.getProperty("rmbC") > 0 and 0 or 1, -- 订单类型,首充记录为1,否则为0
			order_id = msg.platformOrder, -- 本条记录的订单号,对应客户端SDK返回的'bs_trade_no'
		})

		return true
	end

	if orderObject:getProperty("finishTime") > 0 then
		return true
	end

	orderObject:setProperty("status", msg.status)

	redisproxy:srem(string.format("role:%d:orders", roleId), partnerOrderStr)
	return true
end


function _M.shopBuyRpc(agent , data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id
	local count = msg.count or 1

	local dataSet = csvdb["shop_normalCsv"][id]
	if not dataSet then return end

	if dataSet.unlock ~= "" then
		if not role:checkHangPass(tonumber(config.unlock)) then
			skynet.error(string.format("shopBuyRpc,user do not finish hang pass, user_id:%d", role:getProperty("id")))
			return 1
		end
	end

	local buyRecord = role.storeData:getProperty("buyR")
	if math.illegalNum(count, 1, (dataSet.limit == 0 and math.huge or dataSet.limit - (buyRecord[id] or 0))) then 
		skynet.error(string.format("shop buy over limit, user_id:%d, goods_id:%d", role:getProperty("id"), id))
		return 1 
	end

	local cost = {[dataSet.icon] = dataSet.cost * count}

	local desc = "unknown"
	if dataSet.shop == 1 then		-- 普通商店
		desc = "dailyShop"
		local dailySDD = role.dailyData:getProperty("dailySDD")
		if dailySDD[id] then -- 折扣
			cost = math.ceil(dataSet.cost * (1 - dataSet.disount / 100))
		end
	elseif dataSet.shop == 2 then		-- 美食商店
		desc = "dinerShop"
	elseif dataSet.shop == 3 then		-- 竞技场商店
		desc = "pvpShop"
	end

	if not role:checkItemEnough(cost) then return end

	if dataSet.limit ~= 0 then
		buyRecord[id] = (buyRecord[id] or 0) + count
		role.storeData:updateProperty({field = "buyR", value = buyRecord})
	end
	role:costItems(cost, {log = {desc = desc, int1 = id, int2 = count}})

	local gift = {}
	for _id, _count in pairs(dataSet.gift:toNumMap()) do
		gift[_id] = _count * count
	end
	local reward = role:award(gift, {log = {desc = desc, int1 = id, int2 = count}})
	
	if dataSet.shop == 1 then
		role:checkTaskEnter("ShopAll", {count = count})
	end
	local costId, costCount = next(cost)

	role:log("shop_purchase", {
		item_id = id, -- 道具id
		item_type = 0, -- 道具类型,具体见枚举表中道具类型枚举表
		item_level = 0, -- 道具等级
		item_cnt = count, -- 购买数量技术
		currency_type = costId or 0, -- 购买道具消耗的货币类型,记录货币ID
		shop_purchase_current = costCount or 0, -- 购买道具消耗的货币数量
		shop_id = dataSet.shop, -- 商店ID
	})
	SendPacket(actionCodes.Store_shopBuyRpc, MsgPack.pack({reward = reward}))
	return true
end

function _M.getFreeChestRpc(agent, data)
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id

	local config = csvdb["shop_rechargeCsv"][id]
	if not config then return end

    local rechargeRecord = role.storeData:getProperty("payR")
	local getCount = (rechargeRecord[id] or 0)
	if getCount >= config.limit then
		return 1
	end
	local reward, _ = role:award(config.itemFirst, {log = {desc = "freeGift", int1 = id}})

	rechargeRecord[id] = getCount + 1
	role.storeData:updateProperty({field = "payR", value = rechargeRecord})

	SendPacket(actionCodes.Store_getFreeChestRpc, MsgPack.pack({reward = reward}))
	return true
end

function _M.getGrowFundRewardRpc(agent, data)	
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id

	local config = csvdb["reward_newbeeCsv"][id]
	if not config then return end

    local growFundFlag = role.storeData:getProperty("growFund")
	local growFundRecord = role.storeData:getProperty("growFundR")
	
	if growFundFlag == 0 then
		skynet.error("user do not buy grow fund")
		return 1
	end

	if not role:checkHangPass(config.condition) then
		skynet.error(string.format("user do not finish hang pass, user_id:%d", role:getProperty("id")))
		return 1
	end

	local b = string.getbit(growFundRecord, id)
	if string.char(b) == "1" then
		return 1
	end

	growFundRecord = string.setbit(growFundRecord, id)
	role.storeData:updateProperty({field = "growFundR", value = growFundRecord})

	local gift = config.giftFree .. " " .. config.giftLimit
	local reward, _ = role:award(gift, {log = {desc = "grownFund", int1 = id}})

	SendPacket(actionCodes.Store_getGrowFundRewardRpc, MsgPack.pack({reward = reward}))
	return true
end

function _M.getBattlePassRewardRpc(agent, data)	
	local role = agent.role
	local msg = MsgPack.unpack(data)
	local id = msg.id

	local config = csvdb["reward_battlepassCsv"][id]
	if not config then return end

	local timeNow = skynet.timex()
    local battleCardFlag = role.storeData:getProperty("battleCard")
	local battleCardFreeRecord = role.storeData:getProperty("battleFR")
	local battleCardLimitRecord = role.storeData:getProperty("battleLR")

	local freeFlag = string.char(string.getbit(battleCardFreeRecord, id))
	local limitFlag = string.char(string.getbit(battleCardLimitRecord, id))

	if freeFlag == "1" and limitFlag == "1" then
		skynet.error("user already get battle pass reward")
		return 1
	end

	if battleCardFlag == 1 and limitFlag == "1" then
		return 1
	end

	if role:getProperty("battlePoint") < config.point then
		skynet.error(string.format("user do not have enough battle point, user_id:%d", role:getProperty("id")))
		return 1
	end

	local gift = ""
	if  freeFlag == "0" then
		gift = config.giftFree

		battleCardFreeRecord = string.setbit(battleCardFreeRecord, id)
		role.storeData:updateProperty({field = "battleFR", value = battleCardFreeRecord})
	end

	if battleCardFlag == 1 and limitFlag == "0" then
		if gift ~= "" then
			gift = gift .. " "
		end
		gift = gift .. config.giftLimit

		battleCardLimitRecord = string.setbit(battleCardLimitRecord, id)
		role.storeData:updateProperty({field = "battleLR", value = battleCardLimitRecord})
	end
	
	local reward, _ = role:award(gift, {log = {desc = "battleCard", int1 = id}})

	SendPacket(actionCodes.Store_getBattlePassRewardRpc, MsgPack.pack({reward = reward}))
	return true
end

return _M