Transaction = {} local this = Transaction local filename = "Transaction" -- 限制只能对一个人发起交易请求.只有最新的申请会生效.交易申请会有5秒的cd. SYS_TRANSACTIONS = "R$transaction_transactions" SYS_TRANSACTIONS_STATUS = "R$transaction_transactions_status" function Transaction.onLoginEnd(actor) local info = Transaction.getInfo(actor) if table.count(info) <= 0 then return end local rid = getbaseinfo(actor, "rid") local ttInfo = Transaction.getTTInfo(actor) if table.count(ttInfo) > 0 and tostring(ttInfo.targetId) == tostring(rid) then local targetActor = getactor(actor, ttInfo.targetId) if targetActor ~= nil then -- 重登取消交易 sendluamsg( targetActor, LuaMessageIdToSever.TransactionInfo_MsgID, { type = 30, rid = rid } ) end end end function Transaction.onReloadScript(actor) end function Transaction.CheckStatus(actor, rid, msgid, status) return true -- local nowsec = getbaseinfo(actor, "nowsec") -- local playerTransactionInfo = transactions[rid] -- if playerTransactionInfo == nil or nowsec - playerTransactionInfo.sec > 30 then -- sendluamsg(actor, msgid, { -- type = 101, -- status = status -- }) -- return false -- end -- local targetTransactionInfo = transactions[playerTransactionInfo.targetId] -- if targetTransactionInfo == nil or targetTransactionInfo.targetId ~= rid or nowsec - targetTransactionInfo.sec > 30 then -- local targetActor = getactor(actor, playerTransactionInfo.targetId) -- sendluamsg(targetActor, msgid, { -- type = 101, -- status = status -- }) -- return false -- end -- playerTransactionInfo.sec = nowsec -- targetTransactionInfo.sec = nowsec -- return true end function Transaction.getItemDataSimple(actor, item) -- local item2 = getitemattinfo(actor, 1, item.cfgid, item.id) local data = { id = item.id, cfgid = item.cfgid, isServerStyle = true, entries = item.entries, luaextdata = item.luaextdata, count = item.count, type = item.type, basicattr = item.basicattr, luckyattr = item.luckyattr, replacerating = item.replacerating } return data end function Transaction.getInfo(actor) local info = APIGetTable(actor, SYS_TRANSACTIONS) or {} return info end function Transaction.setInfo(actor, info) APISetTable(actor, SYS_TRANSACTIONS, info) end function Transaction.setStatus(actor, status) APISetInt(actor, SYS_TRANSACTIONS_STATUS, status) end function Transaction.getStatus(actor) return APIGetInt(actor, SYS_TRANSACTIONS_STATUS) end function Transaction.getTTInfo(actor) local info = Transaction.getInfo(actor) if info.targetId ~= nil then local targetActor = getactor(actor, info.targetId) if targetActor ~= nil then local ttInfo = Transaction.getInfo(targetActor) return ttInfo end end return {} end function Transaction.clearInfo(actor) local info = Transaction.getInfo(actor) if info.targetId ~= nil then local targetActor = getactor(actor, info.targetId) if targetActor ~= nil then Transaction.setInfo(targetActor, {}) sendluamsg( targetActor, LuaMessageIdToSever.TransactionInfo_MsgID, { type = 30 } ) end end Transaction.setInfo(actor, {}) sendluamsg( actor, LuaMessageIdToSever.TransactionInfo_MsgID, { type = 30 } ) end function Transaction.syncChangeData(actor) local info = Transaction.getInfo(actor) if table.count(info) <= 0 then return end sendluamsg( actor, LuaMessageIdToSever.TransactionInfo_MsgID, { type = 201 } ) local targetActor = getactor(actor, info.targetId) if targetActor ~= nil then sendluamsg( targetActor, LuaMessageIdToSever.TransactionInfo_MsgID, { type = 201 } ) end end function Transaction.onHandlereQuest(actor, msgid, sMsg) local type = sMsg.type local targetId = sMsg.rid local rid = getbaseinfo(actor, "rid") local items = sMsg.items local coin1 = sMsg.coin1 local coin2 = sMsg.coin2 local status = sMsg.status -- 只能修改自身数据.严谨修改对方数据.只能通过接口.通知对方数据发生了变化 local ppInfo = Transaction.getInfo(actor) local targetActor = nil if ppInfo ~= nil and ppInfo.targetId ~= nil then targetActor = getactor(actor, ppInfo.targetId) end if type == 1 then local targetActor = getactor(actor, targetId) if rid == targetId then tipinfo(actor, "无法跟自己交易") return end -- 请求跟其他玩家交易 local name = getbaseinfo(actor, "rolename") sendluamsg( targetActor, msgid, { type = 2, rid = rid, name = name } ) elseif type == 3 then -- 自己接受交易 local targetActor = getactor(actor, targetId) -- 判断交易距离 local playerInfo = getplayermaininfo(actor) local targetInfo = getplayermaininfo(targetActor) if playerInfo.mapid ~= targetInfo.mapid or (math.abs(playerInfo.x - targetInfo.x) >= 4 or math.abs(playerInfo.y - targetInfo.y) >= 4) then tipinfo(actor, "距离过远,无法进行交易") tipinfo(targetActor, "距离过远,无法进行交易") return end -- 判断交易状态 local playerState = getfightstate(actor) local targetState = getfightstate(actor) if playerState == 1 or targetState == 1 then tipinfo(actor, "战斗状态中,无法进行交易") tipinfo(targetActor, "战斗状态中,无法进行交易") return end local nowsec = getbaseinfo(actor, "nowsec") local ptInfo = Transaction.getInfo(actor) local ttInfo = Transaction.getInfo(targetActor) if (ptInfo ~= nil and table.count(ptInfo) > 0 and ptInfo.sec ~= nil and nowsec - ptInfo.sec < 30) or ttInfo ~= nil and table.count(ttInfo) > 0 and ttInfo.sec ~= nil and nowsec - ttInfo.sec < 30 then tipinfo(actor, "交易中,无法进行交易") tipinfo(targetActor, "交易中,无法进行交易") return end -- 对方可能跟其他人交易中 if ttInfo ~= nil and table.count(ttInfo) > 0 and ttInfo.targetId ~= rid then tipinfo(actor, "对方正在交易中,无法进行交易") return end -- 创建交易数据 local d1 = { rid = tostring(rid), sec = nowsec, targetId = targetId, items = {}, coin1 = 0, coin2 = 0 } local d2 = { rid = tostring(getbaseinfo(targetActor, "rid")), sec = nowsec, targetId = rid, items = {}, coin1 = 0, coin2 = 0 } Transaction.setStatus(actor, 5) Transaction.setStatus(targetActor, 5) Transaction.setInfo(actor, d1) Transaction.setInfo(targetActor, d2) -- 打开交易界面 sendluamsg( targetActor, msgid, { type = 4, rid = rid, name = playerInfo.name } ) sendluamsg( actor, msgid, { type = 4, rid = targetId, name = targetInfo.name } ) elseif type == 5 then local ptInfo = Transaction.getInfo(actor) if table.count(ptInfo) <= 0 then return end local ptstatus = Transaction.getStatus(actor) if ptstatus ~= 5 then tipinfo(actor, "当前交易状态无法更换物品") return end -- 检查背包是否有这些道具.没有的直接剔除 local maxCount = 10 local count = 0 local realItem = {} for key, itemId in ipairs(items) do local item = getbagiteminfo(actor, itemId, 1) if item ~= nil and item.isbind ~= true and count < maxCount then count = count + 1 table.insert(realItem, item) end end local coin1Num = getbagitemcountbyid(actor, 10010001) local coin2Num = getbagitemcountbyid(actor, 10020001) if coin1 > coin1Num then coin1 = coin1Num end if coin2 > coin2Num then coin2 = coin2Num end ptInfo.coin1 = coin1 ptInfo.coin2 = coin2 ptInfo.items = realItem ptInfo.itemCount = table.count(realItem) Transaction.setInfo(actor, ptInfo) Transaction.syncChangeData(actor) elseif type == 6 then -- 确定锁定 local ptInfo = Transaction.getInfo(actor) if ptInfo == nil then tipinfo(actor, "1006#交易出错, 请重新开始交易.") return end -- Transaction.setStatus(actor, 5) -- Transaction.setStatus(targetActor, 5) local ptstatus = Transaction.getStatus(actor) if ptstatus == 7 then tipinfo(actor, "已确定交易.无法更改交易状态") return end if status ~= nil and (status == 6 or status == 5) then ptstatus = status else if ptstatus == 6 then ptstatus = 5 local targetActor = getactor(actor, ptInfo.targetId) if targetActor ~= nil then Transaction.setStatus(targetActor, 5) end else ptstatus = 6 end end Transaction.setStatus(actor, ptstatus) Transaction.setInfo(actor, ptInfo) Transaction.syncChangeData(actor) elseif type == 7 then -- 判断背包是否有空格 -- 确定交易 local ptInfo = Transaction.getInfo(actor) if ptInfo == nil then tipinfo(actor, "1007#交易出错, 请重新开始交易.") return end local ptstatus = Transaction.getStatus(actor) if ptstatus == 7 then tipinfo(actor, "交易已锁定,无法修改交易状态.") return end if ptstatus ~= 6 then tipinfo(actor, "请先锁定交易状态.") return end Transaction.setStatus(actor, 7) -- local targetActor = getactor(actor, ptInfo.targetId) -- -- 双方确定交易 -- if ptInfo.status == 7 and ttInfo.status == 7 then -- Transaction.onConfirm(actor, ptInfo, ttInfo) -- -- 同步交易状态 -- sendluamsg(targetActor, msgid, { -- type = 10, -- rid = rid -- }) -- sendluamsg(actor, msgid, { -- type = 10, -- rid = ptInfo.targetId -- }) -- return -- end Transaction.setInfo(actor, ptInfo) Transaction.syncChangeData(actor) elseif type == 30 then local ptInfo = Transaction.getInfo(actor) if ptInfo == nil then return end if ptInfo.targetId ~= nil then local targetActor = getactor(actor, ptInfo.targetId) tipinfo(targetActor, "对方已取消交易") Transaction.setInfo(targetActor, {}) -- 同步交易状态 sendluamsg( targetActor, msgid, { type = 30, rid = rid } ) end sendluamsg( actor, msgid, { type = 30, rid = ptInfo.targetId } ) Transaction.setInfo(actor, {}) elseif type == 101 then -- 这里决定是否交易..因为每个玩家的数据同步都不一样. local ptInfo = Transaction.getInfo(actor) if table.count(ptInfo) <= 0 then return end local ttInfo = Transaction.getTTInfo(actor) if table.count(ttInfo) <= 0 then return end local ptstatus = Transaction.getStatus(actor) local ttstatus = 0 local targetActor = getactor(actor, ptInfo.targetId) if targetActor ~= nil then ttstatus = Transaction.getStatus(targetActor) end if ptstatus ~= 7 or ttstatus ~= 7 then return end Transaction.setStatus(actor, 0) Transaction.setStatus(targetActor, 0) Transaction.onConfirm(actor, ptInfo, ttInfo) -- 同步交易状态 sendluamsg( targetActor, msgid, { type = 10, rid = rid } ) sendluamsg( actor, msgid, { type = 10, rid = ptInfo.targetId } ) elseif type == 201 then local ptInfo = Transaction.getInfo(actor) local ttInfo = Transaction.getTTInfo(actor) if tostring(ptInfo.targetId) ~= tostring(ttInfo.rid) or table.count(ptInfo) <= 0 then -- 出错了。可能多人交易。数据错乱了。 sendluamsg( actor, msgid, { type = 30, rid = ptInfo.targetId } ) tipinfo(actor, "1201#交易出错, 请重新开始交易.") local targetActor = getactor(actor, ttInfo.targetId) if targetActor ~= nil then -- 重登取消交易 sendluamsg( targetActor, msgid, { type = 30, rid = rid } ) tipinfo(targetActor, "1201#交易出错, 请重新开始交易.") end Transaction.setInfo(actor, {}) return end local ptstatus = Transaction.getStatus(actor) local ttstatus = 0 local targetActor = getactor(actor, ptInfo.targetId) if targetActor ~= nil then ttstatus = Transaction.getStatus(targetActor) end sendluamsg( actor, msgid, { type = 202, self = ptInfo, target = ttInfo, selfStatus = ptstatus, targetStatus = ttstatus } ) end end function Transaction.mailItemsToActor(actor, ptInfo, ttInfo) local ptRid = ttInfo.targetId local ptActor = getactor(tonumber(ptRid)) local playerItems = ptInfo.items local reward1 = {} local removeItems = {} for k, v in pairs(playerItems) do -- local item = local cfgItem = ConfigDataManager.getById("cfg_item", v.cfgid) if cfgItem.type == "2" then local cfgEquip = ConfigDataManager.getById("cfg_equip_entryLib", v.cfgid) if cfgEquip ~= nil then local skillInfo = v.skill if v.luaextdata == nil then v.luaextdata = {} end if v.luaextdata.skillinfo == nil then v.luaextdata.skillinfo = skillInfo end if v.luaextdata.originid == nil then v.luaextdata.originid = v.id end end end table.insert(reward1, v) local bagIdx = gainbagidxbyitemid(ptActor, v.id) table.insert(removeItems, bagIdx) end local desc = string.format("交易扣除") if table.count(reward1) > 0 then removeitembyidxlist(ptActor, removeItems, 9999, desc) sendmailbycompleteitems(ptActor, ptInfo.targetId, string.format("交易完成"), "以下是您在交易中获得的道具,请查收。", reward1) end end function Transaction.onConfirm(actor, ptInfo, ttInfo) local playerItemCount = ptInfo.itemCount or 0 local targetItemCount = ttInfo.itemCount or 0 local playerItems = ptInfo.items local targetItems = ttInfo.items local ptRid = ttInfo.targetId local ttRid = ptInfo.targetId if tostring(ptRid) == tostring(ttRid) then messagebox(actor, "无法跟自己交易") return end local ptActor = getactor(actor, ptRid) local ttActor = getactor(actor, ttRid) local playerName = getbaseinfo(ptActor, "rolename") local targetName = getbaseinfo(ttActor, "rolename") if table.count(playerItems) ~= playerItemCount or table.count(targetItems) ~= targetItemCount then messagebox(ptActor, string.format("1100#交易错误", playerName)) messagebox(ttActor, string.format("1100#交易错误", playerName)) Transaction.clearInfo(actor) return end -- 判断道具是否足够 local coin1Num = getbagitemcountbyid(ptActor, 10010001) local coin2Num = getbagitemcountbyid(ptActor, 10020001) if ptInfo.coin1 > coin1Num or ptInfo.coin2 > coin2Num then messagebox(ptActor, string.format("%s道具数量不足", playerName)) messagebox(ttActor, string.format("%s道具数量不足", playerName)) Transaction.clearInfo(actor) return end coin1Num = getbagitemcountbyid(ttActor, 10010001) coin2Num = getbagitemcountbyid(ttActor, 10020001) if ttInfo.coin1 > coin1Num or ttInfo.coin2 > coin2Num then messagebox(ptActor, string.format("%s道具数量不足", targetName)) messagebox(ttActor, string.format("%s道具数量不足", targetName)) Transaction.clearInfo(actor) return end -- 检查物品是否还在背包中 local ptCheckBag = {} for _, v in pairs(playerItems) do local paramMap = {} paramMap["cfgid"] = v.cfgid paramMap["itemcount"] = 1 table.insert(ptCheckBag, paramMap) local bagIdx = gainbagidxbyitemid(ptActor, v.id) local count = getbagitemcountbyid(ptActor, v.cfgid) if bagIdx == 0 or count < v.count then messagebox(ptActor, string.format("%s道具出错,交易失败", playerName)) messagebox(ttActor, string.format("%s道具出错,交易失败", playerName)) Transaction.clearInfo(actor) return end end local canPutBag = checkitemscanputbag(ttActor, ptCheckBag) if tonumber(canPutBag) == 0 and table.notNullOrEmpty(ptCheckBag) then messagebox(ptActor, string.format("%s背包已满,交易失败", targetName)) messagebox(ttActor, string.format("%s背包已满,交易失败", targetName)) Transaction.clearInfo(actor) return end ptCheckBag = {} for _, v in pairs(targetItems) do local paramMap = {} paramMap["cfgid"] = v.cfgid paramMap["itemcount"] = 1 table.insert(ptCheckBag, paramMap) local bagIdx = gainbagidxbyitemid(ttActor, v.id) local count = getbagitemcountbyid(ttActor, v.cfgid) if bagIdx == 0 or count < v.count then messagebox(ptActor, string.format("%s道具出错,交易失败", targetName)) messagebox(ttActor, string.format("%s道具出错,交易失败", targetName)) Transaction.clearInfo(actor) return end end local canPutBag1 = checkitemscanputbag(ptActor, ptCheckBag) if tonumber(canPutBag1) == 0 and table.notNullOrEmpty(ptCheckBag) then messagebox(ptActor, string.format("%s背包已满,交易失败", playerName)) messagebox(ttActor, string.format("%s背包已满,交易失败", playerName)) Transaction.clearInfo(actor) return end if ptInfo.coin1 > 0 then removeitemfrombag(ptActor, 10010001, ptInfo.coin1, 1, 9999, "交易消耗") end if ptInfo.coin2 > 0 then removeitemfrombag(ptActor, 10020001, ptInfo.coin2, 1, 9999, "交易消耗") end if ttInfo.coin1 > 0 then removeitemfrombag(ttActor, 10010001, ttInfo.coin1, 1, 9999, "交易消耗") end if ttInfo.coin2 > 0 then removeitemfrombag(ttActor, 10020001, ttInfo.coin2, 1, 9999, "交易消耗") end if ptInfo.coin1 > 0 then Bag.addItemMapToBag( ttActor, { ["10010001"] = ptInfo.coin1 }, 0, 9999, "交易获得" ) end if ptInfo.coin2 > 0 then Bag.addItemMapToBag( ttActor, { ["10020001"] = ptInfo.coin2 }, 0, 9999, "交易获得" ) end if ttInfo.coin1 > 0 then Bag.addItemMapToBag( ptActor, { ["10010001"] = ttInfo.coin1 }, 0, 9999, "交易获得" ) end if ttInfo.coin2 > 0 then Bag.addItemMapToBag( ptActor, { ["10020001"] = ttInfo.coin2 }, 0, 9999, "交易获得" ) end Transaction.mailItemsToActor(actor, ptInfo, ttInfo) Transaction.mailItemsToActor(actor, ttInfo, ptInfo) Transaction.clearInfo(actor) API.SendCenterMsg(actor, "交易成功", "#00ff00") API.SendCenterMsg(ttActor, "交易成功", "#00ff00") end function Transaction.clear(ptInfo, ttInfo) local transactions = Transaction.GetTransactions() transactions[ptInfo.targetId] = nil transactions[ttInfo.targetId] = nil Transaction.SetTransactions(transactions) end function Transaction.GetTransactions() local transactions = getsysvar(SYS_TRANSACTIONS) if transactions == nil then transactions = {} end return transactions end function Transaction.SetTransactions(transactions) setsysvar(SYS_TRANSACTIONS, transactions) end