gm_gevents - Hook and fire game events

The purpose of this module is to allow you to hook to, and fire, game events. Hooking on the server catches outgoing events, and hooking on the client catches incoming events.

Example usage:


require("gevents")

gevent.InitHook("player_connect")

hook.Add("player_connect", "PConnect", function(event)
	Msg("player_connect:
")
	
	print("Name: "..event:GetString("name"))
	print("Index: "..event:GetInt("index"))
	print("UID: "..event:GetInt("userid"))
	print("Steam ID: "..event:GetString("networkid"))
	print("IP: "..event:GetString("address"))
end )

gevent.InitHook("player_disconnect")

hook.Add("player_disconnect", "PDisconnect", function(event)
	Msg("player_disconnect:
")
	
	print("UID: "..event:GetInt("userid"))
	
	for k, v in pairs(player.GetAll()) do
		if (event:GetInt("userid") == v:UserID()) then
			print("Found entity for "..v:Name())
			break
		end
	end
	
	print("Reason: "..event:GetString("reason"))
	print("Name: "..event:GetString("name"))
	print("Steam ID: "..event:GetString("networkid"))
end )

gevent.InitHook("server_cvar")

hook.Add("server_cvar", "CVarChanged", function(event)
	if (event:GetString("cvarname") == "sv_cheats") then
		print("sv_cheats value changed!")
	end
end )

Functions:


gevent.Create(event_name) //Returns an IGameEvent object for the specified event
gevent.InitHook(event_name) //Must be called before attempting to hook to the event

IGameEvent:Name() //Gets the name of IGameEvent
IGameEvent:Fire() //Fires IGameEvent
IGameEvent:FireClientSide() //Also fires IGameEvent, but locally

IGameEvent:GetBool(field)
IGameEvent:SetBool(field, value)
IGameEvent:GetString(field)
IGameEvent:SetString(field, value)
IGameEvent:GetInt(field)
IGameEvent:SetInt(field, value)
IGameEvent:GetFloat(field)
IGameEvent:SetFloat(field, value)

Uses:

I haven’t played around with this that much, but the events I found most useful were “player_disconnect” and “server_cvar”. Mainly because the PlayerDisconnected hook isn’t available to the client, and “server_cvar” can be used to execute code when CVars flagged with “notify” are changed on the server (sv_cheats for example).

For a full list of events, click here.

Download:

http://bit.ly/101eOS (Includes source)

Bugs:

If you find any, please report them here or email me at chrisaster@live.co.uk.

Sweet balls. Nice work. Just need to extract me a copy of resource/gameevents.res and I’m good to go!

Very nice work. I am most pleased.

Holy shit, this is awesome! :buddy:

[editline]10:41PM[/editline]



//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//=============================================================================

// No spaces in event names, max length 32
// All strings are case sensitive
// total game event byte length must be < 1024
//
// valid data key types are:
//   none   : value is not networked
//   string : a zero terminated string
//   bool   : unsigned int, 1 bit
//   byte   : unsigned int, 8 bit
//   short  : signed int, 16 bit
//   long   : signed int, 32 bit
//   float  : float, 32 bit



"gameevents"
{
	"team_info"				// info about team
	{
		"teamid"	"byte"		// unique team id
		"teamname"	"string"	// team name eg "Team Blue"
	}
	
	"team_score"				// team score changed
	{
		"teamid"	"byte"		// team id
		"score"		"short"		// total team score
	}
	
//////////////////////////////////////////////////////////////////////
// Player events
//////////////////////////////////////////////////////////////////////
	
	"player_team"				// player change his team
	{
		"userid"	"short"		// user ID on server
		"team"		"byte"		// team id
		"oldteam" "byte"		// old team id
		"disconnect" "bool"	// team change because player disconnects
	}
	
	"player_class"				// a player changed his class
	{
		"userid"	"short"		// user ID on server
		"class"		"string"	// new player class / model
	}
	
	"player_death"				// a game event, name may be 32 charaters long
	{
		"userid"	"short"   	// user ID who died				
		"attacker"	"short"	 	// user ID who killed
	}
	
	"player_hurt"
	{
		"userid"	"short"   	// player index who was hurt				
		"attacker"	"short"	 	// player index who attacked
		"health"	"byte"		// remaining health points
	}
	
	"player_chat"				// a public player chat
	{
		"teamonly"	"bool"		// true if team only chat
		"userid" 	"short"		// chatting player 
		"text" 	 	"string"	// chat text
	}
	
	"player_score"				// players scores changed
	{
		"userid"	"short"		// user ID on server
		"kills"		"short"		// # of kills
		"deaths"	"short"		// # of deaths
		"score"		"short"		// total game score
	}
	
	"player_spawn"				// player spawned in game
	{
		"userid"	"short"		// user ID on server
	}
	
	"player_shoot"				// player shoot his weapon
	{
		"userid"	"short"		// user ID on server
		"weapon"	"byte"		// weapon ID
		"mode"		"byte"		// weapon mode
	}
	
	"player_use"
	{
		"userid"	"short"		// user ID on server
		"entity"	"short"		// entity used by player
	}

	"player_changename"
	{
		"userid"	"short"		// user ID on server
		"oldname"	"string"	// players old (current) name
		"newname"	"string"	// players new name
	}

//////////////////////////////////////////////////////////////////////
// Game events
//////////////////////////////////////////////////////////////////////
		
	"game_newmap"				// send when new map is completely loaded
	{
		"mapname"	"string"	// map name
	}
	
	"game_start"				// a new game starts
	{
		"roundslimit"	"long"		// max round
		"timelimit"	"long"		// time limit
		"fraglimit"	"long"		// frag limit
		"objective"	"string"	// round objective
	}
	
	"game_end"				// a game ended
	{
		"winner"	"byte"		// winner team/user id
	}
	
	"round_start"
	{
		"timelimit"	"long"		// round time limit in seconds
		"fraglimit"	"long"		// frag limit in seconds
		"objective"	"string"	// round objective
	}
	
	"round_end"
	{
		"winner"	"byte"		// winner team/user i
		"reason"	"byte"		// reson why team won
		"message"	"string"	// end round message 
	}
	
	"game_message"				// a message send by game logic to everyone
	{
		"target"	"byte"		// 0 = console, 1 = HUD
		"text"		"string"	// the message text
	}

	"break_breakable"
	{
		"entindex"	"long"
		"userid"		"short"
		"material"	"byte"	// BREAK_GLASS, BREAK_WOOD, etc
	}

	"break_prop"
	{
		"entindex"	"long"
		"userid"	"short"
	}
}


Remember that some of these events don’t seem to work.


//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//=============================================================================

// No spaces in event names, max length 32
// All strings are case sensitive
//
// valid data key types are:
//   string : a zero terminated string
//   bool   : unsigned int, 1 bit
//   byte   : unsigned int, 8 bit
//   short  : signed int, 16 bit
//   long   : signed int, 32 bit
//   float  : float, 32 bit
//   local  : any data, but not networked to clients
//
// following key names are reserved:
//   local      : if set to 1, event is not networked to clients
//   unreliable : networked, but unreliable
//   suppress   : never fire this event
//   time	: firing server time
//   eventid	: holds the event ID

"modevents"
{
	"player_death"				// a game event, name may be 32 charaters long
	{
		"userid"	"short"   	// user ID who died				
		"attacker"	"short"	 	// user ID who killed
		"weapon"	"string" 	// weapon name killed used 
	}
	
	"player_hurt_ex"
	{
		"userid"		"short"   	// ent index who was hurt				
		"attacker"		"short"	 	// ent index who attacked
		"health"		"byte"		// remaining health points
		"healthtaken"	"byte"		// remaining health points
	}
	
	"achievement_earned"
	{
		"player"		"byte"		// entindex of the player
		"achievement"	"short"		// achievement ID
	}
	
	"achievement_event" 
	{ 
		"achievement_name"	"string"	// non-localized name of achievement 
		"cur_val"	 "short"	 // # of steps toward achievement 
		"max_val"	 "short"	 // total # of steps in achievement 
	} 
	
	"show_freezepanel"
	{
		"killer"	"short"		// entindex of the killer entity
	}

	"hide_freezepanel"
	{
	}

	"freezecam_started"
	{
	}
	
}


That’s all there is.

What about the ones in the examples? (server_cvar, player_connect/disconnect)

Well, from what I understand Valve doesn’t use the game events to display those in chat or console, the game events from there are used in console.

Haha this is awesome. You can create fake join messages with this.

Code:
[lua]
require(“gevents”)

for i=1, 10 do
local t = gevent.Create(“player_connect”)
t:SetString(“reason”, “I GOT BANZORS”)
t:SetString(“name”, “Friend Nr. " … i … " just joined you. You lucky bastard.”)
t:SetString(“networkid”, “21903”)
t:Fire()
end
[/lua]

Sending players fake achievement events (achievement_earned) can also be quite entertaining :).

Haha I really have to try that out.

[editline]11:52PM[/editline]

Oh cool I found the Secret Phrase. :biggrin:

“player_changename”
{
“userid” “short” // user ID on server
“oldname” “string” // players old (current) name
“newname” “string” // players new name
}
If we finally could prevent namechanges?
setinfo name ASD;alias setinfo “”
^ Was getting far too popular on my server.

“setinfo name” doesn’t seem to trigger any events for me in Garry’s Mod. In other Source games (Counter-Strike Source for example), it’s used for “[Player] has changed name from [oldname] to [newname]”.

This is how the ‘changename’ event works on the episode 1 engine:



] net_showevents 1
] setinfo name test
Game event "player_changename", Tick 3986:
- "userid" = "2"
- "oldname" = "unnamed"
- "newname" = "test"

Would this be of use?

Looks pretty useful, added to OP.

Thats nothing compared to what I gained from this.

Absolutely nothing, actually. The server doesn’t handle achievements (except for those 4 few which we can all SendLua quite easily).

If you really want to cheat achievements then just use this.

Heh, I know.

Yeah, I knew that. I was just mucking around.

Awesome.