Transaction.lua 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. Transaction = {}
  2. local this = Transaction;
  3. local filename = "Transaction";
  4. -- 限制只能对一个人发起交易请求.只有最新的申请会生效.交易申请会有5秒的cd.
  5. -- 交易缓存数据 id = {status=0, sec=0, targetId=0, item={}}
  6. SYS_TRANSACTIONS = "R$transaction_transactions"
  7. function Transaction.onLoginEnd(actor)
  8. -- this.msgId = LuaMessageIdToSever.TransactionInfo_MsgID
  9. end
  10. function Transaction.onReloadScript(actor)
  11. end
  12. function Transaction.CheckStatus(actor, rid, msgid, status)
  13. return true
  14. -- local nowsec = getbaseinfo(actor, "nowsec")
  15. -- local playerTransactionInfo = transactions[rid]
  16. -- if playerTransactionInfo == nil or nowsec - playerTransactionInfo.sec > 30 then
  17. -- sendluamsg(actor, msgid, {
  18. -- type = 101,
  19. -- status = status
  20. -- })
  21. -- return false
  22. -- end
  23. -- local targetTransactionInfo = transactions[playerTransactionInfo.targetId]
  24. -- if targetTransactionInfo == nil or targetTransactionInfo.targetId ~= rid or nowsec - targetTransactionInfo.sec > 30 then
  25. -- local targetActor = getactor(actor, playerTransactionInfo.targetId)
  26. -- sendluamsg(targetActor, msgid, {
  27. -- type = 101,
  28. -- status = status
  29. -- })
  30. -- return false
  31. -- end
  32. -- playerTransactionInfo.sec = nowsec
  33. -- targetTransactionInfo.sec = nowsec
  34. -- return true
  35. end
  36. function Transaction.getItemDataSimple(actor, item)
  37. -- local item2 = getitemattinfo(actor, 1, item.cfgid, item.id)
  38. local data = {
  39. id = item.id,
  40. cfgid = item.cfgid,
  41. isServerStyle = true,
  42. entries = item.entries,
  43. luaextdata = item.luaextdata,
  44. count = item.count,
  45. type = item.type,
  46. basicattr = item.basicattr,
  47. luckyattr = item.luckyattr,
  48. }
  49. return data
  50. end
  51. function Transaction.onHandlereQuest(actor, msgid, sMsg)
  52. local type = sMsg.type
  53. local targetId = sMsg.rid
  54. local rid = getbaseinfo(actor, "rid")
  55. local items = sMsg.items
  56. local coin1 = sMsg.coin1
  57. local coin2 = sMsg.coin2
  58. local transactions = Transaction.GetTransactions();
  59. if type == 1 then
  60. local targetActor = getactor(actor, targetId)
  61. if rid == targetId then
  62. tipinfo(actor, "无法跟自己交易")
  63. return
  64. end
  65. -- 请求跟其他玩家交易
  66. local name = getbaseinfo(actor, "rolename")
  67. sendluamsg(targetActor, msgid, {
  68. type = 2,
  69. rid = rid,
  70. name = name
  71. })
  72. elseif type == 3 then
  73. -- 自己接受交易
  74. local targetActor = getactor(actor, targetId)
  75. -- 判断交易距离
  76. local playerInfo = getplayermaininfo(actor)
  77. local targetInfo = getplayermaininfo(targetActor)
  78. if playerInfo.mapid ~= targetInfo.mapid or
  79. (math.abs(playerInfo.x - targetInfo.x) >= 4 or math.abs(playerInfo.y - targetInfo.y) >= 4) then
  80. tipinfo(actor, "距离过远,无法进行交易")
  81. tipinfo(targetActor, "距离过远,无法进行交易")
  82. transactions[playerInfo.rid] = nil
  83. if targetInfo ~= nil then
  84. transactions[targetInfo.rid] = nil
  85. end
  86. Transaction.SetTransactions(transactions)
  87. return
  88. end
  89. -- 判断交易状态
  90. local playerState = getfightstate(actor)
  91. local targetState = getfightstate(actor)
  92. if playerState == 1 or targetState == 1 then
  93. tipinfo(actor, "战斗状态中,无法进行交易")
  94. tipinfo(targetActor, "战斗状态中,无法进行交易")
  95. -- Transaction.clear(playerInfo, targetInfo)
  96. transactions[playerInfo.rid] = nil
  97. transactions[targetInfo.rid] = nil
  98. Transaction.SetTransactions(transactions)
  99. return
  100. end
  101. local nowsec = getbaseinfo(actor, "nowsec")
  102. local ptInfo = transactions[rid]
  103. local ttInfo = transactions[targetId]
  104. if (ptInfo ~= nil and ptInfo.sec ~= nil and nowsec - ptInfo.sec < 30) or ttInfo ~= nil and ttInfo.sec ~= nil and nowsec -
  105. ttInfo.sec < 30 then
  106. tipinfo(actor, "交易中,无法进行交易")
  107. tipinfo(targetActor, "交易中,无法进行交易")
  108. return
  109. end
  110. -- 对方可能跟其他人交易中
  111. if ttInfo ~= nil and ttInfo.targetId ~= rid then
  112. tipinfo(actor, "对方正在交易中,无法进行交易")
  113. return
  114. end
  115. -- 创建交易数据
  116. local d1 = {
  117. status = 5,
  118. sec = nowsec,
  119. targetId = targetId,
  120. items = {},
  121. otherItems = {},
  122. coin1 = 0,
  123. coin2 = 0,
  124. coinOther1 = 0,
  125. coinOther2 = 0
  126. }
  127. local d2 = {
  128. status = 5,
  129. sec = nowsec,
  130. targetId = rid,
  131. items = {},
  132. otherItems = {},
  133. coin1 = 0,
  134. coin2 = 0,
  135. coinOther1 = 0,
  136. coinOther2 = 0
  137. }
  138. transactions[rid] = d1
  139. transactions[targetId] = d2
  140. Transaction.SetTransactions(transactions)
  141. -- 打开交易界面
  142. sendluamsg(targetActor, msgid, {
  143. type = 4,
  144. rid = rid,
  145. name = playerInfo.name
  146. })
  147. sendluamsg(actor, msgid, {
  148. type = 4,
  149. rid = targetId,
  150. name = targetInfo.name
  151. })
  152. elseif type == 5 then
  153. if Transaction.CheckStatus(actor, rid, msgid, 1) ~= true then
  154. return
  155. end
  156. local ptInfo = transactions[rid]
  157. if ptInfo == nil then
  158. return
  159. end
  160. local ttInfo = transactions[ptInfo.targetId]
  161. if ptInfo.status ~= 5 then
  162. tipinfo(actor, "当前交易状态无法更换物品")
  163. return
  164. end
  165. local targetActor = getactor(actor, ptInfo.targetId)
  166. -- 检查背包是否有这些道具.没有的直接剔除
  167. local maxCount = 10
  168. local count = 0
  169. local realItem = {}
  170. for key, itemId in ipairs(items) do
  171. local item = getbagiteminfo(actor, itemId, 1)
  172. if item ~= nil and item.isbind ~= true and count < maxCount then
  173. count = count + 1
  174. table.insert(realItem, Transaction.getItemDataSimple(actor, item))
  175. end
  176. end
  177. local coin1Num = getbagitemcountbyid(actor, 10010001)
  178. local coin2Num = getbagitemcountbyid(actor, 10020001)
  179. if coin1 > coin1Num then
  180. coin1 = coin1Num
  181. end
  182. if coin2 > coin2Num then
  183. coin2 = coin2Num
  184. end
  185. ptInfo.coin1 = coin1
  186. ptInfo.coin2 = coin2
  187. ptInfo.items = realItem
  188. Transaction.SetTransactions(transactions)
  189. sendluamsg(targetActor, msgid, {
  190. type = 5,
  191. rid = rid,
  192. items = ttInfo.items,
  193. otherItems = ptInfo.items,
  194. coin1 = ttInfo.coin1,
  195. coin2 = ttInfo.coin2,
  196. coinOther1 = ptInfo.coin1,
  197. coinOther2 = ptInfo.coin2
  198. })
  199. sendluamsg(actor, msgid, {
  200. type = 5,
  201. rid = ptInfo.targetId,
  202. items = ptInfo.items,
  203. otherItems = ttInfo.items,
  204. coin1 = ptInfo.coin1,
  205. coin2 = ptInfo.coin2,
  206. coinOther1 = ttInfo.coin1,
  207. coinOther2 = ttInfo.coin2
  208. })
  209. elseif type == 6 then
  210. if Transaction.CheckStatus(actor, rid, msgid, 2) ~= true then
  211. return
  212. end
  213. -- 确定锁定
  214. local ptInfo = transactions[rid]
  215. if ptInfo == nil then
  216. tipinfo(actor, "未知错误.")
  217. return
  218. end
  219. if ptInfo.status == 7 then
  220. tipinfo(actor, "已确定交易.无法更改交易状态")
  221. return
  222. end
  223. local ttInfo = transactions[ptInfo.targetId]
  224. if ptInfo.status == 6 then
  225. ptInfo.status = 5
  226. ttInfo.status = 5
  227. else
  228. ptInfo.status = 6
  229. end
  230. Transaction.SetTransactions(transactions)
  231. local targetActor = getactor(actor, ptInfo.targetId)
  232. -- 锁定时.再同步双方的信息
  233. sendluamsg(targetActor, msgid, {
  234. type = 5,
  235. rid = rid,
  236. items = ttInfo.items,
  237. otherItems = ptInfo.items,
  238. coin1 = ttInfo.coin1,
  239. coin2 = ttInfo.coin2,
  240. coinOther1 = ptInfo.coin1,
  241. coinOther2 = ptInfo.coin2
  242. })
  243. sendluamsg(actor, msgid, {
  244. type = 5,
  245. rid = ptInfo.targetId,
  246. items = ptInfo.items,
  247. otherItems = ttInfo.items,
  248. coin1 = ptInfo.coin1,
  249. coin2 = ptInfo.coin2,
  250. coinOther1 = ttInfo.coin1,
  251. coinOther2 = ttInfo.coin2
  252. })
  253. sendluamsg(targetActor, msgid, {
  254. type = 6,
  255. rid = rid,
  256. isLock = ttInfo.status == 6,
  257. isLockOther = ptInfo.status == 6 or ptInfo.status == 7,
  258. isConfirm = ttInfo.status == 7,
  259. isConfirmOther = ptInfo.status == 7
  260. })
  261. sendluamsg(actor, msgid, {
  262. type = 6,
  263. rid = ptInfo.targetId,
  264. isLock = ptInfo.status == 6,
  265. isLockOther = ttInfo.status == 6 or ttInfo.status == 7,
  266. isConfirm = ptInfo.status == 7,
  267. isConfirmOther = ttInfo.status == 7
  268. })
  269. elseif type == 7 then
  270. if Transaction.CheckStatus(actor, rid, msgid, 3) ~= true then
  271. return
  272. end
  273. -- 判断背包是否有空格
  274. -- IsBagFullOrHasSpace
  275. -- 确定交易
  276. local ptInfo = transactions[rid]
  277. if ptInfo == nil then
  278. tipinfo(actor, "未知错误.")
  279. return
  280. end
  281. if ptInfo.status == 7 then
  282. tipinfo(actor, "交易已锁定,无法修改交易状态.")
  283. return
  284. end
  285. if ptInfo.status ~= 6 then
  286. tipinfo(actor, "请先锁定交易状态.")
  287. return
  288. end
  289. local ttInfo = transactions[ptInfo.targetId]
  290. ptInfo.status = 7
  291. Transaction.SetTransactions(transactions)
  292. local targetActor = getactor(actor, ptInfo.targetId)
  293. -- 双方确定交易
  294. if ptInfo.status == 7 and ttInfo.status == 7 then
  295. Transaction.onConfirm(actor, ptInfo, ttInfo)
  296. -- Transaction.SetTransactions(transactions)
  297. -- 同步交易状态
  298. sendluamsg(targetActor, msgid, {
  299. type = 10,
  300. rid = rid
  301. })
  302. sendluamsg(actor, msgid, {
  303. type = 10,
  304. rid = ptInfo.targetId
  305. })
  306. return
  307. end
  308. Transaction.SetTransactions(transactions)
  309. -- 同步交易状态
  310. sendluamsg(targetActor, msgid, {
  311. type = 7,
  312. rid = rid,
  313. isLock = ttInfo.status == 6,
  314. isLockOther = ptInfo.status == 6 or ptInfo.status == 7,
  315. isConfirm = ttInfo.status == 7,
  316. isConfirmOther = ptInfo.status == 7
  317. })
  318. sendluamsg(actor, msgid, {
  319. type = 7,
  320. rid = ptInfo.targetId,
  321. isLock = ptInfo.status == 6,
  322. isLockOther = ttInfo.status == 6 or ttInfo.status == 7,
  323. isConfirm = ptInfo.status == 7,
  324. isConfirmOther = ttInfo.status == 7
  325. })
  326. elseif type == 30 then
  327. if Transaction.CheckStatus(actor, rid, msgid, 1) ~= true then
  328. return
  329. end
  330. local ptInfo = transactions[rid]
  331. if ptInfo == nil then
  332. return
  333. end
  334. local targetActor = getactor(actor, ptInfo.targetId)
  335. tipinfo(targetActor, "对方已取消交易")
  336. -- 同步交易状态
  337. sendluamsg(targetActor, msgid, {
  338. type = 30,
  339. rid = rid
  340. })
  341. sendluamsg(actor, msgid, {
  342. type = 30,
  343. rid = ptInfo.targetId
  344. })
  345. local ttInfo = transactions[ptInfo.targetId]
  346. Transaction.clear(ptInfo, ttInfo)
  347. elseif type == 101 then
  348. if Transaction.CheckStatus(actor, rid, msgid, 1) ~= true then
  349. return
  350. end
  351. elseif type == 1001 then
  352. -- Transaction.mailToBag(actor)
  353. end
  354. end
  355. local cfgMailId = 107000
  356. function Transaction.mailToBag(actor)
  357. local cfgMail = ConfigDataManager.getById("cfg_mail", cfgMailId)
  358. local mails = getmailinfo(actor)
  359. for key, mail in pairs(mails) do
  360. local isTransactionMail = mail.cfgid == EmailConfig.TRANSACTION
  361. if isTransactionMail ~= true then
  362. if mail.title == cfgMail.title then
  363. isTransactionMail = true
  364. end
  365. end
  366. if isTransactionMail then
  367. getemailitems(actor, mail.mailid)
  368. changemailstate(actor, 3, mail.mailid)
  369. end
  370. end
  371. end
  372. function Transaction.mailItemsToActor(actor, ptInfo, ttInfo)
  373. local ptRid = ttInfo.targetId
  374. local ttRid = ptInfo.targetId
  375. local ptActor = getactor(tonumber(ptRid))
  376. -- local ttActor = getactor(tonumber(ttRid))
  377. local playerItems = ptInfo.items;
  378. -- local playerName = getbaseinfo(ptActor, "rolename")
  379. -- local targetName = getbaseinfo(ttActor, "rolename")
  380. local reward1 = {}
  381. local removeItems = {}
  382. for k, v in pairs(playerItems) do
  383. local cfgItem = ConfigDataManager.getById("cfg_item", v.cfgid)
  384. if cfgItem.type == "2" then
  385. local cfgEquip = ConfigDataManager.getById("cfg_equip_entryLib", v.cfgid)
  386. if cfgEquip ~= nil then
  387. local skillInfo = v.skill
  388. if v.luaextdata == nil then
  389. v.luaextdata = {}
  390. end
  391. if v.luaextdata.skillinfo == nil then
  392. v.luaextdata.skillinfo = skillInfo
  393. end
  394. if v.luaextdata.originid == nil then
  395. v.luaextdata.originid = v.id
  396. end
  397. end
  398. end
  399. table.insert(reward1, v)
  400. local bagIdx = gainbagidxbyitemid(ptActor, v.id)
  401. table.insert(removeItems, bagIdx)
  402. -- destroyitemafter(ptActor, bagIdx)
  403. -- removeItems[bagIdx] = v.count
  404. -- removeitembyidxlist(ptActor, {bagIdx}, 9999, "")
  405. end
  406. local desc = string.format("交易扣除")
  407. if table.count(reward1) > 0 then
  408. removeitembyidxlist(ptActor, removeItems, 9999, desc)
  409. sendmailbycompleteitems(ptActor, ptInfo.targetId, string.format("交易完成"),
  410. "以下是您在交易中获得的道具,请查收。", reward1)
  411. end
  412. end
  413. function Transaction.onConfirm(actor, ptInfo, ttInfo)
  414. local playerItems = ptInfo.items;
  415. local targetItems = ttInfo.items;
  416. local ptRid = ttInfo.targetId
  417. local ttRid = ptInfo.targetId
  418. if tostring(ptRid) == tostring(ttRid) then
  419. messagebox(actor, "无法跟自己交易")
  420. return
  421. end
  422. local ptActor = getactor(actor, ptRid)
  423. local ttActor = getactor(actor, ttRid)
  424. local playerName = getbaseinfo(ptActor, "rolename")
  425. local targetName = getbaseinfo(ttActor, "rolename")
  426. -- 判断道具是否足够
  427. local coin1Num = getbagitemcountbyid(ptActor, 10010001)
  428. local coin2Num = getbagitemcountbyid(ptActor, 10020001)
  429. if ptInfo.coin1 > coin1Num or ptInfo.coin2 > coin2Num then
  430. messagebox(ptActor, string.format("%s道具数量不足", playerName))
  431. messagebox(ttActor, string.format("%s道具数量不足", playerName))
  432. Transaction.clear(ptInfo, ttInfo)
  433. return
  434. end
  435. coin1Num = getbagitemcountbyid(ttActor, 10010001)
  436. coin2Num = getbagitemcountbyid(ttActor, 10020001)
  437. if ttInfo.coin1 > coin1Num or ttInfo.coin2 > coin2Num then
  438. messagebox(ptActor, string.format("%s道具数量不足", targetName))
  439. messagebox(ttActor, string.format("%s道具数量不足", targetName))
  440. Transaction.clear(ptInfo, ttInfo)
  441. return
  442. end
  443. -- 检查物品是否还在背包中
  444. local ptCheckBag = {}
  445. for _, v in pairs(playerItems) do
  446. local paramMap = {}
  447. paramMap["cfgid"] = v.cfgid
  448. paramMap["itemcount"] = 1
  449. table.insert(ptCheckBag, paramMap)
  450. local bagIdx = gainbagidxbyitemid(ptActor, v.id)
  451. local count = getbagitemcountbyid(ptActor, v.cfgid)
  452. if bagIdx == 0 or count < v.count then
  453. messagebox(ptActor, string.format("%s道具出错,交易失败", playerName))
  454. messagebox(ttActor, string.format("%s道具出错,交易失败", playerName))
  455. Transaction.clear(ptInfo, ttInfo)
  456. return
  457. end
  458. end
  459. local canPutBag = checkitemscanputbag(ttActor, ptCheckBag)
  460. if tonumber(canPutBag) == 0 and table.notNullOrEmpty(ptCheckBag) then
  461. messagebox(ptActor, string.format("%s背包已满,交易失败", targetName))
  462. messagebox(ttActor, string.format("%s背包已满,交易失败", targetName))
  463. Transaction.clear(ptInfo, ttInfo)
  464. return
  465. end
  466. ptCheckBag = {}
  467. for _, v in pairs(targetItems) do
  468. local paramMap = {}
  469. paramMap["cfgid"] = v.cfgid
  470. paramMap["itemcount"] = 1
  471. table.insert(ptCheckBag, paramMap)
  472. local bagIdx = gainbagidxbyitemid(ttActor, v.id)
  473. local count = getbagitemcountbyid(ttActor, v.cfgid)
  474. if bagIdx == 0 or count < v.count then
  475. messagebox(ptActor, string.format("%s道具出错,交易失败", targetName))
  476. messagebox(ttActor, string.format("%s道具出错,交易失败", targetName))
  477. Transaction.clear(ptInfo, ttInfo)
  478. return
  479. end
  480. end
  481. local canPutBag1 = checkitemscanputbag(ptActor, ptCheckBag)
  482. if tonumber(canPutBag1) == 0 and table.notNullOrEmpty(ptCheckBag) then
  483. messagebox(ptActor, string.format("%s背包已满,交易失败", playerName))
  484. messagebox(ttActor, string.format("%s背包已满,交易失败", playerName))
  485. Transaction.clear(ptInfo, ttInfo)
  486. return
  487. end
  488. if ptInfo.coin1 > 0 then
  489. removeitemfrombag(ptActor, 10010001, ptInfo.coin1, 1, 9999, "交易消耗")
  490. end
  491. if ptInfo.coin2 > 0 then
  492. removeitemfrombag(ptActor, 10020001, ptInfo.coin2, 1, 9999, "交易消耗")
  493. end
  494. if ttInfo.coin1 > 0 then
  495. removeitemfrombag(ttActor, 10010001, ttInfo.coin1, 1, 9999, "交易消耗")
  496. end
  497. if ttInfo.coin2 > 0 then
  498. removeitemfrombag(ttActor, 10020001, ttInfo.coin2, 1, 9999, "交易消耗")
  499. end
  500. if ptInfo.coin1 > 0 then
  501. additemmaptobag(ttActor, {
  502. ["10010001"] = ptInfo.coin1
  503. }, 0, 9999, "交易获得")
  504. end
  505. if ptInfo.coin2 > 0 then
  506. additemmaptobag(ttActor, {
  507. ["10020001"] = ptInfo.coin2
  508. }, 0, 9999, "交易获得")
  509. end
  510. if ttInfo.coin1 > 0 then
  511. additemmaptobag(ptActor, {
  512. ["10010001"] = ttInfo.coin1
  513. }, 0, 9999, "交易获得")
  514. end
  515. if ttInfo.coin2 > 0 then
  516. additemmaptobag(ptActor, {
  517. ["10020001"] = ttInfo.coin2
  518. }, 0, 9999, "交易获得")
  519. end
  520. Transaction.mailItemsToActor(actor, ptInfo, ttInfo)
  521. Transaction.mailItemsToActor(actor, ttInfo, ptInfo)
  522. Transaction.clear(ptInfo, ttInfo)
  523. tipinfo(actor, "交易成功")
  524. end
  525. function Transaction.clear(ptInfo, ttInfo)
  526. local transactions = Transaction.GetTransactions()
  527. transactions[ptInfo.targetId] = nil
  528. transactions[ttInfo.targetId] = nil
  529. Transaction.SetTransactions(transactions)
  530. end
  531. function Transaction.GetTransactions()
  532. local transactions = getsysvar(SYS_TRANSACTIONS)
  533. if transactions == nil then
  534. transactions = {}
  535. end
  536. return transactions
  537. end
  538. function Transaction.SetTransactions(transactions)
  539. setsysvar(SYS_TRANSACTIONS, transactions)
  540. end