Mon premier script mIRC date de 1998. C'était un alias de trois lignes qui affichait l'heure en couleur dans le channel. Rien de spectaculaire, mais quand j'ai vu le texte coloré apparaître à l'écran en tapant /heure, j'ai eu le déclic. Vingt-cinq ans plus tard, le mIRC Scripting Language (mSL) existe toujours, avec la même syntaxe unique, les mêmes identifiants préfixés par $, et la même courbe d'apprentissage qui fait fuir les développeurs confirmés et fascine les débutants. Voici un guide complet pour maîtriser ce langage atypique.
Le mSL : un langage à part
Le mSL ne ressemble à rien d'autre. Ce n'est pas du C, pas du Basic, pas du Perl. C'est un langage conçu spécifiquement pour automatiser un client IRC, et cette spécialisation se reflète dans chaque aspect de sa syntaxe.
Les identifiants — ces fonctions préfixées par $ — sont le cœur du langage. $nick renvoie le pseudo de l'expéditeur d'un message, $chan le channel courant, $me votre propre pseudo. Il en existe des centaines, couvrant tous les aspects d'IRC et du système d'exploitation.
; Les identifiants de base
$nick ; Pseudo de l'expéditeur du message courant
$chan ; Channel courant
$me ; Votre pseudo
$address ; Masque d'hôte de l'expéditeur
$time ; Heure actuelle (HH:nn:ss)
$date ; Date actuelle
$1 $2 $3 ; Paramètres passés à un alias
$1- ; Tous les paramètres à partir du premier
$network ; Nom du réseau IRC
$server ; Adresse du serveur connecté
$os ; Système d'exploitation
Le code mSL est écrit dans des fichiers .mrc ou directement dans l'éditeur de scripts intégré à mIRC (Alt+R). Il existe trois sections principales : les aliases (commandes personnalisées), les remote scripts (événements), et les popups (menus contextuels).
Les aliases : vos premières commandes
Un alias est une commande personnalisée. Vous tapez /nomalias dans mIRC et le code associé s'exécute. C'est le point d'entrée le plus simple pour apprendre le scripting.
; Alias simple : afficher un message
alias bonjour {
msg $active Bonjour à tous, je suis $me et il est $time !
}
; Alias avec paramètre
alias slap {
if ($1 == $null) {
echo -a Syntaxe : /slap <pseudo>
return
}
describe $active gifle $1 avec un poisson géant.
}
; Alias avec retour de valeur (identifiant personnalisé)
alias duree {
var %s = $1
var %h = $int($calc(%s / 3600))
var %m = $int($calc((%s % 3600) / 60))
var %rest = $calc(%s % 60)
return %h $+ h $+ %m $+ m $+ %rest $+ s
}
; Utilisation : echo -a $duree(3661) → affiche "1h1m1s"
La différence entre msg et echo est fondamentale. msg #canal texte envoie un message visible par tout le monde dans le channel. echo -a texte affiche du texte uniquement dans votre fenêtre locale. Quand vous déboguez, utilisez echo. Beaucoup de débutants ont spammé des channels entiers avec des msg de debug.
$+. Ne le confondez pas avec un espace. abc $+ def produit abcdef, tandis que abc def produit abc def (avec l'espace). C'est la source de bugs la plus fréquente en mSL, et elle affecte même les scripteurs expérimentés.Les événements : réagir automatiquement
Les événements permettent à votre script de réagir à ce qui se passe sur IRC : quelqu'un rejoint un channel, envoie un message, change de pseudo, se fait kicker. La syntaxe est on NIVEAU:ÉVÉNEMENT:PARAMÈTRES:CIBLE:{code}.
; Événement : quelqu'un rejoint un channel
on *:JOIN:#moncanal:{
if ($nick != $me) {
msg $chan Bienvenue $nick ! Tapez !aide pour la liste des commandes.
}
}
; Événement : message reçu dans un channel
on *:TEXT:!aide*:#:{
notice $nick Commandes disponibles : !aide, !regles, !stats, !ping
}
on *:TEXT:!ping:#:{
msg $chan Pong ! Latence serveur : $server $+ , lag : $round($lag / 1000, 2) $+ s
}
on *:TEXT:!stats:#:{
msg $chan Connecté à $network sur $server depuis $duration($uptime(system,3))
msg $chan Channels : $chan(0) | Utilisateurs ici : $nick($chan, 0)
}
; Événement : message privé
on *:TEXT:*:?:{
echo -a [Privé de $nick] $1-
}
; Événement : kick
on *:KICK:#:{
if ($knick == $me) {
; Rejoin automatique après un kick
timer 1 5 join $chan
echo -a J'ai été kické de $chan par $nick ( $+ $1- $+ ), rejoin dans 5s.
}
}
; Événement : changement de topic
on *:TOPIC:#:{
echo -a Topic de $chan changé par $nick : $1-
}
Le niveau d'accès (* dans les exemples ci-dessus) permet de restreindre qui peut déclencher l'événement. * signifie "tout le monde". Vous pouvez définir des niveaux personnalisés et les attribuer à des masques d'hôte spécifiques dans la Users List. C'est le système de permissions intégré du mSL.
; Niveaux d'accès
; Dans la Users List (Alt+R → Users)
; 100:*!*@host.admin.com
; 50:*!*@*.trusted.net
; Dans le script
on 100:TEXT:!admin*:#:{
; Seuls les utilisateurs de niveau 100+ déclenchent ceci
msg $chan Commande admin exécutée par $nick
}
on 50:TEXT:!modere*:#:{
; Niveau 50+
msg $chan Action de modération par $nick
}
Variables et structures de données
Le mSL distingue deux types de variables : les variables locales (var %x) qui n'existent que pendant l'exécution du bloc courant, et les variables globales (%x sans var) qui persistent entre les exécutions et même entre les redémarrages de mIRC.
; Variable locale : existe uniquement dans ce bloc
alias calcul {
var %a = 10
var %b = 20
var %resultat = $calc(%a + %b)
echo -a Résultat : %resultat
}
; Variable globale : persiste entre les sessions
alias compteur {
if (%compteur == $null) set %compteur 0
inc %compteur
echo -a Compteur : %compteur
}
; Supprimer une variable globale
alias reset {
unset %compteur
echo -a Compteur réinitialisé.
}
; Variables binaires (stockage de données brutes)
alias stockbin {
bset -t &monbuffer 1 Données binaires ici
echo -a Taille : $bvar(&monbuffer, 0) octets
echo -a Contenu : $bvar(&monbuffer, 1-).text
bunset &monbuffer
}
var pour les variables temporaires. Les variables globales polluent l'espace mémoire de mIRC et persistent dans le fichier vars.ini indéfiniment. J'ai vu des installations de mIRC avec des milliers de variables globales oubliées qui dataient de scripts désinstallés depuis des années.Les dialogs : créer une interface graphique
Le mSL permet de créer des fenêtres de dialogue avec des boutons, des champs de texte, des listes, et des onglets. La syntaxe est déclarative — vous décrivez la position et la taille de chaque contrôle, puis vous gérez les événements dans un script séparé.
; Définition de la boîte de dialogue
dialog config_bot {
title "Configuration du Bot"
size -1 -1 300 250
; Onglets
tab "Général", 1, 5 5 290 220
tab "Channels", 2
tab "Protection", 3
; Contenu onglet Général
text "Pseudo du bot :", 10, 15 30 100 20, tab 1
edit "", 11, 120 28 160 22, tab 1
text "Serveur :", 12, 15 60 100 20, tab 1
edit "", 13, 120 58 160 22, tab 1
text "Port :", 14, 15 90 100 20, tab 1
edit "6697", 15, 120 88 80 22, tab 1
check "Utiliser TLS", 16, 15 120 150 20, tab 1
; Contenu onglet Channels
text "Channels à joindre :", 20, 15 30 200 20, tab 2
edit "", 21, 15 50 260 22, tab 2
list 22, 15 80 260 100, tab 2 sort
button "Ajouter", 23, 15 185 80 25, tab 2
button "Supprimer", 24, 100 185 80 25, tab 2
; Boutons communs
button "OK", 100, 120 225 80 25, ok
button "Annuler", 101, 210 225 80 25, cancel
}
; Gestion des événements de la boîte de dialogue
on *:DIALOG:config_bot:init:*:{
; Remplir les champs au chargement
did -a $dname 11 %bot.nick
did -a $dname 13 %bot.server
if (%bot.tls == on) did -c $dname 16
}
on *:DIALOG:config_bot:sclick:100:{
; Bouton OK : sauvegarder les paramètres
set %bot.nick $did($dname, 11)
set %bot.server $did($dname, 13)
set %bot.port $did($dname, 15)
set %bot.tls $iif($did($dname, 16).state == 1, on, off)
echo -a Configuration sauvegardée.
}
on *:DIALOG:config_bot:sclick:23:{
; Bouton Ajouter un channel
var %chan = $did($dname, 21)
if (%chan != $null) {
did -a $dname 22 %chan
did -r $dname 21
}
}
; Ouvrir la boîte de dialogue
alias configbot {
dialog -m config_bot config_bot
}
Les dialogs mIRC ne sont pas belles. Elles ressemblent à des fenêtres Windows 95. Mais elles sont fonctionnelles, et pour un script de bot IRC, c'est suffisant. J'ai vu des gens créer des jukebox MP3 complets avec playlist, contrôles de lecture et affichage du spectre audio — tout en mSL avec des dialogs.
Hash tables : stockage en mémoire
Les hash tables (ajoutées dans mIRC 6.0) sont des structures clé-valeur en mémoire. Elles remplacent les variables globales pour le stockage de données structurées et sont nettement plus performantes pour les grandes quantités de données.
; Créer et utiliser une hash table
alias initdb {
; Créer la table (1000 buckets)
hmake users 1000
; Charger depuis un fichier s'il existe
if ($isfile(users.hsh)) {
hload users users.hsh
echo -a Base utilisateurs chargée : $hget(users, 0).item entrées.
}
}
; Ajouter/modifier un utilisateur
alias adduser {
; /adduser pseudo niveau
if ($2 == $null) {
echo -a Syntaxe : /adduser pseudo niveau
return
}
hadd users $1 $2
hsave users users.hsh
echo -a Utilisateur $1 ajouté avec niveau $2
}
; Vérifier le niveau d'un utilisateur
alias niveau {
var %n = $hget(users, $1)
if (%n == $null) return 0
return %n
}
; Lister tous les utilisateurs
alias listusers {
var %i = 1
while ($hget(users, %i).item != $null) {
echo -a $v1 : $hget(users, $v1)
inc %i
}
}
; Utilisation dans un événement
on *:TEXT:!level*:#:{
var %user = $iif($2 != $null, $2, $nick)
var %lvl = $niveau(%user)
msg $chan Niveau de %user : %lvl
}
; Nettoyage en quittant mIRC
on *:EXIT:{
if ($hget(users)) {
hsave users users.hsh
hfree users
}
}
Les hash tables sont aussi utilisées pour le rate-limiting (stocker les timestamps des dernières commandes par utilisateur), les systèmes de points, les quiz (questions-réponses), et tout ce qui nécessite un accès rapide à des paires clé-valeur.
Exemples pratiques
Voici trois scripts complets et utiles qui illustrent les concepts abordés dans cet article.
Script 1 : système de commandes avec cooldown
; Anti-spam : empêcher l'abus des commandes
alias -l checkflood {
; $1 = nick, $2 = commande, $3 = délai en secondes
var %key = $1 $+ . $+ $2
var %last = $hget(cooldowns, %key)
var %now = $ctime
if (%last != $null) {
if ($calc(%now - %last) < $3) return $true
}
hadd cooldowns %key %now
return $false
}
on *:START:{
hmake cooldowns 100
}
on *:TEXT:!meteo*:#:{
if ($checkflood($nick, meteo, 30)) {
notice $nick Attendez 30 secondes entre chaque !meteo
return
}
var %ville = $iif($2 != $null, $2-, Paris)
msg $chan Météo de %ville : [simulation] 18°C, nuageux.
}
Script 2 : auto-modération basique
; Détection et action sur les messages répétés
on *:TEXT:*:#:{
if ($nick isop $chan) return
; Vérifier les majuscules excessives (plus de 80% du message)
var %upper = $regex($1-, /[A-Z]/g)
var %total = $len($1-)
if (%total > 10 && $calc(%upper / %total * 100) > 80) {
msg $chan $nick $+ , merci de ne pas écrire en majuscules.
return
}
; Vérifier les messages identiques répétés
var %key = repeat. $+ $nick
if ($hget(antiflood, %key) == $1-) {
var %count = $calc($hget(antiflood, %key $+ .count) + 1)
hadd antiflood %key $+ .count %count
if (%count >= 3) {
kick $chan $nick Message répété 3 fois.
hdel antiflood %key
hdel antiflood %key $+ .count
}
}
else {
hadd antiflood %key $1-
hadd antiflood %key $+ .count 1
}
}
Script 3 : quiz simple
; Quiz IRC avec hash table de questions
alias loadquiz {
hmake quiz 100
hadd quiz 1.q Quel est le port standard IRC avec TLS ?
hadd quiz 1.a 6697
hadd quiz 2.q En quelle année IRC a-t-il été créé ?
hadd quiz 2.a 1988
hadd quiz 3.q Qui a créé le protocole IRC ?
hadd quiz 3.a Jarkko Oikarinen
set %quiz.total 3
set %quiz.current 0
echo -a Quiz chargé : %quiz.total questions.
}
alias startquiz {
if (!$hget(quiz)) loadquiz
set %quiz.current $rand(1, %quiz.total)
set %quiz.active $true
msg $active Question : $hget(quiz, %quiz.current $+ .q)
}
on *:TEXT:*:#:{
if (%quiz.active != $true) return
var %reponse = $hget(quiz, %quiz.current $+ .a)
if ($1- == %reponse) {
msg $chan Bravo $nick ! La réponse était bien : %reponse
set %quiz.active $false
}
}
Questions fréquentes
Peut-on déboguer un script mIRC facilement ?
mIRC n'a pas de débogueur intégré au sens classique. La méthode principale est d'utiliser echo -a pour afficher les valeurs des variables à chaque étape. Vous pouvez aussi activer le mode debug dans l'éditeur de scripts (Debug → Enable) pour voir chaque ligne exécutée. C'est rudimentaire, mais ça fonctionne.
Les scripts mIRC sont-ils compatibles entre versions ?
Dans l'ensemble, oui. Khaled Mardam-Bey maintient une compatibilité ascendante très stricte. Un script écrit pour mIRC 6.x fonctionne généralement sans modification sur mIRC 7.x. Les rares incompatibilités sont documentées dans les changelogs de chaque version.
Existe-t-il des IDE ou éditeurs externes pour le mSL ?
Quelques éditeurs tiers existent, comme mSL Editor ou des extensions pour Notepad++, mais l'éditeur intégré de mIRC (Alt+R) reste le plus utilisé. Il offre la coloration syntaxique, la recherche dans les scripts, et l'exécution directe. Pour des scripts complexes, certains scripteurs utilisent un éditeur externe et rechargent le fichier dans mIRC avec /reload -rs fichier.mrc.