I have a ModuleScript with this code in it.

local InsertService = game:GetService("InsertService")
local HttpService = game:GetService("HttpService")

local filesystem = script

local parseDir = require(filesystem.internal.parseDirectory)

local baselua = require(filesystem.base)

local sandbox = function(module) --TODO: does nothing, keeping it here in hopes Roblox implements a way to sandbox
	return setfenv(function()
		require(module)
	end, baselua)
end

local gLua = require(filesystem.base)
local conLua = {}

-- ========
-- autoruns
-- ========

local loadorder = {
	"<<root>>.includes",
	"<<root>>.autorun",
	"<<root>>.postprocesses", -- client only
	"<<root>>.effects",
	"<<root>>.entities",
	"<<root>>.weapons",
}

for _,v in ipairs(loadorder) do
	local searchFor = string.gsub(v, "<<root>>%.", "")
	local directory = filesystem.addon.lua:FindFirstChild(searchFor, false)
	local ignoreAncestor = "" -- not worrying about replication just yet, keep this empty
	if directory ~= nil then
		for _,k in ipairs(directory:GetDescendants()) do
			if (k.ClassName == "ModuleScript") and (k:FindFirstAncestor(ignoreAncestor) == nil) then
				gLua[k.Name] = sandbox(k)
			end
		end
	end
end

-- ========
-- setup
-- ========

local proxy = newproxy(true)

local SourceService = getmetatable(proxy)

SourceService.codingbase = {}

function SourceService.codingbase:module(name, loaders) -- adds the fenv of the calling script to the global libraries
	for i,v in pairs(getfenv()) do
		gLua[i] = v
	end
end

function SourceService.codingbase:get() -- used to set your env to glua
	setfenv(2, gLua)
end

function SourceService.codingbase:include(self, scr) -- sort of the same as :module but for other scripts
	local instance = nil
	if type(scr) == "string" then
		instance = parseDir(filesystem.addon.lua, scr, false, false)
	elseif typeof(scr) == "Instance" then
		instance = scr
	end
	local results = sandbox(instance)
	SourceService.codingbase:get()
	return results
end

function SourceService:getFiles() 
	return filesystem
end

function SourceService:loadAddon(self, addonId) -- loads an addon, disabled for the time being
	return
	--warn("custom addons are currently not supported")
	--if gLua.CLIENT == true then return end
	--local addon = InsertService:LoadAsset(addonId)
	--local addonContent = addon:GetDecendants()
	--local addonfile = addon.addon or addon.gameinfo
	--local addondata = HttpService:JSONDecode(addonfile.Value)
	--for _,v in ipairs(addonContent) do
	--	if v.ClassName == ("Script" or "LocalScript" or "ModuleScript") then
	--		warn("Addon " .. addonId .. " attempted to use a " .. v.ClassName .. ", currently custom scripts are disabled as they cannot be sandboxed. Not loading addon.")
	--		addon:Destroy()
	--		return
	--	end
	--end
	--require(filesystem.internal.MergeHierarchy)(filesystem.addon, addon)
	--return 
end

function SourceService:ReplicateToClient(player)
	print("test")
end

--local meta = getmetatable(proxy)
SourceService.__index = SourceService
SourceService.__tostring = function(self)
	return "Source Service"
end
SourceService.__metatable = "The metatable is locked"

proxy:ReplicateToClient()

return proxy

full script

line 15 inside the script works and prints "test", though when attempting to index from outside the script

require(game.SourceService):ReplicateToClient()

I get the error

attempt to index userdata with 'ReplicateToClient'

I find it especially odd as it will output "Source Service" when printed. Meaning the __tostring metamethod is carrying over, just not the __index. Or possibly some other reason, I'm not sure.

Any Ideas?

9 comments

0

Can you show the whole code please?

0

@imKirda Done.

0

That is actually interesting, if the __tostring metamethod is there, the metatable has not disappeared, try printing getmetatable(require(game.SourceService)).

0

@imKirda appologies for the long response time. getmetatable does return what I set __metatable to. I descovered something really strange though, if I remove the code setting a metamethod it still returns what I set it to prior. Even after reloading the script.

0

I even tried setting the metamethod to nil, still returns the prior value. I know it's running the code to set the metamethods, it will still correctly set non-nil values.

0

I would try and get the Userdata hex, to see if its unique, but I cant unset the __metamethod value.

0

Am i understanding correctly, your code's source changes do not update? Is this code for plugin?

0

@imKirda I asked a new question cause I wasn't sure if you'd see the comment, I expain it better there. https://scriptinghelpers.org/questions/121938

0

sorry i won't be able to help you with this