Petsox

advancedLua.lua

Aug 22nd, 2022
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.77 KB | Source Code | 0 0
  1.  
  2. local filesystem = require("filesystem")
  3. local unicode = require("unicode")
  4. local bit32 = require("bit32")
  5.  
  6. ----------------------------------------------------------------------------------------------------
  7.  
  8. function _G.getCurrentScript()
  9. local info
  10. for runLevel = 0, math.huge do
  11. info = debug.getinfo(runLevel)
  12. if info then
  13. if info.what == "main" then
  14. return info.source:sub(2, -1)
  15. end
  16. else
  17. error("Failed to get debug info for runlevel " .. runLevel)
  18. end
  19. end
  20. end
  21.  
  22. ----------------------------------------------------------------------------------------------------
  23.  
  24. function bit32.merge(number2, number1)
  25. local cutter = math.ceil(math.log(number1 + 1, 256)) * 8
  26. while number2 > 0 do
  27. number1, number2, cutter = bit32.bor(bit32.lshift(bit32.band(number2, 0xFF), cutter), number1), bit32.rshift(number2, 8), cutter + 8
  28. end
  29.  
  30. return number1
  31. end
  32.  
  33. function bit32.numberToByteArray(number)
  34. local byteArray = {}
  35.  
  36. repeat
  37. table.insert(byteArray, 1, bit32.band(number, 0xFF))
  38. number = bit32.rshift(number, 8)
  39. until number <= 0
  40.  
  41. return byteArray
  42. end
  43.  
  44. function bit32.numberToFixedSizeByteArray(number, size)
  45. local byteArray, counter = {}, 0
  46.  
  47. repeat
  48. table.insert(byteArray, 1, bit32.band(number, 0xFF))
  49. number = bit32.rshift(number, 8)
  50. counter = counter + 1
  51. until number <= 0
  52.  
  53. for i = 1, size - counter do
  54. table.insert(byteArray, 1, 0x0)
  55. end
  56.  
  57. return byteArray
  58. end
  59.  
  60. function bit32.byteArrayToNumber(byteArray)
  61. local result = byteArray[1]
  62. for i = 2, #byteArray do
  63. result = bit32.bor(bit32.lshift(result, 8), byteArray[i])
  64. end
  65.  
  66. return result
  67. end
  68.  
  69. function bit32.bitArrayToByte(bitArray)
  70. local result = 0
  71. for i = 1, #bitArray do
  72. result = bit32.bor(bitArray[i], bit32.lshift(result, 1))
  73. end
  74.  
  75. return result
  76. end
  77.  
  78. ----------------------------------------------------------------------------------------------------
  79.  
  80. function math.round(num)
  81. if num >= 0 then
  82. return math.floor(num + 0.5)
  83. else
  84. return math.ceil(num - 0.5)
  85. end
  86. end
  87.  
  88. function math.roundToDecimalPlaces(num, decimalPlaces)
  89. local mult = 10 ^ (decimalPlaces or 0)
  90. return math.round(num * mult) / mult
  91. end
  92.  
  93. function math.getDigitCount(num)
  94. return num == 0 and 1 or math.ceil(math.log(num + 1, 10))
  95. end
  96.  
  97. function math.shorten(number, digitCount)
  98. local shortcuts = {
  99. "K",
  100. "M",
  101. "B",
  102. "T"
  103. }
  104.  
  105. local index = math.floor(math.log(number, 1000))
  106. if number < 1000 then
  107. return number
  108. elseif index > #shortcuts then
  109. index = #shortcuts
  110. end
  111.  
  112. return math.roundToDecimalPlaces(number / 1000 ^ index, digitCount) .. shortcuts[index]
  113. end
  114.  
  115. ----------------------------------------------------------------------------------------------------
  116.  
  117. -- function filesystem.path(path)
  118. -- return path:match("^(.+%/).") or ""
  119. -- end
  120.  
  121. -- function filesystem.name(path)
  122. -- return path:match("%/?([^%/]+)%/?$")
  123. -- end
  124.  
  125. function filesystem.extension(path, lower)
  126. local extension = path:match("[^%/]+(%.[^%/]+)%/?$")
  127. return (lower and extension) and (unicode.lower(extension)) or extension
  128. end
  129.  
  130. function filesystem.hideExtension(path)
  131. return path:match("(.+)%..+") or path
  132. end
  133.  
  134. function filesystem.isFileHidden(path)
  135. if path:match("^%..+$") then
  136. return true
  137. end
  138.  
  139. return false
  140. end
  141.  
  142. function filesystem.sortedList(path, sortingMethod, showHiddenFiles, filenameMatcher, filenameMatcherCaseSensitive)
  143. if not filesystem.exists(path) then
  144. error("Failed to get file list: directory \"" .. tostring(path) .. "\" doesn't exists")
  145. end
  146.  
  147. if not filesystem.isDirectory(path) then
  148. error("Failed to get file list: path \"" .. tostring(path) .. "\" is not a directory")
  149. end
  150.  
  151. local fileList, sortedFileList = {}, {}
  152. for file in filesystem.list(path) do
  153. if not filenameMatcher or string.unicodeFind(filenameMatcherCaseSensitive and file or unicode.lower(file), filenameMatcherCaseSensitive and filenameMatcher or unicode.lower(filenameMatcher)) then
  154. table.insert(fileList, file)
  155. end
  156. end
  157.  
  158. if #fileList > 0 then
  159. if sortingMethod == "type" then
  160. local extension
  161. for i = 1, #fileList do
  162. extension = filesystem.extension(fileList[i]) or "Script"
  163. if filesystem.isDirectory(path .. fileList[i]) and extension ~= ".app" then
  164. extension = ".01_Folder"
  165. end
  166. fileList[i] = {fileList[i], extension}
  167. end
  168.  
  169. table.sort(fileList, function(a, b) return unicode.lower(a[2]) < unicode.lower(b[2]) end)
  170.  
  171. local currentExtensionList, currentExtension = {}, fileList[1][2]
  172. for i = 1, #fileList do
  173. if currentExtension == fileList[i][2] then
  174. table.insert(currentExtensionList, fileList[i][1])
  175. else
  176. table.sort(currentExtensionList, function(a, b) return unicode.lower(a) < unicode.lower(b) end)
  177. for j = 1, #currentExtensionList do
  178. table.insert(sortedFileList, currentExtensionList[j])
  179. end
  180. currentExtensionList, currentExtension = {fileList[i][1]}, fileList[i][2]
  181. end
  182. end
  183.  
  184. table.sort(currentExtensionList, function(a, b) return unicode.lower(a) < unicode.lower(b) end)
  185.  
  186. for j = 1, #currentExtensionList do
  187. table.insert(sortedFileList, currentExtensionList[j])
  188. end
  189. elseif sortingMethod == "name" then
  190. sortedFileList = fileList
  191. table.sort(sortedFileList, function(a, b) return unicode.lower(a) < unicode.lower(b) end)
  192. elseif sortingMethod == "date" then
  193. for i = 1, #fileList do
  194. fileList[i] = {fileList[i], filesystem.lastModified(path .. fileList[i])}
  195. end
  196.  
  197. table.sort(fileList, function(a, b) return unicode.lower(a[2]) > unicode.lower(b[2]) end)
  198.  
  199. for i = 1, #fileList do
  200. table.insert(sortedFileList, fileList[i][1])
  201. end
  202. else
  203. error("Unknown sorting method: " .. tostring(sortingMethod))
  204. end
  205.  
  206. local i = 1
  207. while i <= #sortedFileList do
  208. if not showHiddenFiles and filesystem.isFileHidden(sortedFileList[i]) then
  209. table.remove(sortedFileList, i)
  210. else
  211. i = i + 1
  212. end
  213. end
  214. end
  215.  
  216. return sortedFileList
  217. end
  218.  
  219. function filesystem.directorySize(path)
  220. local size = 0
  221. for file in filesystem.list(path) do
  222. if filesystem.isDirectory(path .. file) then
  223. size = size + filesystem.directorySize(path .. file)
  224. else
  225. size = size + filesystem.size(path .. file)
  226. end
  227. end
  228.  
  229. return size
  230. end
  231.  
  232. function filesystem.readUnicodeChar(file)
  233. local byteArray = {string.byte(file:read(1))}
  234.  
  235. local nullBitPosition = 0
  236. for i = 1, 7 do
  237. if bit32.band(bit32.rshift(byteArray[1], 8 - i), 0x1) == 0x0 then
  238. nullBitPosition = i
  239. break
  240. end
  241. end
  242.  
  243. for i = 1, nullBitPosition - 2 do
  244. table.insert(byteArray, string.byte(file:read(1)))
  245. end
  246.  
  247. return string.char(table.unpack(byteArray))
  248. end
  249.  
  250. ----------------------------------------------------------------------------------------------------
  251.  
  252. function table.serialize(array, prettyLook, indentationWidth, indentUsingTabs, recursionStackLimit)
  253. checkArg(1, array, "table")
  254.  
  255. recursionStackLimit = recursionStackLimit or math.huge
  256. local indentationSymbolAdder = string.rep(indentUsingTabs and " " or " ", indentationWidth or 2)
  257. local equalsSymbol = prettyLook and " = " or "="
  258.  
  259. local function serializeRecursively(array, currentIndentationSymbol, currentRecusrionStack)
  260. local result, nextIndentationSymbol, keyType, valueType, stringValue = {"{"}, currentIndentationSymbol .. indentationSymbolAdder
  261.  
  262. if prettyLook then
  263. table.insert(result, "\n")
  264. end
  265.  
  266. for key, value in pairs(array) do
  267. keyType, valueType, stringValue = type(key), type(value), tostring(value)
  268.  
  269. if prettyLook then
  270. table.insert(result, nextIndentationSymbol)
  271. end
  272.  
  273. if keyType == "number" then
  274. table.insert(result, "[")
  275. table.insert(result, key)
  276. table.insert(result, "]")
  277. table.insert(result, equalsSymbol)
  278. elseif keyType == "string" then
  279. -- Короч, если типа начинается с буковки, а также если это алфавитно-нумерическая поеботня
  280. if prettyLook and key:match("^%a") and key:match("^[%w%_]+$") then
  281. table.insert(result, key)
  282. else
  283. table.insert(result, "[\"")
  284. table.insert(result, key)
  285. table.insert(result, "\"]")
  286. end
  287.  
  288. table.insert(result, equalsSymbol)
  289. end
  290.  
  291. if valueType == "number" or valueType == "boolean" or valueType == "nil" then
  292. table.insert(result, stringValue)
  293. elseif valueType == "string" or valueType == "function" then
  294. table.insert(result, "\"")
  295. table.insert(result, stringValue)
  296. table.insert(result, "\"")
  297. elseif valueType == "table" then
  298. if currentRecusrionStack < recursionStackLimit then
  299. table.insert(
  300. result,
  301. table.concat(
  302. serializeRecursively(
  303. value,
  304. nextIndentationSymbol,
  305. currentRecusrionStack + 1
  306. )
  307. )
  308. )
  309. else
  310. table.insert(result, "\"…\"")
  311. end
  312. end
  313.  
  314. table.insert(result, ",")
  315.  
  316. if prettyLook then
  317. table.insert(result, "\n")
  318. end
  319. end
  320.  
  321. -- Удаляем запятую
  322. if prettyLook then
  323. if #result > 2 then
  324. table.remove(result, #result - 1)
  325. end
  326.  
  327. table.insert(result, currentIndentationSymbol)
  328. else
  329. if #result > 1 then
  330. table.remove(result, #result)
  331. end
  332. end
  333.  
  334. table.insert(result, "}")
  335.  
  336. return result
  337. end
  338.  
  339. return table.concat(serializeRecursively(array, "", 1))
  340. end
  341.  
  342. function table.unserialize(serializedString)
  343. checkArg(1, serializedString, "string")
  344.  
  345. local result, reason = load("return " .. serializedString)
  346. if result then
  347. result, reason = pcall(result)
  348. if result then
  349. return reason
  350. else
  351. return nil, reason
  352. end
  353. else
  354. return nil, reason
  355. end
  356. end
  357.  
  358. table.toString = table.serialize
  359. table.fromString = table.unserialize
  360.  
  361. function table.toFile(path, array, prettyLook, indentationWidth, indentUsingTabs, recursionStackLimit, appendToFile)
  362. checkArg(1, path, "string")
  363. checkArg(2, array, "table")
  364.  
  365. filesystem.makeDirectory(filesystem.path(path) or "")
  366.  
  367. local file, reason = io.open(path, appendToFile and "a" or "w")
  368. if file then
  369. file:write(table.serialize(array, prettyLook, indentationWidth, indentUsingTabs, recursionStackLimit))
  370. file:close()
  371. else
  372. error("Failed to open file for writing: " .. tostring(reason))
  373. end
  374. end
  375.  
  376. function table.fromFile(path)
  377. checkArg(1, path, "string")
  378.  
  379. local file, reason = io.open(path, "r")
  380. if file then
  381. local data, reason = table.unserialize(file:read("*a"))
  382. file:close()
  383.  
  384. if data then
  385. return data
  386. else
  387. error("Failed to unserialize file \"" .. path .. "\": " .. tostring(reason))
  388. end
  389. else
  390. error("Failed to open file \"" .. path .. "\" for reading: " .. tostring(reason))
  391. end
  392. end
  393.  
  394. function table.copy(tableToCopy)
  395. local function copyTableRecursively(source, destination)
  396. for key, value in pairs(source) do
  397. if type(value) == "table" then
  398. destination[key] = {}
  399. doTableCopy(source[key], destination[key])
  400. else
  401. destination[key] = value
  402. end
  403. end
  404. end
  405.  
  406. local result = {}
  407. copyTableRecursively(tableToCopy, result)
  408.  
  409. return result
  410. end
  411.  
  412. function table.size(t)
  413. local size = 0
  414. for key in pairs(t) do size = size + 1 end
  415. return size
  416. end
  417.  
  418. function table.contains(t, object)
  419. for _, value in pairs(t) do
  420. if value == object then
  421. return true
  422. end
  423. end
  424. return false
  425. end
  426.  
  427. function table.indexOf(t, object)
  428. for i = 1, #t do
  429. if t[i] == object then
  430. return i
  431. end
  432. end
  433. end
  434.  
  435. function table.sortAlphabetically(t)
  436. table.sort(t, function(a, b) return a < b end)
  437. end
  438.  
  439. ----------------------------------------------------------------------------------------------------
  440.  
  441. function string.brailleChar(a, b, c, d, e, f, g, h)
  442. return unicode.char(10240 + 128*h + 64*g + 32*f + 16*d + 8*b + 4*e + 2*c + a)
  443. end
  444.  
  445. function string.canonicalPath(str)
  446. return string.gsub("/" .. str, "%/+", "/")
  447. end
  448.  
  449. function string.optimize(str, indentationWidth)
  450. str = string.gsub(str, "\r\n", "\n")
  451. str = string.gsub(str, " ", string.rep(" ", indentationWidth or 2))
  452. return str
  453. end
  454.  
  455. function string.optimizeForURLRequests(code)
  456. if code then
  457. code = string.gsub(code, "([^%w ])", function (c)
  458. return string.format("%%%02X", string.byte(c))
  459. end)
  460. code = string.gsub(code, " ", "+")
  461. end
  462. return code
  463. end
  464.  
  465. function string.unicodeFind(str, pattern, init, plain)
  466. if init then
  467. if init < 0 then
  468. init = -#unicode.sub(str, init)
  469. elseif init > 0 then
  470. init = #unicode.sub(str, 1, init - 1) + 1
  471. end
  472. end
  473.  
  474. a, b = string.find(str, pattern, init, plain)
  475.  
  476. if a then
  477. local ap, bp = str:sub(1, a - 1), str:sub(a,b)
  478. a = unicode.len(ap) + 1
  479. b = a + unicode.len(bp) - 1
  480. return a, b
  481. else
  482. return a
  483. end
  484. end
  485.  
  486. function string.limit(s, limit, mode, noDots)
  487. local length = unicode.len(s)
  488. if length <= limit then return s end
  489.  
  490. if mode == "left" then
  491. if noDots then
  492. return unicode.sub(s, length - limit + 1, -1)
  493. else
  494. return "…" .. unicode.sub(s, length - limit + 2, -1)
  495. end
  496. elseif mode == "center" then
  497. local integer, fractional = math.modf(limit / 2)
  498. if fractional == 0 then
  499. return unicode.sub(s, 1, integer) .. "…" .. unicode.sub(s, -integer + 1, -1)
  500. else
  501. return unicode.sub(s, 1, integer) .. "…" .. unicode.sub(s, -integer, -1)
  502. end
  503. else
  504. if noDots then
  505. return unicode.sub(s, 1, limit)
  506. else
  507. return unicode.sub(s, 1, limit - 1) .. "…"
  508. end
  509. end
  510. end
  511.  
  512. function string.wrap(data, limit)
  513. if type(data) == "string" then data = {data} end
  514.  
  515. local wrappedLines, result, preResult, position = {}
  516.  
  517. -- Дублируем таблицу строк, шоб не перекосоебить ченить переносами
  518. for i = 1, #data do
  519. wrappedLines[i] = data[i]
  520. end
  521.  
  522. -- Отсечение возврата каретки-ебуретки
  523. local i = 1
  524. while i <= #wrappedLines do
  525. local position = string.unicodeFind(wrappedLines[i], "\n")
  526. if position then
  527. table.insert(wrappedLines, i + 1, unicode.sub(wrappedLines[i], position + 1, -1))
  528. wrappedLines[i] = unicode.sub(wrappedLines[i], 1, position - 1)
  529. end
  530.  
  531. i = i + 1
  532. end
  533.  
  534. -- Сам перенос
  535. local i = 1
  536. while i <= #wrappedLines do
  537. result = ""
  538.  
  539. for word in wrappedLines[i]:gmatch("[^%s]+") do
  540. preResult = result .. word
  541.  
  542. if unicode.len(preResult) > limit then
  543. if unicode.len(word) > limit then
  544. table.insert(wrappedLines, i + 1, unicode.sub(wrappedLines[i], limit + 1, -1))
  545. result = unicode.sub(wrappedLines[i], 1, limit)
  546. else
  547. table.insert(wrappedLines, i + 1, unicode.sub(wrappedLines[i], unicode.len(result) + 1, -1))
  548. end
  549.  
  550. break
  551. else
  552. result = preResult .. " "
  553. end
  554. end
  555.  
  556. wrappedLines[i] = result:gsub("%s+$", ""):gsub("^%s+", "")
  557.  
  558. i = i + 1
  559. end
  560.  
  561. return wrappedLines
  562. end
  563.  
  564. ----------------------------------------------------------------------------------------------------
  565.  
  566. return {loaded = true}
Add Comment
Please, Sign In to add comment