Jump to content
×
×
  • Create New...

C++ - Ban In Game + Raison


Recommended Posts

Centre de Téléchargement

Télécharger ( 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

Tellement fière de mon 100 ème message que plus jamais je ne posterais sur FE. ( 100 messages en 5 ans) Pour fêter cela j'ai mis un avatar :heart:

Link to comment

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

Le code a était edité dans le premier message !

Tellement fière de mon 100 ème message que plus jamais je ne posterais sur FE. ( 100 messages en 5 ans) Pour fêter cela j'ai mis un avatar :heart:

Link to comment
  • 4 weeks later...
  • 1 year 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

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


  • Flux d'Activité

    1. 38

      Rodnia.net | PVM | International | The Great Conqueror |

    2. 0

      [JAVA] Starloco

    3. 0

      Recherche CMS arkalys 2021

    4. 0

      AresiaCMS

    5. 62

      [CMS] Acamar Cms

    6. 3

      Éditeur Item 2.43 à 2.53

  • Recently Browsing

    • No registered users viewing this page.

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.