• Opposite of UMSG?
    12 replies, posted
Hey guys. I'm having a pretty big problem in my gamemode. In the gamemode, you can chat with NPCs and when you talk to the Black Smith npc, a box of weapons spawns on his desk when you purchase through the NPC talking script. The thing is, the talking script is clientside but the weapon box entity is a serverside entity and i can't use [CODE]function spawnS(c) local s = ents.Create("wep_box"); s:SetPos(Vector(-936.4385,3618.53225,365.03125)); s:SetAngles(Angle(0,0,0)); s:SetContents(c,10,4.0); s:Spawn(); end [/CODE]because the wep_box entity is serverside. So I thought, maybe I should make a secret console command to pass this data to the server and so I made a command [B]2124SS[/B] and you would just use [CODE]function spawnS(c) LocalPlayer():ConCommand("2124SS " .. tostring(c)); end[/CODE]This worked fine! Only one problem.. Roleplayers could type [B]2124SS knife[/B] into their console if they ever found out the command. Finding out the command would be easy for them because of SMART valve's AutoComplete in console so if they just type [B]2[/B] into their console, it would show an option to AutoComplete [B]2124SS[/B] and they could figure out the arguments. Then I thought of making the console command secure by adding [CODE]function spawnS(c) [B]if(ply:GetNWBool("awaitingWB") == true)then[/B] local s = ents.Create("wep_box"); s:SetPos(Vector(-936.4385,3618.53225,365.03125)); s:SetAngles(Angle(0,0,0)); s:SetContents(c,10,4.0); s:Spawn(); [B]end[/B] end [/CODE] And set the player's boolean to TRUE before calling the ConCommand part. Didn't accept it.[B] My question is- Is there a way to send information to the server from clients [/B][I](probably not because this would make hacking possible with clientside scripts on other servers)[/I][B] OR a way to DISABLE the AutoComplete on a console command to hide it from being seen.[/B] [U][I][B]~Micah S. Allen[/B][/I][/U]
A secret console command is the worst way to go. It can be exploited so easily, you'll be in trouble quickly. The absolute best thing to do is to simply make a console command, and then inside that console command, check if the player is near the NPC's talking distance, as so: [lua] if npc:GetPos():Distance(ply:GetPos()) < 100 then // create weapon box end [/lua]
You could generate a random UniqueID for each person on the initial spawn, send it to the client by umsg then send the console command with the person's uniqueid as the last argument. Then do a check that if the last argument doesn't equal the player's uniqueid then return. Aslong as the uniqueid isnt networked, you should be fine.
My way is better because the other can still be exploited since it relies on the client
Or even better, you could set a bool on the client if they bought it then do what Gbps did plus a trace. But that is all still abusable.
add a secret hash that gets send in the console command to.
Serversides checks are the only thing that can be effective. Don't bother with the other stuff.
Personally, I'd make the console command look like something dangerous to type like "dumpclientdlls" or something.
Here's something I made a while ago. [lua]if SERVER then usermessage = {} usermessage.Hooks = {} function usermessage.Hook( name, func ) usermessage.Hooks[name] = func end concommand.Add("umsg",function(pl,cmd,args) local name,info = args[1], {} if not usermessage.Hooks[name] then error("Unhandled usermessage " .. name .. " from player " .. pl:Name() .. "!") end table.remove(args,1) status, err = pcall( function(str) info = glon.decode(str) end, table.concat( args, " " ) ) if not status then error("Malformed usermessage " .. name .. " from player " .. pl:Name() .. "!") end usermessage.Hooks[name](pl,info) end) end if CLIENT then umsg = {} umsg.CurMessage = "" umsg.CurObjs = {} function umsg.Start( name ) if umsg.CurMessage != "" then ErrorNoHalt("There is already an active usermessage! Overriding...") end if string.Explode(" ",name)[2] then error("Name must not contain a space...") end umsg.CurMessage = name umsg.CurObjs = {} end function umsg.Object( obj ) if not umsg.CurMessage or umsg.CurMessage == "" then return end table.insert( umsg.CurObjs, obj ) end function umsg.End() RunConsoleCommand("umsg", umsg.CurMessage, glon.encode( umsg.CurObjs ) ) umsg.CurMessage = "" umsg.CurObjs = {} end end[/lua]
Kind of obvious, but if you don't want them running a command, prefix it with ~. 99% of people have console bound so that if they type that key it instantaneously closes, and if they somehow happen to do that, there's no way to run the autocomplete. Edit: Come to think of it, autocomplete only works if the client has the file that the command is in. If your file is on the server end, the client will never know about the file unless they type the exact name. Just putting that out there.
Commands begun with ~ work fine for autocomplete. This has been mentioned in other threads before. The ~ character is what copy and paste is for.
Around here nobody has their console bound to ~ as it's not setup properly by default. And even then there is no reason you'd want to rely on a console command staying secret. Just decide if the command should be run serverside, what's the problem with that? [editline]12:50AM[/editline] The ~ not being used for console is probably true for a ton of countries, so definitely not 99% of all players.
I have my console bound to ~. What's wrong with that?
Sorry, you need to Log In to post a reply to this thread.