script_name('ML-AutoReboot')
script_version_number(7)
script_version('1.1')
script_author('FYP')
script_description('reloads edited scripts automatically')
script_moonloader(021)
script_properties('work-in-pause')
local ffi = require 'ffi'
ffi.cdef[[
typedef void* HANDLE;
typedef void* LPSECURITY_ATTRIBUTES;
typedef unsigned long DWORD;
typedef int BOOL;
typedef const char *LPCSTR;
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
BOOL __stdcall GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime);
HANDLE __stdcall CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
BOOL __stdcall CloseHandle(HANDLE hObject);
]]
--- Config
autoreloadDelay = 500 -- ms
---
function main()
-- for the reload case
onSystemInitialized()
while true do
wait(autoreloadDelay)
if files ~= nil then
for fpath, saved_time in pairs(files) do
local file_time = get_file_modify_time(fpath)
if file_time ~= nil and (file_time[1] ~= saved_time[1] or file_time[2] ~= saved_time[2]) then
local scr = find_script_by_path(fpath)
if scr ~= nil then
print('Reloading "' .. scr.name .. '"...')
scr:reload()
else
print('Loading "' .. fpath .. '"...')
script.load(fpath)
end
files[fpath] = file_time -- update time
end
end
end
end
end
function onSystemInitialized()
if not initialized then
init()
end
end
function init()
initialized = true
files = {}
-- store all loaded scripts
for _, s in ipairs(script.list()) do
local time = get_file_modify_time(s.path)
if time ~= nil then
files[s.path] = time
end
end
end
function find_script_by_path(path)
for _, s in ipairs(script.list()) do
if s.path == path then
return s
end
end
return nil
end
function get_file_modify_time(path)
local handle = ffi.C.CreateFileA(path,
0x80000000, -- GENERIC_READ
0x00000001 + 0x00000002, -- FILE_SHARE_READ | FILE_SHARE_WRITE
nil,
3, -- OPEN_EXISTING
0x00000080, -- FILE_ATTRIBUTE_NORMAL
nil)
local filetime = ffi.new('FILETIME[3]')
if handle ~= -1 then
local result = ffi.C.GetFileTime(handle, filetime, filetime + 1, filetime + 2)
ffi.C.CloseHandle(handle)
if result ~= 0 then
return {tonumber(filetime[2].dwLowDateTime), tonumber(filetime[2].dwHighDateTime)}
end
end
return nil
end