Página 1 de 1

[LUA] Modify package.path globally

Enviado: 10 Ago 2020, 12:33
por HzanRsxa2959
Note: This is for MoonLoader lua.
Hey guys, I tried setting package.path inside a script before launching another script from the previous script. The problem is that in the new script, package.path has its default value instead of the changed value. I though package.path was global? I have searched the internet for any workarounds and all say that I should modify package.path, but if it is local instead of global, then how do I set it for a script before launching it? Is there any way to pass a variable to script before launching it?

Here are two scripts:
1.lua:

Código: Selecionar tudo

function main()
    print("path:", package.path)
    wait(500)
    package.path = "C:\\Test;" .. package.path
    print("changed path:", package.path)
end
[font][font]2nd moon[/font][/font][font][font] :[/font][/font]

Código: Selecionar tudo

function main()
    print("path:", package.path)
    wait(1000)
    print("changed path:", package.path)
end
 Here is moonloader.log:

Código: Selecionar tudo

[20:25:28.789445] (script)	1.lua: path:   D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.luac;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.luac
[20:25:28.790444] (script)	2.lua: path:   D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.luac;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.luac
[20:25:32.814680] (script)	1.lua: changed path:   C:\Test;D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.luac;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.luac
[20:25:32.814680] (system)	1.lua: Script terminated. (id:1)
[20:25:32.814680] (script)	2.lua: changed path:   D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\libstd\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?.luac;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.lua;D:\Grand Theft Auto San Andreas\GAME\moonloader\lib\?\init.luac
[20:25:32.814680] (system)	2.lua: Script terminated. (id:2)
Notice how 1.lua changes the path, but the change only applies to 1.lua, and not 2.lua. Is there any way to globally change the path for lua module loading during runtime? Or any method to pass the modified package.path to the new script before launching it (using script.load) ?

Re: [LUA] Modify package.path globally

Enviado: 10 Ago 2020, 13:07
por Um_Geek
Notice how 1.lua changes the path, but the change only applies to 1.lua, and not 2.lua. Is there any way to globally change the path for lua module loading during runtime? Or any method to pass the modified package.path to the new script before launching it (using script.load) ?

does it help?

export_test.lua

Código: Selecionar tudo

EXPORTS = {
	path = package.path
}

function main()
	while true do
		wait(40)
	end
end

import_test.lua

Código: Selecionar tudo

local ex = import("export_test")

function main()
	while true do
		printStringNow(ex.path, 100)
		wait(50)
	end
end

Re: [LUA] Modify package.path globally

Enviado: 10 Ago 2020, 13:37
por HzanRsxa2959
Thank you, but I already tried that method.

Here is another method I tried:
Opening the script and writing this at its top (using lua):

Código: Selecionar tudo

function getWorkingDirectory() return thisScript().directory end
It did not add library support, but did change the working directory to local.
But I think this seems a little overkill, editing other people's scripts. What do you think?
Also it does not work with compiled scripts (.luac).


Here is some code from my mod at the topic: Scripts from Mod Loader

Código: Selecionar tudo

for i, file in ipairs(smdl.filterFiles({"lua", "luac"}, "moonloader") ) do
	script.load(file)
end
What I am trying to do is to load another script without it being modified, but changing its global variables for my variables.
Is there any way to pass package.path using script.load? What about other variables?
The variables of the launched script that I want to modify are:
getWorkingDirectory() >>> thisScript().directory
package.path >>> modified package.path
package.cpath >>> modified package.cpath

This way, it can support libraries and mod loader.

Maybe a way other than script.load? I would appreciate if you can show me any known method to do this.

Re: [LUA] Modify package.path globally  [RESOLVIDO]

Enviado: 10 Ago 2020, 22:05
por Um_Geek
maybe using c ++ with ffi.

Imagem

It is already advanced for me.

Re: [LUA] Modify package.path globally

Enviado: 11 Ago 2020, 12:10
por HzanRsxa2959
I don't know ffi, but have been trying to learn it. Severe lack of tutorials for that. We'll see where it goes.

I think this is the proper method. Thanks, I will try that when I can.

In the meantime:
1.
I have tried modifying the value of _G, but it is also script-dependent, like wtf? Why are there so many restrictions for something that is so simple in regular lua? _G is literally the table of global environment! Why is it local to scripts?

2. Another method is a workaround I found using threads and chunks:
SpoilerAbrir

Código: Selecionar tudo

script_author("HzanRsxa2959")
script_version("2.0")
script_description("Adds partial support for loading MoonLoader scripts from Mod Loader.")
script_properties("work-in-pause")
script_dependencies("___SearchModLoaderLog")

function startChildScript(file, name, dir, ppath, cpath)
	local file, name, dir, ppath, cpath = file, name, dir, ppath, cpath

	function getWorkingDirectory() return dir end

	ppath = dir .. "\\?.lua;" .. ppath
	ppath = dir .. "\\?.luac;" .. ppath
	ppath = dir .. "\\?\\init.lua;" .. ppath
	ppath = dir .. "\\?\\init.luac;" .. ppath
	cpath = dir .. "\\?.dll;" .. cpath
	package.path, package.cpath = ppath, cpath

	print("Loading", file)
	loadfile(file, 'bt', _G)()
end

local skip = false

local loadml = import(thisScript().name)
if loadml and loadml.file then
	script_name(loadml.name)
	lua_thread.create(startChildScript, loadml.file, loadml.name, loadml.dir, loadml.ppath, loadml.cpath)
	skip = true
end

if not skip then
	local smdl = import("___SearchModLoaderLog.lua")

	print("Started.")

	local added = {}
	local ppath, cpath = package.path, package.cpath
	for i, file in ipairs(smdl.filterFiles({"lua", "luac", "dll"}) ) do
		local subfolder = smdl.getParentPath(file)
		if not added[subfolder] then

			local parentdir, islib
			repeat
				parentdir = string.lower(string.sub(subfolder, 1, -14) )
				if parentdir ~= [[moonloader\lib]] then
					islib = true
					break
				end
			until parentdir

			if islib then
				ppath = subfolder .. "\\?.lua;" .. ppath
				ppath = subfolder .. "\\?.luac;" .. ppath
				ppath = subfolder .. "\\?\\init.lua;" .. ppath
				ppath = subfolder .. "\\?\\init.luac;" .. ppath
				cpath = subfolder .. "\\?.dll;" .. cpath
				added[subfolder] = true
				print("Added library path", subfolder)
			end
		end
	end

	for i, file in ipairs(smdl.filterFiles({"lua", "luac"}, "moonloader") ) do
		local name = string.sub(file, #smdl.getParentPath(file) + 2, -1)
		EXPORTS = {file = file, name = name, dir = smdl.getParentPath(file), ppath = ppath, cpath = cpath}
		script.load(thisScript().path)
	end

	print("Done.")
end

Scripts do work:
  • getWorkingDirectory(), package.path, package.cpath and any other global variables can be modified before loading the script.
but it is very buggy:
  • script_name() does not work.
  • script.path and script.directory return value for original script and are read-only.
I actually ran _Grinch's cheat-menu with the second method, but it crashes the game after about half a minute of opening the menu. I think it's because of loading the images? Huh, crashing the game with lua. Never thought I would see the day.

Anyways, thanks for pointing me in the right direction. I'll keep trying.

Re: [LUA] Modify package.path globally

Enviado: 11 Ago 2020, 18:59
por Um_Geek
if i find something i will inform.

I actually ran _Grinch's cheat-menu with the second method, but it crashes the game after about half a minute of opening the menu. I think it's because of loading the images? Huh, crashing the game with lua. Never thought I would see the day.
General scripts that use 'imgui' can crash if not loaded from the default directory.