• Need Help creating a name script
    42 replies, posted
Hello. I am working on an SWRP server, and I need help with making a name creation system. In a nutshell, what I am aiming for, is when a player first joins, he/she will be prompted with a UI to enter a name, and then after that a string of 5 randomly generated (and preferably unique) numbers will be prefixed to the name. After doing this, they cannot change their name using /rpname or any of the other darkrp name changes. Any help is greatly appreciated, thanks!
bump
[img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/GM/PlayerInitialSpawn]GM:PlayerInitialSpawn[/url] [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/vgui/Create]vgui.Create[/url] [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Player/SetPData]Player:SetPData[/url] [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Player/GetPData]Player:GetPData[/url] Add these together, then add some Lua and a bit of magic and you're done.
[QUOTE=GalaxyBeatzz;52687722][img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/GM/PlayerInitialSpawn]GM:PlayerInitialSpawn[/url] [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/vgui/Create]vgui.Create[/url] [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Player/SetPData]Player:SetPData[/url] [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Player/GetPData]Player:GetPData[/url] Add these together, then add some Lua and a bit of magic and you're done.[/QUOTE] I'm new to lua, some extended help would be nice, however I will do my best. Also using SQL, how could I check if a uid exists, so instead of using initial spawn, it will check if they have data on the table. (This way, I don't have to completely reset playerdata) [editline]16th September 2017[/editline] I have this, however I doubt it would work to check if the data already exists: [CODE] function checkForName(ply) sql.Query( "SELECT uid FROM swrp_playernames WHERE uid = " .. ply:UniqueID() .. ";") end) [/CODE]
[QUOTE=jonnyetiz;52688225] [CODE] function checkForName(ply) sql.Query( "SELECT uid FROM swrp_playernames WHERE uid = " .. ply:UniqueID() .. ";") end) [/CODE][/QUOTE] Does the gamemode even use the built-in SQL system like that? I mean you can [I]literally[/I] count the number of rows where rows > 1 is valid data. Maybe [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/sql/QueryValue]sql.QueryValue[/url]? Check whether the return value is valid and boom, valid entry.
[QUOTE=kpjVideo;52688665]Does the gamemode even use the built-in SQL system like that? I mean you can [I]literally[/I] count the number of rows where rows > 1 is valid data.[/QUOTE] Yes, the base gamemode is DarkRP, and I want to make sure that a UID has data, not that there IS data, so if someone joins the first time but crash or leaves without doing the UI, they will be prompted with it until they have data on the table.
Is it just me or is PData in any case easier to use than SQL Queries for a beginner to coding?
[QUOTE=GalaxyBeatzz;52689033]Is it just me or is PData in any case easier to use than SQL Queries for a beginner to coding?[/QUOTE] i dunno, is it?
[QUOTE=jonnyetiz;52689068]i dunno, is it?[/QUOTE] Seeing that ply:GetPData( "FirstJoin", false ) and ply:SetPData( "FirstJoin, true ) is basically doing the same as a big SQL Query but way simpler I suggest you use that instead.
--snip-- [editline]16th September 2017[/editline] [QUOTE=GalaxyBeatzz;52689073]Seeing that ply:GetPData( "FirstJoin", false ) and ply:SetPData( "FirstJoin, true ) is basically doing the same as a big SQL Query but way simpler I suggest you use that instead.[/QUOTE] Aha, I understand. So after they complete the form, we would run ply:SetPData( "FirstJoin, true" )
[QUOTE=jonnyetiz;52689083]--snip--[/QUOTE] Two things, recommend you use true and false here and also choose a more original name, you don't want to overwrite someone else's data. uid, name, money, things like that are too common. I always like to choose names that are hardly ever chosen, such as GLXY_MONEYDATA for example. You might wanna go with like Jonnyetiz_UID [editline]17th September 2017[/editline] The point is also, if you're a starter this might not be the easiest project to make and there are solutions sort of like this already out there.
[QUOTE=GalaxyBeatzz;52689088]Two things, recommend you use true and false here and also choose a more original name, you don't want to overwrite someone else's data. uid, name, money, things like that are too common. I always like to choose names that are hardly ever chosen, such as GLXY_MONEYDATA for example. You might wanna go with like Jonnyetiz_UID [editline]17th September 2017[/editline] The point is also, if you're a starter this might not be the easiest project to make and there are solutions sort of like this already out there.[/QUOTE] I went with ply:GetPData( "HasName", false ) Generally the data I will need to store will be the name and the 5 numbers that come before the name (I don't think I should need the UID anymore with ply:GetPData, as the only reason for the UID was for SQLite to read who's data is whose)
[QUOTE=jonnyetiz;52689097]I went with ply:GetPData( "HasName", false ) Generally the data I will need to store will be the name and the 5 numbers that come before the name (I don't think I should need the UID anymore with ply:GetPData, as the only reason for the UID was for SQLite to read who's data is whose)[/QUOTE] In that case store the whole thing, why would you store both Galaxy and 28393 for example if you could also just store the string "Galaxy#28393" and then use [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/string/Split]string.Split[/url] and split it where you have put the #, plus it looks cool because B.Net and Discord uses the #.
[QUOTE=GalaxyBeatzz;52689112]In that case store the whole thing, why would you store both Galaxy and 28393 for example if you could also just store the string "Galaxy#28393" and then use [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/string/Split]string.Split[/url] and split it where you have put the #, plus it looks cool because B.Net and Discord uses the #.[/QUOTE] Could I do it without the # in between, and also remember how I want the number to be randomly generated between 11111 and 99999. In a nutshell, They enter their name in the gui(I figured that part out) The GUI takes that name, and then generates the random number Saves the data, then whenever they are ingame their name will display as ##### Name [editline]16th September 2017[/editline] Here's what I have so far: cl_namegui.lua [CODE] function DrawGUI() local frame = vgui.Create( "DFrame" ) frame:Center frame:SetSize( 200, 400 ) frame:MakePopup() frame:ShowCloseButton( false ) --Description Text description = vgui.Create( "DLabel", frame ) description:SetPos( 50, 50 ) description:SetText( "Enter your desired name. Do not worry about anything other than your name, as you will be automatically assigned a number!" ) description:SizeToContents() --Where the name will be entered name_entry = vgui.Create( "DTextEntry", frame ) name_entry:SetSize( 100, 20 ) name_entry:SetPos( 50, 250 ) --Button to submit the name to the server. submit_button = vgui.Create( "DButton", frame ) submit_button:SetSize( 100, 50 ) submit_button:SetPos( 50, 350 ) submit_button:SetText( "Submit!" ) submit_button.DoClick = function() net.Start ( "send_name" ) net.WriteString( name_entry:GetValue() ) net.SendToServer() end end net.Receive( "opennamegui", DrawGUI ) [/CODE] and sv_namingsystem.lua [CODE] util.addNetworkString ( "opennamegui" ) plyNumber = math.random( 11111, 99999 ) -- Check if a UID has a name assigned in case the player crashes or does not complete the form on first spawn. if ply:GetPData( "HasName", false ) then net.Start( "opennamegui" ) net.Send( ply ) end net.Receive( "send_name", ply:SetPData( "HasName", true ) ) [/CODE]
You could but it would be easier to store with a seperator. For the random part I guess you should make a table in your database which contains the already taken IDs and have a math.random( 0, 99999 ) run everytime until it finds an ID that hasn't been taken yet. It's not efficient but it should work
[QUOTE=GalaxyBeatzz;52689223]You could but it would be easier to store with a seperator. For the random part I guess you should make a table in your database which contains the already taken IDs and have a math.random( 0, 99999 ) run everytime until it finds an ID that hasn't been taken yet. It's not efficient but it should work[/QUOTE] Wait so if Im using PData, where is that database?
[QUOTE=jonnyetiz;52689229]Wait so if Im using PData, where is that database?[/QUOTE] PData does SQL but more compact. It's in the same place as your DB would normally be
[QUOTE=GalaxyBeatzz;52689244]PData does SQL but more compact. It's in the same place as your DB would normally be[/QUOTE] What table would it be under though Also, I don't know how to test the script [editline]17th September 2017[/editline] Getting the error: [CODE] [ERROR] lua/sv_namingsystem.lua:6: attempt to index global 'ply' (a function value) 1. unknown - lua/sv_namingsystem.lua:6 [/CODE] when I execute sv_namingsystem.lua (Using same exact code as seen above)
I think you need to follow a basic tutorial for GLua first seeing the kinds of issues you get. Anyways the specific issue you get has to do with ply not being predefined, you first have to define ply somewhere, for example in an InitialSpawn hook by using [code]hook.Add( "PlayerInitialSpawn", "J_FirstSpawn", function( ply )[/code]
[QUOTE=GalaxyBeatzz;52689653]I think you need to follow a basic tutorial for GLua first seeing the kinds of issues you get. Anyways the specific issue you get has to do with ply not being predefined, you first have to define ply somewhere, for example in an InitialSpawn hook by using [code]hook.Add( "PlayerInitialSpawn", "J_FirstSpawn", function( ply )[/code][/QUOTE] This seems to have fixed it, however now I'm trying to figure out a reliable way of testing the script.
So far, here is what I have: cl_namegui.lua [code]function DrawNameGUI() local frame = vgui.Create( "DFrame" ) frame:SetSize( 200, 400 ) frame:Center() frame:SetTitle( "" ) frame:SetDraggable( false ) frame:MakePopup() frame:ShowCloseButton( false ) function frame:Paint( w, h ) draw.RoundedBox( 5, 0, 0, 200, 400, Color( 10, 10, 10, 220 ) ) draw.RoundedBoxEx( 5, 0, 0, 200, 20, Color( 240, 85, 0, 220 ), true, true, false, false ) draw.SimpleText( "Character Namer", "Default", 100, 10, color_white, 1, 1 ) end --Description Text description = vgui.Create( "RichText", frame ) description:Dock( FILL ) description:SetPos( 25, 50 ) description:InsertColorChange( 255, 255, 255, 255 ) description:AppendText( "Enter your desired name! Do not worry about adding anything other than your name, as everything else (numbers, rank, etc.) will automatically be added!") description:InsertColorChange( 255, 0, 0, 255 ) description:AppendText( "\n\n\n\nWAIT! Make sure your name is RP-friendly or it will be changed!\n\n Please only use letters.\n Must be 3 or more characters, max 15." ) description:SetVerticalScrollbarEnabled( false ) --Where the name will be entered name_entry = vgui.Create( "DTextEntry", frame ) name_entry:SetText( "Enter name here" ) name_entry:SetSize( 150, 20 ) name_entry:SetPos( 25, 250 ) name_entry:Dock( NODOCK ) name_entry:SetNumeric( false ) name_entry:SetAllowNonAsciiCharacters( false ) name_entry.OnTextChanged = function(self) local txt = self:GetValue() local amt = string.len(txt) if amt > 15 then self:SetText(self.OldText) self:SetValue(self.OldText) else self.OldText = txt end end name_entry.OnTextChanged = function() if tonumber(name_entry:GetValue()) == nil then return false end end --Button to submit the name to the server. submit_button = vgui.Create( "DButton", frame ) submit_button:SetSize( 100, 50 ) submit_button:SetPos( 50, 300 ) submit_button:SetText( "Submit!" ) submit_button:Dock( BOTTOM ) submit_button.DoClick = function() net.Start ( "send_hasname" ) net.SendToServer() net.Start ( "send_namedata" ) net.WriteString( name_entry:GetValue() ) net.SendToServer() local txt = name_entry:GetValue() local amt = string.len(txt) if amt < 3 then notenough:SetVisible( true ) notenough:IsActive( true ) elseif amt >= 3 then frame:Close() end end end net.Receive( "opennamegui", DrawNameGUI )[/code] sv_namingsystem.lua [code]util.AddNetworkString( "opennamegui" ) util.AddNetworkString( "send_hasname" ) util.AddNetworkString( "send_namedata" ) concommand.Add( "debugnamegui", function( ply, cmd, args) print "[Naming Debug]: Attempting to run the Name GUI" net.Start( "opennamegui" ) net.Send( ply ) net.Receive( "send_name", ply:SetPData( "HasName", true ) ) end) hook.Add( "PlayerInitialSpawn", "CheckIfHasName", function( ply ) print "[Naming Debug]: Player has Spawned" if ply:GetPData( "HasName", false )then net.Start( "opennamegui" ) net.Send( ply ) elseif ply:GetPData( "HasName", true ) then return nil end net.Receive( "send_name", ply:SetPData( "HasName", true ) ) net.Receive( "send_namedata", ply:SetPData( "Name", true ) ) end) plyNumber = math.random( 11111, 99999 )[/code] Currently, the GUI will open whenever the player spawns until the server has the PData for HasName (Which will be successfully set once the name is sent. Now, I don't know how to get this to work.) Firstly, I will need to save the name as a pdata, and then do the random number generator. (plyNumber will handle generating it, but I still will need to find a way to apply it.) To be clear: I suppose what I am asking is this: ply:SetPData( "Name", ) What would I put after "Name" that would correspond to the data recieved from "send_namedata" (If you look at the clientside file, it sends the value stated in the textbox using send_namedata)
I can probably for the number just do something like ply:SetPData( "Number", plyNumber )
bump
I have a slight idea of what you want to accomplish and you're making it sound so complicated when it really isn't? [code] hook.Add( "PlayerInitialSpawn", "CheckIfHasName", function( ply ) print "[Naming Debug]: Player has Spawned" if ply:GetPData( "HasName", false )then net.Start( "opennamegui" ) net.Send( ply ) elseif ply:GetPData( "HasName", true ) then return nil end net.Receive( "send_name", ply:SetPData( "HasName", true ) ) net.Receive( "send_namedata", ply:SetPData( "Name", true ) ) end) [/code] indentation is very important, not only to you but to use as well because it makes it easier to read. here: [code] hook.Add( "PlayerInitialSpawn", "CheckIfHasName", function( ply ) -- THE SECOND ARGUMENT TO GETPDATA IS THE DEFAULT VALUE IT WILL RETURN IF THE PLAYER DOES NOT HAVE A NAME -- CURRENTLY YOU'RE SNEDIMG HIM THE UI EVNE IF YOU HAVE NAME???????? if (ply:GetPData("HasName", false)) then return; end -- SINCE WE DON'T HAVE A NAME WE DO OUR UI XD net.Start("opennamegui") net.Send(ply) end); [/code] Why do you need a random number generator when the PData is attached to the client? Since you're sending a net message to the client once he spawns, you might want to delay it by a second or two to make sure the client is fully loaded.
[QUOTE=Invule;52702153]I have a slight idea of what you want to accomplish and you're making it sound so complicated when it really isn't? [code] hook.Add( "PlayerInitialSpawn", "CheckIfHasName", function( ply ) print "[Naming Debug]: Player has Spawned" if ply:GetPData( "HasName", false )then net.Start( "opennamegui" ) net.Send( ply ) elseif ply:GetPData( "HasName", true ) then return nil end net.Receive( "send_name", ply:SetPData( "HasName", true ) ) net.Receive( "send_namedata", ply:SetPData( "Name", true ) ) end) [/code] indentation is very important, not only to you but to use as well because it makes it easier to read. here: [code] hook.Add( "PlayerInitialSpawn", "CheckIfHasName", function( ply ) -- THE SECOND ARGUMENT TO GETPDATA IS THE DEFAULT VALUE IT WILL RETURN IF THE PLAYER DOES NOT HAVE A NAME -- CURRENTLY YOU'RE SNEDIMG HIM THE UI EVNE IF YOU HAVE NAME???????? if (ply:GetPData("HasName", false)) then return; end -- SINCE WE DON'T HAVE A NAME WE DO OUR UI XD net.Start("opennamegui") net.Send(ply) end); [/code] Why do you need a random number generator when the PData is attached to the client? Since you're sending a net message to the client once he spawns, you might want to delay it by a second or two to make sure the client is fully loaded.[/QUOTE] The RNG is for the numbers in front of the name [editline]20th September 2017[/editline] [QUOTE=jonnyetiz;52702209]The RNG is for the numbers in front of the name[/QUOTE] And I stated the following: I don't know how to attach a string that is sent from the cl_namegui.lua to PData.
[QUOTE=jonnyetiz;52702209]The RNG is for the numbers in front of the name [editline]20th September 2017[/editline] And I stated the following: I don't know how to attach a string that is sent from the cl_namegui.lua to PData.[/QUOTE] :snip: I see, just do string .. numberGen which becomes "name number" e.g "jonny 1231" read about concatenating here: [url]https://www.lua.org/pil/3.4.html[/url]
[QUOTE=Invule;52702242]:snip: I see, just do string .. numberGen which becomes "name number" e.g "jonny 1231" read about concatenating here: [url]https://www.lua.org/pil/3.4.html[/url][/QUOTE] I know, but I dont know how to attach that the Name string sent from cl_namegui.lua
[img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Player/SetPData]Player:SetPData[/url] Provides an example on how to use it.
[QUOTE=Invule;52702271][img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Player/SetPData]Player:SetPData[/url] Provides an example on how to use it.[/QUOTE] sigh... I am saying that I do not know how to get a string that is sent from another file. I know how set and get pdata works, but I can't figure out how to get string from something sent from a file, which is the data from: [CODE]net.Start ( "send_namedata" ) net.WriteString( name_entry:GetValue() ) net.SendToServer()[/CODE]
net.Receive and net.ReadString I suggest you read this: [url]https://wiki.garrysmod.com/page/Net_Library_Usage[/url]
Sorry, you need to Log In to post a reply to this thread.