[Recherche] Messages instantanés sur plusieur avatars.

Répondre
Partager Rechercher
Bonjour à tous.

Je me tourne vers vous pour une recherche de script.

c'est un script qui permettrai de pouvoir dialoguer entre plusieurs résidents de second life mais sans utiliser ni groupe, ni conférence. tout se passerai dans le chat local.
le but de ce script est de type roleplay.

exemple pour situé un peu l'action:
/me prend n'étant pas disponible auprès de son clan, se met devant son ordinateur et lance une conférence vocal avec ses différents membres éparpillés aux quatre coins de second life.


alors le KIKANKOI :

Qui?: tout le monde
Quand?: Quand on clic sur l'objet on active le script
Quoi?: Sert à échanger un dialogue entre plusieurs avatar tout en restant dans le chat local. nous recevons les messages dans le local.

J'ai testé la fonction boucle du script ainsi que l'utilisation des Key d'avatars.
même si un message prédéfinit s'envois bien en direction d'autre avatars, envoyer un message instantané a plusieurs c'est compliqué pour mon cerveau. Je n'ai réussi qu'a envoyer un message à un seul avatar.

Merci de votre temps

Cordiallement VashSV Kohime

PS voici le script que j'ai dans mon inventaire:


Code:
integer t;
list cles=[""]; // ecrire les Keys des différents destinataires entre "" espacer d'une virgule/ exemple : "","","","","","",""
string message="Votre Telephone se met à sonner, vous décrochez pour écouter le message";
list agents = [];
list handles = [];
list messages = [];
key namerequest;
integer i;
default
{
    touch_start(integer total_number)
    { 
     {          
     llPlaySound("033b040c-cdee-ec40-c50e-e95e5c8a480a", 1.0);  
     llSay(0, llDetectedName(i) + ", merci d'écrire votre message en une ligne puis de l'envoyer");
     }      
        while( t < llGetListLength(cles) )
        {
            llInstantMessage(llList2Key(cles,t),message);
            t++;
        }
        t=0;
        {
            agents += llDetectedKey(i);
            handles += llListen(0, "", llDetectedKey(i), "");
        }
    }
    listen(integer channel, string name, key id, string message)
    {
        while( t < llGetListLength(cles) )
           {
             if (llGetListLength(cles) ) 
 
                {
                llInstantMessage(llList2Key(cles,t), name + ": " + message);
                t++;
                } 
                t=0;
                llSay(0," Votre message a été envoyé avec succes");
                llResetScript();
            } 
 
 
    }
}
Bonjour VashSV,

plusieurs problèmes dans ton script.
Dans le touch_start :
Code:
    touch_start(integer total_number)
    { 
     {          
     llPlaySound("033b040c-cdee-ec40-c50e-e95e5c8a480a", 1.0);  
     llSay(0, llDetectedName(i) + ", merci d'écrire votre message en une ligne puis de l'envoyer");
     }      
        while( t < llGetListLength(cles) )
        {
            llInstantMessage(llList2Key(cles,t),message);
            t++;
        }
        t=0;
        {
            agents += llDetectedKey(i);
            handles += llListen(0, "", llDetectedKey(i), "");
        }
    }
total_number représente le nombre total d'avatars qui ont touché l'objet en même temps. Le serveur renvoie à ton script la valeur de cette variable.
Ces avatars sont numérotés de 0 à total_number, c'est la variable i dans llDetectedName(i) : tu demandes au serveur de renvoyer le nom de l'avatar numéro i;
Il faut donc que ton script donne une valeur à la variable i;
Comme il y a très peu de chance que plusieurs avatars touchent l'objet exactement en même temps, il suffit de prendre le premier (et censément seul) avatar ayant touché : le numéro 0.
Code:
llSay(0, llDetectedName(0) + ", merci d'écrire(...)
Même remarque pour llDetectedKey(i);.

Ce qui donnerait :
Code:
    touch_start(integer total_number)
    { 
     llPlaySound("033b040c-cdee-ec40-c50e-e95e5c8a480a", 1.0);  
     llSay(0, llDetectedName(0) + ", merci d'écrire votre message en une ligne puis de l'envoyer");

        while( t < llGetListLength(cles) )
        {
            llInstantMessage(llList2Key(cles,t),message);
            t++;
        }
     t=0;
     agents += llDetectedKey(0);
     handles += llListen(0, "", llDetectedKey(0), "");
    }
Il y encore un certain nombre de remarques à faire, mais vu l'heure, ça sera pour plus tard
Il y a aussi un aspect à prendre en compte, c'est que la fonction llInstantMessage bloque l'exécution du script pendant 2 secondes. Je ne sais pas à combien d'avatars tu veux envoyer un message, mais s'ils sont nombreux ça peut poser des problèmes d'interactivité. La solution dans ce cas est de créer plusieurs scripts pour l'envoi des messages, tu limites donc à 2 secondes le délai à chaque fois. Mais il y en a qui te diront que tu vas créer du lag .

Je te donne une petite trame de script opérationnel :

Code PHP:

list cles=[""]; // ecrire les Keys des différents destinataires entre "" espacer d'une virgule/ exemple : "","","","","","",""
default
{
    
state_entry() {
        
llOwnerSay("Touchez moi si vous désirez envoyer un message");
    }

    
touch_end(integer total_number) {
        if(
llDetectedKey(0) == llGetOwner())
            
state mess;
    }
}

state mess
{
    
state_entry() {
        
llSetTimerEvent(60.0);
        
llListen(-111""NULL_KEY"");
        
string s "Vous désirez envoyer un message au groupe" +
            
"\nVous avez une minute pour entrer votre message ici :" +
            
"(Touchez-moi si vous voulez annuler)";
        
llTextBox(llGetOwner(), s, -111);
    }

    
touch_end(integer total_number) {
        if(
llDetectedKey(0) == llGetOwner()) {
            
llOwnerSay("Requête annulée...");
            
state default;
        }
    }
    
    
listen(integer channelstring namekey idstring message) {
        if(
message != "") {
            
llSetTimerEvent(.0);
            
llOwnerSay("Envoi du message au groupe...");
            
integer n llGetListLength(cles);
            while(
n--) {
                
key k llList2Key(clesn);
                
llOwnerSay("Envoi du message à l'avatar dont la clé est : " + (string)k);
                
llInstantMessage(kmessage);
            }
        }
        
state default;
    }

    
timer() {
        
llOwnerSay("Délai écoulé !");
        
state default;
    }

    
state_exit() {
        
llSetTimerEvent(.0);
    }


Dernière modification par bestmomo ; 17/08/2012 à 23h58.
Merci Bestmomo pour ton script qui est parfait

je l'ai modifié légèrement pour qu'il ai une utilité dans le rôle play. vu que nous devons écrire dans le chat général j'ai retirer la textbox puis ajouté une commande pour activer le script (pour les sims médiéval qui n'on pas de téléphone cela permettra d'utilisé le script d'une autre manière).
puis rajout du nom pour eviter les spams inconnus car le but etant de rp pas de spammer.

voila ce que ça donne, peu de changement car tu l'as fait en grande partie.

Merci encore Bestmomo c'est du top


Code:
list cles=[""]; // ecrire les Keys des différents destinataires entre "" espacer d'une virgule/ exemple : "","","","","","",""
string password;
default
{
    state_entry() 
    {
        llSay( 0,"Touchez moi si vous désirez envoyer un message" );
        llListen(87, "", NULL_KEY, ""); // channel a changer si vous souhaiter une commande d'activation par chat local
     } 
 
     listen(integer channel, string name, key id, string text)
      { 
         if (text=="a") // texte a changer pour le mot de passe de la commande 
 
         {
          state mess;
         }
      }
 
    touch_end(integer total_number) {
        if(llDetectedKey(0))
            state mess;
    }
}
state mess
{
    state_entry() {
        llSetTimerEvent(60.0);
        llListen(0, "", NULL_KEY, "");
        llSay( 0,"Vous décrocher le combiné telephonique" );
 
 
    }
    touch_end(integer total_number) {
        if(llDetectedKey(0)) {
            llSay(0, "Requête annulée..." );
            state default;
        }
    }
 
    listen(integer channel, string name, key id, string message) {
        if(message != "")
        {
            llSetTimerEvent(.0);
            llSay(0, "Envoi du message au groupe..." );
            integer n = llGetListLength(cles);
            while(n--) {
                key k = llList2Key(cles, n);
                llInstantMessage(k,name + ":"+ " " + message);
            }
        }
        state default;
    }
    timer() {
        llSay(0, "Délai écoulé !" );
        state default;
    }
    state_exit() {
        llSetTimerEvent(.0);
    }
}

Dernière modification par VashSV Kohime ; 18/08/2012 à 03h13.
Apparemment, tu veux autoriser l'accès au dispositif au propriétaire (qui doit toucher l'objet), et à tout autre avatar, qui doit au préalable saisir un mot de passe.

Code PHP:

    touch_end(integer total_number) {
        if(
llDetectedKey(0))
            
state mess
Lorsque tu utilises
Code PHP:

if(condition
, le test est VRAI dès que "condition" est différent de zéro.
Or, tu utilises llDetectedKey( 0) comme condition, c'est à dire la clé de l'avatar qui a touché, qui n'est jamais égale à 0.
En d'autres termes, tu ne vérifies rien, n'importe quel avatar qui touche l'objet peut envoyer un message. Si c'est le but, autant enlever le test. Dans le cas contraire, garde le test du script de Best :
Code PHP:

 if(llDetectedKey(0) == llGetOwner()) 

Ce qui se traduit en bon Français par :
"si la clé de celui qui a touché l'objet est la même que la clé du propriétaire"

Il peut-être intéressant de mémoriser la clé de chaque personne qui s'identifie par un mot de passe, pour lui éviter de retaper le mot de passe à chaque message.
Tu déclares une list "autorises", puis :
Code PHP:

      listen(integer channelstring namekey idstring text)
      { 
         if (
text=="a"// texte a changer pour le mot de passe de la commande 
 
         
{
          if (
llListFindList(autorises,[id]) != -1)  autorises += [id];
          
state mess;
         }
      } 
la clé id est la valeur transmis par : listen(integer channel, string name, key id, string text)

Code PHP:

  if (llListFindList(autorises,[id]) != -1)  autorises += [id]; 

"si la clé de l'avatar qui a parlé (et prononcé le mot de passe) n'est pas dans la liste autorisés, ajouter cette clé à la liste"

Pour que, par la suite, cet avatar puisse utiliser le téléphone par un simple click, il faut modifer le test dans le touch_end :
Code PHP:

    touch_end(integer total_number) {
        if((
llDetectedKey(0)==llGetOwner()) || (llListFindList(autorises,[llDetectedKey(0)]) != -1))
            
state mess
Autre solution : au démarrage du script, ajouter la clé du propriétaire à la liste des autorisés :
Code PHP:

default
{
    
state_entry() 
    {
        
autorises = [llGetOwner()];
        
state attente;
   }
}

state attente
{
(...)
 
     
listen(integer channelstring namekey idstring text)
      { 
         if (
text=="a"// texte a changer pour le mot de passe de la commande 
 
         
{
          
orateur id;
          if (
llListFindList(autorises,[id]) != -1autorises += [id];
          
state mess;
         }
      }
(...) 
Dans la deuxième partie de ton script :
Code PHP:

    touch_end(integer total_number) {
        if(
llDetectedKey(0)) {
            
llSay(0"Requête annulée..." );
            
state default;
        } 
Comme dit plus haut, avec if(llDetectedKey( 0)) tu ne vérifies rien.
Si tu utilises
Code PHP:

if (llDetectedKey(0) == llGetOwner()) 

, c'est uniquement le propriétaire de l'objet qui peut annuler la requête. Un autre utilisateur, qui se serait identifié par mot de passe, ne le pourrait pas.
Pour que l'annulation puisse être faite par celui qui a initié la requête, il faut mémoriser sa clé par une variable orateur dans le listen et le touch_end de state default.
Et tant qu'à faire, tu peux alors en profiter pour limiter l'écoute à celui qui a décroché le téléphone, de manière à éviter que quelqu'un d'autre qui se trouve à proximité n'envoie "prout bidule" à ton groupe, lorsque tu viens de toucher l'objet.
Code PHP:

llListen(0""orateur""); 

Ton test
Code PHP:

if(message != ""
n'a aucun effet. Si le message est vide, c'est qu'il n'y a pas de message, et l'événement listen n'est pas déclenché.
Autant supprimer le test.

Une dernière astuce :
Le message reçu commence toujours par le nom de l'objet émetteur, suivi d'un double point.
Si ton objet s'appelle telephone V1.0, et que l'avatar Jean Leterrible dit "je mangerais bien un troupeau de moutons", le destinataire reçoit :
telephone V1.0 : Jean le Terrible : je mangerais bien un troupeau de moutons

L'astuce souvent utilisée consiste à renommer temporairement l'objet par la fonction llSetObjectName(name); , en lui donnant le nom de l'avatar qui parle.
Le destinataire verra alors s'afficher :
Jean le Terrible : je mangerais bien un troupeau de moutons
Ce qui a tout de même une autre gueule

Au final, ça donnerait :
Code PHP:

list cles=[""]; // ecrire les Keys des différents destinataires entre "" espacer d'une virgule/ exemple : "","","","","","",""
string password;
list 
autorises;
key orateur;

default
{
    
state_entry() 
    {
        
autorises = [llGetOwner()];
        
state attente;
   }
}

state attente
{
    
state_entry() 
    {
        
llSay0,"Touchez moi si vous désirez envoyer un message" );
        
llListen(87""NULL_KEY""); // channel a changer si vous souhaiter une commande d'activation par chat local
     

 
     
listen(integer channelstring namekey idstring text)
      { 
         if (
text=="a"// texte a changer pour le mot de passe de la commande 
 
         
{
          
orateur id;
          if (
llListFindList(autorises,[id]) != -1autorises += [id];
          
state mess;
         }
      }
 
    
touch_end(integer total_number) {
        if(
llListFindList(autorises,[llDetectedKey(0)]) != -1)
         {
          
orateur llDetectedKey(0);
          
state mess;
         }
    }
}
state mess
{
    
state_entry() {
        
llSetTimerEvent(60.0);
        
llListen(0""orateur"");
        
llSay0,"Vous décrocher le combiné telephonique" );
 
 
    }
    
touch_end(integer total_number) {
        if(
llDetectedKey(0) == orateur) {
            
llSay(0"Requête annulée..." );
            
state attente;
        }
    }
 
    
listen(integer channelstring namekey idstring message) {
        
llSetTimerEvent(.0);
        
llSay(0"Envoi du message au groupe..." );
        
string oldname llGetObjectName();
        
llSetObjectName(name);
        
integer n llGetListLength(cles);
        while(
n--) {
            
key k llList2Key(clesn);
            
llInstantMessage(k,message);
        }
        
llSetObjectName(oldname);
        
state attente;
    }
    
timer() {
        
llSay(0"Délai écoulé !" );
        
state attente;
    }
    
state_exit() {
        
llSetTimerEvent(.0);
    }

Notre matou a vraiment de grandes qualités didactiques .

Il y a toutefois deux trucs qui m'interpellent (comme on dit...) :


  1. Lorsque l'objet est en mode d'envoi de message il devient inactif pour un autre utilisateur susceptible de l'utiliser sans que celui-ci sache pourquoi ses clics réitérés sont sans effets. Il serait peut-être judicieux d'afficher, dans un texte flottant par exemple, l'état "occupé" du téléphone.
  2. Si le groupe se compose de beaucoup de membres le système devient très vite lourd étant donné le délai de 2s pour chaque envoi individuel si on veut un certain niveau d'interactivité et la seule solution alors est de déléguer l'envoi à des scripts esclaves.
merci pour les astuces Bestmomo et Black cats.

pour le moment les groupes sont de petites envergure donc peu de souci au niveau des 2 secondes.
mais ça va se généraliser auprès du rôle play vu qu'on me demande le téléphone donc le souci des 2 secondes se posera par la suite, obligatoirement.

le système doit pouvoir répondre au clic de n'importe quel avatar et pouvoir être utilisé via une commande.
Apres je me demande s'il est possible d'automatisé le système pour qu'une personne qui désir contacter une autre personne dont la clé n'est pas configuré dans le script soit possible.

Enfin, pour ce qui est de la commande par mot de passe c'est uniquement pour les régions médiévales Fantasy qui ne possède pas de téléphone. ça peut être par télépathie par exemple donc le clic pour tous est le mieux placé.


il y a beaucoup d'idée pour étoffer ce script tout en essayant de pas créer trop de lag comme décocher le mono qui réduit le poids du script par exemple.

en tout cas, un Grand Merci à vous deux pour ce script qui fonctionne tres bien

Dernière modification par VashSV Kohime ; 18/08/2012 à 16h23.
Citation :
Publié par VashSV Kohime
... tout en essayant de pas créer trop de lag comme décocher le mono qui réduit le poids du script par exemple.
...
ça ce n'est pas garanti du tout.
Un script non mono prend toujours 16ko sur le serveur, quel que soit sa taille.
Un script mono prend la taille dont il a besoin; la mémoire est allouée dynamiquement, même si le serveur lui réserve 64k.
Donc un petit script comme celui là te prendra en mono quelques ko et en non mono 16ko!
Mais le mono, à instruction égale, prend plus de mémoire. Alors un script important (plus d'une centaine de ligne) te prendras 16ko en non mono et par exemple 18 ou 20ko en mono. ça c'est exact. Mais ce n'est valable que pour les gros scripts. Pour 80% des cas, un script en mono prend moins de mémoire.
En plus dans ton cas, le mono est indispensable. Sinon, adieu les caractères accentués.
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés