Documentation
Toutes les pages
Entrée des Bots  -  par FSMOD

Entrée des Bots

Les codes sources soit-disant officiels que j'ai glanés sur le net il y a quelques années présentaient dans leur ensemble quelques incohérences heureusement non bloquantes mais la principale d'entre elles se manifestait par l'impossibilité d'admettre des bots dans le jeu, malgré une configuration rigoureuse. Curieusement leur IA était présente ainsi que toutes les fonctions destinés à leur gestion.

La simple modification suivante les a invités manu-militari, à participer au combat tongue

Modification du code sources

Fichier g_client.c

Dans la fonction ClientConnect recherchez la ligne suivante

 if ( strlen(guid) < 32 )

La remplacer par

 if ( !(isBot) && (strlen(guid) < 32) )  // *FSMOD* Autorise l'arrivéee des bots

-=eek=-

Publié le 10/03/2019 15:47  Prévisualiser...   Imprimer...   Haut
Chargement des Bots  -  par FSMOD

CHARGEMENT DES BOTS

Vous avez sans doute remarqué qu'après une suppression totale des bots au cours du jeu, soit par une action "kick allbots" ou suite à une rotation de map avec chargement d'une nouvelle liste de bots, ces derniers mettaient un temps fou à entrer sur le terrain.

Cette lenteur se révèle préjudiciable dans le cas par exemple où, après une petite map qui ne nécessitait que 4 ou 5 bots, une nouvelle map plus grande était lancée avec une douzaine de bots. Avant que cet objectif numérique soit atteint, il fallait attendre une grosse poignée de secondes.

Voici une petite modification très simple qui va accélérer leur envie de se battre frown

Modification du code sources

Fichier g_bots.c

Dans la fonction G_CheckMinimumPlayers recherchez les lignes suivantes

// only check once each 10 seconds
    if (checkminimumplayers_time > level.time - 10000)

Les remplacer par

// *FSMOD* Vérif toutes les secondes
    if (checkminimumplayers_time > level.time - 1000)

Nota: Une valeur inférieure à 1000 peut être de nature à stresser le serveur et conduire éventuellement au crash.

-=cry=-

Publié le 10/03/2019 14:49  Prévisualiser...   Imprimer...   Haut
Pseudos Bot multiples  -  par FSMOD

Les pseudos multiples des bots

Rocmod dans sa version originelle présente une propension particulière a charger des bots portant le même pseudo. Outre le fait que ce processus n'est guère rationnel, les bots de même nom ont forcement les mêmes paramètres et le jeu perd un peu en diversité.

Un simple suffixe numéral est incrémenté à chaque fois qu'un bot utilise le même pseudo. A noter que cette incrémentation reste valable si d'aventure des joueurs réels se connectent avec le même pseudo, mais dans ce cas cela ne pose pas de problème particulier.

Modification du code sources

Fichier g_client.c

Dans la fonction ClientUserInfoChanged recherchez le passage suivant

 // See if we need to find a new name because the one they chose is taken
    Q_strncpyz ( origname, client->pers.netname,  MAX_NETNAME - 5 );
    while ( G_FindClientByName ( client->pers.netname, clientNum ) )
    {
        Com_sprintf ( client->pers.netname, MAX_NETNAME, "%s(%d)", origname, namecount );
        namecount++;
    }

Remplacez le par

 

/*
    // See if we need to find a new name because the one they chose is taken
    Q_strncpyz ( origname, client->pers.netname,  MAX_NETNAME - 5 );
    while ( G_FindClientByName ( client->pers.netname, clientNum ) )
    {
        Com_sprintf ( client->pers.netname, MAX_NETNAME, "%s(%d)", origname, namecount );
        namecount++;
    }

*/


// *********************** FSMOD On vire les bots de même nom **********************


    Q_strncpyz ( origname, client->pers.netname,  MAX_NETNAME - 30 );

    while ( G_FindClientByName ( client->pers.netname, clientNum ) )
    {

        if ((g_entities[clientNum].r.svFlags & SVF_BOT))

        {
            Com_sprintf ( client->pers.netname, MAX_NETNAME, "%s(%d)", origname, namecount );
              trap_SendConsoleCommand( EXEC_INSERT, va("kick %s",client->pers.netname) );

        }
        else
        {
            Com_sprintf ( client->pers.netname, MAX_NETNAME, "%s ^3[%d]", origname, namecount );

            namecount++;
        }
    }

// ***************************  Fin FSMOD  ************************************

-=smile=-

Publié le 09/03/2019 18:52  Prévisualiser...   Imprimer...   Haut
Ping Bots  -  par FSMOD

Pings Bots

Quelques lignes de code juste pour attribuer un pseudo ping aux bots. Je dis 'pseudo' car ce ping aléatoire au gré des parties, n'affectera en rien leur ping réel qui restera à zéro au regard d'internet. Ce ping artificiel n'apparaitra que dans le panel des scores.

Il existe un autre codage qui permet de leur attribuer un ping réel et falsifier ainsi les statistiques d'un serveur traceur comme GameTracker mais là n'est pas l'objet de ce développement.

Modification du code sources

Fichier g_local.h

Après

 extern    vmCvar_t    g_refereePass;

Ajouter

 extern     vmCvar_t g_botPing;  // *FSMOD* ping aléatoire bots

Fichier g_main.c

Après

 vmCvar_t    g_refereePass;

Ajouter

 vmCvar_t    g_botPing;   // *FSMOD* ping aléatoire bot

Après

 { &g_refereePass, "g_refereePass", "none", CVAR_INTERNAL|CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },

Ajouter

{ &g_botPing, "g_botPing", "0",  CVAR_ARCHIVE, 0, qfalse }, // *FSMOD* ping aléatoire bots 

Fichier g_bot.c

Recherchez la fonction G_CountBotPlayers

La remplacer par la suivante

 

/*
===============
G_CountBotPlayers
===============
*/
int G_CountBotPlayers( int team )
{
    int            i;
    int            n;
    int            num;
    gclient_t      *cl;

    num = 0;

    for ( i=0 ; i< g_maxclients.integer ; i++ )
    {
        cl = level.clients + i;
        if ( cl->pers.connected != CON_CONNECTED )
        {
            continue;
        }

        if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) )
        {
            continue;
        }

        if ( team >= 0 && cl->sess.team != team )
        {
            continue;
        }

        if (g_botPing.integer )
        {
            cl->ps.ping = Q_irand(12, 87);  //  *FSMOD* Ping aléatoire pour bots
        }

            num++;

    }

    for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ )
    {
        if( !botSpawnQueue[n].spawnTime )
        {
            continue;
        }

        if ( botSpawnQueue[n].spawnTime > level.time )
        {
            continue;
        }

        if (g_botPing.integer )
        {
            cl->ps.ping = Q_irand(12, 87);  //  *FSMOD* Ping aléatoire pour bots
        }

        num++;


    }

    return num;
}

Le CVAR g_botPing qui commande la fonction, est en "read only memory". Un changement de la valeur binaire de celui-ci (1 ou 0), ne sera effectif qu'à la rotation de la map.

-=cry=-

Publié le 09/03/2019 16:52  Prévisualiser...   Imprimer...   Haut
Poids des armes  -  par FSMOD

POIDS DES ARMES

Une anomalie propre à SOF2 consiste à ne pas prendre en compte le poids de l'arme dans les mouvements du joueur qui la porte. Ainsi un joueur qui tient un M60 de plus de 10 kilos se meut aussi rapidement que celui qui tient un couteau de 100 grammes. La hauteur des sauts n'est pas non plus affectée par cette différence.

Les codes qui suivent rétablissent la bonne proportion.

Modifications du code sources

Fichier g_local.h

Après

 #define    FOFS(x) ((int)&(((gentity_t *)0)->x))

Ajouter

 

//Ajustement speed et gravity en fonction du poids de l'arme *FSMOD*

extern    vmCvar_t   g_wpnMove; // commande générale

extern    vmCvar_t   g_knifeSpeed;
extern    vmCvar_t   g_coltSpeed;
extern    vmCvar_t   g_socomSpeed;
extern    vmCvar_t   g_talonSpeed;
extern    vmCvar_t   g_shotgunSpeed;
extern    vmCvar_t   g_uziSpeed;
extern    vmCvar_t   g_m3a1Speed;
extern    vmCvar_t   g_mp5Speed;
extern    vmCvar_t   g_usasSpeed;
extern    vmCvar_t   g_m4Speed;
extern    vmCvar_t   g_ak74Speed;
extern    vmCvar_t   g_sigSpeed;
extern    vmCvar_t   g_sniperSpeed;
extern    vmCvar_t   g_m60Speed;
extern    vmCvar_t   g_mm1Speed;
extern    vmCvar_t   g_rpgSpeed;
extern    vmCvar_t   g_m84Speed;
extern    vmCvar_t   g_smohgSpeed;
extern    vmCvar_t   g_m15Speed;
extern    vmCvar_t   g_anm14Speed;

extern    vmCvar_t   g_knifeGravity;
extern    vmCvar_t   g_coltGravity;
extern    vmCvar_t   g_socomGravity;
extern    vmCvar_t   g_talonGravity;
extern    vmCvar_t   g_shotgunGravity;
extern    vmCvar_t   g_uziGravity;
extern    vmCvar_t   g_m3a1Gravity;
extern    vmCvar_t   g_mp5Gravity;
extern    vmCvar_t   g_usasGravity;
extern    vmCvar_t   g_m4Gravity;
extern    vmCvar_t   g_ak74Gravity;
extern    vmCvar_t   g_sigGravity;
extern    vmCvar_t   g_sniperGravity;
extern    vmCvar_t   g_m60Gravity;
extern    vmCvar_t   g_mm1Gravity;
extern    vmCvar_t   g_rpgGravity;
extern    vmCvar_t   g_m84Gravity;
extern    vmCvar_t   g_smohgGravity;
extern    vmCvar_t   g_m15Gravity;
extern    vmCvar_t   g_anm14Gravity;


// Fin *FSMOD*

Fichier g_main.c

Après

 vmCvar_t    g_explosionGore;

Ajouter

 

// Ajustement speed et gravity en fonction du poids de l'arme *FSMOD*

vmCvar_t   g_wpnMove;

vmCvar_t   g_knifeSpeed;
vmCvar_t   g_coltSpeed;
vmCvar_t   g_socomSpeed;
vmCvar_t   g_talonSpeed;
vmCvar_t   g_shotgunSpeed;
vmCvar_t   g_uziSpeed;
vmCvar_t   g_m3a1Speed;
vmCvar_t   g_mp5Speed;
vmCvar_t   g_usasSpeed;
vmCvar_t   g_m4Speed;
vmCvar_t   g_ak74Speed;
vmCvar_t   g_sigSpeed;
vmCvar_t   g_sniperSpeed;
vmCvar_t   g_m60Speed;
vmCvar_t   g_mm1Speed;
vmCvar_t   g_rpgSpeed;
vmCvar_t   g_m84Speed;
vmCvar_t   g_smohgSpeed;
vmCvar_t   g_m15Speed;
vmCvar_t   g_anm14Speed;

vmCvar_t   g_knifeGravity;
vmCvar_t   g_coltGravity;
vmCvar_t   g_socomGravity;
vmCvar_t   g_talonGravity;
vmCvar_t   g_shotgunGravity;
vmCvar_t   g_uziGravity;
vmCvar_t   g_m3a1Gravity;
vmCvar_t   g_mp5Gravity;
vmCvar_t   g_usasGravity;
vmCvar_t   g_m4Gravity;
vmCvar_t   g_ak74Gravity;
vmCvar_t   g_sigGravity;
vmCvar_t   g_sniperGravity;
vmCvar_t   g_m60Gravity;
vmCvar_t   g_mm1Gravity;
vmCvar_t   g_rpgGravity;
vmCvar_t   g_m84Gravity;
vmCvar_t   g_smohgGravity;
vmCvar_t   g_m15Gravity;
vmCvar_t   g_anm14Gravity;

// Fin *FSMOD*

Après

 { &g_motd10, "g_motd10", "", 0, 0.0f, 0.0f, 0, qfalse },

Ajouter

 

// Ajustement speed et gravity en fonction du poids de l'arme *FSMOD*

   { &g_wpnMove, "g_wpnMove", "0",CVAR_SERVERINFO|CVAR_ARCHIVE, 0, 0, qfalse },

   { &g_knifeSpeed, "g_knifeSpeed", "1", 0, 0, qfalse },
   { &g_coltSpeed, "g_coltSpeed", "0.95", 0, 0, qfalse },
   { &g_socomSpeed, "g_socomSpeed", "0.95", 0, 0, qfalse },
   { &g_talonSpeed, "g_talonSpeed", "0.95", 0, 0, qfalse },
   { &g_shotgunSpeed, "g_shotgunSpeed", "0.9", 0, 0, qfalse },
   { &g_uziSpeed, "g_uziSpeed", "0.9", 0, 0, qfalse },
   { &g_m3a1Speed, "g_m3a1Speed", "0.9", 0, 0, qfalse },
   { &g_mp5Speed, "g_mp5Speed", "0.9", 0, 0, qfalse },
   { &g_usasSpeed, "g_usasSpeed", "0.9", 0, 0, qfalse },
   { &g_m4Speed, "g_m4Speed", "0.8", 0, 0, qfalse },
   { &g_ak74Speed, "g_ak74Speed", "0.78", 0, 0, qfalse },
   { &g_sigSpeed, "g_sigSpeed", "0.75", 0, 0, qfalse },
   { &g_sniperSpeed, "g_sniperSpeed", "0.70", 0, 0, qfalse },
   { &g_m60Speed, "g_m60Speed", "0.6", 0, 0, qfalse },
   { &g_mm1Speed, "g_mm1Speed", "0.78", 0, 0, qfalse },
   { &g_rpgSpeed, "g_rpgSpeed", "0.7", 0, 0, qfalse },
   { &g_m84Speed, "g_m84Speed", "1", 0, 0, qfalse },
   { &g_smohgSpeed, "g_smohgSpeed", "1", 0, 0, qfalse },
   { &g_m15Speed, "g_m15Speed", "1", 0, 0, qfalse },
   { &g_anm14Speed, "g_anm14Speed", "1", 0, 0, qfalse },

   { &g_knifeGravity, "g_knifeGravity", "1", 0, 0, qfalse },
   { &g_coltGravity, "g_coltGravity", "1", 0, 0, qfalse },
   { &g_socomGravity, "g_socomGravity", "1", 0, 0, qfalse },
   { &g_talonGravity, "g_talonGravity", "1", 0, 0, qfalse },
   { &g_shotgunGravity, "g_shotgunGravity", "1", 0, 0, qfalse },
   { &g_uziGravity, "g_uziGravity", "1", 0, 0, qfalse },
   { &g_m3a1Gravity, "g_m3a1Gravity", "1", 0, 0, qfalse },
   { &g_mp5Gravity, "g_mp5Gravity", "1", 0, 0, qfalse },
   { &g_usasGravity, "g_usasGravity", "1", 0, 0, qfalse },
   { &g_m4Gravity, "g_m4Gravity", "1", 0, 0, qfalse },
   { &g_ak74Gravity, "g_ak74Gravity", "1", 0, 0, qfalse },
   { &g_sigGravity, "g_sigGravity", "1", 0, 0, qfalse },
   { &g_sniperGravity, "g_sniperGravity", "1.1", 0, 0, qfalse },
   { &g_m60Gravity, "g_m60Gravity", "1.5", 0, 0, qfalse },
   { &g_mm1Gravity, "g_mm1Gravity", "1.2", 0, 0, qfalse },
   { &g_rpgGravity, "g_rpgGravity", "1.4", 0, 0, qfalse },
   { &g_m84Gravity, "g_m84Gravity", "1", 0, 0, qfalse },
   { &g_smohgGravity, "g_smohgGravity", "1", 0, 0, qfalse },
   { &g_m15Gravity, "g_m15Gravity", "1", 0, 0, qfalse },
   { &g_anm14Gravity, "g_anm14Gravity", "1", 0, 0, qfalse },

// Fin *FSMOD*

Fichier g_active.c

Dans la fonction ClientThink, après

 client->ps.speed = g_speed.value;

Ajouter

 

// Ajustement speed et gravity en fonction du poids de l'arme *FSMOD*


if ( g_wpnMove.integer)
  {

      switch(client->ps.weapon) {
      case WP_KNIFE:
         client->ps.speed *= g_knifeSpeed.value;
         break;
      case WP_M1911A1_PISTOL:
         client->ps.speed *= g_coltSpeed.value;
         break;
      case WP_USSOCOM_PISTOL:
         client->ps.speed *= g_socomSpeed.value;
         break;
      case WP_SILVER_TALON:
         client->ps.speed *= g_talonSpeed.value;
         break;
      case WP_M590_SHOTGUN:
         client->ps.speed *= g_shotgunSpeed.value;
         break;
      case WP_MICRO_UZI_SUBMACHINEGUN:
         client->ps.speed *= g_uziSpeed.value;
         break;
      case WP_M3A1_SUBMACHINEGUN:
         client->ps.speed *= g_m3a1Speed.value;
         break;
      case WP_MP5:
         client->ps.speed *= g_mp5Speed.value;
         break;
      case WP_USAS_12_SHOTGUN:
         client->ps.speed *= g_usasSpeed.value;
         break;
      case WP_M4_ASSAULT_RIFLE:
         client->ps.speed *= g_m4Speed.value;
         break;
      case WP_AK74_ASSAULT_RIFLE:
         client->ps.speed *= g_ak74Speed.value;
         break;
      case WP_SIG551:
         client->ps.speed *= g_sigSpeed.value;
         break;
      case WP_MSG90A1:
         client->ps.speed *= g_sniperSpeed.value;
         break;
      case WP_M60_MACHINEGUN:
         client->ps.speed *= g_m60Speed.value;
         break;
      case WP_MM1_GRENADE_LAUNCHER:
         client->ps.speed *= g_mm1Speed.value;
         break;
      case WP_RPG7_LAUNCHER:
         client->ps.speed *= g_rpgSpeed.value;
         break;
      case WP_M84_GRENADE:
         client->ps.speed *= g_m84Speed.value;
         break;
      case WP_SMOHG92_GRENADE:
         client->ps.speed *= g_smohgSpeed.value;
         break;
      case WP_ANM14_GRENADE:
         client->ps.speed *= g_m15Speed.value;
         break;
      case WP_M15_GRENADE:
         client->ps.speed *= g_anm14Speed.value;
         break;
      default:
         break;
   };


      switch(client->ps.weapon) {
      case WP_KNIFE:
         client->ps.gravity *= g_knifeGravity.value;
         break;
      case WP_M1911A1_PISTOL:
         client->ps.gravity *= g_coltGravity.value;
         break;
      case WP_USSOCOM_PISTOL:
         client->ps.gravity *= g_socomGravity.value;
         break;
      case WP_SILVER_TALON:
         client->ps.gravity *= g_talonGravity.value;
         break;
      case WP_M590_SHOTGUN:
         client->ps.gravity *= g_shotgunGravity.value;
         break;
      case WP_MICRO_UZI_SUBMACHINEGUN:
         client->ps.gravity *= g_uziGravity.value;
         break;
      case WP_M3A1_SUBMACHINEGUN:
         client->ps.gravity *= g_m3a1Gravity.value;
         break;
      case WP_MP5:
         client->ps.gravity *= g_mp5Gravity.value;
         break;
      case WP_USAS_12_SHOTGUN:
         client->ps.gravity *= g_usasGravity.value;
         break;
      case WP_M4_ASSAULT_RIFLE:
         client->ps.gravity *= g_m4Gravity.value;
         break;
      case WP_AK74_ASSAULT_RIFLE:
         client->ps.gravity *= g_ak74Gravity.value;
         break;
      case WP_SIG551:
         client->ps.gravity *= g_sigGravity.value;
         break;
      case WP_MSG90A1:
         client->ps.gravity *= g_sniperGravity.value;
         break;
      case WP_M60_MACHINEGUN:
         client->ps.gravity *= g_m60Gravity.value;
         break;
      case WP_MM1_GRENADE_LAUNCHER:
         client->ps.gravity *= g_mm1Gravity.value;
         break;
      case WP_RPG7_LAUNCHER:
         client->ps.gravity *= g_rpgGravity.value;
         break;
      case WP_M84_GRENADE:
         client->ps.gravity *= g_m84Gravity.value;
         break;
      case WP_SMOHG92_GRENADE:
         client->ps.gravity *= g_smohgGravity.value;
         break;
      case WP_ANM14_GRENADE:
         client->ps.gravity *= g_m15Gravity.value;
         break;
      case WP_M15_GRENADE:
         client->ps.gravity *= g_anm14Gravity.value;
         break;
      default:
         break;

      };

  }


// Fin *FSMOD*

Les coefficients speed et gravity paramétrés par défaut peuvent être revus et adaptés à votre convenance dans le fichier de configuration du serveur, comme l'exemple ci-dessous propre à mon serveur:

seta g_wpnMove  1  // valide les coeff g_speed et g_gravity en fonction de l'arme (0 par défaut)
 
seta g_knifespeed          1     //"1"
seta g_coltspeed          0.96  //"0.95"
seta g_socomspeed         0.96  //"0.95"
seta g_talonspeed         0.94  //"0.95"
seta g_shotgunspeed       0.9   //"0.9"
seta g_uzispeed           0.9   //"0.9"
seta g_m3a1speed          0.85  //"0.9"
seta g_mp5speed           0.89  //"0.9"
seta g_usasspeed          0.83  //"0.9"
seta g_m4speed            0.84  //"0.8"
seta g_ak74speed          0.85  //"0.78"
seta g_sigspeed           0.91  //"0.75"
seta g_sniperspeed        0.81  //"0.70"
seta g_m60speed           0.6   //"0.6"
seta g_mm1speed           0.80  //"0.78"
seta g_rpgspeed           0.72  //"0.7"
seta g_m84speed           0.99  //"1"
seta g_smohgspeed         0.99  //"1"
seta g_m15speed           0.98  //"1"
seta g_anm14speed         0.97  //"1"

seta g_knifegravity       1     //"1"
seta g_coltgravity        1.11  //"1"
seta g_socomgravity       1.10  //"1"
seta g_talongravity       1.14  //"1"
seta g_shotgungravity     1.20  //"1"
seta g_uzigravity         1.21  //"1"
seta g_m3a1gravity        1.26  //"1"
seta g_mp5gravity         1.19  //"1"
seta g_usasgravity        1.32  //"1"
seta g_m4gravity          1.30  //"1"
seta g_ak74gravity        1.31  //"1"
seta g_siggravity         1.21  //"1"
seta g_snipergravity      1.36  //"1.1"
seta g_m60gravity         1.70  //"1.5"
seta g_mm1gravity         1.34  //"1.2"
seta g_rpggravity         1.50  //"1.4"
seta g_m84gravity         1.05  //"1"
seta g_smohggravity       1.05  //"1"
seta g_m15gravity         1.08  //"1"
seta g_anm14gravity       1.09  //"1"

Les valeurs après les les doubles slashes représentent les valeurs par défaut inscrites dans le code.

Enfin pour les puristes voici un tableau récapitulatif sur le poids approximatif  des armes, leur coefficient speed/gravity et leur impact sur la vitesse et la gravité induites, sur des bases respectives de 340 et 500.
Ces valeurs de base peuvent bien sûr être modifiées dans votre configuration serveur. Les valeurs induites seront toujours proportionnelles en fonction des coefficients attribués.

Le poids du couteau sert de référence basique pour le reste des armes.

ARME POIDS en kg Coef speed Coef gravity Speed (340) Gravity (500)
Knife 0,120 1 1 340 500
Colt 1,2 0,96 1,11 326 555
Socom 1 0,96 1,10 326 550
Talon 1,7 0,94 1,14 319 570
Shotgun 3 0,90 1,20 306 600
Uzi 4,45 0,85 1,26 289 630
M3A1 4,45 0,85 1,26 289 630
MP5 2,9 0,89 1,19 302 595
USAS 5,45 0,83 1,32 282 660
M4 5 0,84 1,30 285 650
AK47 5,1 0,85 1,31 289 655
SIG 3,3 0,91 1,21 309 605
Sniper 6,20 0,81 1,36 275 680
M60 13 0,60 1,70 204 850
MM1 5,7 0,80 1,34 272 670
RPG7 9 0,72 1,50 244 750
M84 0,250 0,99 1 05 336 525
SMOGH 0,270 0,99 1,05 336 525
M15 0,850 0,98 1 08 333 540
ANM14 0,900 0,98 1,09 329 545

-=smile=-

Publié le 09/03/2019 14:53  Prévisualiser...   Imprimer...   Haut
Fonction Scanner  -  par FSMOD

La fonction scanner

A l'instar du défunt PunkBuster, la fonction scanner de ROCmod examine les fichiers des joueurs et effectue des comparaisons pour s’assurer que ces fichiers n’ont pas été modifiés ou remplacés. Ces opérations sont conduites selon l'algorithme de cryptage MD5.
Cependant, contrairement à l’outil MD5 de PunkBuster qui ne peut scanner que les fichiers pk3 dans leur globalité, la fonction scanning examine les fichiers individuellement.

Si un joueur a installé un fichier pk3 visant à modifier un skin ou un modèle d'arme particulier, modifiant ainsi l'empreinte numérique de sa valeur par défaut, la fonction scanning détectera l'incohérence et émettra un signal au serveur.
A ce stade il convient de préciser que ces modifications de skins affectent tout particulièrement les fichiers shaders. Certains scripts peuvent même rendre des aspects tellement brillants ou scintillants, appelés glowskin, qu'ils trahissent immanquablement la position des cibles.
Si les scripts sont encore plus élaborés ils peuvent rendre la cible visible à travers les obstacles. Ces extrêmes s'apparentent alors à une véritable tricherie.
C'est donc le scanning des fichiers shaders qui fera l'objet d'une attention particulière. Il est, bien entendu, tout à fait possible de configurer d'autres types de fichiers comme des maps, des models, des textures, des scripts, etc...


Dans la version 2.2v les shaders ont été légèrement recodés de manière à améliorer la matité des joueurs tout en leur attribuant une certaine notion de relief. Il n'y pas là, matière à qualifier ce petit artifice, de triche, n'en déplaise aux puristes intellectuellement étriqués.

Rocmod 2.1c Rocmod 2.2v
shadorig.jpg shadmod.jpg

Le scanning de fichiers est entièrement configurable sur le serveur, par le biais du fichier scanlist.cfg. Il suffit de définir quels seront les shaders visés ainsi que les options choisies en cas d'inéquation serveur/client.


Le fichier scanlist.cfg a le format suivant :

[action] [clef MD5] [nom du fichier]

Exemple:

a 8EEC06E5835BBC3EEB8F5E644994E2D6 shaders/effects.shader

Notez que le nom du fichier doit inclure son arborescence complète.

Chaque ligne commence par une action définie comme suit:

  • k   Le joueur est éjecté du serveur
  • m   Diffusion d'un message d’avertissement à tous les joueurs du serveur
  • a   Diffusion d’un avertissement à tous les administrateurs du serveur
  • l    Aucune action mais enregistrement dans le fichier scanner.log du serveur

Chaque fois qu’une asymétrie est détectée entre la valeur MD5 stockée dans le fichier cfg et la valeur retournée par le client, l’action prévue est validée.
Il existe de nombreux programmes disponibles pour calculer la valeur MD5 d’un fichier.
Personnellement j'utilise MD5 Calculator que vous trouverez en téléchargement sur le site.

Afin de vous éviter des codages fastidieux je vous livre ICI la liste complète de tous les shaders originels de SOF2 associés à leur cryptage MD5.

Comme tous les fichiers de configurations SOF2, le fichier scanlist.cfg a des limites Il autorise un maximum de 1024 entrées, et un poids total de 64k maximum. Il est donc conseillé de ne pas joindre tous les shaders dans ce fichiers, mais plutôt choisir les plus importants comme ceux qui sont les plus affectés par les scripts de triche. Ce sont les suivants:

 b9cd3323fbc56d99431fd84a1564e882 shaders/average_armor.shader
 1e7bc7b37a947f9adf78f4c2dbe39c55 shaders/average_sleeves.shader
 d0d5b200265cea08ae4fd1b87cb5736c shaders/bolt_ons.shader
 4f308e94750f8943182096922cc17e49 shaders/chem_suit.shader
 4de825bfd8e490b8b06c205505c26735 shaders/common.shader
 77f230fb6242676a638cf2cad1cf405b shaders/fat.shader
 4e27ca88e61446799f38ef7fe6b52278 shaders/female_armor.shader
 df18be9d6e25bdf3c521e09cad8871c4 shaders/female_pants.shader
 4355ab860469feee3c327a7c2cf8be1c shaders/female_skirt.shader
 acb4cc30c12a9d0cb86455545e1875b2 shaders/snow.shader
 7e16a82229238e918cedebf36e6e18ad shaders/suit_long_coat.shader
 57119dc252b4a4eea94927a9d21a080f shaders/suit_sleeves.shader
 b530dfdbfbb09989028adc0d41d21d33 shaders/weapons.shader

Notez également que certains fichiers sont automatiquement modifiés par Rocmod ou par quelques maps (comme gfx.shader) aussi le scanning de la version originale de ces fichiers échouera toujours.
Il est important de spécifier que le client doit posséder la même version client que celle qui est installée en référencement sur le serveur afin que les résultats du scanning soient probants. Les clients qui ne possèdent pas la bonne version ne pourront pas faire l'objet d'un scanning efficient.
Coté serveur, le CVAR g_verifyClients doit être activé, et il est recommandé d'activer également les options de ce CVAR pour avertir et éventuellement sanctionner les joueurs qui n’auraient pas la bonne version client.

La saine gestion d'un serveur est à ce prix.

Pour dédramatiser ce sujet, if est nécessaire de nuancer l'examen des résultats obtenus suite au scanning d'un client qui aurait révélé des discordances. Tous les shaders modifiés ne sont pas synonymes de triche avérée. Certains skins visant à modifier l'aspect des armes ou des tenues sont totalement inoffensifs et n'apportent qu'une touche de personnalisation pour des joueurs anticonformistes.
La détection d'une dissymétrie serveur/client ne pourra générer chez un Admin consciencieux qu'un sentiment de doute mais ne devrait pas le conduire à procéder à une éradication systématique d'un joueur.
Comme en Justice, le bénéfice du doute devrait être accordé au prévenu.
frown  

Un dernier avertissement
Le scanning des joueurs, car ce sont bien tous les joueurs qui sont concernés, aucun ne pouvant être visé particulièrement, peut amener à des latences du serveur en fonction du nombre de joueurs, du nombre de shaders concernés et des CVARS liés au scan. Il sera donc judicieux d'activer la fonction scanner sporadiquement lorsqu'un Sysop aura détecté un joueur douteux.
Faut-il encore qu'un Sysop soit présent.
Plutôt que d'utiliser le CVAR g_scannerInterval évoqué ci-après, j'ai créé dans ma version 2.2, le CVAR g_scanAllow dont les codes sources sont disponibles en rubrique CODAGE sur le présent site.
Il permet par un simple bind, d'activer ou désactiver la fonction scanning

new.gif CVARS liés à la fonction scanner:

g_scannerInterval
    défaut: 0
    info  : Fixe en secondes l'intervalle entre chaque requête envoyée par le serveur vers les joueurs.
              Une valeur trop faible peut provoquer des pertes de données retour et engendrer des latences pour les joueurs.
              Mise à 0, la fonction scanning est désactivée. Une valeur voisine de 10 est correcte. A tester toutefois.
    
    
g_scannerRepeat
    défaut: 3
    info  : Fixe le nombre de fois où une requête de scanning sera répétée avant de constater qu'il n'y a pas de discordance.
               Détermine également le nombre de fois où les messages d'avertissement seront diffusés avant de reprendre le scan.           

Et pour terminer un petit extrait de mon fichier scanner.log :

logd.jpg

-=tongue=-

Publié le 07/03/2019 17:44  Prévisualiser...   Imprimer...   Haut
Scanner  -  par FSMOD

CVAR g_scanAllow

Ce CVAR permet d'activer ou désactiver plus aisément la fonction SCANNER

Modification du code sources

Fichier g_local.h

Après

  extern    vmCvar_t    g_allowAdminGhost;

Ajouter

  extern vmCvar_t g_scanAllow;  //*FSMOD*

Fichier g_main.c

Après

 vmCvar_t    g_allowAdminGhost;

Ajouter

 vmCvar_t    g_scanAllow; //*FSMOD*

Après

  { &g_allowAdminGhost, "g_allowAdminGhost", "0", CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse },

Ajouter

 { &g_scanAllow, "g_scanAllow", "0", CVAR_SERVERINFO | CVAR_ARCHIVE, 0.0f, 0.0f, 0, qfalse }, //*FSMOD*

Fichier g_active.c

Rechercher dans la fonction ClientThink la ligne suivante

if ( level.time > client->sess.modData->scanTimer && g_scannerInterval.integer &&   !client->sess.modData->scanPaused && client->sess.modData->versionVerified && scanlist.scanListCount )

La remplacer par

if ( level.time > client->sess.modData->scanTimer && g_scannerInterval.integer && g_scanAllow.integer &&  !client->sess.modData->scanPaused && client->sess.modData->versionVerified && scanlist.scanListCount ) //*FSMOD*

-=smile=-

Publié le 07/03/2019 17:42  Prévisualiser...   Imprimer...   Haut
Seta name et boucles VSTR  -  par FSMOD
SETA NAME ET BOUCLES VSTR

Lorsque vous définissez votre pseudo dans votre fichier de configuration vous avez certainement écrit  ce genre de texte:

seta name "Mon Pseudo Il Est Bo"

Je n'ai mis aucune couleur de manière à être plus lisible. Vous remarquerez les intervalles entre chaque mot du pseudo. Ce type de libellé restitue parfaitement le texte, espaces inclus, tout au long du jeu et ne crée aucun bug.

Maintenant on admet que vous désirez changer de pseudo durant la partie. J'ai évoqué la méthode dans ma doc qui consiste a utiliser une boucle VSTR mais j'ai toutefois omis de préciser un point important.

Considérons la boucle suivante
Comme précisé plus haut, je n'ai pas mis de caractères de couleur pour une meilleure lisibilité.


 
       bind n "vstr nom00"

     set nom00 "seta name Amigo ; bind n vstr nom01"
     set nom01 "seta name Bandit  Manchot ; bind n vstr nom02"
     set nom02 "seta name BloodyMary ; bind n vstr nom03"
     set nom03 "seta name Aristocrate ; bind n vstr nom00"

Chaque pression sur la touche n doit normalement appeler le pseudo suivant. Pour la première action le pseudo Amigo se substituera a votre pseudo initial
Par contre l'action suivante n'affichera pas Bandit Manchot mais enverra en haut de votre écran le message suivant :
 
shot0170.jpg



Pourquoi?

 
Très simple. A l'instar de la nature, SOF2 a horreur du vide. Ainsi l'espace dans le pseudo Bandit Manchot présentera une phase blocante dans la boucle.

Remède:

Soit éviter les noms composés dans les boucles VSTR ou combler les espaces par un underscore, un tilde ou tout autre caractère. Le pseudo Bandit~Manchot, ainsi modifié rétablira le fonctionnement de la boucle.

Une autre solution plus adéquate consistera à introduire des doubles croches supplémentaires en début et fin du nom composé. Ainsi la boucle VSTR pourra s'écrire ainsi:

     bind n "vstr nom00"

     set nom00 "seta name Amigo ; bind n vstr nom01"
     set nom01 "seta name "Bandit Manchot" ; bind n vstr nom02"
     set nom02 "seta name BloodyMary ; bind n vstr nom03"
     set nom03 "seta name Aristocrate ; bind n vstr nom00"



Par ailleurs le délai de 10s que j'ai fixé n'invalide pas l'incrémentation de la boucle.
Ce qui veut dire que pendant les 10s d'attente, chaque fois que la touche n sera pressée, la boucle avancera d'un cran. Au résultat, à l'issue des 10s lorsque le programme valide le changement, l'action sur n générera le pseudo présent et non celui que l'on s'attendait à voir normalement dans la suite logique de la boucle.
 
N'en soyez donc pas surpris.

-=smile=-
Publié le 05/02/2019 18:03  Prévisualiser...   Imprimer...   Haut
Pack sons et serveurs  -  par FSMOD
SERVEURS ET PACK SONS


Problématique

Si vous jouez sur plusieurs serveurs vous serez peut-être tenté de charger les packs sons propres à chaque serveur et de les installer dans votre répertoire BASE. Cela ne posera pas de problème dans la mesure où les 83 sons standards sont généralement repris dans chaque pack. Cela vous permet d'utiliser vos binds configurés sur ces 83 sons quelque soit le serveur. Il n'y a éventuellement que la couleur et la présentation des textes associés qui pourront varier.

Cependant j'ai rencontré quelques serveurs, qui par ignorance ou égoïsme introduisent leurs propres sons dans la plage des 83 premiers. Effet déplorable car votre bind, qui d'habitude envoie les félicitations à votre assassin, lui décochera peut-être à la place un fuck you des plus agressifs.

Au delà des 83 sons, chaque clan offre un panel très large et très varié de ses conceptions sonores. Les sons suivants sont donc numérotés à partir de 84 et peuvent aller jusqu'à 1024 sur la version originale de ROCmod (ma version ROCmod 2.2v peut admettre 2048 sons). C'est donc dans cette plage supérieure que les problèmes se présentent d'un serveur à l'autre.

Admettons que vous avez bindé la touche F1 sur le son numéro 400 du serveur X. Vous obtiendrez un son X et un texte X qui ne correspondront certainement pas avec le son et le texte 400 du serveur Y.

Solution
 
Elle consiste tout d'abord à installer le pack sons de chaque serveur concerné sur lequel vous vous connectez, dans le ou les répertoires dédiés à un mode du serveur. Par exemple si vous jouez sur mon serveur, il conviendra de placer mon pack sons dans votre répertoire ROCMOD. Au même titre si vous joignez un serveur tournant sous GOLDRUSH, le pack sons sera placé dans votre répertoire GOLDRUSH.
Si d'autres serveurs utilisent ROCMOD, leurs pack sons respectifs pourront également être placés dans votre répertoire ROCMOD.  Tout ceci dans un souci de clarté dans l'ordonnancement et l'accès de vos fichiers.

Ensuite il est nécessaire de concevoir pour chaque serveur un fichier txt renfermant tous vos binds.
Lorsque vous connectez un de vos serveurs favoris, le mien pourquoi pas (LOL), il suffit de taper en mode console, exec fsmod_sound.txt ,en admettant que vos binds liés à mon serveur soient inclus dans un fichier que vous aurez baptisé fsmod_sounds.txt.

Cette méthode est correcte, toutefois elle n'est valable que dans le cas où vous quittez SOF entre chaque connexion vers un nouveau serveur. En effet, l'exécution d'un fichier vient abonder la mémoire de votre jeu et le fait d'effectuer une simple déconnexion puis reconnexion à un autre serveur, ne réinitialise pas la mémoire. Des lancements cumulatifs de fichier exe peuvent conduire à un plantage.

Cas d'un changement de serveur sous un autre mode

Si vous incluez dans votre fichier autoexec.cfg, outre vos fichiers de configuration générale, le fichier fsmod_sound.txt, pour reprendre l'exemple précédent et que vous connectiez mon serveur tournant sous ROCMOD, tout se passera bien. En effet ce fichier sera lancé automatiquement par l'autoexec et vous bénéficierez de vos binds .
Maintenant si vous désirez quitter mon serveur pour connecter un autre serveur sous GOLDRUSH par une simple déconnexion et que vous lanciez en mode console le fichier gold_sound.txt, en supposant que ce dernier fichier renferme vos binds liés à ce serveur, il peut se produire un beau plantage. 

Explication:

Lorsque vous lancez SOF, le pointeur va d'abord lire le contenu du répertoire MP et l'exécuter. Il parcourra ensuite le répertoire BASE pour charger les maps et les fichiers pk3 système.
Pour terminer il exécutera les fichiers du mode choisi dans votre raccourci de lancement (ROCMOD par exemple)
Si vous changez de serveur et de mode (GOLDRUSH pour poursuivre l'exemple) par une simple déconnexion puis reconnexion, le pointeur exécutera directement les fichiers du répertoire GOLDRUSH en écrasant de la mémoire les fichiers du mode précédent. Par contre les fichiers du répertoire MP, resteront dans la mémoire et de leur taille dépendra un éventuel plantage si d'aventure vous lanciez un nouveau fichier txt. Simple non ?

La bonne méthode

Elle consiste simplement à créer autant d'icônes de raccourci que de serveurs sur lesquels vous avez coutume de jouer. Chaque raccourci renfermera l'essentiel des configurations respectives. Ainsi vous serez toujours obligés de quitter SOF pour reconnecter un nouveau serveur, par un clic sur l'icône de votre choix, ce qui aura pour effet et non des moindres, de réinitialiser proprement les mémoires.


 

-=biggrin=-

Publié le 05/02/2019 18:02  Prévisualiser...   Imprimer...   Haut
HLSW multiple  -  par FSMOD
HLSW MULTIPLE
 

Bien qu'à l'origine dédié à Half Life, HLSW demeure néanmoins  un très bon outil pour surveiller et piloter les serveurs SOF2, entre autres.
Toutefois, il présente un léger défaut, en l'occurrence l'impossibilité de gérer plusieurs serveurs à la fois.


Il existe une astuce très simple pour contourner cette lacune.


Dans le répertoire HLSW, il suffit de créer plusieurs exécutables identiques à l'exécutable d'origine  hlsw.exe et de les baptiser différemment..
 

Comme cet exemple

screen.png

Créer autant d'icônes de raccourcis sur le bureau.
Lancer ensuite tous les raccourcis.

Il vous suffira d'agencer vos fenêtres en fonction de vos préférences et de la taille de votre moniteur.
Personnellement je lance 3 applications d'HLSW en même temps et je les affiche sur un deuxième moniteur.


3_hlsw.jpg

=smile=-
Publié le 05/02/2019 18:01  Prévisualiser...   Imprimer...   Haut
Rubriques

Vous êtes ici :   Accueil » Documentation