• UtilX -- Extending GLua -- Need community input
    371 replies, posted
So, I was thinking, why don't we get a group of experienced and helpful LUA coders together and work on an Lua (.lua) library called UtilX. UtilX would extend what Team Garry has done with the util library by adding new, useful functions that coders are using all the time, but are scattered around different files and gamemodes. We could all work together to compile those useful functions, whether it be mathematical or otherwise, and include them for use with other gamemodes. From then, we could see about it being included in a release of Gmod, and have it available to all coders. Simple Example: [lua] // Get a player's total playing time function utilx.GetPlayerTime(ply) return ply.Created; end [/lua] What I ask from the community: I would like a few snippets of code or devoted coders who would like to help with this project. Even if the function is as simple as returning the player's total playing time, if it is useful, it's worth including into the library. P.S. I'm not one of those crappy 9 year old who start projects as "creative lead." I'm an experienced Lua coder, and look forward to contributing greatly to this project if started. Need moar info? o There will be a clientside and a serverside library. The serverside library will automatically give the client the library. o I will be giving correct credit for every piece of code donated o I'm in the process of setting up a Google Code SVN for updates o The library will only be included when [ require("utilx") ] is called. o I will add more info as the progress goes on.
[lua] local meta = FindMetaTable( "Player" ) if (!meta) then return end function meta:GetUserGroup() return self:GetNetworkedString( "UserGroup" ) end [/lua] Always annoyed me how there wasn't a function for this..
Thanks for the input :)
[QUOTE=dvondrake;16509440]I'd love to see something like this. Just purely in Lua or are we also talking about making our own Lua bindings by means of a DLL? (Is that even possible?)[/QUOTE] 1) Yes, it is very possible. 2) Maybe. I'm sure adding some C++/C to Lua could do wonders, just because C++/C has about everything single function a computer can do. Heh.
[b]InSet( object:value, vararg list ... )[/b] - used to determine if value is inside the list of parameters. [code] function utilx.InSet( val, ... ) local k, v for k, v in ipairs{ ... } do if v == val then return true end end return false end [/code] [b]Usage:[/b] [code] if utilx.InSet( ent:GetClass( ), "prop_door_rotating", "player", "prop_vehicle_jeep" ) then ent:Remove( ) end [/code] [b]HasBit( value, bit )[/b] Used to determine if the bit value contains the mask bit ( I think that's what I mean, correct me if I am wrong ). [code] function utilx.HasBit( value, bit ) return ( value & bit ) == bit end [/code] [b]Usage:[/b] [code] local a, b, c, d, firemodes, mask a = 0x01 b = 0x02 c = 0x04 d = 0x08 firemodes = a & b & d if utilx.HasBit( firemodes, c ) then --Do something end [/code] [b]SimplePointEntity( string:class )[/b] Creates a simple point entity with no special methods ( pretty much stolen from thomasfn, I believe ) [code] function utilx.SimplePointEntity( class ) local t t = { } t.Type = "point" t.Base = "base_point" t.Data = { } function t:SetKeyValue( k, v ) self.Data[ k ] = v end function t:GetKeyValue( k ) return self.Data[ k ] end scripted_ents.Register( t, class ) end [/code] [b]Usage[/b] [code] utilx.SimplePointEntity( "info_player_zombie" ) utilx.SimplePointEntity( "info_player_human" ) [/code] [b]FastExplode( str:string, str:sep )[/b] Performs a very fast, pattern-based explode on the string [code] function utilx.FastExplode( str, sep ) local k, t t = { } for k in str:gmatch( "[^" .. sep .. "]+" ) do table.insert( t, k ) end return t end [/code] [b]Usage[/b] [code] local k, v for k, v in ipairs( utilx.FastExplode( file.Read( "sometextfile.txt" ), "\n" ) ) do --Code here end [/code] Just some untested code to get this started for the heck of it.
How about [url=http://www.facepunch.com/showthread.php?t=769480]this[/url]? It's supposed to be a standalone library, but you can still include it in the pack.
[lua] function utilx.Clean(str) return string.gsub(tostring(str), "[:/\\\"*%?<>]", "_") end [/lua] [b]Usage:[/b] [lua] file.Write("Something/"..tostring(utilx.Clean(self:SteamID()))..".txt", "Windows likes the file name.") [/lua] Not much but it saves a few seconds.
[lua]function utilx.IndexFromValue( tbl, val ) for k, v in pairs( tbl ) do if ( v == val ) return k end end end[/lua] May come in handy.
[lua] function utilx.GetSoundLength(strPath) return string.ToMinutesSeconds(SoundDuration(strPath)) end [/lua] This may also come in handy.
Great input! Adding to the library as we speak. @Nevec Would you like it as utilx. or utilx.string. ?
On the server: [code]datastream.Hook("utilxStreamToSV",function(ply,id,handler,enc,dec) datastream.StreamToClients(ply,"utilxStreamToCL",dec:SteamID()) end)[/code] On the client: [code]function utilx.SteamID(ply) if SERVER then return end datastream.StreamToServer("utilxStreamToSV",ply) datastream.Hook("utilxStreamToCL",function(id,handler,enc,dec) return dec end) end[/code] Example: [code]print(utilx.SteamID(LocalPlayer()))[/code] I think this should work. Someone might want to check me on this.
You are not returning anything! You might want to do something like this: [lua] function utilx.SteamID(ply) if SERVER then return end datastream.StreamToServer("utilxStreamToSV",ply) return datastream.Hook("utilxStreamToCL",function(id,handler,enc,dec) return dec end) end [/lua] [editline]06:49PM[/editline] Might still not work though!
Why not just do this: Server: [lua] function utilx.ClientSteamID(ply,stmid) ply:SetNWString("SteamID",stmid) end hook.Add("PlayerAuthed","utilx.ClientSteamID",utilx.ClientSteamID) [/lua] Client: [lua] function utilx.ClientSteamID() if LocalPlayer():GetNWString("SteamID") ~= "" then LocalPlayer().SteamID = LocalPlayer():GetNWString("SteamID") end hook.Add("PlayerIntialSpawn","utilx.ClientSteamID",utilx.ClientSteamID) local plymeta = FindMetaTable("Player") function plymeta:SteamID() return LocalPlayer().SteamID end [/lua] I know, I know, "OMG! He used NWVars!" I specifically made it so it uses the NWVar only once, then uses SteamID on the LocalPlayer to cache the variable locally, and a clientside SteamID function to return the cache'd variable.
[QUOTE=Gbps;16523090]Why not just do this: Server: [lua] function utilx.ClientSteamID(ply,stmid) ply:SetNWString("SteamID",stmid) end hook.Add("PlayerAuthed","utilx.ClientSteamID",utilx.ClientSteamID) [/lua] Client: [lua] function utilx.ClientSteamID() if LocalPlayer():GetNWString("SteamID") ~= "" then LocalPlayer().SteamID = LocalPlayer():GetNWString("SteamID") end hook.Add("PlayerIntialSpawn","utilx.ClientSteamID",utilx.ClientSteamID) local plymeta = FindMetaTable("Player") function plymeta:SteamID() return LocalPlayer().SteamID end [/lua] I know, I know, "OMG! He used NWVars!" I specifically made it so it uses the NWVar only once, then uses SteamID on the LocalPlayer to cache the variable locally, and a clientside SteamID function to return the cache'd variable.[/QUOTE] why do u use LocalPlayer().SteamID in a meta function use self.SteamID i actually overwrite player:SteamID() for the best results
[QUOTE=commander204;16523018]You are not returning anything! You might want to do something like this: [lua] function utilx.SteamID(ply) if SERVER then return end datastream.StreamToServer("utilxStreamToSV",ply) return datastream.Hook("utilxStreamToCL",function(id,handler,enc,dec) return dec end) end [/lua] [editline]06:49PM[/editline] Might still not work though![/QUOTE] I'm not returning the function. Note the "return dec" in the hook. That returns the steamid streamed from the server. You could also just use the [url=http://www.facepunch.com/showthread.php?t=778190]gmcl_steamid[/url] module. But whatever.
[QUOTE=Gbps;16520440]@Nevec Would you like it as utilx. or utilx.string. ?[/QUOTE] It's best to keep it as a separate module. The 'string' module is actually the metatable for string objects, so you can do something like this.. "string_var:startswith( ... );". Of course, by hacking up the metatable you can achieve the same thing, but you don't want to do that. [QUOTE=Entoros;16523765]I'm not returning the function. Note the "return dec" in the hook. That returns the steamid streamed from the server.[/QUOTE] Returning something in a callback function won't do anything in your situation. The function would return nil and nothing would happen, because you're not actually returning from the main function. Except that you'd be creating and adding a new callback each time you call it. There's also completely no reason to cache nw vars on the client, and there's no reason not to ever use them. Nw vars are fine when you need a shared variable. In this case you do - so it's fine. When you call 'GetNWVar' on the client, it just looks up the name on a list and returns it. When you call 'SetNWVar' on the server, it will set it only once and send it to each player only once. The only time you may want to substitute nw vars for a custom system is when you don't want them shared with all players.
[QUOTE=Bang Train;16523329]why do u use LocalPlayer().SteamID in a meta function use self.SteamID i actually overwrite player:SteamID() for the best results[/QUOTE] 1) It doesn't matter, because it's clientside, and self would be LocalPlayer anyways. 2) I did overwrite player:SteamID, if you didn't notice. [editline]04:28PM[/editline] [QUOTE=Nevec;16525044] There's also completely no reason to cache nw vars on the client, and there's no reason not to ever use them. Nw vars are fine when you need a shared variable. In this case you do - so it's fine. When you call 'GetNWVar' on the client, it just looks up the name on a list and returns it. When you call 'SetNWVar' on the server, it will set it only once and send it to each player only once. The only time you may want to substitute nw vars for a custom system is when you don't want them shared with all players.[/QUOTE] Still, having it look thought the table of NWvars to find the variable is still slower, may it be a few milliseconds, than having the variable saved and ready in it's own place. Yet, I do not find your argument invalid.
[QUOTE=Gbps;16526130]1) It doesn't matter, because it's clientside, and self would be LocalPlayer anyways. 2) I did overwrite player:SteamID, if you didn't notice. [editline]04:28PM[/editline] Still, having it look thought the table of NWvars to find the variable is still slower, may it be a few milliseconds, than having the variable saved and ready in it's own place. Yet, I do not find your argument invalid.[/QUOTE] but what if u want the steamid of another player and not necessarily your own?
Then you wouldn't be able to find ply.SteamID anyways, and you would just keep replace [lua] return LocalPlayer().SteamID [/lua] with [lua] return self:GetNWString("SteamID") [/lua]
>using datastream >experienced coder >not a nine-year-old >stupid completely unnecessary function to access player.Created haha yeah ok [highlight](User was banned for this post ("Trolling" - mahalis))[/highlight]
There's something to be said for the guy with 932 posts but still uses the default avatar. I specifically put in the description that it was a [u]simple[/u] function. Another function: [lua] function utilx.FindPointsInLine(vector1,vector2) local PointsTable = {} for i=1,100 do PointsTable[i] = LerpVector(i*0.01,vector1,vector2) end return PointsTable end [/lua] It returns a table of all the points(vectors) that make up the line between vector1 and vector2. [editline]10:38PM[/editline] [lua] function utilx.GetPlayerTrace(ply,distance) local pos = ply:GetShootPos() local ang = ply:GetAimVector() local tracedata = {} tracedata.start = pos tracedata.endpos = pos+(ang*distance) tracedata.filter = ply local trace = util.TraceLine(tracedata) return trace; end [/lua] In a sense, it's GetPlayerTrace with the added distance argument that is "missing" from the current ply:GetPlayerTrace()
[QUOTE=Gbps;16531989]There's something to be said for the guy with 932 posts but still uses the default avatar.[/quote] Yeah sorry that I'm not trying to be E-popular with a hilarious so random XD avatar or shitty library nobody intelligent would use ever man doesn't THAT sound familiar
[QUOTE=Gbps;16531989] Another function: [code here] It returns a table of all the points(vectors) that make up the line between vector1 and vector2.[/QUOTE] But it's always 100 points no matter how big the distance between the vectors? Shouldn't it be relative to the length? Also, some short functions to get a table of maps and gamemodes (get the servers on the client optional). [b]GetGamemodes + GetMaps[/b] Server: [code]datastream.StreamToClients(player.GetAll(),"utilxMapList",file.Find("../maps/*.bsp")) datastream.StreamToClients(player.GetAll(),"utilxGamemodeList",file.Find("../gamemodes/*")) [/code] Shared: [code]local utilxmaps = {} datastream.Hook("utilxMapList",function(handler,id,enc,dec) utilxmaps = dec end) function utilx.GetGamemodes(usesv) if SERVER then return file.Find("../maps/*.bsp") end if CLIENT then if usesv == true then return utilxmaps else return file.Find("../maps/*.bsp") end end end local utilxgms = {} datastream.Hook("utilxGamemodeList",function(handler,id,enc,dec) utilxgms = dec end) function utilx.GetGamemodes(usesv) if SERVER then return file.Find("../gamemodes/*") end if CLIENT then if usesv == true then return utilxgms else return file.Find("../gamemodes/*") end end end[/code] Somebody should check that though. Also, some others: [b]Alphebatize[/b] - alphabetize tables [code]function utilx.Alphabetize(tab) table.sort(tab,function(a,b) return a < b end) end[/code] [b]ChatPrint[/b] - easily print in color to one or multiple players [code]function utilx.ChatPrint(ply,msg,col) if type(ply) == "table" then for _,v in ipairs(ply) do if not col then v:SendLua("chat.AddText(Color(255,255,255,255),\""..msg.."\")") else v:SendLua("chat.AddText("..col..",\""..msg.."\")") end end else if not col then ply:SendLua("chat.AddText(Color(255,255,255,255),\""..msg.."\")") else ply:SendLua("chat.AddText("..col..",\""..msg.."\")") end end end[/code]
[QUOTE=Daman3456;16532987]Yeah sorry that I'm not trying to be E-popular with a hilarious so random XD avatar or shitty library nobody intelligent would use ever man doesn't THAT sound familiar[/QUOTE] No-one cares what you think so piss off unless you have something to contribute.
I don't really know if vgui things should be in there, but what is with an utilx.MessageBox(Title,Message,blur) function. I always hate to code about ~13 lines of code just to show a simple messagebox [lua] function utilx.vgui.MessageBox(Title,Text,blur) local MessageBoxFrame = vgui.Create ("DFrame") MessageBoxFrame:SetSize( string.len(Text) * 10,100) MessageBoxFrame:SetTitle(Title) MessageBoxFrame:Center() MessageBoxFrame:SetVisible( true ) MessageBoxFrame:MakePopup() MessageBoxFrame:SetBackgroundBlur( blur ) local MessageLabel = vgui.Create ("DLabel", MessageBoxFrame) MessageLabel:SetText(Text) MessageLabel:SizeToContents() MessageLabel:Center() local MessageBoxOk = vgui.Create ("DButton", MessageBoxFrame) MessageBoxOk:SetText( "OK" ) MessageBoxOk:SetPos( MessageBoxFrame:GetWide() - 55, MessageBoxFrame:GetTall() - 30) MessageBoxOk:SetWide( 50) function MessageBoxOk:DoClick() MessageBoxFrame:Close() end end [/lua] [B] Usage: [/B] [lua] utilx.MessageBox("Error!","Requested player has not been found",true) [/lua]
[QUOTE=Alex22;16538613]I don't really know if vgui things should be in there, but what is with an utilx.MessageBox(Title,Message,blur) function. I always hate to code about ~13 lines of code just to show a simple messagebox[/QUOTE] There's already a function for that.. [url=http://wiki.garrysmod.com/?title=G.Derma_Message]Derma_Message[/url]
Except Garry forgot the gui.EnableScreenClicker(true) hurf durf
I'd like some way of adding binds to the options menu, it would function exactly like concommand.Add, but it adds it to the list. For TF2 you make changes to kb_act.lst in scripts, but this is probably only read on startup and would require changes to the menu code.
[lua] function utilx.AddSteamFriend(steamid) local expl = string.Explode(":", steamid) local serverid, accountid = tonumber(expl[2]), tonumber(expl[3]) local friendid = string.format("765%0.f", accountid * 2 + 61197960265728 + serverid) local panel = vgui.Create("HTML") panel:SetSize(1,1) panel:OpenURL("http://www.garry.tv/go.php?steam://friends/add/"..friendid) timer.Simple(10, panel.Remove, panel) end [/lua] I found this in a older script I had. It's pretty useful for scoreboards and stuff.
[QUOTE=slayer3032;16551200][lua] function utilx.AddSteamFriend(steamid) local expl = string.Explode(":", steamid) local serverid, accountid = tonumber(expl[2]), tonumber(expl[3]) local friendid = string.format("765%0.f", accountid * 2 + 61197960265728 + serverid) local panel = vgui.Create("HTML") panel:SetSize(1,1) panel:OpenURL("http://www.garry.tv/go.php?steam://friends/add/"..friendid) timer.Simple(10, panel.Remove, panel) end [/lua] I found this in a older script I had. It's pretty useful for scoreboards and stuff.[/QUOTE] Nice one! :D
Sorry, you need to Log In to post a reply to this thread.