Jump to content
Sanchez

[C++]In-game ban with reason

Recommended Posts

Hi,
 
In this thread I will show you how to do an in-game ban for your GMs. First of all, you need to make a new column in the account.account. The name of the field should be reason and select varchar as type.
 
a1_2014_2_15_1qw3dn1wyw.jpg
 
Or just use this in your console to create the field:
 

ALTER TABLE account ADD reason VARCHAR(256);

 
Now open game/cmd.cpp and search for this:
 

ACMD(do_block_chat);

 
Add this under that:
 

ACMD(do_ban);

 
Search for this still in the game/cmd.cpp:
 

{ "block_chat_list",do_block_chat_list,	0,			POS_DEAD,	GM_PLAYER	},

 
Make a new line and add this under that:
 

{ "ban", do_ban, 0, POS_DEAD, GM_IMPLEMENTOR },

 
At this point you can change the rights for the command:
 
GM_PLAYER - do NOT choose this!
GM_LOW_WIZARD
GM_WIZARD
GM_HIGH_WIZARD
GM_GOD
GM_IMPLEMENTOR
 
Search for this event in game/cmd_gm.cpp:
 

ACMD(do_block_chat)

 
Add this under that:
 

ACMD(do_ban)

Now time to add the complete code to ACMD(do_ban):
 

	// Args
	char arg1[256], arg2[256], arg3[256];

	// Local variables
	const char*  szName;
	const char*  szReason;
	int			 iDuration;

	one_argument(two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3));

	// Invalid syntax
	if (!*arg1 || !*arg2 || !*arg3)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "Invalid Syntax, usage: <player name> <time in hours> <reason> tip: don't use spaces in the reason, use _");
		return;
	}

	szName		= arg1;
	iDuration	= atoi(arg2);
	szReason	= arg3;

	if (iDuration <= 0)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "Duration can't be 0 or minus.");
		return;
	}

	LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(szName);

	if (!tch)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "%s is not playing", szName);
		return;
	}

	if (!tch->GetDesc())
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "%s don't have desc", szName);
		return;
	}

	if (tch == ch)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "What's wrong with you? Don't ban yourself");
		return;
	}

	if (tch->GetGMLevel() > GM_PLAYER)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "Do not ban GMs");
		return;
	}

	std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery("UPDATE account.account SET availDt = FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i), reason = '%s' WHERE id = %d", iDuration * 3600, szReason, tch->GetDesc()->GetAccountTable().id));
	
	tch->GetDesc()->DelayedDisconnect(5);

	sys_log(0, "%s[%d] banned %s for %i hours with reason: %s", ch->GetName(), ch->GetPlayerID(), szName, iDuration, szReason);

	ch->ChatPacket(CHAT_TYPE_INFO, "%s has been banned for %i hours with reason: %s", szName, iDuration, szReason);

 
Check how it works:
 
/ban <player name> <duration in hours> <reason>
 
Example:
 
/ban Doe 24 Hacking

In-game:
 
a1_2014_2_10_30hss99pfd.jpg

Database, account table:
 
a1_2014_2_10_clxl5q3xmx.jpg
 
syslog:
 
Feb 10 03:30:15.890000 :: Sanchez[57735] banned Doe for 24 hours with reason: Hacking


If you have any question or suggestion, please just reply to this topic.
 
Kind Regards,
Sanchez

  • Love 39

Share this post


Link to post

Very nice share friend.

@Vanilla, maybe you want add this to vanilla core project :P

  • Love 1

Share this post


Link to post

Isnt the varchar max len only 255?

Gesendet von meinem Nexus 5 mit Tapatalk

  • Love 1

Share this post


Link to post

that's really nice, alot better than using custom ban reasons in the client and setting the word in status of account.account db

  • Love 1

Share this post


Link to post

Hi guys,

 

I made a small update, the first post has been edited with these changes:

 

  1. GMs now can't ban another GMs
  2. The banned user will be disconnected in 5 seconds
  • Love 3

Share this post


Link to post

Why you have this part in your code?

if (!ch || ch->GetGMLevel() != GM_IMPLEMENTOR) // Again change here the rights
{
    sys_log(0, "do_ban without rights %s[%d]", ch->GetName(), ch->GetPlayerID());
    return;
}

The command interpreter is already checking the permissions.

 

Kind regards

Sphinx

  • Love 4

Share this post


Link to post

I know, but I don't think its a bad idea to recheck again.

 

The other functions of ymir dont recheck the permissions.

But if you think you have more security with this check then use it.

 

  • Love 1

Share this post


Link to post

Yes, I feel much better with this check. Maybe I'm a paranoid or something.

  • Love 4

Share this post


Link to post

Yes, I feel much better with this check. Maybe I'm a paranoid or something.

 

LMFAO  :D  :D  :D

  • Love 1

Share this post


Link to post

Hi good morning, as I can make a second query? I want to enter data into a second table outside, for instance that "banlist" I may get a second query? how i can do?

 
The second table contains the user id, user name, start date, end date and reason of the ban, it would be possible to do this?

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `banlist`
-- ----------------------------
DROP TABLE IF EXISTS `banlist`;
CREATE TABLE `banlist` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(24) CHARACTER SET ascii NOT NULL,
`begins` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`finish` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`reason` varchar(256) CHARACTER SET ascii DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin5;

-- ----------------------------
-- Records of banlist
-- ----------------------------
INSERT INTO banlist VALUES ('1', 'Test', '2014-03-26 00:24:59', '0000-00-00 00:00:00', 'hack');

Share this post


Link to post

Sure it's possible. I'm not tested, but here it is:

DBManager::instance().DirectQuery("INSERT INTO account.banlist (id, name, begins, finish, reason) VALUES ('%d', %s, NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i, %s)", LCHARACTER->GetAID(), LCHARACTER->GetName(), duration * 3600, reason);
  • Love 1

Share this post


Link to post

 

Sure it's possible. I'm not tested, but here it is:

DBManager::instance().DirectQuery("INSERT INTO account.banlist (id, name, begins, finish, reason) VALUES ('%d', %s, NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i, %s)", LCHARACTER->GetAID(), LCHARACTER->GetName(), duration * 3600, reason);

 

I refer to include the two queries, which you already provided in the source + I need, you understand my idea? as might be included in the source without generating an error? I tried adding a new line but would not let me compile
 
Thank you for your response sanchez. 
 
This generates an error when I compile. My knowledge c++  is very basic 
LCHARACTER = CHARACTER_MANAGER::instance().FindPC(name);
 
std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery("UPDATE account.account SET status = 'BLOCK', availDt = FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i), reason = '%s' WHERE id = %d", duration * 3600, reason, LCHARACTER->GetAID()));
std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery("INSERT INTO account.banlist (id, name, begins, finish, reason) VALUES ('%d', %s, NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i, %s)", LCHARACTER->GetAID(), LCHARACTER->GetName(), duration * 3600, reason);

LDESC->DelayedDisconnect(5);

Share this post


Link to post

Rename the second msg to msg1 or to something else, but you don't need that.

 

Just use this:

DBManager::instance().DirectQuery("INSERT INTO account.banlist (id, name, begins, finish, reason) VALUES ('%d', %s, NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i, %s)", LCHARACTER->GetAID(), LCHARACTER->GetName(), duration * 3600, reason);
  • Love 2

Share this post


Link to post

 

Rename the second msg to msg1 or to something else, but you don't need that.

 

Just use this:

DBManager::instance().DirectQuery("INSERT INTO account.banlist (id, name, begins, finish, reason) VALUES ('%d', %s, NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i, %s)", LCHARACTER->GetAID(), LCHARACTER->GetName(), duration * 3600, reason);

 

I know it is unnecessary, the second query is to enter data into a table outside account, to have a ban list on the website, you understand? That thinking we will not ban users every second can be a little "extra" work to game, I do not suppose a large consumption, I'm wrong? 
 
Thank you very much for your answers Sanchez hope to return the favor.
  • Love 1

Share this post


Link to post

Sorry, but I don't understand you. What is the problem or what?

  • Love 1

Share this post


Link to post

Sorry, but I don't understand you. What is the problem or what?

 

 

Sorry my bad english, no problem Sanchez, everything is perfect thank you very much for your advice! a hug

Share this post


Link to post

I have problem with query. Syslog:

http://wklej.to/AkvfE

Can you help? I have reason i account.account.

Share this post


Link to post

Try this:

"UPDATE account.account SET status = 'BLOCK', availDt = 'FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i)', reason = '%s' WHERE id = '%d'"

Share this post


Link to post

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...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.