Jump to content
La fin ?! Elle est là ! ×
×
×
  • Create New...

C++ - Ban In Game + Raison


Recommended Posts

Centre de Téléchargement

Hidden Content

    Give reaction to this post to see the hidden content.
( Interne )

Bonsoir à tous,

 

Voici un tutoriel pour pouvoir ban un joueur connecté directement en jeu. Le tutoriel de base vient de Metin2Dev par Sanchez. Je l'ai modifié à un endroit, parce qu'elle fonctionnait pas pour moi.

 

1. Créer une table sql dans la base account :

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `ban_ingame`
-- ----------------------------
DROP TABLE IF EXISTS `ban_ingame`;
CREATE TABLE `ban_ingame` (
 `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=3 DEFAULT CHARSET=latin5;

-- ----------------------------
-- Records of ban_ingame
-- ----------------------------
 

2. Ouvrez le fichier cmd.cpp ( dans le dossier game) et cherchez la ligne suivante :

ACMD(do_block_chat);
 

Ajoutez juste en dessous :

ACMD(do_ban);
 

3. Cherchez la ligne suivante :

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

et ajoutez ceci en dessous :

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

4. Cherchez la fonction suivante :

ACMD(do_block_chat)
{
// GM이 아니거나 block_chat_privilege가 없는 사람은 명령어 사용 불가
if (ch && (ch->GetGMLevel() < GM_HIGH_WIZARD && ch->GetQuestFlag("chat_privilege.block") <= 0))
{
	ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("그런 명령어는 없습니다"));
	return;
}

char arg1[256];
argument = one_argument(argument, arg1, sizeof(arg1));

if (!*arg1)
{
	if (ch)
		ch->ChatPacket(CHAT_TYPE_INFO, "Usage: block_chat  (0 to off)");

	return;
}

const char* name = arg1;
long lBlockDuration = parse_time_str(argument);

if (lBlockDuration < 0)
{
	if (ch)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "잘못된 형식의 시간입니다. h, m, s를 붙여서 지정해 주십시오.");
		ch->ChatPacket(CHAT_TYPE_INFO, "예) 10s, 10m, 1m 30s");
	}
	return;
}

sys_log(0, "BLOCK CHAT %s %d", name, lBlockDuration);

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

if (!tch)
{
	CCI * pkCCI = P2P_MANAGER::instance().Find(name);

	if (pkCCI)
	{
		TPacketGGBlockChat p;

		p.bHeader = HEADER_GG_BLOCK_CHAT;
		strlcpy(p.szName, name, sizeof(p.szName));
		p.lBlockDuration = lBlockDuration;
		P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGBlockChat));
	}
	else
	{
		TPacketBlockChat p;

		strlcpy(p.szName, name, sizeof(p.szName));
		p.lDuration = lBlockDuration;
		db_clientdesc->DBPacket(HEADER_GD_BLOCK_CHAT, ch ? ch->GetDesc()->GetHandle() : 0, &p, sizeof(p));
	}

	if (ch)
		ch->ChatPacket(CHAT_TYPE_INFO, "Chat block requested.");

	return;
}

if (tch && ch != tch)
	tch->AddAffect(AFFECT_BLOCK_CHAT, POINT_NONE, 0, AFF_NONE, lBlockDuration, 0, true);
}
// END_OF_BLOCK_CHAT
 

Ajoutez juste après ceci :

ACMD(do_ban)
{
    // Args
    char arg1[256], arg2[256], arg3[256];

    // Local variables
    const char*  szName;
    const char*  szReason;
    char         szReasonEscape[1024];
    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:  tip: don't use spaces in the reason, use _");
        return;
    }

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

    DBManager::instance().EscapeString(szReasonEscape, sizeof(szReasonEscape), szReason, strlen(szReason));
    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 msg(DBManager::instance().DirectQuery("INSERT INTO account2.ban_ingame (id, name, begins, finish, reason) VALUES ('%d', '%s', NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i), '%s')", tch->GetAID(), tch->GetName(), iDuration * 3600, szReasonEscape));
    DBManager::instance().DirectQuery("UPDATE account2.account SET availDt = FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i) WHERE id = %d", iDuration * 3600, tch->GetAID());
    tch->GetDesc()->DelayedDisconnect(5);

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

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

}
 

INFORMATIONS :

std::auto_ptr msg(DBManager::instance().DirectQuery("INSERT INTO account.ban_ingame (id, name, begins, finish, reason) VALUES ('%d', '%s', NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i), '%s')", tch->GetAID(), tch->GetName(), iDuration * 3600, szReason));
 

Va insérer les informations dans votre table "ban_ingame". Si vous changez le nom de table dans navicat, n'oubliez pas de changer le nom de la fonction ici aussi.

DBManager::instance().DirectQuery("UPDATE account.account SET status = 'BLOCK' WHERE id = %d", tch->GetAID());
 

Va bannir le compte du joueur dans la table account.account , dans la colonne statut, celui-ci passera de "OK" à "BLOCK".

 

Le compte banni se déconnecte automatiquement.

  • Funky Emulation 1
Link to comment
Share on other sites

Attention aux failles de sécurité !

 

Le string de raison n'est pas escapé et il n'y a visiblement aucune restriction sur les caractères que l'on peut y mettre.

 

Même si cette commande ne peut logiquement être utilisée que par un Game Master, il serait tout de même dommage de laisser une vulnérabilité capable de supprimer ou modifier l'ensemble de vos données sql !

 

 

Voici la commande corrigée:

 

ACMD(do_ban)
{
// Args
char arg1[256], arg2[256], arg3[256];

// Local variables
const char*		szName;
const char*		szReason;
char			szReasonEscape[1024];
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:  tip: don't use spaces in the reason, use _");
	return;
}

szName		= arg1;
iDuration	= atoi(arg2);
szReason	= arg3;
// Escape szReason to szReasonEscape
DBManager::instance().EscapeString(szReasonEscape, sizeof(szReasonEscape), szReason, strlen(szReason));

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 msg(DBManager::instance().DirectQuery("INSERT INTO account.ban_ingame (id, name, begins, finish, reason) VALUES ('%d', '%s', NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i), '%s')", tch->GetAID(), tch->GetName(), iDuration * 3600, szReasonEscape));
DBManager::instance().DirectQuery("UPDATE account.account SET status = 'BLOCK' WHERE id = %d", tch->GetAID());
tch->GetDesc()->DelayedDisconnect(5);

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

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

 

 

 

Je n'ai pas testé mais ça devrait fonctionner.

 

 

 

De plus, je n'ai pas compris pourquoi le status du compte est mis à BLOCK alors que seul availDt pourrait directement avoir la date de fin du bannissement pour que le débannissement soit automatique.

 

Il faudrait remplacer :

DBManager::instance().DirectQuery("UPDATE account.account SET status = 'BLOCK' WHERE id = %d", tch->GetAID());

par :

DBManager::instance().DirectQuery("UPDATE account.account SET availDt = FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i) WHERE id = %d", iDuration * 3600, tch->GetAID());

 

 

Petite remarque supplémentaire, il me semble qu'il n'est pas nécessaire de sélectionner la table account dans les query.

Pour ceux qui ont modifié le nom des tables, je pense, mais sans certitude, que l'on peut simplement retirer "account." des deux query.

 

 

Merci tout de même !

Link to comment
Share on other sites

  • 4 weeks later...
  • 3 weeks later...

Faut vérifier la date programmé sur ton serveur dédier car apparemment

 

 

Si ta date est mal configuré, la commande là ne sert à rien:

 

FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP())

 

En conséquent tu peux te reconnecter directement ...

Link to comment
Share on other sites

  • 8 months later...

Pour ma part, même en ayant mis mon dédié à l'heure en ajoutant :

ntpdate_enable="YES" au fichier /etc/rc.conf

 

Ça ne fonctionne pas, le joueur est déco et peut se reco aussi tôt.

La table ban_ingame se rempli bien mais le statut du compte reste sur OK.

PS : Je suis sous les files 2016 by FE.

Link to comment
Share on other sites

  • 10 months later...

Le code donnez partie 4 n'est pas fonctionnel chez moi. 

 

Celui-ci l'est : 

 
ACMD(do_ban)
{
	// Args
	char arg1[256], arg2[256], arg3[256];

	// Local variables
	const char*  szName;
	const char*  szReason;
	char		 szReasonEscape[1024];
	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;

	DBManager::instance().EscapeString(szReasonEscape, sizeof(szReasonEscape), szReason, strlen(szReason));
	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("INSERT INTO account.ban_ingame (id, name, begins, finish, reason) VALUES ('%d', '%s', NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i), '%s')", tch->GetAID(), tch->GetName(), iDuration * 3600, szReasonEscape));
	DBManager::instance().DirectQuery("UPDATE account.account SET availDt = FROM_UNIXTIME(UNIX_TIMESTAMP(CURRENT_TIMESTAMP()) + %i) WHERE id = %d", iDuration * 3600, tch->GetAID());
	tch->GetDesc()->DelayedDisconnect(5);

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

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

}

[/spoiler]

Edited by Holly
  • J'adore 1
Link to comment
Share on other sites

 Share



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.