• Chat Command with an argument - Finding a players name
    9 replies, posted
Hi everyone. I feel like I've messed up. The base lua files are yelling at me [CODE] [ERROR] lua/includes/util.lua:184: attempt to index local 'object' (a number value) 1. IsValid - lua/includes/util.lua:184 2. unknown - addons/ulib/lua/ulib/shared/hook.lua:186 [/CODE] basically, I'm trying to make a whois system that opens a derma menu when someone types !whois <name>. I've never done anything like this before, so I apologise if my code creates seizures [CODE] hook.Add("PlayerSay", 0, function( ply, text, teamc, alive ) local whois = string.Explode(" ", text); local namae = player.GetAll() if( whois[1] == "!whois" and (string.find( whois[2], namae, 0, true ))) then print("help") end return "" end) [/CODE] Yes I have googled it, ( chat commands with arguments site:facepunch.com ), and all I get is frameworks to add multiple. I just want to make this one command. So if anyone could point me towards where I should be I'd be very grateful.
I'm pretty sure that the 2nd argument of string.find only takes a string, and you are giving it a table.
[QUOTE=EvacX;41671313]I'm pretty sure that the 2nd argument of string.find only takes a string, and you are giving it a table.[/QUOTE] Hm. Would there be any other way to find the second argument? I'm stumped.
[code]function findPlayer(name) for k,v in pairs(player.GetAll()) do if string.find(name,v:Nick()) then return v end end return false end hook.Add("PlayerSay", 0, function( ply, text, teamc, alive ) local whois = string.Explode(" ", text); local pl = findPlayer(whois[2]) if( whois[1] == "!whois" and pl) then print(pl:Nick().." was found.") end return "" end)[/code] Untested, and doesn't check for multiple matches, but should work.
[QUOTE=KarmaLord;41682271][code]function findPlayer(name) for k,v in pairs(player.GetAll()) do if string.find(name,v:Nick()) then return v end end return false end hook.Add("PlayerSay", 0, function( ply, text, teamc, alive ) local whois = string.Explode(" ", text); local pl = findPlayer(whois[2]) if( whois[1] == "!whois" and pl) then print(pl:Nick().." was found.") end return "" end)[/code] Untested, and doesn't check for multiple matches, but should work.[/QUOTE] Doesn't it seem a bit silly check if there's a player match even if the first word isn't "!whois"?
Getting the same error, I might just rewrite it again. guhguhg
I wrote this as an example for someone else using a console command method: [lua]concommand.Add( "mycmd", function( ply, cmd, args ) -- ply is the person that calls it IE __YOU__!!! -- cmd, I've never used -- args is what you want to use -- You can do it one of several ways: -- if you know the ent index of the player, take Entity( tonumber( args[1] ) ) and you have your player. -- If you want to target by name, you need to search: local _match = NULL; for k, v in pairs( player.GetAll( ) ) do local _find = string.find( string.lower( v:Nick( ) ), string.lower( args[ 1 ] ) ); -- Returns nil if pattern not found, otherwise it returns index or so: [url]http://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/index15fa.html[/url] if ( !_find ) then continue; else _match = v; break; end end if ( IsValid( _match ) && _match:IsPlayer( ) ) then print( "We found the player you were looking for, their steamid is : " .. _match:SteamID( ) ) else print( "The force was not with you on this one young grasshopper." ) end end )[/lua] Feel free to use an adapt it. For PlayerSay, I'd say look into this: // Here's a PlayerSay Example -- Tested and working.... [lua]function GM:PlayerSay ( Player, text, private ) // // Do /commands privatly, !commands publicly // local _cmd = "whois"; local _bSlash = string.StartWith( text, "/" .. _cmd ) local _bExclaim = string.StartWith( text, "!" .. _cmd ) if ( _bSlash || _bExclaim ) then // Here's where you can call your data. local _arg = string.sub( text, string.len( _cmd ) + 3 ); local _match = NULL; for k, v in pairs( player.GetAll( ) ) do local _find = string.find( string.lower( v:Nick( ) ), string.lower( _arg ) ); if ( !_find ) then continue; else _match = v; break; end end print( tostring( _match ) ); if ( !_bExclaim ) then return ""; end end end[/lua]
Thanks all above me, especially Acecool <3 One last question if anyone wants to tell me to not explode everything: I want to now use v:Nick() as the player in question in a information menu. Would I use the net library? I've never used it before and it's kind of scary. I don't really know where to start. For example, in TTT, I can just use self.Player as I'm utilising the PANEL:DoRightClick() feature. But I'm trying to make it work in sandbox, and the menu is all clientside. So Acecools code goes in init.lua, and the derma menu is in cl_init? Or should I make a new file? [URL=http://wiki.garrysmod.com/page/Using_the_net_library]I'm looking here,[/URL] and it seems like I'd use in init.lua[CODE] util.AddNetworkString( "Menu" ) (at the top because it needs time?), net.Start( "Menu" ), net.Send( "Menu" )[/CODE] Then in cl_init I'd do [CODE]net.Recieve( "Menu", function( v ) --create menu using v:Nick() end)[/CODE] Or would I have to define the Nick of the player again? I think it'd be cool to learn this, so if anyone could point me in the right direction I would be very extremely muchly grateful.
Instead of sending the full length of a name, I'd personally send Player:EntIndex( ) which is a number. You can re-reference that Player Nick on the other side using Entity( EntIndex ):Nick( ). Is this for the Sandbox scoreboard, or what? The Sandbox scoreboard allows use of self.Player in as it's referenced in the code. Here's some of the sandbox code: [lua]self.AvatarButton.DoClick = function() self.Player:ShowProfile() end self.Mute.DoClick = function() self.Player:SetMuted( !self.Muted ) end[/lua] You'd just have to add the right-click functionality to the name, for it to popup a menu. But self.Player exists, so you wouldn't need to network anything unless you want to take administrative action ( whereby you send the command to the server, the server verifies who you are and that your intentions are within the scope of your power, then carries them out -- unless it's a client-side mic mute or something for the client... ) My code was an example of two ways to do a search.. Well, one way, but with the scoreboard everything is in front of you, so you don't need to "search". Just create the code so you can click their name to popup a menu or whatever you want to do.
I've already made that, I'm just messing around to see if I could make it open via chat command. Thank you so much acecool, you're a really good teacher!
Sorry, you need to Log In to post a reply to this thread.