Bienvenue sur JeuxOnLine - MMO, MMORPG et MOBA !
Les sites de JeuxOnLine...
 

Panneau de contrôle

Recherche | Retour aux forums

JOL Archives

[script de sécurité indispensable] Validation des personnages à l'entrée d'un module

Par Lumina le 1/7/2002 à 23:34:44 (#1742010)

J'ai trouvé une parade contre les abus qui permettent à l'heure actuelle de passer au travers des deux filtres officiels "Enforce Legal Characters" et "Item Level Restrictions".

Il s'agit d'un script à placer dans votre module dans :
- module properties
- Events
- OnClientEnter

Le voici :

// validation du personnage et de son inventaire
// à l'arrivée sur le module (pour NwN v1.19)
// auteur : Lumina
// création : 1 Juillet 2002
// derniere modification : 2 Juillet 2002 (v1.0 #3)
// module properties -> Events -> OnClientEnter

void valid_slot(int nInventorySlot, object oPC)
{
object oItem = GetItemInSlot(nInventorySlot, oPC);
if (GetIsObjectValid(oItem) && GetPlotFlag(oItem))
{
SetPlotFlag(oItem, 0);
// vérifie pour chaque objet qu'il puisse etre équipé normalement
AssignCommand(oPC, ActionUnequipItem(oItem));
AssignCommand(oPC, ActionEquipItem(oItem, nInventorySlot));
}
}

void destroy_slot(int nInventorySlot, object oPC)
{
object oItem = GetItemInSlot(nInventorySlot, oPC);
if (GetIsObjectValid(oItem))
{
DestroyObject(oItem);
}
}

void main()
{
object oPC = GetEnteringObject();
if (GetIsPC(oPC))
{
// retire le flag PLOT du personnage
if (GetPlotFlag(oPC)) { SetPlotFlag(oPC, 0); }
// retire le flag PLOT de chaque objet de l'inventaire
object oItem = GetFirstItemInInventory(oPC);
while (GetIsObjectValid(oItem))
{
if (GetPlotFlag(oItem)) { SetPlotFlag(oItem, 0); }
oItem = GetNextItemInInventory(oPC);
}
// retire le flag PLOT de chaque objet equipe dans chaque slot
valid_slot(INVENTORY_SLOT_ARMS, oPC);
valid_slot(INVENTORY_SLOT_ARROWS, oPC);
valid_slot(INVENTORY_SLOT_BELT, oPC);
valid_slot(INVENTORY_SLOT_BOLTS, oPC);
valid_slot(INVENTORY_SLOT_BOOTS, oPC);
valid_slot(INVENTORY_SLOT_BULLETS, oPC);
valid_slot(INVENTORY_SLOT_CHEST, oPC);
valid_slot(INVENTORY_SLOT_CLOAK, oPC);
valid_slot(INVENTORY_SLOT_HEAD, oPC);
valid_slot(INVENTORY_SLOT_LEFTHAND, oPC);
valid_slot(INVENTORY_SLOT_LEFTRING, oPC);
valid_slot(INVENTORY_SLOT_NECK, oPC);
valid_slot(INVENTORY_SLOT_RIGHTHAND, oPC);
valid_slot(INVENTORY_SLOT_RIGHTRING, oPC);
// detruit les objets dans les slots speciaux
destroy_slot(INVENTORY_SLOT_CARMOUR, oPC);
destroy_slot(INVENTORY_SLOT_CWEAPON_B, oPC);
destroy_slot(INVENTORY_SLOT_CWEAPON_L, oPC);
destroy_slot(INVENTORY_SLOT_CWEAPON_R, oPC);
}
}


Que fait ce script ? Il retire le flag PLOT de la personne et de chaque objet afin que ceux-ci ne puissent plus etre equipés abusivement. Il nettoie aussi les slots spéciaux.

Probleme
Vous avez un Plot Item pour votre module et vous ne voulez pas qu'il perde son flag si un personnage le possede à l'entrée du module, comme par exemple la Pierre de Rappel.

Solution 1
Contentez vous alors de faire un "servervault" pour votre module et interdisez les "localvault". Votre module est sans doute trop évolué pour permettre à n'importe quel personnage d'y participer.

Solution 2
Détruisez l'objet de l'inventaire du joueur et redonnez-lui en un neuf. Surtout, ne vous contentez pas de remettre le flag PLOT a cet objet ! En effet, il est parfaitement possible de modifier l'objet avec l'éditeur, et on peut imaginer une Pierre de Rappel qui donne des bonus partout et qui peut s'équiper comme des bottes par exemple !

Voilà ! Avec ce script, il ne me devrait plus être possible de creer un module de personnalisation complet des personnages, mais c'est une bonne chose d'une certaine manière. :)

Par leokhorn le 2/7/2002 à 0:05:38 (#1742205)

Juste une question: j'ai bien vu qu'on pouvait mettre un flag Plot à des objets mais après avoir lu ces explications je me demande à quoi ça sert vraiment. Ce sont des objets uniques et indispensables c'est bien ça?... Est-ce que les objets avc un flag Plot sont épargnés par les protections de base de NWN?

Par Lumina le 2/7/2002 à 0:25:49 (#1742297)

Voici ce que possede de special un objet "plot" :
- il passe tous les filtres officiels de sécurité
- il peut etre equipé par n'importe qui, sans prerequis, meme si il necessite le niveau 40 minimum
- il est indestructible, c'est à dire qu'il se retrouve toujours dans la fontaine du temple de Tyr si tu le perds

Par ZeDuckMaster le 2/7/2002 à 8:59:19 (#1743236)

sympa comme script :)
mais quelques questions :
- c'est quoi ces slots speciaux ?
- sinon y'aurait pas moyen de lister tous les plots-items d'un module et donc de verifier leur validité sur le joueur ?

Par Lumina le 2/7/2002 à 10:35:30 (#1743577)

- Les slots speciaux sont les slots de créature utilisés généralement pour les monstres. Il y a un emplacement d'armure naturelle et trois emplacements d'arme naturelle. Il n'est pas directement possible d'y équiper quoi que ce soit, mais au moyen d'un script ça devient possible. Ils sont généralement utilisés pour donner des caractéristiques de sous-race (drow, duergar, aasimar, dragon, vampire, etc.).

- Le probleme comme je l'ai dit, c'est que meme si un plot item est particulier à un module, on peut le modifier hors du module ...
Il ne faut donc pas se contenter d'une verification, mais il faut détruire l'objet et en creer un nouveau pour tous les plot item spécifique au module.
Je vais ajouter un bout de script d'exemple pour ça.

Par Xune Vrinn le 2/7/2002 à 10:40:44 (#1743602)

Il y a un autre script intéressant qu'on peut trouver sur Lyoness et qui broadcast certaines informations intéressantes sur les PJs entrant aux MJs.

Il serait aussi judicieux de le placer avec le script de Lumina. ;)

Par Lumina le 2/7/2002 à 17:55:14 (#1745749)

Voici maintenant un script avancé qui permet d'avoir une liste d'objets spécifiques au module qui ne devront pas perdre leur flag PLOT :

// validation du personnage et de son inventaire
// à l'arrivée sur le module (pour NwN v1.19)
// auteur : Lumina
// création : 1 Juillet 2002
// derniere modification : 2 Juillet 2002 (v1.1 #4)
// installation : module properties -> Events -> OnClientEnter

int is_module_item(string sTag)
{
// ajoutez une ligne par objet specifique a votre module
// exemple pour "Stone of Recall" :
if (sTag == "NW_IT_RECALL") return (1); // Stone of Recall
return (0);
}

string get_item_template(string sTag)
{
// ajoutez une ligne par objet specifique a votre module
// exemple pour "Stone of Recall" :
// (ici, cas particulier avec template identique au tag)
// (mais ce n'est pas toujours le cas)
if (sTag == "NW_IT_RECALL") return ("NW_IT_RECALL"); // Stone of Recall
return (");
}

void valid_slot(int nInventorySlot, object oPC)
{
object oItem = GetItemInSlot(nInventorySlot, oPC);
if (GetIsObjectValid(oItem) && GetPlotFlag(oItem))
{
if (is_module_item(GetTag(oItem)))
{
string sTemplate = get_item_template(GetTag(oItem));
DestroyObject(oItem);
object oItem = CreateItemOnObject(sTemplate, oPC, 1);
AssignCommand(oPC, ActionEquipItem(oItem, nInventorySlot));
}
else
{
SetPlotFlag(oItem, 0);
// vérifie pour chaque objet qu'il puisse etre équipé normalement
AssignCommand(oPC, ActionUnequipItem(oItem));
AssignCommand(oPC, ActionEquipItem(oItem, nInventorySlot));
}
}
}

void destroy_slot(int nInventorySlot, object oPC)
{
object oItem = GetItemInSlot(nInventorySlot, oPC);
if (GetIsObjectValid(oItem))
{
if (is_module_item(GetTag(oItem)))
{
string sTemplate = get_item_template(GetTag(oItem));
DestroyObject(oItem);
object oItem = CreateItemOnObject(sTemplate, oPC, 1);
AssignCommand(oPC, ActionEquipItem(oItem, nInventorySlot));
}
else
{
DestroyObject(oItem);
}
}
}

void main()
{
object oPC = GetEnteringObject();
if (GetIsPC(oPC))
{
// retire le flag PLOT du personnage
if (GetPlotFlag(oPC)) { SetPlotFlag(oPC, 0); }
string sPlotItemList = "l_1";
string sPlotStackList = "l_2";
int nIndex = 0;
object oItem = GetFirstItemInInventory(oPC);
while (GetIsObjectValid(oItem))
{
if (GetPlotFlag(oItem))
{
// reinitialise les plot items specifiques au module
if (is_module_item(GetTag(oItem)))
{
SetLocalString(oPC, sPlotItemList+IntToString(nIndex),
get_item_template(GetTag(oItem)));
SetLocalInt(oPC, sPlotStackList+IntToString(nIndex),
GetNumStackedItems(oItem));
nIndex++;
DestroyObject(oItem);
}
// retire le flag PLOT pour les autres
else
{
SetPlotFlag(oItem, 0);
}
}
oItem = GetNextItemInInventory(oPC);
}
// redonne les plot items qui furent retires
int i;
for (i = 0; i < nIndex; i++)
{
CreateItemOnObject(GetLocalString(oPC,
sPlotItemList+IntToString(i)), oPC, GetLocalInt(oPC,
sPlotStackList+IntToString(i)));
DeleteLocalString(oPC, sPlotItemList+IntToString(i));
DeleteLocalInt(oPC, sPlotStackList+IntToString(i));
}
// retire le flag PLOT de chaque objet equipe dans chaque slot
valid_slot(INVENTORY_SLOT_ARMS, oPC);
valid_slot(INVENTORY_SLOT_ARROWS, oPC);
valid_slot(INVENTORY_SLOT_BELT, oPC);
valid_slot(INVENTORY_SLOT_BOLTS, oPC);
valid_slot(INVENTORY_SLOT_BOOTS, oPC);
valid_slot(INVENTORY_SLOT_BULLETS, oPC);
valid_slot(INVENTORY_SLOT_CHEST, oPC);
valid_slot(INVENTORY_SLOT_CLOAK, oPC);
valid_slot(INVENTORY_SLOT_HEAD, oPC);
valid_slot(INVENTORY_SLOT_LEFTHAND, oPC);
valid_slot(INVENTORY_SLOT_LEFTRING, oPC);
valid_slot(INVENTORY_SLOT_NECK, oPC);
valid_slot(INVENTORY_SLOT_RIGHTHAND, oPC);
valid_slot(INVENTORY_SLOT_RIGHTRING, oPC);
// detruit les objets dans les slots speciaux
destroy_slot(INVENTORY_SLOT_CARMOUR, oPC);
destroy_slot(INVENTORY_SLOT_CWEAPON_B, oPC);
destroy_slot(INVENTORY_SLOT_CWEAPON_L, oPC);
destroy_slot(INVENTORY_SLOT_CWEAPON_R, oPC);
}
}


Remarques
Ici, chaque fois qu'on rencontre un plot item spécifique au module, on le détruit et on le recrée apres. Ceci est indispensable pour éviter que quelqu'un ne modifie l'objet en dehors du module.

Comment ca fonctionne ?
Ajoutez votre liste d'objets dans les deux premieres fonctions is_module_item(string sTag) et get_item_template(string sTag) de la meme maniere que pour l'exemple avec la Pierre de Rappel.

JOL Archives 1.0.1
@ JOL / JeuxOnLine