Skip to content

Commit 884bc7a

Browse files
Preflight V1 (#1186)
1 parent ffdbf54 commit 884bc7a

File tree

18 files changed

+1090
-425
lines changed

18 files changed

+1090
-425
lines changed

libs/https/smods-https.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ if not isThread then -- In main thread
240240
if threadContent then
241241
return threadContent
242242
end
243-
local file = assert(NFS.read(SMODS.path.."/libs/https/smods-https.lua"))
243+
local file = assert(SMODS.NFS.read(SMODS.path.."/libs/https/smods-https.lua"))
244244
local data = love.filesystem.newFileData(file, '=[SMODS _ "smods-https-thread.lua"]') -- name is a silly hack to get lovely to register the curl module
245245
threadContent = data
246246
return data

libs/nativefs/nativefs.lua

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,4 +492,61 @@ else
492492
end
493493
end
494494

495+
local redirects = {}
496+
497+
function nativefs.smodsAddRedirect(realPath, lfsPath)
498+
if redirects[realPath] then return false, 'A redirect with path "' .. realPath .. '" already exists' end
499+
redirects[realPath] = lfsPath
500+
return true
501+
end
502+
503+
local function getRedirectPath(realPath)
504+
for p, r in pairs(redirects) do
505+
local len = #p
506+
local sub = realPath:sub(0, len + 1)
507+
if sub == p then return r end
508+
if sub == p .. "/" then return r .. "/" .. realPath:sub(len + 2) end
509+
end
510+
return false
511+
end
512+
513+
local function patchSimple(n, l) -- Simple funcions always have the path as the first argument
514+
return function (path, ...)
515+
local red = getRedirectPath(path)
516+
if red then return l(red, ...) end
517+
return n(path, ...)
518+
end
519+
end
520+
521+
for _, v in ipairs{"newFile", "unmount", "write", "append", "lines", "load", "getDirectoryItems", "getInfo", "createDirectory", "remove", "mount", "newFileData"} do
522+
nativefs[v] = patchSimple(nativefs[v], love.filesystem[v])
523+
end
524+
nativefs.getDirectoryItemsInfo = patchSimple(nativefs.getDirectoryItemsInfo, getDirectoryItemsInfo)
525+
526+
do
527+
local nRead = nativefs.read
528+
local lRead = love.filesystem.read
529+
function nativefs.read(containerOrName, nameOrSize, sizeOrNil)
530+
if sizeOrNil then -- Container defined
531+
local red = getRedirectPath(nameOrSize)
532+
if red then return lRead(containerOrName, red, sizeOrNil) end
533+
return nRead(containerOrName, nameOrSize, sizeOrNil)
534+
elseif not nameOrSize then
535+
local red = getRedirectPath(containerOrName)
536+
if red then return lRead(red, nameOrSize, sizeOrNil) end
537+
return nRead(containerOrName, nameOrSize, sizeOrNil)
538+
else
539+
if type(nameOrSize) == 'number' or nameOrSize == 'all' then
540+
local red = getRedirectPath(containerOrName)
541+
if red then return lRead(red, nameOrSize, sizeOrNil) end
542+
return nRead(containerOrName, nameOrSize, sizeOrNil)
543+
else
544+
local red = getRedirectPath(nameOrSize)
545+
if red then return lRead(containerOrName, red, sizeOrNil) end
546+
return nRead(containerOrName, nameOrSize, sizeOrNil)
547+
end
548+
end
549+
end
550+
end
551+
495552
return nativefs

lovely/core.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ priority = -5
88
target = "game.lua"
99
pattern = "self.SPEEDFACTOR = 1"
1010
position = "after"
11-
payload = "initSteamodded()"
11+
payload = 'require "SMODS.preflight.loader".initSteamodded()'
1212
match_indent = true
1313

1414
[[patches]]
@@ -19,12 +19,10 @@ sources = ["src/core.lua"]
1919

2020
[[patches]]
2121
[patches.module]
22-
before = "main.lua"
2322
source = "version.lua"
2423
name = "SMODS.version"
2524

2625
[[patches]]
2726
[patches.module]
28-
before = "main.lua"
2927
source = "release.lua"
3028
name = "SMODS.release"

lovely/fixes.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,8 @@ target = 'main.lua'
613613
match_indent = true
614614
position = 'after'
615615
pattern = '--To control when steam communication happens, make sure to send updates to steam as little as possible'
616-
payload = '''local cwd = NFS.getWorkingDirectory()
617-
NFS.setWorkingDirectory(love.filesystem.getSourceBaseDirectory())
616+
payload = '''local cwd = SMODS.NFS.getWorkingDirectory()
617+
SMODS.NFS.setWorkingDirectory(love.filesystem.getSourceBaseDirectory())
618618
'''
619619

620620
[[patches]]
@@ -623,7 +623,7 @@ target = 'main.lua'
623623
match_indent = true
624624
position = 'before'
625625
pattern = '--Set up the render window and the stage for the splash screen, then enter the gameloop with :update'
626-
payload = '''NFS.setWorkingDirectory(cwd)
626+
payload = '''SMODS.NFS.setWorkingDirectory(cwd)
627627
'''
628628

629629
[[patches]]
@@ -850,4 +850,4 @@ local card = Card(_area.T.x, _area.T.y, G.CARD_W, G.CARD_H, card_init.front, car
850850
'''
851851
payload = '''
852852
card:add_to_deck()
853-
'''
853+
'''

lovely/libs.toml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,27 @@ priority = -5
66
[[patches]]
77
[patches.module]
88
source = "libs/json/json.lua"
9-
before = "main.lua"
109
name = "json"
1110

1211
[[patches]]
1312
[patches.module]
1413
source = "libs/nativefs/nativefs.lua"
15-
before = "main.lua"
1614
name = "nativefs"
1715

16+
# We use our own module because we modifed it
17+
# and other mods may vendor their own which doesn't
18+
# have our patches
1819
[[patches]]
1920
[patches.module]
20-
source = "libs/https/luajit-curl.lua"
21-
before = "main.lua"
22-
name = "luajit-curl"
21+
source = "libs/nativefs/nativefs.lua"
22+
name = "SMODS.nativefs"
2323

24-
[[patches]] # Ensure the thread can also load this
24+
[[patches]]
2525
[patches.module]
2626
source = "libs/https/luajit-curl.lua"
27-
before = '=[SMODS _ "smods-https-thread.lua"]'
2827
name = "luajit-curl"
2928

3029
[[patches]]
3130
[patches.module]
3231
source = "libs/https/smods-https.lua"
33-
before = "main.lua"
3432
name = "SMODS.https"

lovely/preflight.toml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
[manifest]
2+
version = "1.0.0"
3+
dump_lua = true
4+
priority = -11
5+
6+
[[patches]]
7+
[patches.module]
8+
source = "src/preflight/sharedUtil.lua"
9+
name = "SMODS.preflight.sharedUtil"
10+
11+
[[patches]]
12+
[patches.module]
13+
source = "src/preflight/logging.lua"
14+
name = "SMODS.preflight.logging"
15+
16+
[[patches]]
17+
[patches.module]
18+
source = "src/preflight/loader.lua"
19+
name = "SMODS.preflight.loader"
20+
21+
[[patches]]
22+
[patches.module]
23+
source = "src/preflight/sharedUI.lua"
24+
name = "SMODS.preflight.sharedUI"
25+
26+
[[patches]]
27+
[patches.module]
28+
source = "src/preflight/core.lua"
29+
before = "main.lua"
30+
load_now = true
31+
name = "SMODS.preflight.core"
32+
33+
[[patches]]
34+
[patches.pattern]
35+
target = '=[lovely SMODS.preflight.core "src/preflight/core.lua"]'
36+
pattern = "local lovely_path = false -- This line is patched, don't edit it"
37+
position = "at"
38+
payload = """local lovely_path = [[{{lovely_hack:patch_dir}}/]]"""
39+
match_indent = true
40+
41+
[[patches]]
42+
[patches.pattern]
43+
target = "main.lua"
44+
pattern = "if (love.system.getOS() == 'OS X' ) and (jit.arch == 'arm64' or jit.arch == 'arm') then jit.off() end"
45+
position = "before"
46+
payload = """if SMODS and SMODS.preflight_force_quit then if SMODS.preflight_quit_before then SMODS.preflight_quit_before() end return end"""
47+
match_indent = true

lovely/shaders.toml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ pattern = '''self.SHADERS[shader_name] = love.graphics.newShader("resources/shad
1111
position = "at"
1212
payload = '''
1313
local shader = "resources/shaders/"..filename
14-
local lovely_success, lovely = pcall(require, "lovely")
15-
if lovely_success and lovely.apply_patches then
16-
shader = assert(lovely.apply_patches(filename, love.filesystem.read(shader)))
17-
end
14+
local lovely = require "lovely"
15+
shader = assert(lovely.apply_patches(filename, love.filesystem.read(shader)))
1816
self.SHADERS[shader_name] = love.graphics.newShader(shader)
1917
'''
20-
match_indent = true
18+
match_indent = true

src/core.lua

Lines changed: 34 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,45 @@
1-
--- STEAMODDED CORE
2-
--- MODULE CORE
3-
4-
SMODS = {}
5-
MODDED_VERSION = require'SMODS.version'
6-
RELEASE_VERSION = require'SMODS.release'
7-
SMODS.id = 'Steamodded'
8-
SMODS.version = MODDED_VERSION:gsub('%-STEAMODDED', '')
9-
SMODS.can_load = true
10-
SMODS.meta_mod = true
11-
SMODS.config_file = 'config.lua'
12-
13-
-- Include lovely and nativefs modules
14-
local nativefs = require "nativefs"
15-
local lovely = require "lovely"
16-
local json = require "json"
17-
18-
local lovely_mod_dir = lovely.mod_dir:gsub("/$", "")
19-
NFS = nativefs
20-
-- make lovely_mod_dir an absolute path.
21-
-- respects symlink/.. combos
22-
NFS.setWorkingDirectory(lovely_mod_dir)
23-
lovely_mod_dir = NFS.getWorkingDirectory()
24-
-- make sure NFS behaves the same as love.filesystem
25-
NFS.setWorkingDirectory(love.filesystem.getSaveDirectory())
26-
27-
JSON = json
28-
29-
local function set_mods_dir()
30-
local love_dirs = {
31-
love.filesystem.getSaveDirectory(),
32-
love.filesystem.getSourceBaseDirectory()
33-
}
34-
for _, love_dir in ipairs(love_dirs) do
35-
if lovely_mod_dir:sub(1, #love_dir) == love_dir then
36-
-- relative path from love_dir
37-
SMODS.MODS_DIR = lovely_mod_dir:sub(#love_dir+2)
38-
NFS.setWorkingDirectory(love_dir)
39-
return
40-
end
41-
end
42-
SMODS.MODS_DIR = lovely_mod_dir
43-
end
44-
set_mods_dir()
45-
46-
local function find_self(directory, target_filename, target_line, depth)
47-
depth = depth or 1
48-
if depth > 3 then return end
49-
for _, filename in ipairs(NFS.getDirectoryItems(directory)) do
50-
local file_path = directory .. "/" .. filename
51-
local file_type = NFS.getInfo(file_path).type
52-
if file_type == 'directory' or file_type == 'symlink' then
53-
if not NFS.getInfo(file_path.."/.lovelyignore") then
54-
local f = find_self(file_path, target_filename, target_line, depth+1)
55-
if f then return f end
56-
end
57-
elseif filename == target_filename then
58-
local first_line = NFS.read(file_path):match('^(.-)\n')
59-
if first_line == target_line then
60-
-- use parent directory
61-
return directory:match('^(.+/)')
62-
end
63-
end
64-
end
65-
end
66-
67-
SMODS.path = find_self(SMODS.MODS_DIR, 'core.lua', '--- STEAMODDED CORE')
68-
1+
assert(SMODS.path, "SMODS was not properly setup.\n\n!!!!!!!!!!!!!!\nPlease make sure your lovely is up to date (Minimum lovely v0.9.0)\n!!!!!!!!!!!!!!")
692
for _, path in ipairs {
703
"src/ui.lua",
714
"src/index.lua",
725
"src/utils.lua",
736
"src/overrides.lua",
747
"src/game_object.lua",
75-
"src/logging.lua",
768
"src/compat_0_9_8.lua",
77-
"src/loader.lua",
789
} do
79-
assert(load(NFS.read(SMODS.path..path), ('=[SMODS _ "%s"]'):format(path)))()
10+
assert(load(SMODS.NFS.read(SMODS.path..path), ('=[SMODS _ "%s"]'):format(path)))()
8011
end
8112

13+
function boot_print_stage(stage)
14+
if not SMODS.booted then
15+
boot_timer(nil, "STEAMODDED - " .. stage, 0.95)
16+
end
17+
end
18+
19+
local catimg = NFS.getInfo(SMODS.path.."assets/cat.png") and love.graphics.newImage(love.filesystem.newFileData(NFS.read(SMODS.path.."assets/cat.png")))
20+
function boot_timer(_label, _next, progress)
21+
progress = progress or 0
22+
G.LOADING = G.LOADING or {
23+
font = love.graphics.setNewFont("resources/fonts/m6x11plus.ttf", 20),
24+
love.graphics.dis
25+
}
26+
local realw, realh = love.window.getMode()
27+
love.graphics.setCanvas()
28+
love.graphics.push()
29+
love.graphics.setShader()
30+
love.graphics.clear(0, 0, 0, 1)
31+
love.graphics.setColor(0.6, 0.8, 0.9, 1)
32+
if progress > 0 then love.graphics.rectangle('fill', realw / 2 - 150, realh / 2 - 15, progress * 300, 30, 5) end
33+
love.graphics.setColor(1, 1, 1, 1)
34+
love.graphics.setLineWidth(3)
35+
love.graphics.rectangle('line', realw / 2 - 150, realh / 2 - 15, 300, 30, 5)
36+
if catimg then love.graphics.draw(catimg, realw/2 - 264, realh/2 - 27, 0, 1, 1); love.graphics.rectangle('line', realw/2 - 264, realh/2 - 27, 96, 96, 5) end
37+
love.graphics.print("LOADING: " .. _next, realw / 2 - 150, realh / 2 + 40)
38+
love.graphics.pop()
39+
love.graphics.present()
40+
41+
G.ARGS.bt = G.ARGS.bt or love.timer.getTime()
42+
G.ARGS.bt = love.timer.getTime()
43+
end
8244
sendInfoMessage("Steamodded v" .. SMODS.version, "SMODS")
45+

src/crash_handler.lua

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,18 @@ end
492492
-- Note: The below code is not from the original StackTracePlus.lua
493493
local stackTraceAlreadyInjected = false
494494

495+
local function doRestart()
496+
if SMODS and SMODS.restart_game then
497+
SMODS.restart_game()
498+
else
499+
local test, msg = pcall(function()
500+
require"lovely".reload_patches()
501+
end)
502+
if not test then sendErrorMessage("Failed to reload patches... " .. tostring(msg), "StackTrace") end
503+
love.event.quit("restart")
504+
end
505+
end
506+
495507
function getDebugInfoForCrash()
496508
local version = VERSION
497509
if not version or type(version) ~= "string" then
@@ -803,13 +815,13 @@ function injectStackTrace()
803815

804816
for e, a, b, c in love.event.poll() do
805817
if e == "quit" then
806-
return 1
818+
return a or 0
807819
elseif e == "keypressed" and a == "escape" then
808820
return 1
809821
elseif e == "keypressed" and a == "c" and love.keyboard.isDown("lctrl", "rctrl") then
810822
copyToClipboard()
811823
elseif e == "keypressed" and a == "r" then
812-
SMODS.restart_game()
824+
doRestart()
813825
elseif e == "keypressed" and a == "down" then
814826
scrollDown()
815827
elseif e == "keypressed" and a == "up" then
@@ -829,7 +841,7 @@ function injectStackTrace()
829841
elseif e == "gamepadpressed" and b == "dpup" then
830842
scrollUp()
831843
elseif e == "gamepadpressed" and b == "a" then
832-
return "restart"
844+
doRestart()
833845
elseif e == "gamepadpressed" and b == "x" then
834846
copyToClipboard()
835847
elseif e == "gamepadpressed" and (b == "b" or b == "back" or b == "start") then
@@ -847,7 +859,7 @@ function injectStackTrace()
847859
if pressed == 1 then
848860
return 1
849861
elseif pressed == 3 then
850-
return "restart"
862+
doRestart()
851863
elseif pressed == 4 then
852864
copyToClipboard()
853865
end

src/game_object.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
--- STEAMODDED CORE
22
--- MODULE API
33

4+
local NFS = SMODS.NFS
5+
46
function loadAPIs()
57
-------------------------------------------------------------------------------------------------
68
--- API CODE GameObject

0 commit comments

Comments
 (0)