Files
StellaSora_DataLua/lua/functions.lua
T
SL1900 35c8d87e86 Update - 1.4.0.73
EN: 1.4.0.73
CN: 1.4.0.74
JP: 1.4.0.77
KR: 1.4.0.80
2025-12-25 19:00:00 +09:00

523 lines
11 KiB
Lua

function clone(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for key, value in pairs(object) do
new_table[_copy(key)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
function class(classname, super)
local superType = type(super)
local cls
if superType ~= "function" and superType ~= "table" then
superType = nil
end
if superType == "function" or super and super.__ctype == 1 then
cls = {}
if superType == "table" then
for k, v in pairs(super) do
cls[k] = v
end
cls.__create = super.__create
cls.super = super
else
cls.__create = super
end
function cls.ctor()
end
cls.__cname = classname
cls.__ctype = 1
function cls.new(...)
local instance = cls.__create(...)
for k, v in pairs(cls) do
instance[k] = v
end
instance.class = cls
instance:ctor(...)
return instance
end
else
if super then
cls = clone(super)
cls.super = super
else
cls = {
ctor = function(...)
end
}
end
cls.__cname = classname
cls.__ctype = 2
cls.__index = cls
function cls.new(...)
local instance = setmetatable({}, cls)
instance.class = cls
instance:ctor(...)
return instance
end
end
return cls
end
function import(moduleName, currentModuleName)
local currentModuleNameParts
local moduleFullName = moduleName
local offset = 1
while true do
if string.byte(moduleName, offset) ~= 46 then
moduleFullName = string.sub(moduleName, offset)
if currentModuleNameParts and 0 < #currentModuleNameParts then
moduleFullName = table.concat(currentModuleNameParts, ".") .. "." .. moduleFullName
end
break
end
offset = offset + 1
if not currentModuleNameParts then
if not currentModuleName then
local n, v = debug.getlocal(3, 1)
currentModuleName = v
end
currentModuleNameParts = string.split(currentModuleName, ".")
end
table.remove(currentModuleNameParts, #currentModuleNameParts)
end
return require(moduleFullName)
end
function handler(obj, method, uiComponent)
return function(...)
if uiComponent == nil then
return method(obj, ...)
else
return method(obj, uiComponent, ...)
end
end
end
function ui_handler(obj, method, uiComponent, nIndex)
return function(...)
if type(nIndex) == "number" then
return method(obj, uiComponent, nIndex, ...)
else
return method(obj, uiComponent, ...)
end
end
end
function dotween_callback_handler(obj, method, ...)
local tbParameter = {}
for i = 1, select("#", ...) do
local param = select(i, ...)
table.insert(tbParameter, param)
end
return function()
if obj ~= nil and type(method) == "function" then
local ok, error = pcall(method, obj, table.unpack(tbParameter))
if not ok then
printError(error)
end
end
end
end
function safe_call_cs_func(cs_func, ...)
local tbParameter = {}
for i = 1, select("#", ...) do
local param = select(i, ...)
table.insert(tbParameter, param)
end
local ok, result = pcall(cs_func, table.unpack(tbParameter))
if not ok then
printError(result)
else
return result
end
end
function safe_call_cs_func2(cs_func, ...)
local tbParameter = {}
for i = 1, select("#", ...) do
local param = select(i, ...)
table.insert(tbParameter, param)
end
local tbResult = {
pcall(cs_func, table.unpack(tbParameter))
}
if not tbResult[1] then
printError(tbResult[2])
else
table.remove(tbResult, 1)
return table.unpack(tbResult)
end
end
function table.nums(t)
local count = 0
for k, v in pairs(t) do
count = count + 1
end
return count
end
function table.keys(hashtable)
local keys = {}
for k, v in pairs(hashtable) do
keys[#keys + 1] = k
end
return keys
end
function table.values(hashtable)
local values = {}
for k, v in pairs(hashtable) do
if v ~= json.null then
values[#values + 1] = v
end
end
return values
end
function table.merge(dest, src)
for k, v in pairs(src) do
dest[k] = v
end
end
function table.insertto(dest, src, begin)
begin = checkint(begin)
if begin <= 0 then
begin = #dest + 1
end
local len = #src
for i = 0, len - 1 do
dest[i + begin] = src[i + 1]
end
end
function checknumber(value, base)
return tonumber(value, base) or 0
end
function checkint(value)
return math.round(checknumber(value))
end
function math.round(value)
value = checknumber(value)
return math.floor(value + 0.5)
end
function checkbool(value)
return value ~= nil and value ~= false
end
function checktable(value)
if type(value) ~= "table" then
value = {}
end
return value
end
function isset(hashtable, key)
local t = type(hashtable)
return (t == "table" or t == "userdata") and hashtable[key] ~= nil
end
function table.indexof(array, value, begin)
for i = begin or 1, #array do
if array[i] == value then
return i
end
end
return 0
end
function table.keyof(hashtable, value)
for k, v in pairs(hashtable) do
if v == value then
return k
end
end
return nil
end
function table.removebyvalue(array, value, removeall)
local c, i, max = 0, 1, #array
while i <= max do
if array[i] == value then
table.remove(array, i)
c = c + 1
i = i - 1
max = max - 1
if not removeall then
break
end
end
i = i + 1
end
return c
end
function table.map(t, fn)
for k, v in pairs(t) do
t[k] = fn(v, k)
end
end
function table.walk(t, fn)
for k, v in pairs(t) do
fn(v, k)
end
end
function table.shuffle(t)
local n = #t
while 2 < n do
local k = math.random(n)
t[n], t[k] = t[k], t[n]
n = n - 1
end
return t
end
function table.filter(t, fn)
for k, v in pairs(t) do
if not fn(v, k) then
t[k] = nil
end
end
end
function table.unique(t, bArray)
local check = {}
local n = {}
local idx = 1
for k, v in pairs(t) do
if not check[v] then
if bArray then
n[idx] = v
idx = idx + 1
else
n[k] = v
end
check[v] = true
end
end
return n
end
function string.htmlspecialchars(input)
for k, v in pairs(string._htmlspecialchars_set) do
input = string.gsub(input, k, v)
end
return input
end
function string.restorehtmlspecialchars(input)
for k, v in pairs(string._htmlspecialchars_set) do
input = string.gsub(input, v, k)
end
return input
end
function string.nl2br(input)
return string.gsub(input, "\n", "<br />")
end
function string.text2html(input)
input = string.gsub(input, "\t", " ")
input = string.htmlspecialchars(input)
input = string.gsub(input, " ", "&nbsp;")
input = string.nl2br(input)
return input
end
function string.split(input, delimiter)
input = tostring(input)
delimiter = tostring(delimiter)
if delimiter == "" then
return false
end
local pos, arr = 0, {}
for st, sp in function()
return string.find(input, delimiter, pos, true)
end, nil, nil do
table.insert(arr, string.sub(input, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(input, pos))
return arr
end
function string.ltrim(input)
return string.gsub(input, "^[ \t\n\r]+", "")
end
function string.rtrim(input)
return string.gsub(input, "[ \t\n\r]+$", "")
end
function string.trim(input)
input = string.gsub(input, "^[ \t\n\r]+", "")
return string.gsub(input, "[ \t\n\r]+$", "")
end
function string.ucfirst(input)
return string.upper(string.sub(input, 1, 1)) .. string.sub(input, 2)
end
local urlencodechar = function(char)
return "%" .. string.format("%02X", string.byte(char))
end
function string.urlencode(input)
input = string.gsub(tostring(input), "\n", "\r\n")
input = string.gsub(input, "([^%w%.%- ])", urlencodechar)
return string.gsub(input, " ", "+")
end
function string.urldecode(input)
input = string.gsub(input, "+", " ")
input = string.gsub(input, "%%(%x%x)", function(h)
return string.char(checknumber(h, 16))
end)
input = string.gsub(input, "\r\n", "\n")
return input
end
function string.utf8len(input)
local len = string.len(input)
local left = len
local cnt = 0
local arr = {
0,
192,
224,
240,
248,
252
}
while left ~= 0 do
local tmp = string.byte(input, -left)
local i = #arr
while arr[i] do
if tmp >= arr[i] then
left = left - i
break
end
i = i - 1
end
cnt = cnt + 1
end
return cnt
end
function string.formatnumberthousands(num)
local formatted = tostring(checknumber(num))
local k
while true do
formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", "%1,%2")
if k == 0 then
break
end
end
return formatted
end
function string.append_all(buffer, ...)
for i = 1, select("#", ...) do
table.insert(buffer, (select(i, ...)))
end
end
function print_dump(data, showMetatable, lastCount)
if type(data) ~= "table" then
if type(data) == "string" then
print("\"", data, "\"")
else
print(tostring(data))
end
else
local count = lastCount or 0
count = count + 1
print("{\n")
if showMetatable then
for i = 1, count do
print("\t")
end
local mt = getmetatable(data)
print("\"__metatable\" = ")
print_dump(mt, showMetatable, count)
print(",\n")
end
for key, value in pairs(data) do
for i = 1, count do
print("\t")
end
if type(key) == "string" then
print("\"", key, "\" = ")
elseif type(key) == "number" then
print("[", key, "] = ")
else
print(tostring(key))
end
print_dump(value, showMetatable, count)
print(",\n")
end
for i = 1, lastCount or 0 do
print("\t")
end
print("}")
end
if not lastCount then
print("\n")
end
end
function setfenv(fn, env)
local i = 1
while true do
local name = debug.getupvalue(fn, i)
if name == "_ENV" then
debug.upvaluejoin(fn, i, function()
return env
end, 1)
break
elseif not name then
break
end
i = i + 1
end
return fn
end
function getfenv(fn)
local i = 1
while true do
local name, val = debug.getupvalue(fn, i)
if name == "_ENV" then
return val
elseif not name then
break
end
i = i + 1
end
end
function run_with_env(env, fn, ...)
setfenv(fn, env)
fn(...)
end
local sortedKeys = function(t)
local keys = {}
for k in pairs(t) do
if type(k) == "number" then
table.insert(keys, k)
end
end
table.sort(keys)
return keys
end
function ipairsSorted(t)
local keys = sortedKeys(t)
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
function orderedFormat(formatStr, ...)
local args = {
...
}
return (formatStr:gsub("{([^}]+)}", function(placeholder)
local patterns = {".-_(%d+)$", "^(%d+)$"}
for _, pattern in ipairs(patterns) do
local num = placeholder:match(pattern)
if num then
local index = tonumber(num) + 1
return tostring(args[index] or "")
end
end
return "{" .. placeholder .. "}"
end))
end
function clearFloat(a)
local floor = math.floor(a)
local ceil = math.ceil(a)
if math.abs(a - floor) < 1.0E-10 then
return floor
end
if math.abs(a - ceil) < 1.0E-10 then
return ceil
end
return a
end