Jump to content

[HELP] Gang Invites


Recommended Posts

So i made gui for invites and tried to make whenever gang leader invites some player it would setTeam,setSkin,setColor,setTag but idk how

Client:

Spoiler

addEvent ("gang.invite", true);
addEventHandler("gang.invite", root,
    function(inviter, gang_name)
		if isElement (gangs.window["invite"]) then return end
        gangs.window["invite"] = guiCreateWindow(540, 636, 285, 91, "GANG INVITE", true)
		guiWindowSetSizable(gangs.window["invite"], false)
        guiSetAlpha(gangs.window["invite"], 0.72)

        gangs.label["invite"] = guiCreateLabel(176, 64, 101, 18, "Press 'N' to reject", true, gangs.window["invite"])   
        guiLabelSetHorizontalAlign(gangs.label["invite"], "center", false)
        gangs.label["invite1"] = guiCreateLabel(10, 17, 267, 21, inviter:getName().." has invited you to the gang '"..gang_name.."'", true, gangs.window["invite"])
        guiLabelSetHorizontalAlign(gangs.label["invite1"], "center", false)
        gangs.label["invite2"] = guiCreateLabel(10, 64, 113, 18, "Press 'J' to accept", true, gangs.window["invite"])
        guiLabelSetHorizontalAlign(gangs.label["invite2"], "center", false)
        bindKey ("J", "down", respondInvite);
		bindKey ("N", "down", respondInvite);	
    end
);

function respondInvite (key, state)
	if key == "j" then 
		triggerServerEvent ("onPlayerRespondedToInvite", localPlayer, true);
	elseif key == "n" then 
		triggerServerEvent ("onPlayerRespondedToInvite", localPlayer, false);
	end	
	unbindKey ("J", "down", respondInvite);
	unbindKey ("N", "down", respondInvite);
	if isElement (gangs.window["invite"]) then 
		gangs.window["invite"]:destroy();
	end	
end 

 

SERVER

Spoiler

function InviteToGang(inviter, gang_name)
  setPlayerTeam ( source, gang_name)
  setPlayerNametagColor ( source, r or 255, g or 255, b or 255 )
  setPedSkin ( source, teamS )
  setPlayerName(source, "["..teamT.."]"..getPlayerName(source))
addEventHandler( "onPlayerRespondedToInvite", resourceRoot, InviteToGang )

 

btw how to make max number in editbox like RGB 255 if higher turn to 255

 

Link to comment

Here's some notes:

  • In the snippet you provided you are missing the gangs table that should contain window and label tables in it to store the GUI elements you are creating.
  • All of your GUI elements are using relative positioning, but your coordinates are absolute. This means your elements are 540% from the left and 636% from the top. They are off-screen. I disabled relative positioning and now you can see them on the screen. Keep in mind that absolute positioning can introduce problems like small screen size not being able to see elements positioned outside of the screen bounds. I suggest centering your GUI window using guiGetScreenSize.
  • You are passing the inviter through as an argument to the gang.invite event. I prefer sending it over as the source, as they might as well just act as the source since you don't need any other data at the moment in place of that. Feel free to turn it back to the old way if you prefer it that way.
  • You are also passing the team name to the client, rather than the team element. While I understand why that would be useful to some way mitigate potential team rename exploiting, I still believe going with the actual team element is better since that is what you were invited to join at the end of the day. You can handle potential bad behavior separate from this script.
  • When you run triggerServerEvent, you are giving it only one argument, a boolean. However, the server-side function expects inviter and gang_name.
  • Your InviteToGang server-side function is missing an end.
  • Your onPlayerRespondedToInvite server-side event is missing, you only have an event handler, but you haven't actually added the event first.
  • You should be using root for the event handler.
  • You're mixing MTA and Lua OOP with functional style, I suggest choosing one style so your code is consistent.
  • Because of safety reasons and circumstances allow it, you can and should use client instead of source server-side.
  • You are trying to set the player to a team using just the team name. However, you need a team element for the setPlayerTeam function. Use getTeamFromName to retrieve the team element, or just use the team element the client has sent to the server.
  • You are missing the r, g, b, teamS, teamT variables in the snippet you provided. I suggest binding this data to the team element instead using element data or some other storage, since this data is to the best of my knowledge team-specific, correct? Otherwise you just need to define those variables, if you haven't already.
  • You are trying to set the player name using their current player name and a tag prefixing it. However, if the player is already in a team, their current name will include that as well. I suggest using element data or some other form of storage to save the player's original player name upon joining the server and then using that to set their name later.
  • Now... this whole system has a few security related issues which are sort of easy to handle. I would send info of the transaction that they are signed to do, like we do now (team, inviter), and then use that data server-side to confirm that they are in fact doing what they are supposed to, and not trying to join a team they were not requested to join, since right now a hacker would technically be able to exploit that by sending a different team to the server, and it would believe it since there is nothing to confirm it. For now I think this will work for you fine, but perhaps something for you to do, is to improve the security. It's not hard; in fact, you can just use tables to save these transactions before sending them to the client and compare this data to what the client sends the server. I just don't want to write everything for you, so that's your next challenge if you're up for it.
  • For your question regarding the 0-255 limit, Dimos7 provided you with a good answer. Use onClientGUIChanged and perhaps a couple other GUI events to determine when the edit box has changed. Then compare the value with your limit.

Also, I suggest using /debugscript 3 in-game to see syntax errors in your script...

Anyway, here's the whole thing commented below.

Client-side

-- Initialize the gangs table with window and label tables that contain our GUI elements
local gangs = {
	window = { },
	label = { }
}

addEvent( "gang.invite", true )
addEventHandler( "gang.invite", root,
	function( team )
		-- If we already have an invite window open, or team doesn't exist, stop here
		if isElement( gangs.window["invite"] ) or not isElement( team ) then
			return
		end

		-- Save our inviter and team to the gangs table
		gangs.inviter = source
		gangs.team = team

		-- Note that I changed "true" to "false" for absolute positioning on all of the GUI elements
		gangs.window["invite"] = guiCreateWindow( 540, 636, 285, 91, "GANG INVITE", false )
		guiWindowSetSizable( gangs.window["invite"], false )
		guiSetAlpha( gangs.window["invite"], 0.72 )

		gangs.label["invite"] = guiCreateLabel( 176, 64, 101, 18, "Press 'N' to reject", false, gangs.window["invite"] )
		guiLabelSetHorizontalAlign( gangs.label["invite"], "center", false )

		-- Use team:getName( ) to get the name of the team element, instead of using team name directly
		gangs.label["invite1"] = guiCreateLabel( 10, 17, 267, 21, source:getName( ) .. " has invited you to the gang '" .. team:getName( ) .. "'", false, gangs.window["invite"] )
		guiLabelSetHorizontalAlign( gangs.label["invite1"], "center", false )

		gangs.label["invite2"] = guiCreateLabel( 10, 64, 113, 18, "Press 'J' to accept", false, gangs.window["invite"] )
		guiLabelSetHorizontalAlign( gangs.label["invite2"], "center", false )

		bindKey( "J", "down", respondInvite )
		bindKey( "N", "down", respondInvite )
	end
)

function respondInvite( key )
	-- If we want to accept the invite and the team still exists...
	if key == "j" and isElement( gangs.team ) then
		triggerServerEvent( "onPlayerRespondedToInvite", localPlayer, true, gangs.inviter, gangs.team )

	-- We don't want to accept the invite
	elseif key == "n" then
		triggerServerEvent( "onPlayerRespondedToInvite", localPlayer, false, gangs.inviter, gangs.team )

	-- The team doesn't exist anymore
	elseif not isElement( gangs.team ) then
		outputChatBox( "This gang does not exist anymore.", 255, 0, 0 )
	end

	if isElement( gangs.window["invite"] ) then
		gangs.window["invite"]:destroy( )
	end

	-- Let's clean our inviter and team from the gangs table
	gangs.inviter = nil
	gangs.team = nil

	unbindKey( "J", "down", respondInvite )
	unbindKey( "N", "down", respondInvite )
end

Server-side

-- Let's define a new getTag method for Team elements, which uses element data "tag"
function Team:getTag( )
	return self:getData( "tag" )
end

-- Let's define a new getSkin method for Team elements, which uses element data "skin"
function Team:getSkin( )
	return self:getData( "skin" )
end

-- Let's define a new getOriginalName method for Player elements, which uses element data "name"
function Player:getOriginalName( )
	return self:getData( "name" )
end

-- Let's save MTA's original setTeam method as _setTeam
Player._setTeam = Player.setTeam

-- Let's create a wrapper function for setTeam so we can do all of our operations in one go
-- You can also ignore the custom part by providing "true" to the second argument like so: setTeam( theTeam, true )
function Player:setTeam( team, ignoreCustom )
	-- Set our team using MTA's setTeam method first
	self:_setTeam( team )

	-- If the team provided is an element and we are not ignoring custom code
	if isElement( team ) and ignoreCustom ~= true then
		-- Set our nametag color according to the team color (you can use setColor( r, g, b ) to set it )
		self:setNametagColor( team:getColor( ) )

		-- Get our team skin
		local skin = team:getSkin( )

		-- If we have a team skin, set it, otherwise clear it using a default skin ID (here it is set to 0)
		self:setModel( tonumber( skin ) or 0 )

		-- Get our team tag
		local tag = team:getTag( )

		-- If we have a team tag, let's set it, otherwise use their original player name
		if tag and #tag > 0 then
			self:setName( "[" .. tag .. "]" .. self:getOriginalName( ) )
		else
			self:setName( self:getOriginalName( ) )
		end
	end
end

-- When a player joins the server
addEventHandler( "onPlayerJoin", root,
	function( )
		-- Save their name to element data "name" to use later
		source:setData( "name", source:getName( ), false )
	end
)

-- Let's create a Player method for inviting a player to a team
function Player:inviteToTeam( team, inviter )
	-- If the team exists
	if isElement( team ) then
		-- Let's trigger that client event for this player
		return triggerClientEvent( self, "gang.invite", inviter or self, team )
	end

	return false
end

-- Let's take in our wasAccepted boolean, inviter and team
function InviteToGang( wasAccepted, inviter, team )
	-- If we have a team element
	if isElement( team ) then
		-- If the invitation was accepted
		if wasAccepted then
			-- Set the player's team
			client:setTeam( team )

			-- Let the player know
			outputChatBox( "You accepted the gang invitation.", client, 0, 255, 0 )

		-- If the invitation was not accepted
		else
			-- Let the player know
			outputChatBox( "You ignored the gang invitation.", client, 255, 0, 0 )
		end
	elseif wasAccepted then -- If the invite was accepted but we had no team element, let's say we don't have that team anymore
		outputChatBox( "This gang does not exist.", client, 255, 0, 0 )
	end
end
-- Add the onPlayerRespondedToInvite event first
addEvent( "onPlayerRespondedToInvite", true )
addEventHandler( "onPlayerRespondedToInvite", root, InviteToGang )

Tested and working using the following script:

local teamName, teamSkin, teamTag = "TestTeam", 1, "ASD"
addEventHandler("onResourceStart", resourceRoot, function()
	local team = Team.getFromName(teamName)
	if not team then
		team = Team.create(teamName)
		if team then
			team:setData("skin", teamSkin)
			team:setData("tag", teamTag)
		end
	end
end)
addCommandHandler("inviteme", function(player)
	player:inviteToTeam(Team.getFromName(teamName), player)
	outputChatBox("invite sent", player)
end)
addCommandHandler("deletemyteam", function(player)
	local team = player:getTeam()
	if isElement(team) then
		team:destroy()
		outputChatBox("team destroyed", player)
	end
end)

 

Edited by myonlake
  • Thanks 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...