Transaction = {} local this = Transaction; local filename = "Transaction"; -- 限制只能对一个人发起交易请求.只有最新的申请会生效.交易申请会有5秒的cd. -- 交易缓存数据 id = {status=0, sec=0, targetId=0, item={}} SYS_TRANSACTIONS = "R$transaction_transactions" function Transaction.onLoginEnd(actor) -- this.msgId = LuaMessageIdToSever.TransactionInfo_MsgID 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, } return data 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 transactions = Transaction.GetTransactions(); 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, "距离过远,无法进行交易") transactions[playerInfo.rid] = nil if targetInfo ~= nil then transactions[targetInfo.rid] = nil end Transaction.SetTransactions(transactions) return end -- 判断交易状态 local playerState = getfightstate(actor) local targetState = getfightstate(actor) if playerState == 1 or targetState == 1 then tipinfo(actor, "战斗状态中,无法进行交易") tipinfo(targetActor, "战斗状态中,无法进行交易") -- Transaction.clear(playerInfo, targetInfo) transactions[playerInfo.rid] = nil transactions[targetInfo.rid] = nil Transaction.SetTransactions(transactions) return end local nowsec = getbaseinfo(actor, "nowsec") local ptInfo = transactions[rid] local ttInfo = transactions[targetId] if (ptInfo ~= nil and ptInfo.sec ~= nil and nowsec - ptInfo.sec < 30) or ttInfo ~= nil and ttInfo.sec ~= nil and nowsec - ttInfo.sec < 30 then tipinfo(actor, "交易中,无法进行交易") tipinfo(targetActor, "交易中,无法进行交易") return end -- 对方可能跟其他人交易中 if ttInfo ~= nil and ttInfo.targetId ~= rid then tipinfo(actor, "对方正在交易中,无法进行交易") return end -- 创建交易数据 local d1 = { status = 5, sec = nowsec, targetId = targetId, items = {}, otherItems = {}, coin1 = 0, coin2 = 0, coinOther1 = 0, coinOther2 = 0 } local d2 = { status = 5, sec = nowsec, targetId = rid, items = {}, otherItems = {}, coin1 = 0, coin2 = 0, coinOther1 = 0, coinOther2 = 0 } transactions[rid] = d1 transactions[targetId] = d2 Transaction.SetTransactions(transactions) -- 打开交易界面 sendluamsg(targetActor, msgid, { type = 4, rid = rid, name = playerInfo.name }) sendluamsg(actor, msgid, { type = 4, rid = targetId, name = targetInfo.name }) elseif type == 5 then if Transaction.CheckStatus(actor, rid, msgid, 1) ~= true then return end local ptInfo = transactions[rid] if ptInfo == nil then return end local ttInfo = transactions[ptInfo.targetId] if ptInfo.status ~= 5 then tipinfo(actor, "当前交易状态无法更换物品") return end local targetActor = getactor(actor, ptInfo.targetId) -- 检查背包是否有这些道具.没有的直接剔除 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, Transaction.getItemDataSimple(actor, 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 Transaction.SetTransactions(transactions) sendluamsg(targetActor, msgid, { type = 5, rid = rid, items = ttInfo.items, otherItems = ptInfo.items, coin1 = ttInfo.coin1, coin2 = ttInfo.coin2, coinOther1 = ptInfo.coin1, coinOther2 = ptInfo.coin2 }) sendluamsg(actor, msgid, { type = 5, rid = ptInfo.targetId, items = ptInfo.items, otherItems = ttInfo.items, coin1 = ptInfo.coin1, coin2 = ptInfo.coin2, coinOther1 = ttInfo.coin1, coinOther2 = ttInfo.coin2 }) elseif type == 6 then if Transaction.CheckStatus(actor, rid, msgid, 2) ~= true then return end -- 确定锁定 local ptInfo = transactions[rid] if ptInfo == nil then tipinfo(actor, "未知错误.") return end if ptInfo.status == 7 then tipinfo(actor, "已确定交易.无法更改交易状态") return end local ttInfo = transactions[ptInfo.targetId] if ptInfo.status == 6 then ptInfo.status = 5 ttInfo.status = 5 else ptInfo.status = 6 end Transaction.SetTransactions(transactions) local targetActor = getactor(actor, ptInfo.targetId) -- 锁定时.再同步双方的信息 sendluamsg(targetActor, msgid, { type = 5, rid = rid, items = ttInfo.items, otherItems = ptInfo.items, coin1 = ttInfo.coin1, coin2 = ttInfo.coin2, coinOther1 = ptInfo.coin1, coinOther2 = ptInfo.coin2 }) sendluamsg(actor, msgid, { type = 5, rid = ptInfo.targetId, items = ptInfo.items, otherItems = ttInfo.items, coin1 = ptInfo.coin1, coin2 = ptInfo.coin2, coinOther1 = ttInfo.coin1, coinOther2 = ttInfo.coin2 }) sendluamsg(targetActor, msgid, { type = 6, rid = rid, isLock = ttInfo.status == 6, isLockOther = ptInfo.status == 6 or ptInfo.status == 7, isConfirm = ttInfo.status == 7, isConfirmOther = ptInfo.status == 7 }) sendluamsg(actor, msgid, { type = 6, rid = ptInfo.targetId, isLock = ptInfo.status == 6, isLockOther = ttInfo.status == 6 or ttInfo.status == 7, isConfirm = ptInfo.status == 7, isConfirmOther = ttInfo.status == 7 }) elseif type == 7 then if Transaction.CheckStatus(actor, rid, msgid, 3) ~= true then return end -- 判断背包是否有空格 -- IsBagFullOrHasSpace -- 确定交易 local ptInfo = transactions[rid] if ptInfo == nil then tipinfo(actor, "未知错误.") return end if ptInfo.status == 7 then tipinfo(actor, "交易已锁定,无法修改交易状态.") return end if ptInfo.status ~= 6 then tipinfo(actor, "请先锁定交易状态.") return end local ttInfo = transactions[ptInfo.targetId] ptInfo.status = 7 Transaction.SetTransactions(transactions) local targetActor = getactor(actor, ptInfo.targetId) -- 双方确定交易 if ptInfo.status == 7 and ttInfo.status == 7 then Transaction.onConfirm(actor, ptInfo, ttInfo) -- Transaction.SetTransactions(transactions) -- 同步交易状态 sendluamsg(targetActor, msgid, { type = 10, rid = rid }) sendluamsg(actor, msgid, { type = 10, rid = ptInfo.targetId }) return end Transaction.SetTransactions(transactions) -- 同步交易状态 sendluamsg(targetActor, msgid, { type = 7, rid = rid, isLock = ttInfo.status == 6, isLockOther = ptInfo.status == 6 or ptInfo.status == 7, isConfirm = ttInfo.status == 7, isConfirmOther = ptInfo.status == 7 }) sendluamsg(actor, msgid, { type = 7, rid = ptInfo.targetId, isLock = ptInfo.status == 6, isLockOther = ttInfo.status == 6 or ttInfo.status == 7, isConfirm = ptInfo.status == 7, isConfirmOther = ttInfo.status == 7 }) elseif type == 30 then if Transaction.CheckStatus(actor, rid, msgid, 1) ~= true then return end local ptInfo = transactions[rid] if ptInfo == nil then return end local targetActor = getactor(actor, ptInfo.targetId) tipinfo(targetActor, "对方已取消交易") -- 同步交易状态 sendluamsg(targetActor, msgid, { type = 30, rid = rid }) sendluamsg(actor, msgid, { type = 30, rid = ptInfo.targetId }) local ttInfo = transactions[ptInfo.targetId] Transaction.clear(ptInfo, ttInfo) elseif type == 101 then if Transaction.CheckStatus(actor, rid, msgid, 1) ~= true then return end elseif type == 1001 then -- Transaction.mailToBag(actor) end end local cfgMailId = 107000 function Transaction.mailToBag(actor) local cfgMail = ConfigDataManager.getById("cfg_mail", cfgMailId) local mails = getmailinfo(actor) for key, mail in pairs(mails) do local isTransactionMail = mail.cfgid == EmailConfig.TRANSACTION if isTransactionMail ~= true then if mail.title == cfgMail.title then isTransactionMail = true end end if isTransactionMail then getemailitems(actor, mail.mailid) changemailstate(actor, 3, mail.mailid) end end end function Transaction.mailItemsToActor(actor, ptInfo, ttInfo) local ptRid = ttInfo.targetId local ttRid = ptInfo.targetId local ptActor = getactor(tonumber(ptRid)) -- local ttActor = getactor(tonumber(ttRid)) local playerItems = ptInfo.items; -- local playerName = getbaseinfo(ptActor, "rolename") -- local targetName = getbaseinfo(ttActor, "rolename") local reward1 = {} local removeItems = {} for k, v in pairs(playerItems) do 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) -- destroyitemafter(ptActor, bagIdx) -- removeItems[bagIdx] = v.count -- removeitembyidxlist(ptActor, {bagIdx}, 9999, "") 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 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") -- 判断道具是否足够 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.clear(ptInfo, ttInfo) 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.clear(ptInfo, ttInfo) 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.clear(ptInfo, ttInfo) 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.clear(ptInfo, ttInfo) 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.clear(ptInfo, ttInfo) 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.clear(ptInfo, ttInfo) 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 additemmaptobag(ttActor, { ["10010001"] = ptInfo.coin1 }, 0, 9999, "交易获得") end if ptInfo.coin2 > 0 then additemmaptobag(ttActor, { ["10020001"] = ptInfo.coin2 }, 0, 9999, "交易获得") end if ttInfo.coin1 > 0 then additemmaptobag(ptActor, { ["10010001"] = ttInfo.coin1 }, 0, 9999, "交易获得") end if ttInfo.coin2 > 0 then additemmaptobag(ptActor, { ["10020001"] = ttInfo.coin2 }, 0, 9999, "交易获得") end Transaction.mailItemsToActor(actor, ptInfo, ttInfo) Transaction.mailItemsToActor(actor, ttInfo, ptInfo) Transaction.clear(ptInfo, ttInfo) tipinfo(actor, "交易成功") 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