Résolu Récupéré message dans le tchat [Java]

Kenda

Architecte en herbe
16 Juillet 2016
292
1
2
125
32
www.youtube.com
Bonjour Bonsoir,

Actuellement en création d'un petit plugin entre amis, je cherche à faire un plugin de "calcule mentale" en gros, un calcul est mis dans le tchat, et l'utilisateur dois écrire le calcule dans le tchat.

Et justement, j'aimerai savoir comment je pourrais le récupéré.

J'utilise le "AsyncPlayerChatEvent" avec une ArrayList pour y stocker mon nombre. Cela est assez optimal ? :confused:


Car justement je n'arrive pas à récupéré le nombre que le joueur donne.

Merci bien de l'aide :)
 
Solution
Bonsoir,

Si tu veux récupérer le résultat d'un calcul sous forme de String, tu peux aussi passer par l'API de scripting :
Java:
public class ScriptEngines {
   private static final ScriptEngineManager MANAGER = new ScriptEngineManager();

   public static ScriptEngine create() {
      ScriptEngine engine = MANAGER.getEngineByName("JavaScript");
      if(engine == null)
         throw new UnsupportedOperationException("JavaScript is not supported");
  
      return engine;
   }
}

public class Foo {
   public static void bar() {
      ScriptEngine js = ScriptEngines.create();
      String expr = "(2 + 4) * 2";
      
      // TODO: si 'expr' est donné par le joueur,
      // vérifier qu'il ne peut pas faire exécuter du code sur...

Detobel36

Créateur de plugins (PhoenixRebirth)
Support
17 Août 2012
10 530
24
2 247
347
27
Bruxelles - Belgique
www.phoenix-rebirth.fr
Salut,

C'est bien AsyncPlayerChatEvent qu'il faut utilisé...
Après, cela dépend comment tu veux que les joueurs indiquent leur calcul. Il faut également voir si le calcul est par jour ou pour tout le serveur.

Si tu fais, par joueur et un message contient un calcul avec une opération et deux nombres (donc: x + y ou x * y ect).
Pour faire cela, tu peux avoir un code qui ressemblerait à ceci:
Java:
private final HashMap<Player, Double> playerResult = new HashMap<Player, Double>();

@EventHandler
public void on PlayerChat(AsyncPlayerChatEvent event) {
    final String message = event.getMessage();
    final Double result = parseAndMadeCalcul(message);
    playerResult.put(event.getPlayer(), result);
}

private Double parseAndMadeCalcul(String strMessage) {
    final Double result;
    final String operation = getOperation(strMessage);
    final String[] chiffres = strMessage.split(operation);

    if(chiffres.length == 2) {
        final double chiffre1 = Double.parseDouble(chiffres[0]);
        final double chiffre2 = Double.parseDouble(chiffres[1]);
        result = madeCalcul(chiffre1, chiffre2, operation);
    } else {
        // Message d'erreur
    }

    return result;
}

private String getOperation(String strMessage) {
    String operation;
    if(strMessage.con tains("+")) {
        operation = "+";
    } else if(strMessage.con tains("*")) {
        operation = "*";
    } else if(strMessage.con tains("/")) {
        operation = "/";
    } // ...
    return operation;
}

private Double madeCalcul(Double chiffre1, Double chiffre2, String operation) {
    Double result;
    if(operation.equals("+")) {
        result = chiffre1 + chiffre2;
    } else if(operation.equals("*")) {
        result = chiffre1 * chiffre2;
    } else if(operation.equals("/")) {
        result = chiffre1 / chiffre2;
    } // ...
    return result;
}
Attention: il y a un bug sur le forum m'interdisant d'écrire "contains" et "onPlayer...". Donc j'ai rajouté des espaces !


Cordialement,
Detobel36
 

Kenda

Architecte en herbe
16 Juillet 2016
292
1
2
125
32
www.youtube.com
Salut,

C'est bien AsyncPlayerChatEvent qu'il faut utilisé...
Après, cela dépend comment tu veux que les joueurs indiquent leur calcul. Il faut également voir si le calcul est par jour ou pour tout le serveur.

Si tu fais, par joueur et un message contient un calcul avec une opération et deux nombres (donc: x + y ou x * y ect).
Pour faire cela, tu peux avoir un code qui ressemblerait à ceci:
Java:
private final HashMap<Player, Double> playerResult = new HashMap<Player, Double>();

@EventHandler
public void on PlayerChat(AsyncPlayerChatEvent event) {
    final String message = event.getMessage();
    final Double result = parseAndMadeCalcul(message);
    playerResult.put(event.getPlayer(), result);
}

private Double parseAndMadeCalcul(String strMessage) {
    final Double result;
    final String operation = getOperation(strMessage);
    final String[] chiffres = strMessage.split(operation);

    if(chiffres.length == 2) {
        final double chiffre1 = Double.parseDouble(chiffres[0]);
        final double chiffre2 = Double.parseDouble(chiffres[1]);
        result = madeCalcul(chiffre1, chiffre2, operation);
    } else {
        // Message d'erreur
    }

    return result;
}

private String getOperation(String strMessage) {
    String operation;
    if(strMessage.con tains("+")) {
        operation = "+";
    } else if(strMessage.con tains("*")) {
        operation = "*";
    } else if(strMessage.con tains("/")) {
        operation = "/";
    } // ...
    return operation;
}

private Double madeCalcul(Double chiffre1, Double chiffre2, String operation) {
    Double result;
    if(operation.equals("+")) {
        result = chiffre1 + chiffre2;
    } else if(operation.equals("*")) {
        result = chiffre1 * chiffre2;
    } else if(operation.equals("/")) {
        result = chiffre1 / chiffre2;
    } // ...
    return result;
}
Attention: il y a un bug sur le forum m'interdisant d'écrire "contains" et "onPlayer...". Donc j'ai rajouté des espaces !


Cordialement,
Detobel36

Ok, merci de cette réponse, même si c'étais pas vraiment cela à quoi m'attendre, mais sa peut gravement m'aider :)

En gros, pour le moment, je fais des tests, puis je rajouterai surement un fichier de config avec des calculs mis dedans et sa prendra un calcul aléatoire.

Merci de cette aide :)
 

ShE3py

Enbogueuse
Support
26 Septembre 2015
4 087
160
459
247
21
Mìlhüsa
Bonsoir,

Si tu veux récupérer le résultat d'un calcul sous forme de String, tu peux aussi passer par l'API de scripting :
Java:
public class ScriptEngines {
   private static final ScriptEngineManager MANAGER = new ScriptEngineManager();

   public static ScriptEngine create() {
      ScriptEngine engine = MANAGER.getEngineByName("JavaScript");
      if(engine == null)
         throw new UnsupportedOperationException("JavaScript is not supported");
  
      return engine;
   }
}

public class Foo {
   public static void bar() {
      ScriptEngine js = ScriptEngines.create();
      String expr = "(2 + 4) * 2";
      
      // TODO: si 'expr' est donné par le joueur,
      // vérifier qu'il ne peut pas faire exécuter du code sur
      // le serveur (à voir si c'est possible),
      // avec une expression régulière par ex.
  
      try {
         int result = ((Number) js.eval(expr)).intValue();
     
         // result = 12
      }
      catch(ScriptException | ClassCastException | NullPointerException e) {
         // ScriptException: 'expr' n'est pas une expression valide (ex: « 1 + »)
         // ClassCastException: 'expr' n'est pas un nombre (ex: « abc »)
         // NullPointerException: 'expr' ne renvoie rien (ex: « print("hmmm") »)
     
         e.printStackTrace();
      }
   }
}

Pour lire le nombre que le joueur a dit :
Java:
@EventHandler
public void onPlayerChat(AsyncPlayerChatEvent e) {
   String message = e.getMessage();
   int nb;

   try {
      nb = Integer.parseInt(message);
   }
   catch(NumberFormatException ignored) {
      return; // 'message' n'est pas un nombre entier
   }

   // faire qqch avec 'nb'
}

Après si tu veux avoir des nombres décimaux, passe par des floats/doubles, mais du coup tu ne peux plus comparer avec == parce que sinon tu auras quelques petites erreurs, du type 0.1 + 0.2 == 0.30000000000000004 (!= 0.3).

Et sinon pour associer une valeur à un joueur, ne passe pas par une Map<Player, T> mais par une Map<UUID, T>, la première ne supporte pas les reconnexion.
Tu peux éventuellement passer par une WeakHashMap<Player, T>, mais bon elle ne supporte toujours pas les reconnexions, et faut comprendre ce qu'est une WeakReference<T>, et pourquoi elles doivent être utilisées dans ce cas.

Cordialement,
ShE3py.
 
  • J'aime
Reactions: Detobel36
Solution