delitem.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. --[[
  2. 扣除玩家的物品
  3. ]]
  4. local skynet = require "skynet"
  5. require "skynet.manager"
  6. local logger = require "logger"
  7. local config = require "model.asset"
  8. local queue = require "skynet.queue"
  9. local cjson = require "cjson"
  10. local synchronized = queue()
  11. local namecenter = skynet.localname(".namecenter")
  12. local temp_config = mt
  13. local cjson = require "cjson"
  14. local redisdriver = require "skynet.db.redis"
  15. local stringify = require "stringify"
  16. local redis
  17. -- local z_trace = require "zlf_log"
  18. -- local z_trace = z_trace.trace
  19. local authz = {
  20. yytx = "lee@YY-Games.520"
  21. }
  22. local whitelist = {
  23. ["127.0.0.1"] = true,
  24. ["14.29.136.211"] = true,
  25. ["222.212.88.4"] = true,
  26. }
  27. -- 更具名字添加id
  28. local function get_id(name)
  29. return skynet.call(namecenter,"lua","findby", name)
  30. end
  31. -- 读取数据
  32. local function get_data(uid, key)
  33. local ret = redis:HMGET(string.format("character:%s", uid), key)
  34. if ret[1] then
  35. if key == "coins" -- 金币
  36. -- or key == "exp" -- 角色经验
  37. or key == "pkpoint" -- 竞技积分
  38. or key == "diamonds" -- 钻石
  39. or key == "friendship" -- 友情点
  40. or key == "contribute" -- 公会贡献
  41. or key == "advintegral" -- 公会冒险积分
  42. or key == "recharge_point" -- 充值积分
  43. or key == "research_note" -- 研究笔记 --PK3-1148
  44. or key == "megacoin" -- mege点
  45. or key == "bind_diamonds" -- 绑定钻石
  46. or key == "budo_point" -- 道馆积分
  47. or key == "manual_exp" -- 训练师手册积分 --PK3-1077
  48. or key == "explore" -- 探险值
  49. or key == "explore_exp" -- 探险经验
  50. or key == "gashapon_num" -- 扭蛋积分
  51. or key == "smeltpoint" -- 熔炼点
  52. or key == "uid"
  53. or key == "nickname"
  54. or key == "span_elf_king_point" -- 跨服至尊天王积分 -- CDPK3-86
  55. or key == "ruins_point" -- 古代金币 -- CDPK3-276 宝可梦遗迹
  56. then
  57. return ret[1]
  58. else
  59. return skynet.unpack(ret[1])
  60. end
  61. else
  62. return nil
  63. end
  64. end
  65. -- 设置数据
  66. local function set_data(uid, key, data)
  67. if data then
  68. if type(data) == "table" then
  69. redis:HMSET(string.format("character:%s", uid), key, skynet.packstring(data))
  70. else
  71. redis:HMSET(string.format("character:%s", uid), key, data)
  72. end
  73. end
  74. end
  75. -- 检查玩家是否存在
  76. local function check_receiver(uid)
  77. local ret = get_data(uid, "uid")
  78. return ret
  79. end
  80. local cmd = {}
  81. local err = {
  82. err_info = cjson.encode({state = 403, msg = "没有找到那个字段 3"}),
  83. err_than = cjson.encode({state = 403, msg = "扣除的值过大 4"}),
  84. err_find = cjson.encode({state = 403, msg = "扣除的sid不存在"}),
  85. err_empty = cjson.encode({state = 403,msg = "table里面的数据为空 8"}),
  86. err_elf = cjson.encode({state = 403, msg = "没有找到该精灵 ------ 3"}),
  87. err_set = cjson.encode({state = 403, msg = "精灵使用中"}),
  88. }
  89. function cmd.currency(key, value, uid)
  90. local info = get_data(uid, key)
  91. if not info then return err.err_info end
  92. info = tonumber(info)
  93. logger.trace(" key = %s, value = %s", key, value)
  94. if value > info then return err.err_than end
  95. info = info - value
  96. set_data(uid, key, info)
  97. end
  98. function cmd.pokemon_exp(key, value, uid)
  99. local info = get_data(uid, "elfdata")
  100. if not info then return err.err_info end
  101. if value > info.experience then return err.err_than end
  102. info.experience = info.experience - value
  103. set_data(uid, "elfdata", info)
  104. end
  105. function cmd.item(sid, num, uid)
  106. local info = get_data(uid, "bagdata")
  107. if not info then return err.err_info end
  108. if info.item[sid] then
  109. local value = (info.item[sid].num or 0) - num
  110. if value == 0 then
  111. info.item[sid] = nil
  112. info.num = info.num - 1 -- 被占用格子的数量
  113. elseif value > 0 then
  114. info.item[sid].num = value
  115. else
  116. return err.err_than
  117. end
  118. else
  119. return err.err_find
  120. end
  121. -- 保存数据
  122. set_data(uid, "bagdata", info)
  123. end
  124. -- TODO: 扣除符文碎片
  125. function cmd.rune(sid, num, uid)
  126. local info = get_data(uid, "elf_rune")
  127. if not info then return err.err_info end
  128. -- 统计数量
  129. local del = {}
  130. for k, v in pairs(info.rune_bag) do
  131. if v.sid == sid then
  132. table.insert(del, k)
  133. end
  134. end
  135. if #del == num then
  136. for _, id in pairs(del) do
  137. info.rune_bag[id] = nil
  138. info.rune_bagnum = info.rune_bagnum or 1
  139. info.rune_bagnum = info.rune_bagnum - 1
  140. end
  141. set_data(uid, "elf_rune", info)
  142. else
  143. return err.err_than
  144. end
  145. end
  146. -- TODO: 扣除携带品--CDPK3-271
  147. function cmd.carry(sid, num, uid)
  148. local info = get_data(uid, "elf_carry_items")
  149. if not info then return err.err_info end
  150. -- 统计数量
  151. local del = {}
  152. for k, v in pairs(info.carry_items_bag) do
  153. if v.sid == sid then
  154. table.insert(del, k)
  155. end
  156. end
  157. if #del == num then
  158. for _, id in pairs(del) do
  159. info.carry_items_bag[id] = nil
  160. info.carry_items_num = info.carry_items_num or 1
  161. info.carry_items_num = info.carry_items_num - 1
  162. end
  163. set_data(uid, "elf_carry_items", info)
  164. else
  165. return err.err_than
  166. end
  167. end
  168. -- TODO: 扣除代金券 CDPK3-1002
  169. function cmd.coupon(cid, sid, uid) -- cid:配置id sid:唯一id
  170. local info = get_data(uid, "coupon")
  171. if not info then return err.err_info end
  172. logger.trace("################ sid:%s, cid:%s", sid, cid)
  173. if info.bag[sid] and info.bag[sid].cid == cid then
  174. info.bag[sid] = nil
  175. set_data(uid, "coupon", info)
  176. else
  177. return err.err_than
  178. end
  179. end
  180. function cmd.fashion(id, num, uid)
  181. local info = get_data(uid, "dress")
  182. if not info then return err.err_info end
  183. --[[
  184. if info.owned[id] then
  185. if id == info.carry then
  186. info.carry = nil
  187. end
  188. info.owned[id] = nil
  189. set_data(uid, "dress", info)
  190. end
  191. ]]
  192. if info.owned[id] then
  193. if id == info.carry then
  194. info.carry = nil
  195. end
  196. -- info.owned[id] = nil
  197. if info.owned[id][1] > num then
  198. info.owned[id][1] = info.owned[id][1] - num
  199. elseif info.owned[id][1] == num then
  200. -- 已经进阶过得时装必须保留一件
  201. if info.owned[id][2] > 0 then
  202. return err.err_than
  203. end
  204. info.owned[id] = nil
  205. else
  206. return err.err_than
  207. end
  208. set_data(uid, "dress", info)
  209. end
  210. end
  211. function cmd.title(id, _, uid) --PK3-1030
  212. local info = get_data(uid, "title")
  213. if not info then return err.err_info end
  214. if info.titlelist[id] then
  215. if id == info.settitle then
  216. info.settitle = nil
  217. end
  218. info.titlelist[id] = nil
  219. set_data(uid, "title", info)
  220. end
  221. end
  222. function cmd.debris(sid, num, uid)
  223. local info = get_data(uid, "oncedata")
  224. if not info then return err.err_info end
  225. if info.debris and info.debris[sid] and info.debris[sid].num and info.debris[sid].num > 0 then
  226. local snum = info.debris[sid].num - num
  227. if snum == 0 then
  228. info.debris[sid] = nil
  229. elseif snum > 0 then
  230. info.debris[sid].num = snum
  231. else
  232. return err.err_than
  233. end
  234. set_data(uid, "oncedata", info)
  235. else
  236. return err.err_than
  237. end
  238. end
  239. function cmd.rune_debris(sid, num , uid)
  240. local info = get_data(uid, "rune_debris")
  241. if not info then return err.err_info end
  242. local rnum = 0
  243. if info.runedebris and info.runedebris[sid] and info.runedebris[sid].num and info.runedebris[sid].num > 0 then
  244. rnum = info.runedebris[sid].num
  245. end
  246. if rnum == 0 then
  247. return err.err_than
  248. end
  249. local value = rnum - num
  250. if value == 0 then
  251. info.runedebris[sid] = nil
  252. elseif value > 0 then
  253. info.runedebris[sid].num = value
  254. else
  255. return err.err_than
  256. end
  257. set_data(uid, "rune_debris", info)
  258. end
  259. function cmd.carry_debris(sid, num , uid)
  260. local info = get_data(uid, "carry_debris")
  261. if not info then return err.err_info end
  262. local rnum = 0
  263. if info.carrydebris and info.carrydebris[sid] and info.carrydebris[sid].num and info.carrydebris[sid].num > 0 then
  264. rnum = info.carrydebris[sid].num
  265. end
  266. if rnum == 0 then
  267. return err.err_than
  268. end
  269. local value = rnum - num
  270. if value == 0 then
  271. info.carrydebris[sid] = nil
  272. elseif value > 0 then
  273. info.carrydebris[sid].num = value
  274. else
  275. return err.err_than
  276. end
  277. set_data(uid, "carry_debris", info)
  278. end
  279. -- elf_awaken={[1]={sid = sid, lv = 0}}}, -- 觉醒降级 sid 精灵的模板id lv 觉醒的等级
  280. function cmd.elf_awaken(key, value, uid)
  281. if not next(value) then return err.err_empty end
  282. local info = get_data(uid, "elf_awaken")
  283. if not info then return err.err_info end
  284. local elfdata = get_data(uid, "elfdata")
  285. local function add(individual)
  286. local he = 0
  287. for _, v in pairs(individual) do
  288. he = he + v
  289. end
  290. return he
  291. end
  292. for _, elf in pairs(value) do
  293. if (not elf.individual) or elf.individual <= 0 then
  294. return cjson.encode({errno = 400, host = header.host, info = "精灵的个体值未空或0 ------- 1"})
  295. end
  296. local sign = true
  297. for id, elf_info in pairs(elfdata.elflist) do
  298. if elf_info.sid == elf.sid then
  299. local he = add(elf_info.individual)
  300. -- 精灵定位
  301. if he == elf.individual then
  302. -- 查找修改觉醒数据
  303. for k, v in pairs(info.awaken_list) do
  304. if v.sid == elf.sid and v.lv == elf.lv then
  305. if info.awaken_list[k].lv > 0 then
  306. -- d.awaken_list[k].lv = d.awaken_list[k].lv - 1
  307. info.awaken_list[k].lv = info.awaken_list[k].lv - 1
  308. else
  309. info.awaken_list[k] = nil
  310. end
  311. sign = false
  312. break
  313. end
  314. end
  315. -- break
  316. end
  317. end
  318. end
  319. if sign then return err.err_elf end
  320. end
  321. set_data(uid, "elf_awaken", info)
  322. end
  323. -- TODO: 扣除精灵
  324. function cmd.pokemon(e_sid, e_id, uid)
  325. local info = get_data(uid, "elfdata")
  326. if not info then return err.err_info end
  327. local state_info = get_data(uid, "elf_state")
  328. if not state_info then return err.err_info end
  329. local function check_elf(id, state_info)
  330. if state_info.elf_employ[id] then
  331. return true
  332. end
  333. end
  334. local detail = {}
  335. if info.elflist[e_id] and info.elflist[e_id].sid == e_sid then
  336. if check_elf(e_id, state_info) then
  337. return err.err_set -- 精灵使用中
  338. end
  339. info.elfcount.bagnum = info.elfcount.bagnum - 1
  340. detail = info.elflist[e_id]
  341. info.elflist[e_id] = nil
  342. set_data(uid, "elfdata", info)
  343. else
  344. return err.err_elf
  345. end
  346. return nil, detail
  347. end
  348. -- 类型邮件系统
  349. -- http://服务器ip地址:端口号/delitem?code="xxx"&uid="00-xx"&json=移除的道具or代币列表
  350. -- http://192.168.108.19:9002/delitem?code="xxx"&uid="00-xx"&json={"items":[[104,0,10000000],[102,0,3000],[1,20014,100]]}
  351. --[[ -- PK3-1366 数据统计
  352. local log = skynet.localname('.log')
  353. local function record(character, opcode, context)
  354. assert(character)
  355. assert(opcode)
  356. local bytes = cjson.encode({
  357. opcode=opcode,
  358. uid=character.uid,
  359. nickname=character.nickname,
  360. context=context,
  361. date=os.time()
  362. })
  363. skynet.send(log, "lua", "record", character.uid, bytes)
  364. end
  365. ]]
  366. local log = require "model.log" -- PK3-1366 数据统计
  367. local function fire(character, module, event, specific)
  368. assert(module)
  369. assert(event)
  370. assert(type(module) == "string")
  371. assert(type(event) == "string")
  372. --[[
  373. record(character, "event", {
  374. module=module,
  375. type=event,
  376. specific=specific
  377. })
  378. ]] -- PK3-1366 数据统计
  379. logger.trace(" ### specific %s", stringify(specific))
  380. log.fire(character,module,event, specific)
  381. end
  382. local delitem = function(args, ipaddr,header)
  383. return synchronized(function()
  384. logger.trace("处理来自主机 %s 的 扣除 请求", ipaddr)
  385. -- 验证主机id
  386. if not whitelist[ipaddr] then
  387. -- return cjson.encode({errno = 403, host = header.host, info = "不信任ip"})
  388. end
  389. -- 验证gm账号
  390. local code = string.sub(args.code, 1, 16)
  391. -- if code ~= content.sign then
  392. -- return cjson.encode({state = 403, msg = "账号或密码错误"})
  393. -- end
  394. -- 连接数据库
  395. local conf = assert(option.redis)
  396. redis = redisdriver.connect(conf)
  397. redis:select(0)
  398. -- 目标玩家的处理过程: 验证玩家uid是否存在
  399. logger.trace(" args = %s", stringify(args))
  400. --[[local uid = check_receiver(args.uid)
  401. if not uid then
  402. redis:disconnect()
  403. return cjson.encode({state = 403, msg = "没有找到该玩家 2 "})
  404. end]]
  405. local uid
  406. if args.name then
  407. uid =get_id(args.name)
  408. elseif args.uid then
  409. uid=args.uid
  410. elseif (not args.uid) and (not args.name) then
  411. return cjson.encode({state = 403,msg= "请输入玩家uid或者玩家name"})
  412. end
  413. uid=check_receiver(uid)
  414. if not uid then
  415. redis:disconnect()
  416. return cjson.encode({state = 403, msg = "没有找到该玩家 2 "})
  417. end
  418. local ok, delinfo = pcall(cjson.decode, args.json)
  419. logger.trace(" delinfo = %s", stringify(delinfo))
  420. if not ok then
  421. redis:disconnect()
  422. return cjson.encode({state = 403, msg = "内容错误"})
  423. end
  424. -- 循环处理需要处理得数据
  425. local entity = {}
  426. local key, value, ret
  427. for _, v in ipairs(delinfo.items) do
  428. if v[1] == GOODS_MONEY then -- 货币 精灵经验单独处理
  429. key = MONEY_TYPE[v[2]] -- 货币字段名
  430. value = v[3] -- 需要扣除得值
  431. if key == "exp1" then
  432. ret = cmd.pokemon_exp(key, value, uid)
  433. else
  434. ret = cmd.currency(key, value, uid)
  435. end
  436. entity[key] = value
  437. elseif v[1] == GOODS_ITEM then -- 道具
  438. ret = cmd.item(v[2], v[3], uid) -- 道具id, 数量
  439. entity["item"] = {[v[2]] = v[3] }
  440. elseif v[1] == TYPE_ELF then -- 精灵
  441. local detail
  442. ret,detail = cmd.pokemon(v[2], v[3], uid) -- 精灵模板, 精灵唯一id
  443. entity["pokemon"] = {[v[2]] = detail }
  444. elseif v[1] == TYPE_FASHION then -- 时装
  445. ret = cmd.fashion(v[2], v[3], uid) -- 时装id
  446. entity["fashion"] = {v[2]}
  447. elseif v[1] == TYPE_DEBRIS then -- 碎片
  448. ret = cmd.debris(v[2], v[3], uid) -- 碎片id, 数量
  449. entity["debris"] = {[v[2]] = v[3]}
  450. elseif v[1] == TYPE_RUNE then -- 符文
  451. ret = cmd.rune(v[2], v[3], uid) -- 符文id, 数量
  452. entity["rune"] = {v[2]}
  453. elseif v[1] == TYPE_RUNEDEBRIS then -- 符文碎片
  454. ret = cmd.rune_debris(v[2], v[3], uid) -- 碎片id, 数量
  455. entity["rune_debris"] = {[v[2]] = v[3]}
  456. elseif v[1] == TYPE_TITLE then -- 称号 --PK3-1030
  457. ret = cmd.title(v[2], v[3], uid) -- 称号
  458. entity["title"] = {v[2]}
  459. elseif v[1] == TYPE_CARRY then -- 符文
  460. ret = cmd.carry(v[2], v[3], uid) -- 符文id, 数量
  461. entity["carry"] = {v[2]}
  462. elseif v[1] == TYPE_CARRYDEBRIS then -- 符文碎片
  463. ret = cmd.carry_debris(v[2], v[3], uid) -- 碎片id, 数量
  464. entity["carry_debris"] = {[v[2]] = v[3]}
  465. elseif v[1] == TYPE_COUPON then -- CDPK3-1002 代金券
  466. ret = cmd.coupon(v[2], v[3], uid) -- 符文id, 数量
  467. entity["coupon"] = {v[2]}
  468. else
  469. return cjson.encode({state = 403, msg = "没有需要修改的数据 9"})
  470. end
  471. end
  472. if ret then
  473. -- 数据库断开
  474. redis:disconnect()
  475. return ret
  476. else
  477. logger.trace(" entity = %s" , stringify(entity))
  478. entity.other = delinfo.items -- PK3-1366 数据统计
  479. entity.note = "web_delitem"
  480. fire({
  481. uid = uid,
  482. nickname = get_data(uid, "nickname")
  483. }, "delitem", "delitem", entity)
  484. redis:disconnect()
  485. return cjson.encode({state = 200, msg = "success"})
  486. end
  487. end)
  488. end
  489. return delitem