Util.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. local Config = require("Config")
  2. local pi = math.acos(-1)
  3. local sqrt2 = math.sqrt(2)
  4. local os = _G.os
  5. local math = _G.math
  6. local floor = math.floor
  7. local cos = math.cos
  8. local sin = math.sin
  9. local atan2 = math.atan2
  10. function getTableCount(s)
  11. local count = 0
  12. if s == nil then return count end
  13. for _ in pairs(s) do
  14. count = count + 1
  15. end
  16. return count
  17. end
  18. function copyTableSimple(s, t, noNewTB)
  19. for k, v in pairs(s) do
  20. if type(v) == "table" then
  21. if not noNewTB then
  22. t[k] = {}
  23. end
  24. copyTableSimple(v, t[k])
  25. else
  26. t[k] = v
  27. end
  28. end
  29. end
  30. function copyTable(s)
  31. if not s then return end
  32. local t = {}
  33. copyTableSimple(s,t)
  34. return t
  35. end
  36. function initTable(tb)
  37. if not tb then return end
  38. for k in pairs(tb) do
  39. tb[k]= nil
  40. end
  41. end
  42. function cleanTable(s)
  43. for k,v in pairs(s) do
  44. s[k] = nil
  45. end
  46. end
  47. function getBit(n, index)
  48. local div = 2 ^ index
  49. return (n - n % div) / div % 2
  50. end
  51. function setBit(n, index)
  52. local bit = getBit(n, index)
  53. if bit ~= 0 then
  54. assert()
  55. end
  56. return n + 2 ^ index
  57. end
  58. function hypot(a, b)
  59. return math.sqrt(a * a + b * b)
  60. end
  61. local out = {}
  62. local out_len = 0
  63. function printTable(tb, step)
  64. if not step then
  65. step = 0
  66. out_len = 0
  67. end
  68. for k, v in pairs(tb) do
  69. for i = 1, step do
  70. out_len = out_len + 1
  71. out[out_len] = " "
  72. end
  73. if type(k) == "number" then
  74. out_len = out_len + 1
  75. out[out_len] = "["
  76. end
  77. out_len = out_len + 1
  78. out[out_len] = k
  79. if type(k) == "number" then
  80. out_len = out_len + 1
  81. out[out_len] = "]"
  82. end
  83. out_len = out_len + 1
  84. out[out_len] = "="
  85. if type(v) == "string" then
  86. out_len = out_len + 1
  87. out[out_len] = "\""
  88. end
  89. out_len = out_len + 1
  90. out[out_len] = type(v) == "table" and "" or v
  91. if type(v) == "boolean" then
  92. out[out_len] = tostring(v)
  93. end
  94. if type(v) == "string" then
  95. out_len = out_len + 1
  96. out[out_len] = "\""
  97. end
  98. out_len = out_len + 1
  99. out[out_len] = "\n"
  100. if type(v) == "table" then
  101. printTable(v, step + 1)
  102. end
  103. end
  104. if step == 0 then
  105. local str = table.concat(out, nil, 1, out_len)
  106. print(str)
  107. return str
  108. end
  109. end
  110. function serialize(val, name, skipmap, depth, buf)
  111. skipmap = skipmap or {} -- 用来检测循环引用
  112. depth = depth or 0
  113. buf = buf or {}
  114. local indent = string.rep(" ", depth)
  115. local t = type(val)
  116. if t == "string" then
  117. table.insert(buf, string.format("%q", val))
  118. elseif t == "number" or t == "boolean" or t == "nil" then
  119. table.insert(buf, tostring(val))
  120. elseif t == "table" then
  121. -- 循环引用检测
  122. if skipmap[val] then
  123. table.insert(buf, skipmap[val])
  124. return buf
  125. end
  126. skipmap[val] = string.format("<%s>", name or "table")
  127. table.insert(buf, "{\n")
  128. local idx = 1
  129. for k, v in pairs(val) do
  130. -- 拼 key
  131. if type(k) == "string" and k:match("^[%a_][%w_]*$") then
  132. table.insert(buf, indent .. " " .. k .. " = ")
  133. else
  134. table.insert(buf, indent .. " [" )
  135. serialize(k, nil, skipmap, 0, buf)
  136. table.insert(buf, "] = ")
  137. end
  138. -- 拼 value
  139. serialize(v, nil, skipmap, depth + 1, buf)
  140. table.insert(buf, ",\n")
  141. end
  142. table.insert(buf, indent .. "}")
  143. elseif t == "function" then
  144. table.insert(buf, string.format("<function:%s>", tostring(val)))
  145. elseif t == "userdata" then
  146. table.insert(buf, string.format("<userdata:%s>", tostring(val)))
  147. elseif t == "thread" then
  148. table.insert(buf, string.format("<thread:%s>", tostring(val)))
  149. else
  150. table.insert(buf, "<??>")
  151. end
  152. return buf
  153. end
  154. -- 判断是否同一天
  155. function isSameDay(time1)
  156. if not time1 then
  157. return
  158. end
  159. local now = os.time()
  160. local tToday = os.date("%Y%m%d", now)
  161. local t1 = os.date("%Y%m%d", time1)
  162. if tToday ~= t1 then
  163. return
  164. end
  165. return now
  166. end
  167. -- 判断传入的两个时间是否同一天
  168. function isSameDayByTimes(time1,time2)
  169. if not time1 or not time2 then
  170. return
  171. end
  172. local t1 = os.date("%Y%m%d", time1)
  173. local t2 = os.date("%Y%m%d", time2)
  174. if t1 ~= t2 then
  175. return
  176. end
  177. return true
  178. end
  179. -- 是否同一个月
  180. function isSameMonth(time)
  181. local now = os.date("*t")
  182. local d = os.date("*t",time)
  183. return now.year==d.year and now.month==d.month
  184. end
  185. -- 判断传入时间点与当前时间相差多少天
  186. local tb = {}
  187. function diffDay(time)
  188. local d = os.date("*t",time)
  189. tb.year = d.year
  190. tb.month = d.month
  191. tb.day = d.day
  192. time = os.time(tb)
  193. local nowDay = os.date("*t")
  194. tb.year = nowDay.year
  195. tb.month = nowDay.month
  196. tb.day = nowDay.day
  197. local nowTime = os.time(tb)
  198. return math.ceil(math.abs(nowTime-time)/86400)
  199. end
  200. -- 判断传入时间点与当前时间相差多少小时
  201. function diffHour(time)
  202. local d = os.date("*t",time)
  203. tb.year = d.year
  204. tb.month = d.month
  205. tb.day = d.day
  206. time = os.time(tb)
  207. local nowDay = os.date("*t")
  208. tb.year = nowDay.year
  209. tb.month = nowDay.month
  210. tb.day = nowDay.day
  211. local nowTime = os.time(tb)
  212. return math.ceil(math.abs(nowTime-time)/3600)
  213. end
  214. function diffDayByTimes(time1,time2)
  215. local t1 = os.date("*t",time1)
  216. tb.year = t1.year
  217. tb.month = t1.month
  218. tb.day = t1.day
  219. time1 = os.time(tb)
  220. local t2 = os.date("*t",time2)
  221. tb.year = t2.year
  222. tb.month = t2.month
  223. tb.day = t2.day
  224. time2 = os.time(tb)
  225. return math.ceil(math.abs(time1-time2)/86400)
  226. end
  227. -- 获取本月有多少天
  228. function getMonthDayNum()
  229. local currMonthDate = os.date("*t")
  230. tb.year = currMonthDate.year
  231. tb.month = currMonthDate.month
  232. tb.day = currMonthDate.day
  233. currMonthDate.hour = nil
  234. currMonthDate.min = nil
  235. currMonthDate.sec = nil
  236. currMonthDate.day = 1
  237. tb.day = 1
  238. if tb.month<12 then
  239. tb.month = tb.month + 1
  240. else
  241. tb.year = tb.year+1
  242. tb.month = 1
  243. end
  244. local nextMonthFirstDayTime = os.time(tb)
  245. local currMonthTime = os.time(currMonthDate)
  246. return math.floor(math.abs(nextMonthFirstDayTime-currMonthTime)/86400)
  247. end
  248. -- 取时间间隔 s
  249. function getInterval(time)
  250. if not time then
  251. return math.huge
  252. end
  253. local now = os.time()
  254. return now - time
  255. end
  256. --参数结构:year=****,month=****,day=****
  257. function isTime( startDate, endDate)
  258. local date_min = os.time(startDate) - 12 * 60 * 60
  259. local date_max = os.time(endDate) + 12 * 60 * 60
  260. local tmp_time = os.time()
  261. if not (date_min <= tmp_time and tmp_time < date_max) then
  262. return false
  263. end
  264. return true, date_max - tmp_time
  265. end
  266. -- check time
  267. function checkTime(startTimeConf,endTimeConf)
  268. local nowDate = os.date("*t")
  269. local nowMin = nowDate.hour * 60 + nowDate.min
  270. local startMin = startTimeConf.hour * 60 + startTimeConf.min
  271. local endMin = endTimeConf.hour * 60 + endTimeConf.min
  272. if nowMin >= startMin and nowMin < endMin then
  273. return true
  274. end
  275. end
  276. -- 检查传入时间,是否经过resetTime时间点;
  277. function isTimeOver(time,resetTime)
  278. if not time or not resetTime then
  279. return
  280. end
  281. local nowTime = os.time()
  282. local nowDay = os.date("%d", nowTime) + 0
  283. local nowHour = os.date("%H", nowTime) + 0
  284. local getDay = os.date("%d", time) + 0
  285. local getHour = os.date("%H", time) + 0
  286. local dirty = false
  287. if nowDay == getDay then
  288. if getHour < resetTime and nowHour >= resetTime then
  289. dirty = true
  290. end
  291. elseif nowDay == getDay + 1 then
  292. if nowHour >= resetTime then
  293. dirty = true
  294. end
  295. else
  296. dirty = true
  297. end
  298. return dirty
  299. end
  300. tmpDate = tmpDate or {}
  301. -- 取本月开始时间
  302. function getMonthStartTime(time)
  303. local d = os.date("*t",time)
  304. tmpDate.year = d.year
  305. tmpDate.month = d.month
  306. tmpDate.day = 1
  307. tmpDate.hour = 0
  308. tmpDate.min = 0
  309. tmpDate.sec = 0
  310. return os.time(tmpDate)
  311. end
  312. -- 取本周开始时间 周一凌晨
  313. function getWeekStartTime(time)
  314. local d = os.date("*t",time)
  315. tmpDate.year = d.year
  316. tmpDate.month = d.month
  317. tmpDate.hour = 0
  318. tmpDate.min = 0
  319. tmpDate.sec = 0
  320. local day = nil
  321. if d.wday == 1 then
  322. day = 6
  323. else
  324. day = d.wday - 2
  325. end
  326. tmpDate.day = d.day - day
  327. return os.time(tmpDate)
  328. end
  329. -- 取本日开始时间
  330. function getDayStartTime(time)
  331. local d = os.date("*t",time)
  332. tmpDate.year = d.year
  333. tmpDate.month = d.month
  334. tmpDate.day = d.day
  335. tmpDate.hour = 0
  336. tmpDate.min = 0
  337. tmpDate.sec = 0
  338. return os.time(tmpDate)
  339. end
  340. -- 取相差几天时间
  341. function getNextDayTime(time, day)
  342. local d = os.date("*t",time)
  343. tmpDate.year = d.year
  344. tmpDate.month = d.month
  345. tmpDate.day = d.day
  346. tmpDate.hour = 0
  347. tmpDate.min = 0
  348. tmpDate.sec = 0
  349. local ts = os.time(tmpDate)
  350. local dayTs = day * 86400
  351. return ts + dayTs
  352. end
  353. -- 获取前几天数据
  354. function getLastDayTime(time, day)
  355. local d = os.date("*t",time)
  356. tmpDate.year = d.year
  357. tmpDate.month = d.month
  358. tmpDate.day = d.day
  359. tmpDate.hour = 0
  360. tmpDate.min = 0
  361. tmpDate.sec = 0
  362. local ts = os.time(tmpDate)
  363. local dayTs = day * 86400
  364. return ts - dayTs
  365. end
  366. -- 取本日特定小时时间戳
  367. function getDayHourTime(time, hour)
  368. local d = os.date("*t",time)
  369. tmpDate.year = d.year
  370. tmpDate.month = d.month
  371. tmpDate.day = d.day
  372. tmpDate.hour = hour
  373. tmpDate.min = 0
  374. tmpDate.sec = 0
  375. return os.time(tmpDate)
  376. end
  377. -- 判断传入时间点,是否同周
  378. function isSameWeek(time1,time2)
  379. if not time1 or not time2 then
  380. return
  381. end
  382. return getWeekStartTime(time1) == getWeekStartTime(time2)
  383. end
  384. -- 星期中第几天的数字表示 1(表示星期天)到 7(表示星期六)
  385. function getWeekDay( time )
  386. local time = time or os.time()
  387. local d = os.date("*t",time)
  388. return d.wday
  389. end
  390. -- 处于第几分钟
  391. function getMin(time)
  392. time = time or os.time()
  393. local d = os.date("*t",time)
  394. return d.min
  395. end
  396. function split(str, split_char,isNumber)
  397. local t = {}
  398. while string.len(str)>0 do
  399. local pos = string.find(str, split_char);
  400. if (not pos) then
  401. if isNumber then
  402. t[#t + 1] = tonumber(str) or 0
  403. else
  404. t[#t + 1] = str
  405. end
  406. break
  407. end
  408. local sub_str = string.sub(str, 1, pos - 1)
  409. if isNumber then
  410. t[#t + 1] = tonumber(sub_str) or 0
  411. else
  412. t[#t + 1] = sub_str
  413. end
  414. str = string.sub(str, pos + 1, #str)
  415. end
  416. return t
  417. end
  418. -- 根据KEY从小到大排序
  419. function pairsByKeys(t)
  420. local a = {}
  421. for n in pairs(t) do
  422. a[#a+1] = n
  423. end
  424. table.sort(a)
  425. local i = 0
  426. return function()
  427. i = i + 1
  428. return a[i], t[a[i]]
  429. end
  430. end
  431. function cmptb(a, b)
  432. for k, v in pairs(a) do
  433. if type(v) == "table" then
  434. if type(b[k]) ~= "table" then
  435. return
  436. end
  437. if not cmptb(v, b[k]) then
  438. return
  439. end
  440. else
  441. if b[k] ~= v and k ~= "now" and k ~= "uid" then
  442. return
  443. end
  444. end
  445. end
  446. for k, v in pairs(b) do
  447. if type(v) == "table" then
  448. if type(a[k]) ~= "table" then
  449. return
  450. end
  451. if not cmptb(v, a[k]) then
  452. return
  453. end
  454. else
  455. if a[k] ~= v and k ~= "now" and k ~= "uid" then
  456. return
  457. end
  458. end
  459. end
  460. return true
  461. end
  462. function getWay(dx, dy)
  463. return ((floor(( atan2(dy, dx) + 11.388) / 1.57)) % 4) * 2;
  464. end
  465. function tableIsEmpty(tb)
  466. return _G.next(tb) == nil
  467. end
  468. -- 服务器是否符合
  469. function checkSvrIndex(svrIndexs, svrIndex)
  470. if #svrIndexs < 1 then return true end
  471. if not svrIndex then
  472. svrIndex = Config.SVR_INDEX
  473. end
  474. for i = 1, #svrIndexs do
  475. if svrIndexs[i][1] <= svrIndex and
  476. svrIndex <= svrIndexs[i][2] then
  477. return true
  478. end
  479. end
  480. end
  481. -- 含中文文本长度
  482. function utf8len(content)
  483. local len = string.len(content)
  484. local left = len
  485. local cnt = 0
  486. local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}
  487. while left ~= 0 do
  488. local tmp = string.byte(content, -left)
  489. local i = #arr
  490. while arr[i] do
  491. if tmp >= arr[i] then
  492. left = left - i
  493. break
  494. end
  495. i = i - 1
  496. end
  497. cnt = cnt + 1
  498. end
  499. return cnt
  500. end
  501. function checkRandom(cmpValue)
  502. local r = math.random(0,10000)
  503. if r < cmpValue then
  504. return true
  505. end
  506. end
  507. SEPARATOR = "||"
  508. function format(...)
  509. local str = ""
  510. local t = {}
  511. for k,v in ipairs({...}) do
  512. if k == 1 then
  513. str = str .. v
  514. else
  515. t = split(v, SEPARATOR)
  516. if #t > 1 then
  517. t[1] = string.gsub(t[1],"({(.-)})",function(p1,p2)
  518. p2 = tonumber(p2)
  519. if p2 and t[p2+1] then
  520. return string.sub(t[p2+1], 2)
  521. else
  522. return p1
  523. end
  524. end)
  525. end
  526. if t[1] then
  527. str = str .. SEPARATOR .. t[1]
  528. end
  529. end
  530. end
  531. return str
  532. end
  533. --------------------------------------------------------
  534. --- 新增table.find函数
  535. ---@param1 array 数组
  536. ---@param2 elem 目标元素
  537. --------------------------------------------------------
  538. table.find = function(array,elem)
  539. for idx,e in ipairs(array) do
  540. if e == elem then
  541. return idx
  542. end
  543. end
  544. end
  545. --------------------------------------------------------
  546. --- 新增table.shuffle函数
  547. --- @param1 array 数组
  548. --------------------------------------------------------
  549. table.shuffle = function(array)
  550. for i = 1,#array do
  551. local r = math.random(1,#array)
  552. array[i],array[r] = array[r],array[i]
  553. end
  554. return array
  555. end
  556. --------------------------------------------------------
  557. --- 新增table.copy函数
  558. --- @param1 array 数组
  559. --------------------------------------------------------
  560. function table.copy(object)
  561. -- 已经复制过的table,key为复制源table,value为复制后的table
  562. -- 为了防止table中的某个属性为自身时出现死循环
  563. -- 避免本该是同一个table的属性,在复制时变成2个不同的table(内容同,但是地址关系和原来的不一样了)
  564. local lookup_table = {}
  565. local function _copy(object)
  566. if type(object) ~= 'table' then -- 非table类型都直接返回
  567. return object
  568. elseif lookup_table[object] then
  569. return lookup_table[object]
  570. end
  571. local new_table = {}
  572. lookup_table[object] = new_table
  573. for k,v in pairs(object) do
  574. new_table[_copy(k)] = _copy(v)
  575. end
  576. -- 这里直接拿mt来用是因为一般对table操作不会很粗暴的修改mt的相关内容
  577. return setmetatable(new_table, getmetatable(object))
  578. end
  579. return _copy(object)
  580. end
  581. --------------------------------------------------------
  582. --- 新增table.print_lua_table函数
  583. --- @param1 array 数组
  584. --------------------------------------------------------
  585. local function print_lua_table(lua_table, indent)
  586. indent = indent or 0
  587. for k, v in pairs(lua_table) do
  588. if type(k) == "string" then
  589. k = string.format("%q", k)
  590. end
  591. local szSuffix = ""
  592. if type(v) == "table" then
  593. szSuffix = "{"
  594. end
  595. local szPrefix = string.rep(" ", indent)
  596. formatting = szPrefix.."["..k.."]".." = "..szSuffix
  597. if type(v) == "table" then
  598. print(formatting)
  599. print_lua_table(v, indent + 1)
  600. print(szPrefix.."},")
  601. else
  602. local szValue = ""
  603. if type(v) == "string" then
  604. szValue = string.format("%q", v)
  605. else
  606. szValue = tostring(v)
  607. end
  608. print(formatting..szValue..",")
  609. end
  610. end
  611. end
  612. table.print_lua_table = print_lua_table
  613. -- 打印当前堆栈
  614. function PrintNowStackTrace()
  615. local stackTrace = debug.traceback("", 2)
  616. print("[PrintNowStackTrace] 堆栈信息 "..stackTrace)
  617. end