SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help > Tutorials

Reply
 
Thread Tools Display Modes
Old 06/11/2017, 02:00 PM   #1
TaiRinsuru
Big Clucker
 
TaiRinsuru's Avatar
 
Join Date: Oct 2015
Location: Reputation : 100000
Posts: 144
Reputation: 12
Default Report System with zcmd and sscanf

So, i am here to show you a simple tutorial about /report, /reports, /reply and /acceptreport command.

So here is the full code and i am gonna show you some little explaination:

https://pastebin.com/CRXdiyG4

Lets start with the includes, so we need to get this two includes. I am using sscanf2 and zcmd.

Variables

This is what we are gonna be using on the script below it.
Code:
#define MAX_REPORTS 1000

#define INVALID_REPORT_ID -1

new JustReported[MAX_PLAYERS];

enum rInfo
{
	rReportFrom[MAX_PLAYER_NAME],
	rReporterID,
	rReport[128],
	rReplyTimer,
	rChecker,
	rBeingUsed
}
new Report[MAX_REPORTS][rInfo];

Functions

On OnGameModeInit, add this code. It works as the heartbeat of the server (1 second).
Code:
public OnGameModeInit()
{
	SetTimer("Heartbeat", 1000, 1);
	return 1;
}


Code:
forward Heartbeat();
public Heartbeat()
{
	for(new i = 0; i < MAX_PLAYERS; i++)
	{
	    if(JustReported[i] > 0)
			JustReported--;
	}
	return 1;
}
We need to have a forward first before using public in timers.

Code:
for(new i = 0; i < MAX_PLAYERS; i++)
This will let us loop through all the players online.

Code:
        if(JustReported[i] > 0)
	    JustReported--;

We need to determine whether the player has submitted a report or not. If yes, we reduce it by 1 every 1 second. So when you /report it will not stay at 25 seconds.

Code:
public OnPlayerConnect(playerid)
{
	JustReported[playerid] = 0;
	return 1;
}
Under OnPlayerConnect, add this to make us able to submit a report.

Code:
public OnPlayerDisconnect(playerid, reason)
{
	for(new i = 0; i < MAX_REPORTS; i++)
	{
		if(Report[i][rReporterID] == playerid && Report[i][rChecker] != INVALID_PLAYER_ID)
		{
			Report[i][rReporterID] = INVALID_PLAYER_ID;
			Report[i][rChecker] = INVALID_PLAYER_ID;
			Report[i][rReporterID] = INVALID_PLAYER_ID;
			format(Report[i][rReport], 128, "None");
			format(Report[i][rReportFrom], 128, "None");
			Report[i][rChecker] = INVALID_PLAYER_ID;
			KillTimer(Report[i][rReplyTimer]);
		}
	}
	
	return 1;
}
Under OnPlayerDisconnect, we determine if the player has still have a report. If he still has, we will remove his report or else we will get a bug when an admin accepts it.

Code:
stock SendReportToAdmin(rid, reportfrom, report[])
{
	Report[rid][rReporterID] = reportfrom;
	new string[128], name[MAX_PLAYER_NAME];
	Report[rid][rBeingUsed] = 1;
	GetPlayerName(reportfrom, name, sizeof(name));
	format(Report[rid][rReport], 128, "%s", report);
	format(Report[rid][rReportFrom], 128, "%s", name);
	for(new i = 0; i < MAX_PLAYERS; i++)
	{
	    if(IsPlayerAdmin(i))
	    {
	        format(string, sizeof(string), "Report from: %s (RID: %d): %s", name, rid, report);
			SendClientMessage(i, -1, string);
		}
	}
}
This will let the report submitted to the admins online. Change the IsPlayerAdmin to your admin level variable.


Commands

Code:
CMD:report(playerid, params[])
{
	new string[128];
	if(!isnull(params))
	{
	    if(JustReported[playerid] > 0)
		{
			format(string, sizeof(string), "You already have a report. Please wait %d seconds more.", JustReported[playerid]);
		    SendClientMessage(playerid, -1, string);
			return 1;
		}
		
        if(strlen(params) > 50)
	    	return SendClientMessage(playerid, -1, "Your message is too long - the limit is 50 characters.");
		
		
		new name[MAX_PLAYER_NAME];
		GetPlayerName(playerid, name, sizeof(name));
		
		new reportid;
		for(new i = 0; i < MAX_REPORTS; i++)
		{
		    if(Report[i][rBeingUsed] == 0)
		    {
				reportid = i;
				break;
			}
		}
		
		JustReported[playerid] = 25;
		
	 	SendReportToAdmin(reportid, playerid, params);
	 	SendClientMessage(playerid, -1, "You report has been sent to admins online.");
	}
	else
	{
		SendClientMessage(playerid, -1, "USAGE: /report [reporttext]");
	}
	return 1;
}

CMD:reports(playerid, params[])
{
	if(IsPlayerAdmin(playerid))
	{
		new string[1000];
		SendClientMessage(playerid, -1, "___________________________________________________________");
		SendClientMessage(playerid, -1, "REPORTS:");
		for(new r = 0; r < MAX_REPORTS; r++)
		{
		    if(Report[r][rBeingUsed] == 1)
		    {
		        format(string, sizeof(string), "Report from %s (RID: %d): %s", Report[r][rReportFrom], r, Report[r][rReport]);
			}
		}
		SendClientMessage(playerid, -1, string);
		SendClientMessage(playerid, -1, "___________________________________________________________");
	}
	else
	{
		SendClientMessage(playerid, -1, "You are not an admin.");
	}
	return 1;
}

forward ReplyTimer(reportid);
public ReplyTimer(reportid)
{
	Report[reportid][rReporterID] = INVALID_PLAYER_ID;
	Report[reportid][rChecker] = INVALID_PLAYER_ID;
	format(Report[reportid][rReport], 128, "None");
	format(Report[reportid][rReportFrom], 128, "None");
	Report[reportid][rChecker] = INVALID_PLAYER_ID;
	Report[reportid][rBeingUsed] = 0;
	KillTimer(Report[reportid][rReplyTimer]);
	return 1;
}

CMD:reply(playerid, params[])
{
	new string[128];
	new reportid = INVALID_REPORT_ID;
	for(new i = 0; i < MAX_REPORTS; i++)
	{
		if(Report[i][rReporterID] == playerid && Report[i][rChecker] != INVALID_PLAYER_ID)
		{
			reportid = i;
		}
	}
	if(reportid == INVALID_REPORT_ID)
	{
		SendClientMessage(playerid, -1, "You don't have any reports being reviewed at the moment.");
		return 1;
	}
	if(IsPlayerConnected(Report[reportid][rChecker]))
	{
	    new name[MAX_PLAYER_NAME], checkername[MAX_PLAYER_NAME];
	    GetPlayerName(playerid, name, sizeof(name));
	    GetPlayerName(playerid, checkername, MAX_PLAYER_NAME);
		format(string, sizeof(string), "%s(ID: %d) replies: %s", name, playerid, params);
		SendClientMessage(Report[reportid][rChecker], -1, string);

		format(string, sizeof(string), "Reply sent to %s: %s", checkername, params);
		SendClientMessage(playerid,  -1, string);
	}
	else SendClientMessage(playerid, -1, "Player not connected.");
	return 1;
}

CMD:acceptreport(playerid, params[])
{
	if(IsPlayerAdmin(playerid))
	{
		new string[128], id;
		if(sscanf(params, "d", id)) return SendClientMessage(playerid, -1, "USAGE: /acceptreport [reportid]");
		
		if(Report[id][rBeingUsed] == 0)
		{
			SendClientMessage(playerid, -1, "That report is not being used!");
			return 1;
		}
		
		new playername[MAX_PLAYER_NAME];
		GetPlayerName(playerid, playername, sizeof(playername));
		format(string, sizeof(string), "Admin %s has accepted your report, you have 1 minute to talk to him via /reply", playername);
		SendClientMessage(Report[id][rReporterID], -1, string);
		format(string, sizeof(string), "You had accepted %s's report.", Report[id][rReportFrom]);
		SendClientMessage(playerid, -1, string);
		
		Report[id][rChecker] = playerid;
		Report[id][rBeingUsed] = 0;
		Report[id][rReplyTimer] = SetTimerEx("ReplyTimer", 60000, false, "d", id);
	}
	else
	{
	    SendClientMessage(playerid, -1, "You are not an admin.");
	}
	return 1;
}

The commands part will be explained tomorrow-------
Thanks for watching, hope you rep me.
EDIT: If I might have mistakes, please reply it so i can fix it and also sorry for my english. I do not speak english
__________________
Come and join now

Discord : https://discord.gg/GRFeDvB
TaiRinsuru is offline   Reply With Quote
Old 06/11/2017, 05:37 PM   #2
Logic_
High-roller
 
Logic_'s Avatar
 
Join Date: Jun 2015
Location: NL-RP
Posts: 1,452
Reputation: 263
Default Re: Report System with zcmd and sscanf

Why would you use a timer? I'd prefer to use gettime() as a replacement of it (timer) which is optimized and the most recommended way.
__________________
Ex- Developer/ Ex- Management of Call of Duty: Black Ops 3 [2017 - 2018]
Ex- Palomino Creek RP Developer [2018]
Logic_ is offline   Reply With Quote
Old 06/11/2017, 05:39 PM   #3
Widoh
Little Clucker
 
Join Date: Oct 2017
Posts: 22
Reputation: 3
Default Re: Report System with zcmd and sscanf

Quote:
Originally Posted by Logic_ View Post
Why would you use a timer? I'd prefer to use gettime() as a replacement of it (timer) which is optimized and the most recommended way.
C'mon... 500.000 timers will only eat a 20% of CPU
Widoh is offline   Reply With Quote
Old 07/11/2017, 08:32 AM   #4
Logic_
High-roller
 
Logic_'s Avatar
 
Join Date: Jun 2015
Location: NL-RP
Posts: 1,452
Reputation: 263
Default Re: Report System with zcmd and sscanf

Make your and other's work easier! Timers are inaccurate and why even use other resources when you already have the enough resources!
__________________
Ex- Developer/ Ex- Management of Call of Duty: Black Ops 3 [2017 - 2018]
Ex- Palomino Creek RP Developer [2018]
Logic_ is offline   Reply With Quote
Old 11/11/2017, 06:40 AM   #5
FAStingTV
Little Clucker
 
Join Date: Jul 2017
Posts: 8
Reputation: 0
Default Re: Report System with zcmd and sscanf

PLS HELP https://imgur.com/a/aXaGs
FAStingTV is offline   Reply With Quote
Old 12/11/2017, 09:04 AM   #6
TaiRinsuru
Big Clucker
 
TaiRinsuru's Avatar
 
Join Date: Oct 2015
Location: Reputation : 100000
Posts: 144
Reputation: 12
Default Re: Report System with zcmd and sscanf

Can you post the line which you have error?
__________________
Come and join now

Discord : https://discord.gg/GRFeDvB
TaiRinsuru is offline   Reply With Quote
Old 22/02/2018, 07:24 AM   #7
FAStingTV
Little Clucker
 
Join Date: Jul 2017
Posts: 8
Reputation: 0
Default Re: Report System with zcmd and sscanf

Quote:
Originally Posted by TaiRinsuru View Post
Can you post the line which you have error?
forward Heartbeat();
public Heartbeat()
{
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(JustReported[i] > 0)
JustReported--;
}
return 1;
}
FAStingTV is offline   Reply With Quote
Old 22/02/2018, 08:09 AM   #8
RogueDrifter
High-roller
 
RogueDrifter's Avatar
 
Join Date: Dec 2017
Location: SA-MP Drifting world.
Posts: 1,497
Reputation: 325
Default Re: Report System with zcmd and sscanf

Took him 3 months to reply
__________________
Code:
I'm available to script stuff for cash PM me here or on discord @ Andy[RDZ]#0040
[Tutorial]:Anti-cheat guide ||Mini-game 101||VC/LC maps install||
Array index out of bounds


[Github]:Link [Pastebin]:Link [Forum]:Link [Server]:Link [Discord]:Link




Code:
You may only contact me through the links on my signature, if else then its an impersonating one, i am not on any other place not mentioned in my signature.
RogueDrifter is online now   Reply With Quote
Old 13/03/2018, 01:03 PM   #9
MarioKamani
Big Clucker
 
Join Date: Jan 2017
Posts: 57
Reputation: 4
Default Re: Report System with zcmd and sscanf

Quote:
Originally Posted by FAStingTV View Post
forward Heartbeat();
public Heartbeat()
{
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(JustReported[i] > 0)
JustReported[i]--; // there
}
return 1;
}
the [i]
MarioKamani is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
/report and /acceptreport antonisrodos94 Scripting Help 2 02/10/2013 10:36 AM
help for zcmd report command. eastern Scripting Help 3 19/07/2013 11:00 AM
sscanf & zcmd help..! sscanf inside strcmp PaulDinam Scripting Help 2 26/02/2013 12:47 PM
[Tutorial] How to make a bug report command (ZCMD + sscanf + log) MarkoN Tutorials 10 01/09/2012 01:15 AM
dcmd + sscanf help (/report) Naruto4 Help Archive 1 31/12/2009 10:09 AM


All times are GMT. The time now is 07:21 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.