Aller au contenu
Top-Metin2.org - Vous êtes à la recherche d'un serveur Metin 2 ? ×
×
×
  • Créer...

C++ - Ban In Game + Raison


Messages recommandés

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.

  • Metin2 Dev 2
Lien vers le commentaire
Partager sur d’autres 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 !

Lien vers le commentaire
Partager sur d’autres sites

  • 4 semaines après...
  • 3 semaines après...

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

Lien vers le commentaire
Partager sur d’autres sites

  • 8 mois après...

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.

Lien vers le commentaire
Partager sur d’autres sites

  • 10 mois après...

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]

Modifié par Holly
  • Love 1
Lien vers le commentaire
Partager sur d’autres sites



  • brilliantdiscord_widget
  • Flux d'Activité

    1. 0

      OldEraMT2 | Classique 2009 Oldschool | Niveau 99 | 7 langues | Sans pay2win | Bêta fermée

    2. 6

      problème de connexion à mon serveur local (je suis débutant dans ce genre d'entreprise )

    3. 2

      problème de lancement serveur

    4. 9
    5. 0

      [PVM/PVP] ATLAX2 - EASY PLAY

    6. 2

      problème de lancement serveur

Information importante

Conditions d’utilisation / Politique de confidentialité / Règles / Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.