utils.lua 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224
  1. local cjson = require "cjson"
  2. local skynet = require "skynet"
  3. local crypt = require "crypt"
  4. function cjson_encode(obj)
  5. return cjson.encode(obj)
  6. end
  7. function cjson_decode(json)
  8. return cjson.decode(json)
  9. end
  10. function skynet_time()
  11. return math.ceil(skynet.time())
  12. end
  13. function is_robot(uid)
  14. return uid < 1000000
  15. end
  16. -- 将时间区间转换成秒
  17. -- 年:y year
  18. -- 周:w week
  19. -- 日:d day
  20. -- 时:h hour
  21. -- 分:m minute
  22. -- 秒:s second
  23. function convert_second(t)
  24. if is_empty(t) or type(t) ~= "table" then
  25. return 0
  26. end
  27. local second = t.second or t.s or 0
  28. local minute = t.minute or t.m or 0
  29. local hour = t.hour or t.h or 0
  30. local day = t.day or t.d or 0
  31. local week = t.week or t.w or 0
  32. local year = t.year or t.y or 0
  33. day = day + week * 7 + year * 365
  34. hour = hour + day * 24
  35. minute = minute + hour * 60
  36. second = second + minute * 60
  37. return second
  38. end
  39. -- 格式化时间
  40. function os_date(fmt, time)
  41. -- 计算时区差值
  42. if DIFF_TIME_ZONE == nil then
  43. local now = os.time()
  44. DIFF_TIME_ZONE = math.ceil(8 * 3600 - os.difftime(now, os.time(os.date("!*t", now))))
  45. print("skynet_time ", string.format("DIFF_TIME_ZONE[%s]", tostring(DIFF_TIME_ZONE)))
  46. end
  47. time = time + DIFF_TIME_ZONE
  48. return os.date(fmt, time)
  49. end
  50. function date_time(t)
  51. return os.date("%Y-%m-%d %H:%M:%S", t)
  52. end
  53. function jm_reload_module(module_name)
  54. -- print("reload config,", module_name)print
  55. -- 只针对配置更新
  56. package.loaded[module_name] = nil
  57. return require(module_name)
  58. end
  59. --创建定时器
  60. function create_timeout(ti, func, ...)
  61. local active = true
  62. local args = {...}
  63. skynet.timeout(
  64. ti,
  65. function()
  66. if active then
  67. active = false
  68. func(table.unpack(args))
  69. end
  70. end
  71. )
  72. local timer = {}
  73. timer.is_timeout = function()
  74. return not active
  75. end
  76. timer.delete = function()
  77. local is_active = active
  78. active = false
  79. return is_active
  80. end
  81. return timer
  82. end
  83. -- 创建循环定时器
  84. -- times 执行次数(负数时无限次)
  85. -- time 间隔时间(单位0.01秒)
  86. -- func 执行函数
  87. -- ... 对应参数
  88. function create_timer(times, time, func, ...)
  89. local active = true
  90. local isPause = false
  91. local args = {...}
  92. local run_timer
  93. run_timer = function()
  94. if times == 0 or not active then
  95. active = false
  96. return
  97. end
  98. -- 小于0时不处理;非整数不合法,转成整数
  99. if times > 0 then
  100. times = math.floor(times - 1)
  101. if times < 0 then
  102. times = 0
  103. end
  104. end
  105. skynet.timeout(time, run_timer)
  106. if not isPause then
  107. func(table.unpack(args))
  108. end
  109. end
  110. run_timer()
  111. -- 定时器查看与控制
  112. local timer = {}
  113. timer.is_timeout = function()
  114. return not active
  115. end
  116. -- 关闭操作
  117. timer.delete = function()
  118. local is_active = active
  119. active = false
  120. return is_active
  121. end
  122. -- 暂停操作
  123. timer.pause = function()
  124. local is_pause = isPause
  125. isPause = true
  126. return is_pause
  127. end
  128. -- 继续操作
  129. timer.continue = function()
  130. local is_pause = isPause
  131. isPause = false
  132. return is_pause
  133. end
  134. return timer
  135. end
  136. --根据权重筛选,real为true时,总权重不大于0时,不做随机
  137. function key_rand(obj, real)
  138. local weight = {}
  139. local t = 0
  140. for k, v in ipairs(obj) do
  141. t = t + (v.weight or v.w)
  142. weight[k] = t
  143. end
  144. if t <= 0 then
  145. if real then
  146. return
  147. else
  148. return math.random(#obj)
  149. end
  150. end
  151. local c = math.random(1, t)
  152. for k, v in ipairs(weight) do
  153. if c < v then
  154. return k
  155. end
  156. end
  157. return #weight
  158. end
  159. function random_list_by_weight(list, key)
  160. if list == nil then
  161. return
  162. end
  163. local subkey = key or "weight"
  164. local weights = {}
  165. local t = 0
  166. for k, v in ipairs(list) do
  167. t = t + v[subkey]
  168. weights[k] = t
  169. end
  170. if t == 0 then
  171. return
  172. end
  173. local c = math.random(0, t)
  174. for k, v in ipairs(weights) do
  175. if c <= v then
  176. return k
  177. end
  178. end
  179. return 1
  180. end
  181. -- 一定量的物品随机分配特定份数,返回分配数量列表
  182. function rand_divide(total, count)
  183. assert(total >= count)
  184. local list = {}
  185. local sum = 0
  186. for i = 1, count do
  187. local num = math.random(total, total * 10)
  188. table.insert(list, num)
  189. sum = sum + num
  190. end
  191. table.sort(list)
  192. local left = total
  193. local res = {}
  194. for k, v in ipairs(list) do
  195. local real = math.floor(v * total / sum)
  196. real = real > 0 and real or 1
  197. table.insert(res, real)
  198. left = left - real
  199. end
  200. if left > 0 then
  201. local index = math.random(count)
  202. res[index] = res[index] + left
  203. end
  204. return res
  205. end
  206. -- 从一定的元素中选择特定量的元素,返回索引列表
  207. function rand_choice(total, count)
  208. assert(total >= count)
  209. local list = {}
  210. local sum = 0
  211. for i = 1, total do
  212. local num = math.random(total * 10)
  213. table.insert(list, {index = i, weight = num})
  214. end
  215. table.sort(
  216. list,
  217. function(u, v)
  218. return u.weight > v.weight
  219. end
  220. )
  221. local res = {}
  222. for i = 1, count do
  223. table.insert(res, list[i].index)
  224. end
  225. return res
  226. end
  227. -- 从一定的元素中选择特定量的元素,返回索引列表(有权重)
  228. function rand_choice_by_weight(list, count)
  229. local randList = table.copy(list)
  230. assert(#randList >= count)
  231. local indexList = {}
  232. for i = 1, count do
  233. local index = key_rand(randList)
  234. table.remove(randList, index)
  235. table.insert(indexList, index)
  236. end
  237. for i = #indexList, 1, -1 do
  238. for j = i - 1, 1, -1 do
  239. if indexList[i] >= indexList[j] then
  240. indexList[i] = indexList[i] + 1
  241. end
  242. end
  243. end
  244. return indexList
  245. end
  246. --bool转为整型
  247. function bool_to_int(val)
  248. if val then
  249. return 1
  250. else
  251. return 0
  252. end
  253. end
  254. --初始化为默认值
  255. function init_inc(old_val, default_val, inc_val)
  256. if not old_val then
  257. old_val = default_val
  258. end
  259. return old_val + inc_val
  260. end
  261. --两者取较大值
  262. function max(val1, val2)
  263. if val1 > val2 then
  264. return val1
  265. end
  266. return val2
  267. end
  268. --两者取最小值
  269. function min(val1, val2)
  270. if val1 < val2 then
  271. return val1
  272. end
  273. return val2
  274. end
  275. --列表转为发送数据
  276. function empty_to_data(t)
  277. if not t or table.empty(t) then
  278. return nil
  279. end
  280. return t
  281. end
  282. -- 空值判断:nil或常用默认值时返回true,以下情况返回true
  283. -- nil: nil
  284. -- number: 0
  285. -- string: ""
  286. -- boolean: false
  287. -- table: {}
  288. -- userdata: 0x0(null)
  289. -- 注:类似php中以 t 作为条件时为假的情况(除userdata外)
  290. function is_empty(t)
  291. if not t then
  292. return true
  293. end
  294. local tp = type(t)
  295. if tp == "number" and t == 0 then
  296. return true
  297. end
  298. if tp == "string" and t == "" then
  299. return true
  300. end
  301. if tp == "boolean" and t == false then
  302. return true
  303. end
  304. if tp == "table" and not next(t) then
  305. return true
  306. end
  307. if tp == "userdata" then
  308. local ok, res = pcall(cjson_encode, t)
  309. if ok and res == "null" then
  310. return true
  311. end
  312. end
  313. end
  314. --列表随机一个值
  315. function list_rand(obj)
  316. local index = math.random(1, #obj)
  317. return obj[index]
  318. end
  319. function per_hour_timer(f, ...)
  320. while true do
  321. local now = os.date("*t", skynet_time()) -- 每1小时进入循环
  322. local t = (60 - now.min) * 60 * 100
  323. skynet.sleep(t)
  324. f(...)
  325. end
  326. end
  327. function per_day_timer(f, ...)
  328. while true do
  329. local now = os.date("*t", skynet_time())
  330. local t = (23 - now.hour) * 3600 * 100 + (60 - now.min) * 60 * 100
  331. skynet.sleep(t)
  332. f(...)
  333. end
  334. end
  335. -- 每日备份时钟
  336. function per_day_user_backup_timer(f, ...)
  337. while true do
  338. local now = os.date("*t", skynet_time())
  339. -- 凌晨3点开始
  340. local t = (23 - now.hour) * 3600 * 100 + (60 - now.min) * 60 * 100 + 3 * 3600
  341. skynet.sleep(t)
  342. f(...)
  343. end
  344. end
  345. -- 1 time = 0.01s
  346. function per_timer(time, f, ...)
  347. while true do
  348. skynet.sleep(time)
  349. f(...)
  350. end
  351. end
  352. --创建token
  353. function token_create(uid, timestamp, password, secret)
  354. local s = string.format("%s:%s:%s", uid, timestamp, password)
  355. s = crypt.base64encode(crypt.desencode(secret, s))
  356. return s:gsub(
  357. "[+/]",
  358. function(c)
  359. if c == "+" then
  360. return "-"
  361. else
  362. return "_"
  363. end
  364. end
  365. )
  366. end
  367. --解析token
  368. function token_parse(token, secret)
  369. token =
  370. token:gsub(
  371. "[-_]",
  372. function(c)
  373. if c == "-" then
  374. return "+"
  375. else
  376. return "/"
  377. end
  378. end
  379. )
  380. local s = crypt.desdecode(secret, crypt.base64decode(token))
  381. local uid, timestamp, password = s:match("([^:]+):([^:]+):(.+)")
  382. return uid, timestamp, password
  383. end
  384. function time_now_str()
  385. return os.date("%Y-%m-%d %H:%M:%S", skynet_time())
  386. end
  387. function getTimestamp(src)
  388. --从日期字符串中截取出年月日时分秒
  389. local _, _, y, m, d, hour, min, sec = string.find(src, "(%d+)-(%d+)-(%d+)%s*(%d+):(%d+):(%d+)")
  390. local t = {
  391. year = tonumber(y),
  392. month = tonumber(m),
  393. day = tonumber(d),
  394. hour = tonumber(hour),
  395. min = tonumber(min),
  396. sec = tonumber(sec)
  397. }
  398. --把日期时间字符串转换成对应的日期时间
  399. return os.time(t)
  400. end
  401. -- 获取当天秒数
  402. function get_day_timestamp(src)
  403. local h = tonumber(string.sub(src, 1, 2))
  404. local m = tonumber(string.sub(src, 4, 5))
  405. local s = tonumber(string.sub(src, 7, 8))
  406. return h * 3600 + m * 60 + s
  407. end
  408. function is_robot(uid)
  409. return tonumber(uid) < 1000000
  410. end
  411. function is_include_channel(uid_channel, include_channel, not_include_channel)
  412. if not include_channel then
  413. return false
  414. end
  415. if not_include_channel and table.member(not_include_channel, uid_channel) then
  416. return false
  417. end
  418. if table.member(include_channel, 0) then
  419. return true
  420. elseif table.member(include_channel, uid_channel) then
  421. return true
  422. end
  423. return false
  424. end
  425. function is_include_version(version, include_version, not_include_version)
  426. if not include_version then
  427. return false
  428. end
  429. if not_include_version then
  430. for _, v in ipairs(not_include_version) do
  431. if string.find(version, v) == 1 then
  432. return false
  433. end
  434. end
  435. end
  436. for _, v in ipairs(include_version) do
  437. if string.find(version, v) == 1 then
  438. return true
  439. end
  440. end
  441. return false
  442. end
  443. function process_slq_inject(sql)
  444. local strLower = string.lower(sql)
  445. local words = {"and", "exec", "insert", "select", "delete", "update", "truncate"}
  446. for _, word in ipairs(words) do
  447. if string.find(strLower, word) then
  448. return false
  449. end
  450. end
  451. return true
  452. end
  453. function is_include_channel2(uid_channel, include_channel, not_include_channel)
  454. if not_include_channel then
  455. for k, v in ipairs(not_include_channel) do
  456. if v == uid_channel then
  457. return false
  458. end
  459. end
  460. end
  461. if include_channel then
  462. for k, v in ipairs(include_channel) do
  463. if v == uid_channel or v == 0 then -- 0是默认全渠道
  464. return true
  465. end
  466. end
  467. end
  468. return false
  469. end
  470. function is_type(t, values)
  471. for _, v in ipairs(values) do
  472. if type(v) ~= t then
  473. return false
  474. end
  475. end
  476. return true
  477. end
  478. function is_nil(str)
  479. return str == nil or str == ""
  480. end
  481. -- 将nil或null(userdata类型)转换成空table,本来是有效数据的不做改变
  482. function trans_table(tb)
  483. if is_empty(tb) then
  484. return {}
  485. end
  486. return tb
  487. end
  488. -- 检查用户所属城市是否屏蔽城市
  489. function check_city(city_config, city)
  490. if city_config and city then
  491. for _, v in ipairs(city_config) do
  492. local i = string.find(city, v)
  493. if i then
  494. return true
  495. end
  496. end
  497. end
  498. return false
  499. end
  500. -- 检查用户渠道是否开放红包功能
  501. -- 也可以被新版本的过滤格式调用
  502. function check_channel(channel_config, channel)
  503. return not channel_config or (channel_config.t == 1 and table.include(channel_config.c, channel)) or
  504. (channel_config.t == 0 and not table.include(channel_config.c, channel))
  505. end
  506. function check_city1(city_config, city)
  507. return not city_config or (city_config.t == 1 and check_city(city_config.c, city)) or
  508. (city_config.t == 0 and not check_city(city_config.c, city))
  509. end
  510. function date_is_same(date1, date2)
  511. local time_date1 = string.split(date1, "-")
  512. local time_date2 = string.split(date2, "-")
  513. return tonumber(time_date1[1]) == tonumber(time_date2[1]) and tonumber(time_date1[2]) == tonumber(time_date2[2]) and
  514. tonumber(time_date1[3]) == tonumber(time_date2[3])
  515. end
  516. -- 查找两个日期之间的所有日期
  517. -- date2必须大于等于date1
  518. function foreach_day(date1, date2, f)
  519. local date = date1
  520. local t = getTimestamp(date .. " 00:00:00")
  521. while true do
  522. f(date)
  523. if date_is_same(date, date2) then
  524. break
  525. end
  526. t = t + 24 * 3600
  527. date = os.date("%Y-%m-%d", t)
  528. end
  529. end
  530. local function split(s, p)
  531. local rt = {}
  532. string.gsub(
  533. s,
  534. "[^" .. p .. "]+",
  535. function(w)
  536. table.insert(rt, w)
  537. end
  538. )
  539. return rt
  540. end
  541. local function version_to_number(version, digit)
  542. if is_nil(version) then
  543. return 0
  544. end
  545. local arr = split(version, "%.")
  546. local i = 1
  547. if arr[1] == "t" then
  548. i = 2
  549. end
  550. local verCount = tonumber(arr[i]) * 100 + tonumber(arr[i + 1])
  551. if digit and digit == 3 then
  552. if arr[i + 2] then
  553. verCount = verCount * 100 + tonumber(arr[i + 2])
  554. else
  555. verCount = verCount * 100 + 1
  556. end
  557. end
  558. return verCount
  559. end
  560. -- 检查版本是否大于等于指定版本号
  561. function greater_version(version, user_version)
  562. local arr = split(version, "%.")
  563. local digit = #arr
  564. return version_to_number(user_version, digit) >= version_to_number(version, digit)
  565. end
  566. -- 检查版本是否小于等于指定版本号
  567. function less_version(version, user_version)
  568. local arr = split(version, "%.")
  569. local digit = #arr
  570. return version_to_number(user_version, digit) <= version_to_number(version, digit)
  571. end
  572. -- 检查旧版本{t=1, v={"2.11"}}格式
  573. -- version获取玩家app_version
  574. function check_version(version_config, version)
  575. if is_nil(version) then
  576. return false
  577. end
  578. if not version_config then
  579. return true
  580. end
  581. local arr1 = string.split1(version, "%.")
  582. local version1 = string.format("%s.%s", arr1[1], arr1[2])
  583. local version2 = nil
  584. if arr1[1] == "t" or arr1[1] == "T" then
  585. version1 = string.format("%s.%s", arr1[2], arr1[3])
  586. if #arr1 >= 4 then
  587. version2 = string.format("%s.%s.%s", arr1[2], arr1[3], arr1[4])
  588. end
  589. else
  590. if #arr1 >= 3 then
  591. version2 = string.format("%s.%s.%s", arr1[1], arr1[2], arr1[3])
  592. end
  593. end
  594. -- 允许
  595. if version_config.t == 1 then
  596. if table.include(version_config.v, version1) then
  597. return true
  598. end
  599. if version2 and table.include(version_config.v, version2) then
  600. return true
  601. end
  602. return false
  603. end
  604. -- 屏蔽
  605. if version_config.t == 0 then
  606. if version2 then
  607. if table.include(version_config.v, version1) or table.include(version_config.v, version2) then
  608. return false
  609. end
  610. else
  611. if table.include(version_config.v, version1) then
  612. return false
  613. end
  614. end
  615. return true
  616. end
  617. -- 大于等于
  618. if version_config.t == 2 then
  619. if #version_config.v == 1 then
  620. if greater_version(version_config.v[1], version) then
  621. return true
  622. end
  623. end
  624. return false
  625. end
  626. -- 小于等于
  627. if version_config.t == 3 then
  628. if #version_config.v == 1 then
  629. if less_version(version_config.v[1], version) then
  630. return true
  631. end
  632. end
  633. return false
  634. end
  635. -- 包含区间
  636. if version_config.t == 4 then
  637. if #version_config.v == 2 then
  638. if greater_version(version_config.v[1], version) and less_version(version_config.v[2], version) then
  639. return true
  640. end
  641. end
  642. return false
  643. end
  644. -- 不包含区间
  645. if version_config.t == 5 then
  646. if #version_config.v == 2 then
  647. if greater_version(version_config.v[1], version) and less_version(version_config.v[2], version) then
  648. return false
  649. end
  650. end
  651. return true
  652. end
  653. return false
  654. end
  655. -- 获取当天结束时间
  656. function get_day_end_time(currTime, days)
  657. local daySec = 24 * 3600
  658. local addDay = days or 1
  659. local timeout = math.floor((currTime + 8 * 3600) / daySec) * daySec + daySec * addDay - 8 * 3600 - 1
  660. return timeout
  661. end
  662. -- 获取当天开始时间
  663. function get_day_start_time(currTime, days)
  664. local daySec = 24 * 3600
  665. local addDay = days or 0
  666. local timeout = math.floor((currTime + 8 * 3600) / daySec) * daySec + daySec * addDay - 8 * 3600
  667. return timeout
  668. end
  669. -- 版本转字符串
  670. function version_to_string(version, points)
  671. if is_nil(version) then
  672. return "nil"
  673. end
  674. local arr = split(version, "%.")
  675. local i = 1
  676. if arr[1] == "t" then
  677. i = 2
  678. end
  679. local str = ""
  680. local times = points or 2
  681. for j = i, i + times do
  682. local temp = nil
  683. if arr[j] then
  684. temp = string.format("%03d", tonumber(arr[j]))
  685. else
  686. temp = "000"
  687. end
  688. str = str .. temp
  689. end
  690. return str
  691. end
  692. function pairsByKeys(t)
  693. local a = {}
  694. for n in pairs(t) do
  695. a[#a + 1] = n
  696. end
  697. table.sort(a)
  698. local i = 0
  699. return function()
  700. i = i + 1
  701. return a[i], t[a[i]]
  702. end
  703. end
  704. -- 获取当前天数(自1970年)
  705. function get_yday(timestamp)
  706. return math.floor((timestamp + (8 * 3600)) / (3600 * 24))
  707. end
  708. -- 获取周期时间
  709. function get_circle_time(data)
  710. if data == nil or data.m == nil or data.hour == nil or data.min == nil then
  711. return
  712. end
  713. local currTime = skynet_time()
  714. local now = os.date("*t", skynet_time())
  715. -- 每12小时
  716. if data.m == 0 then
  717. return get_circle_time_12h(data)
  718. end
  719. -- 每天
  720. if data.m == 1 then
  721. return get_circle_time_day(data)
  722. end
  723. -- 每周
  724. if data.m == 2 then
  725. return get_circle_time_wday(data)
  726. end
  727. -- 每月
  728. if data.m == 3 then
  729. return get_circle_time_month(data)
  730. end
  731. -- 每季
  732. if data.m == 4 then
  733. return get_circle_time_session(data)
  734. end
  735. -- 每年
  736. if data.m == 5 then
  737. return get_circle_time_year(data)
  738. end
  739. end
  740. -- 时间周期 - 12小时制
  741. function get_circle_time_12h(data)
  742. if data == nil or data.m == nil or data.hour == nil or data.min == nil then
  743. return
  744. end
  745. -- 数据验证
  746. if data.m ~= 0 or data.hour < 0 or data.hour > 11 then
  747. return
  748. end
  749. local currTime = skynet_time()
  750. local now = os.date("*t", currTime)
  751. local dhour = data.hour
  752. if now.hour >= 12 then
  753. dhour = dhour + 12
  754. end
  755. local endTime = os.time({year = now.year, month = now.month, day = now.day, hour = dhour, min = data.min, sec = 0})
  756. if currTime >= endTime then
  757. endTime = endTime + 12 * 3600
  758. end
  759. return endTime, endTime - currTime
  760. end
  761. -- 时间周期 - 每日
  762. function get_circle_time_day(data)
  763. if data == nil or data.m == nil or data.hour == nil or data.min == nil then
  764. return
  765. end
  766. -- 数据验证
  767. if data.m ~= 1 or data.hour < 0 or data.hour > 23 then
  768. return
  769. end
  770. local currTime = skynet_time()
  771. local now = os.date("*t", currTime)
  772. local endTime =
  773. os.time({year = now.year, month = now.month, day = now.day, hour = data.hour, min = data.min, sec = 0})
  774. if currTime >= endTime then
  775. endTime = endTime + 24 * 3600
  776. end
  777. return endTime, endTime - currTime
  778. end
  779. -- 时间周期 - 每周
  780. function get_circle_time_wday(data)
  781. if data == nil or data.m == nil or data.day == nil or data.hour == nil or data.min == nil then
  782. return
  783. end
  784. -- 数据验证
  785. if data.m ~= 2 or data.day < 0 or data.day > 7 or data.hour < 0 or data.hour > 23 then
  786. return
  787. end
  788. local currTime = skynet_time()
  789. local now = os.date("*t", currTime)
  790. local wday = data.day + 1
  791. if wday > 7 then
  792. wday = 1
  793. end
  794. local endTime =
  795. os.time({year = now.year, month = now.month, day = now.day, hour = data.hour, min = data.min, sec = 0})
  796. local diffDays = wday - now.wday
  797. if diffDays < 0 then
  798. diffDays = diffDays + 7
  799. end
  800. endTime = endTime + diffDays * 24 * 3600
  801. if currTime >= endTime then
  802. endTime = endTime + 7 * 24 * 3600
  803. end
  804. return endTime, endTime - currTime
  805. end
  806. -- 时间周期 - 每月
  807. function get_circle_time_month(data)
  808. if data == nil or data.m == nil or data.day == nil or data.hour == nil or data.min == nil then
  809. return
  810. end
  811. -- 数据验证
  812. if data.m ~= 3 or data.day < 0 or data.day > 31 or data.hour < 0 or data.hour > 23 then
  813. return
  814. end
  815. local currTime = skynet_time()
  816. local now = os.date("*t", currTime)
  817. local endTime =
  818. os.time({year = now.year, month = now.month, day = data.day, hour = data.hour, min = data.min, sec = 0})
  819. if currTime >= endTime then
  820. local nMonth = now.month + 1
  821. local nYear = now.year
  822. if nMonth > 12 then
  823. nMonth = 1
  824. nYear = nYear + 1
  825. end
  826. endTime = os.time({year = nYear, month = nMonth, day = data.day, hour = data.hour, min = data.min, sec = 0})
  827. end
  828. return endTime, endTime - currTime
  829. end
  830. -- 时间周期 - 每月
  831. function get_circle_time_session(data)
  832. if data == nil or data.m == nil or data.month == nil or data.day == nil or data.hour == nil or data.min == nil then
  833. return
  834. end
  835. -- 数据验证
  836. if
  837. data.m ~= 4 or data.month < 0 or data.month > 3 or data.day < 0 or data.day > 31 or data.hour < 0 or
  838. data.hour > 23
  839. then
  840. return
  841. end
  842. local currTime = skynet_time()
  843. local now = os.date("*t", currTime)
  844. local cMonth = math.floor(now.month / 3) * 3 + data.month
  845. local endTime =
  846. os.time({year = now.year, month = cMonth, day = data.day, hour = data.hour, min = data.min, sec = 0})
  847. if currTime >= endTime then
  848. cMonth = cMonth + 3
  849. local nYear = now.year
  850. if cMonth > 12 then
  851. cMonth = cMonth - 12
  852. nYear = nYear + 1
  853. end
  854. endTime = os.time({year = nYear, month = cMonth, day = data.day, hour = data.hour, min = data.min, sec = 0})
  855. end
  856. return endTime, endTime - currTime
  857. end
  858. -- 时间周期 - 每月
  859. function get_circle_time_year(data)
  860. if data == nil or data.m == nil or data.day == nil or data.hour == nil or data.min == nil then
  861. return
  862. end
  863. -- 数据验证
  864. if
  865. data.m ~= 5 or data.month < 0 or data.month > 12 or data.day < 0 or data.day > 31 or data.hour < 0 or
  866. data.hour > 23
  867. then
  868. return
  869. end
  870. local currTime = skynet_time()
  871. local now = os.date("*t", currTime)
  872. local nTime =
  873. os.time({year = now.year, month = data.month, day = data.day, hour = data.hour, min = data.hour, sec = 0})
  874. if currTime >= nTime then
  875. nTime =
  876. os.time(
  877. {year = now.year + 1, month = data.month, day = data.day, hour = data.hour, min = data.min, sec = 0}
  878. )
  879. end
  880. return nTime, nTime - currTime
  881. end
  882. -- x的y次方
  883. function g_x_pow_y(x, y)
  884. if x == nil or y == nil then
  885. return 0
  886. end
  887. local count = x
  888. if y > 1 then
  889. for i = 1, y - 1 do
  890. count = count * x
  891. end
  892. end
  893. if x ~= 0 and y == 0 then
  894. return 1
  895. end
  896. return count
  897. end
  898. function RandomWithWeight(list, sum)
  899. if list == nil or #list == 0 then
  900. return 0, 0
  901. end
  902. if sum == nil or sum == 0 then
  903. sum = 0
  904. for _, aWeight in ipairs(list) do
  905. sum = sum + aWeight
  906. end
  907. end
  908. local ret = 1
  909. if sum > 0 then
  910. local r = math.random(1, sum)
  911. local didSum = 0
  912. for index, q in ipairs(list) do
  913. didSum = didSum + q
  914. if r <= didSum then
  915. ret = index
  916. break
  917. end
  918. end
  919. end
  920. return ret, sum
  921. end
  922. -- data: {{3,10},{4,10},{5,10},{6,10},{7,10}}
  923. function getRandomWithWeight(data)
  924. local weight = {}
  925. for k, v in pairs(data) do
  926. table.insert(weight, v[2])
  927. end
  928. local index = RandomWithWeight(weight)
  929. local area = data[index]
  930. return area[1]
  931. end
  932. -- list: {{2,...,10},{3,...,10},{4,...,10}}
  933. function getRandomListByWeightAtLast(list)
  934. local weight = {}
  935. for k, v in ipairs(list) do
  936. table.insert(weight, v[#v])
  937. end
  938. local index = RandomWithWeight(weight)
  939. return list[index], index
  940. end
  941. -- 获取当前月份天数
  942. function getDayAmount()
  943. return os.date("%d", os.time({year = os.date("%Y"), month = os.date("%m") + 1, day = 0}))
  944. end
  945. function timeout_call(ti, ...)
  946. local token = {}
  947. local ret
  948. skynet.fork(
  949. function(...)
  950. ret = table.pack(pcall(skynet.call, ...))
  951. skynet.wakeup(token)
  952. end,
  953. ...
  954. )
  955. skynet.sleep(ti, token)
  956. if ret then
  957. if ret[1] then
  958. return table.unpack(ret, 1, ret.n)
  959. else
  960. error(ret[2])
  961. end
  962. else
  963. -- timeout
  964. return false
  965. end
  966. end
  967. function mysqlEscapeString(str)
  968. local escape_map = {
  969. ["\0"] = "\\0",
  970. ["\b"] = "\\b",
  971. ["\n"] = "\\n",
  972. ["\r"] = "\\r",
  973. ["\t"] = "\\t",
  974. ["\26"] = "\\Z",
  975. ["\\"] = "\\\\",
  976. ["'"] = "\\'",
  977. ['"'] = '\\"'
  978. }
  979. return string.format("%s", string.gsub(str or "", '[\0\b\n\r\t\26\\\'"]', escape_map))
  980. end
  981. local function traceback(msg)
  982. local errorMsg = "safeRun error" .. tostring(msg) .. "\n" .. debug.traceback() .. "\n"
  983. log.error(errorMsg)
  984. return errorMsg
  985. end
  986. function safeRun(func, ...)
  987. local args = {...}
  988. return xpcall(
  989. function()
  990. return func(table.unpack(args))
  991. end,
  992. traceback
  993. )
  994. end
  995. -- 针对有非数组的数字下标的table转换成json
  996. function cjson_sparse_encode(obj)
  997. local cjsonObj = cjson.new()
  998. cjsonObj.encode_sparse_array(true)
  999. return cjsonObj.encode(obj)
  1000. end
  1001. -- 非标准encode,只能用 likeCjsonEncode 来decode
  1002. function likeCjsonEncode(obj)
  1003. if type(obj) ~= "table" then
  1004. return cjson_encode(obj)
  1005. end
  1006. local cjson2 = cjson.new()
  1007. local list = {}
  1008. local findNumKey
  1009. findNumKey = function(info, list, link, deep)
  1010. if type(info) ~= "table" or deep > 100 then
  1011. return
  1012. end
  1013. for k, v in pairs(info) do
  1014. local tp = type(k)
  1015. link = link .. "," .. k .. ":" .. tp
  1016. if type(k) == "number" then
  1017. table.insert(list, link)
  1018. end
  1019. findNumKey(v, list, link, deep + 1)
  1020. end
  1021. end
  1022. findNumKey(obj, list, "start", 0)
  1023. cjson2.encode_sparse_array(true)
  1024. local json = cjson2.encode(obj)
  1025. local data = json
  1026. if #list > 0 then
  1027. data = {["json"] = json, ["numKey"] = list}
  1028. end
  1029. return cjson_encode(data)
  1030. end
  1031. function cleanObjNull(obj)
  1032. if not obj or type(obj) ~= "table" then
  1033. return
  1034. end
  1035. for k, v in pairs(obj) do
  1036. if type(v) == "userdata" then
  1037. obj[k] = nil
  1038. else
  1039. cleanObjNull(v)
  1040. end
  1041. end
  1042. end
  1043. -- 非标准decode,只能decode用 likeCjsonDecode 来encode的string
  1044. function likeCjsonDecode(json)
  1045. local data = cjson_decode(json)
  1046. if type(data) ~= "table" then
  1047. return data
  1048. end
  1049. local cjson2 = cjson.new()
  1050. cjson2.encode_sparse_array(true)
  1051. local numKey = data["numKey"]
  1052. if not numKey then
  1053. return data
  1054. end
  1055. local obj = cjson2.decode(data["json"])
  1056. cleanObjNull(obj)
  1057. local list = {}
  1058. for k, v in ipairs(numKey) do
  1059. local link = string.split(v, ",")
  1060. table.insert(list, link)
  1061. end
  1062. table.sort(
  1063. list,
  1064. function(a, b)
  1065. return #a < #b
  1066. end
  1067. )
  1068. local setNumKey
  1069. setNumKey = function(obj, v, deep, count)
  1070. deep = deep + 1
  1071. if count < deep or type(obj) ~= "table" then
  1072. return
  1073. end
  1074. local keyObj = string.split(v[deep], ":")
  1075. local key = keyObj[2] == "number" and tonumber(keyObj[1]) or keyObj[1] .. ""
  1076. if count == deep then
  1077. key = key .. ""
  1078. local numKey = tonumber(key)
  1079. if obj and obj[key] then
  1080. local tmp = obj[key]
  1081. obj[key] = nil
  1082. obj[numKey] = tmp
  1083. end
  1084. return
  1085. end
  1086. setNumKey(obj[key], v, deep, count)
  1087. end
  1088. for k, v in ipairs(list) do
  1089. setNumKey(obj, v, 1, #v)
  1090. end
  1091. return obj
  1092. end
  1093. -- 字符串转小驼峰
  1094. function formatSmallHump(name)
  1095. local data = {}
  1096. string.gsub(
  1097. name,
  1098. "[^_]+",
  1099. function(w)
  1100. table.insert(data, w)
  1101. end
  1102. )
  1103. local result = {}
  1104. for i, v in ipairs(data) do
  1105. if v ~= "" then
  1106. v = string.lower(v)
  1107. if #result > 0 then
  1108. v = string.gsub(v, "^%l", string.upper)
  1109. end
  1110. table.insert(result, v)
  1111. end
  1112. end
  1113. return table.concat(result)
  1114. end