"attempted to call require with invalid arguments" How to Fix Roblox Studio Luau - roblox

I was making an Egg-Open-Gui for a simulator and when I ran the script it always arrored this:
Attempted to call require with invalid argument(s)
Script Players.Robloxgamer_73738.PlayerGui.Menu.EggScript
the so called "Eggscript" is local
here is my script:
wait(game.Loaded)
wait(5)
local petmodule = require(game:GetService("ServerScriptService"):FindFirstChild("PetModule"))
local cost = script.Parent.Parent.Parent.Cost.Value
local player = game.Players.lo
local openOnceButton = script.Parent.OpenOnce
local autoOpenButton = script.Parent.AutoOpen
openOnceButton.MouseButton1Click:Connect(function()
if player.leaderstats["💸 Money 💸"].Value >= cost then
player.leaderstats["💸 Money 💸"].Value = (player.leaderstats["💸 Money 💸"].Value - cost)
local pet = petmodule.chooseRandomPet()
local petVal = Instance.new("StringValue")
petVal.Name = pet.Name
petVal.Parent = player.PetInventory
game.ReplicatedStorage.HatchEgg:FireServer(pet)
print(pet.Name.." selected")
end
end)

You cannot access ServerScriptService in the client. It will be empty, thus, there will be no child. The FindFirstChild call will return nil, which is obviously invalid. Move the module to ReplicatedStorage.
Besides, you don't seem to understand the client-server model. You can't really change a leaderstat value from the client; it will only affect the client and not the server, so other clients will be unaware of the change. You can use RemoteEvents but make sure that you structure them in a way that it will be safe.

Related

How to get PlayerGUI from a Server Script?

I am working on an inventory system and and now i need to make it save, but when trying to save it prints this in the output
PlayerGui is not a valid member of Player "Players.RidhoMBLR"
local function save(player)
local invTable = {}
for i, v in pairs(player.PlayerGui.ScreenGui.Inventory.InvFrame:GetChildren()) do
if v:IsA("TextButton") then
table.insert(invTable, v)
end
end
dataStore:SetAsync(player.UserId, invTable)
end
players.PlayerRemoving:Connect(save)
While you are accessing the path to the PlayerGui correctly, it is probably not replicated to the server (ie, it's existence is only observable on the client in LocalScripts).
So you will likely need to use a LocalScript to pull all of the relevant information out of the UI, and communicate it up to the server using a RemoteEvent. So move your code to a LocalScript :
local players = game.Players
local saveEvent = game.ReplicatedStorage.RemoteEvent -- find your RemoteEvent here
local function save(player)
-- only tell the server about it if we are the one leaving
if player ~= players.LocalPlayer then
return
end
-- get information about the inventory
local inventory = player.PlayerGui.ScreenGui.Inventory.InvFrame:GetChildren()
local invTable = {}
for i, v in ipairs(intentory) do
if v:IsA("TextButton") then
-- grab the text out of each button
table.insert(invTable, v.Text)
end
end
-- tell the server about our inventory
saveEvent:FireServer(invTable)
end
players.PlayerRemoving:Connect(save)
Then in a server Script, listen for when clients fire the event and save their data then :
local saveEvent = game.ReplicatedStorage.RemoteEvent -- find that same RemoteEvent
-- listen for when players report that they are leaving
saveEvent.OnServerEvent:Connect(function(player, inventoryTable)
-- save their information
dataStore:SetAsync(player.UserId, inventoryTable)
end)
So basically you can't access a player's PlayerGui through the server. PlayerGui is replicated locally for each client, hence in order to interact with a Player's Gui I'd recommend using RemoteEvents. By using Remote events you'd be sending a signal to the client which can then by picked up by a LocalScript. On the local script you can then fire another RemoteEvent back to the server with a list of all the items which you can then SetAsync on the server.

Roblox - attempt to call a nil value

When trying to create a code, that on FireServer with Specific Player chosen a GUI would've been cloned into their PlayerGui, But instead I get a nil value.
Code:
local Blinder = game.ReplicatedStorage.RCD.Blind
Blinder.OnServerEvent:Connect(function(player, PlayerToBlind)
if not player:IsInGroup(7465879) then return false end;
script.BL:Clone().Parent = PlayerToBlind:WaitForChild("PlayerGui")
print("Done")
end)
Basically what I try to reach is if my Admin Panel Remoteevent is fired, and a Target has been chosen, the Targeted Player will become a Cloned GUI into their PlayerGui
Any fix on this error?
The error message itself is telling you that you are calling a function that doesn't exist. This issue is caused by an object not being the type you expect.
Unfortunately, the message is pointing at a line that has a few function calls, so it's difficult to say what is causing the exact error. Either script.BL isn't an object with a Clone() function, or PlayerToBlind isn't an object with a WaitForChild() function.
If you can break the operations into a few different lines and add safety checks along the way, you can guarantee that your code is safe and being called properly.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Blinder = ReplicatedStorage.RCD.Blind
local BL = script.BL
Blinder.OnServerEvent:Connect(function(player, PlayerToBlind)
-- check that the person calling Blinder:FireServer actually provided a PlayerToBlind
assert(type(PlayerToBind) == "string", "Blinder expects PlayerToBind to be the name of a player")
-- escape if the player is not in the appropriate group
if not player:IsInGroup(7465879) then
return
end
-- find the Player object based on the name provided from PlayerToBlind
local blindedPlayer = Players:FindFirstChild(PlayerToBlind)
if not blindedPlayer then
warn("Could not find player named : ", PlayerToBlind)
return
end
-- create a blinding UI on the other player
local targetGui = blindedPlayer:WaitForChild("PlayerGui")
local newBL = BL:Clone()
newBL.Parent = targetGui
print("Done")
end)
By adding asserts into your code, it won't stop your code from breaking, in fact it will force your code to break faster and in expected ways.
The issue has been fixed,
I have been setting up the LocalScript wrong.
(I grabbed the Text from a TextButton, Instead of the TextBox)

Sending a model through remote functions? ROBLOX

well hello there,
So I'll get right to the point..
Everyone knows that in Roblox you have a ReplicatedStorage (for Client and Server) and a ServerStorage (only for Server).
So I want to store all my assets in ServerStorage .. you know, since exploiters/hackers can't see the ServerStorage if they tried.
However my game has virtual worlds..meaning that the client sees different objects than the other clients at any given time, so I can't just load an object from a server scripts because then everyone will see it.
Heres the question: Can I perhaps set up a remote function that lets the Client invoke the Server, and then the Server returns a model object or its location or something like that? And can I then use the Client to load the model into the player's workspace?
^That way I can securely store my important game assets in the serverstorage
The answer to your question is "Yes, you can!"
First off, you're going to want to create a RemoteFunction in the ReplicatedStorage. Call this RemoteFunction, 'GetModel'
Now, we're going to set up a local script inside of the StarterPack. This local script should have the following code:
local RS = game:GetService("ReplicatedStorage")
local RF = RS:WaitForChild("GetModel")
local model = RF:InvokeServer("ModelName") -- This code can go anywhere you'd like it to go. 'ModelName' is the name of the model you want to get.
print(model.Name) -- This will print the model's name.
Alright, so we've setup our code to invoke the remotefunction. Now, let's make that RemoteFunction do something. We'll create a server script inside of ServerScriptService. Here's the code:
local RS = game:GetService("ReplicatedStorage")
local RF = RS:WaitForChild("GetModel")
RF.OnServerInvoke = function(player, modelName)
local model = game.ServerStorage:FindFirstChild(modelName)
if model == nil then
return nil
else
return model
end
end
Most of this is basic code, and from what you said in the question it seems you understand lua fine. Hope I helped you! :)

Roblox - Trying to get InvokeClient Remote Function Working

In my server script called MainGameScript I have this code block:
local myRemoteFunction = Instance.new("RemoteFunction")
myRemoteFunction.Parent = game.Workspace
myRemoteFunction.Name = "GetBuildInfo"
game.Players.PlayerAdded:connect(function(player)
print("[MainGameScript] added player")
for i,v in pairs(Regions) do
if (v.Value == 0) then
Regions[i].Value = player.UserId
break
end
end
local success, result = pcall(function() return myRemoteFunction:InvokeClient(player) end)
if success then
print(result)
else
print("Error calling RemoteFunction GetBuildInfo")
end
end)
I have a LocalScript in game.Workspace called LocalBuildScript which contains this:
function game.workspace.GetBuildInfo.OnClientInvoke()
print("[GetBuildInfo] will send back local build info")
return "this will be returned to the server caller script"
end
The GetBuildInfo function is never called. I have added some debug print lines to the calling function and the process seems to die at the point where it uses pcall... This is almost verbatim the Remote Function Client Invoke example from the Roblox Wiki, no idea why it is not working and am hoping somebody here has some experience using InvokeClient scripts.
Thanks,
Andy
The reason it isn't running is because LocalScripts being referenced by RemoteFunctions are expected to be inside of the Player instance somewhere in it. I'm fairly certain this is the case, as I've implemented a similar test system, but I held my LocalScript inside of the Player instance.

How do I properly impersonate another user in CoCreateInstanceEx using COAUTHIDENTITY?

I am currently working on a MFC application which needs to retrieve data from a COM object running on another system. We already have this same data exchange mechanism working and fully supported when both systems are running Windows XP and the same manually set up user account (i.e. same username and password on both systems, no domain). The trouble is that I am trying to set it up such that I can access this same DCOM system from another computer which has the same user account set up, but is logged in under a corporate Domain user account.
Right now, it works if I manually run my application using Run As and specify the alternate user, but I am looking for a better solution. When I set up the COAUTHIDENTITY for the COSERVERINFO in CoCreateInstanceEx, I specify the username and password for the alternate account, and that doesn't seem to work. I've tried various things in the Domain entry - the computer name of the local computer, of the remote computer, and leaving it blank - but none seem to help.
I tried editing the DCOM permissions for the object on the server computer to allow full access to the Everyone account, but that doesn't seem to help, and I haven't been able to find any meaningful error messages about what's really wrong. It would probably help if I could get some kind of log message on the server computer to see exactly what credentials are coming across when I run it using Run As. Does anybody have any ideas? Or maybe know what the system uses for Domain when you make a DCOM connection from a non-Domain account (a few things imply that the computer name is used, but that doesn't work when I try it).
Code follows:
COAUTHINFO AuthInfo;
COAUTHIDENTITY AuthIdentity;
COSERVERINFO ServerInfo;
MULTI_QI Results;
AuthIdentity.Domain = (unsigned short *) w_domain;
AuthIdentity.DomainLength = wcslen( w_domain);
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
AuthIdentity.Password = (unsigned short *) w_password;
AuthIdentity.PasswordLength = wcslen(w_password);
AuthIdentity.User = (unsigned short *) w_username;
AuthIdentity.UserLength = wcslen(w_username);
AuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CALL;
AuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
AuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
AuthInfo.dwCapabilities = EOAC_NONE;
AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
AuthInfo.pAuthIdentityData = &AuthIdentity;
AuthInfo.pwszServerPrincName = NULL;
ServerInfo.dwReserved1 = 0;
ServerInfo.dwReserved2 = 0;
ServerInfo.pAuthInfo = &AuthInfo;
ServerInfo.pwszName = w_nodename;
Results.pIID = &_uuidof(_DS_SessionContext);
Results.pItf = NULL;
Results.hr = 0;
hr = CoCreateInstanceEx(clsid, NULL, CLSCTX_ALL, &ServerInfo, (ULONG) 1, &Results);
if(FAILED(hr))
{
m_Error.Format("(0x%x) CoCreateInstanceEx for _DS_DataFrame failed.",hr);
m_Error2.Format("Make sure computer IP address is correct and connected.");
CoUninitialize();
UpdateData(false);
UpdateWindow();
return false;
}
pSession = (_DS_SessionContext *)Results.pItf;
hr = pSession->raw_DS_GetVersion(&DSStatus, &version);
if(FAILED(hr))
{
m_Error.Format("(0x%x)GetVersion",hr);
CoUninitialize();
UpdateData(false);
UpdateWindow();
return false;
}
Ah, I figured it out. Turns out that in DCOM, creating the instance and calling functions on it do not automatically use the same security blanket. The authentication info in the COSERVERINFO passed to CoCreateInstanceEx only applies towards creating the instance, and when I call functions on that instance later, then it fails because I am calling those functions using the credentials of the application.
To do it properly, before calling functions on the instance, I must first call (error handling omitted for clarity):
hr = CoSetProxyBlanket(Results.pItf, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, &AuthIdentity, EOAC_NONE);
This sets the security blanket used to call the instance to the same one that was used to create it, and thus everything works.