Skip to content

Instantly share code, notes, and snippets.

@ChocolatMilka
Last active May 1, 2021 13:02
Show Gist options
  • Select an option

  • Save ChocolatMilka/7eb8b4376473eed0d1045c8c2878a47e to your computer and use it in GitHub Desktop.

Select an option

Save ChocolatMilka/7eb8b4376473eed0d1045c8c2878a47e to your computer and use it in GitHub Desktop.
Rajoute des variables dynamiques dans des textes, destiné aux serveurs Minecraft
/**
Ce fichier permet de servir de démonstration,
et en même temps de documentation, avec un benchmark intégré.
Pour plus d'infos: Matteow#6953
**/
import wtf.listenia.api.utils.minecraft.Variables;
import java.util.Arrays;
import java.util.List;
public class VerifyVariables {
public static void main (String[] args) {
Variables.register("grade", (args1 -> {
/* return LuckPermAPiSomeThing.someobject.getGroup( args.player ) */
return args1.getString("truc");
}));
final List<String> truc = Arrays.asList(
"your grade: %grade%",
"line without variable",
"%nonExistantVar%"
);
final Variables variables = new Variables(truc);
// ______________________________________________________________________________/-
//
variables.translateAll(null); //
//
final Variables.Args args3 = new Variables.Args();
args3.set("truc", "o");
System.out.println(variables.translateLine(0, args3)); //
//
// fr: entrainer la jm avant le benchmak //
// en: train the jm before the benchmak //
//
// ______________________________________________________________________________/_
int iter = 1;
for (int k = 0; k < 9; k++) {
final long start = System.nanoTime();
for (int i = 0; i < iter; i++)
variables.translateAll(null);
final long stop = System.nanoTime();
System.out.println("Time elapsed for " + iter + "(" + k + ") iterations : " + (stop-start) + "ns = " + Math.round(((stop-start)/Math.pow(10, 6))) + "ms");
iter *= 10;
}
}
}
package wtf.listenia.api.utils.minecraft;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class Variables {
private static final Map<String, Function<Args, String>> global = new HashMap<>();
private static final Pattern pattern = Pattern.compile("%([A-z0-9]{1,99})(:([^%]*))?%");
private final Map<Integer, Cache> argsMap = new HashMap<>(); // key : line number
private final List<String> stringList;
/**
* Permet d'instancier le traducteur de variable
* En spécifiant la liste de phrase à traduire.
* @param stringList liste de phrases où les variables doivent s'appliquer.
*/
public Variables (final List<String> stringList) {
this.stringList = stringList;
for (int i = 0; i < stringList.size(); i++) {
String line = stringList.get(i);
final Cache cache = new Cache();
final Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
final String name = matcher.group(1);
// if (global.containsKey(name)) {
final Args args = new Args();
if (matcher.groupCount() == 3) {
try {
args.map = Arrays.stream(matcher.group(3).split(","))
.map(entry -> entry.split("="))
.collect(Collectors.toMap(entry -> entry[0], entry -> entry[1]));
line = line.replaceFirst(matcher.group(), "%" + name + "%");
} catch (final Exception ignore) { }
} else {
args.map = new HashMap<>();
}
System.out.println("pre-cache: " + cache.names.toString());
cache.names.add(name);
cache.arguments.add(args);
// }
}
stringList.set(i, line);
this.argsMap.put(i, cache);
}
}
public static final class Cache {
final List<String> names = Collections.synchronizedList(new ArrayList<>());
final List<Args> arguments = Collections.synchronizedList(new ArrayList<>());
}
/**
* Permet d'appliquer la ré-écriture
* @param origin paramètres d'origine.
* @param additionnal nouveaux paramètres.
* @return fusion des deux, le nouveau en priorité.
*/
protected final Args fixArgs (final Args origin, final Args additionnal) {
if (additionnal != null) {
if (additionnal.map != null) {
if (origin.map != null) {
origin.map.putAll(additionnal.map);
} else {
origin.map = additionnal.map;
}
}
if (additionnal.player != null) origin.player = additionnal.player;
if (additionnal.world != null) origin.world = additionnal.world;
}
if (origin.map != null) {
if (origin.map.containsKey("player")) origin.player = (Player) origin.map.get("player");
if (origin.map.containsKey("world")) origin.world = (World) origin.map.get("world");
}
return origin;
}
/**
* Permet de traduire qu'une seule ligne.
* Assurez-vous que l'index existe, sinon une erreur sera déclenchée.
*
* @param index place de la ligne dans la liste.
* @param additionnal permet de [re]écrire des paramètres.
* peut être null si pas utilisé.
* @return la ligne avec les variables appliquées.
*/
public final String translateLine (final int index, final Args additionnal) {
final Cache cache = this.argsMap.get(index);
String out = this.stringList.get(index);
final Iterator<String> itNames = cache.names.iterator();
final Iterator<Args> itArgs = cache.arguments.iterator();
while (itNames.hasNext() && itArgs.hasNext()) {
final String name = itNames.next();
final Args args = this.fixArgs(itArgs.next(), additionnal);
// permet de overwrite au dernier moment
if (global.containsKey(name)) {
out = StringUtils.replaceOnce(out, "%" + name + "%", global.get(name).apply(args));
}
}
return out;
}
/**
* Permet d'appliquer toutes les variables sur toutes les lignes.
* Puis de les récupérer sous forme de liste.
* @param additionnal permet de [re]écrire des paramètres.
* peut être null si pas utilisé.
* @return les phrases avec les variables traduites sous forme de liste.
*/
public final List<String> translateAll (final Args additionnal) {
final List<String> out = new ArrayList<>();
for (int i = 0; i < this.countLines(); i++)
out.add(this.translateLine(i, additionnal));
return out;
}
/**
* Permet de compter le nombre de ligne.
* @return le nombre de ligne fournises en entrée.
*/
public final int countLines () {
return this.stringList.size();
}
/**
* Permet de créer des arguments, dites "sous-variables",
* Afin d'influer sur le résultat d'une variable générée.
*/
public static final class Args {
public Player player;
public World world;
private Map<String, Object> map;
/**
* Permet de définir une sous-variable variable.
* @param key nom de la sous-variable.
*
* @param value valeur attribuée à la sous-variable.
*/
public void set (final String key, final Object value) {
if (map == null)
map = new HashMap<>();
map.put(key, value);
}
/**
* Permet de récupérer la valeur d'une sous-variable si elle existe.
* @param key nom de la sous-variable.
* @return contenu de la sous-variable.
*/
public Object get (final String key) {
return (map != null) ? map.get(key) : null;
}
/**
* Permet de récupérer la valeur d'une sous-variable si elle existe.
* Le type de retour est en String.
*
* @param key nom de la sous-variable.
* @return contenu de la sous-variable.
*/
public String getString (final String key) {
return (map != null) ? String.valueOf(map.get(key)) : null;
}
/**
* Permet de récupérer la valeur d'une sous-variable si elle existe.
* Le type de retour est un entier.
*
* Peut provoquer une erreur si la valeur n'est pas un Int.
*
* @param key nom de la sous-variable.
* @return contenu de la sous-variable.
*/
public int getInt (final String key) {
return (map != null) ? (int) map.get(key) : 0;
}
/**
* Permet de récupérer la valeur d'une sous-variable si elle existe.
* Le type de retour est un entier.
*
* Peut provoquer une erreur si la valeur n'est pas un Int.
*
* @param key nom de la sous-variable.
* @return contenu de la sous-variable.
*/
public double getDouble (final String key) {
return (map != null) ? (double) map.get(key) : 0;
}
}
/**
* Permet de définir une variable avec sa fonction qui la résoudra
* @param name nom de la variable à créer.
* @param generator la fonction qui fournis les args et qui renvoie la valeur de la variable.
*/
public static void register (final String name, final Function<Args, String> generator) {
global.put(name, generator);
}
/**
* Permet d'obtenir la valeur d'une variable.
* @param name nom de variable.
* @param args les arguments qui sont optionnels.
* @return la valeur de la variable si elle existe (sinon "").
*/
public static String get (final String name, final Args args) {
final Function<Args, String> data;
if ((data = global.get(name)) != null) {
return data.apply(args);
}
return "";
}
/**
* Permet d'avoir la liste des variables utilisée dans une phrase.
* @param string phrase à analyser.
* @param header préfix (symbole).
* @param footer suffix (symbole).
* @return la liste des variables utilisées.
*/
public static Set<String> findVariables (final String string, final String header, final String footer) {
final Set<String> out = new HashSet<>();
for (final String name: global.keySet()) {
if (string.contains(header + name + footer))
out.add(name);
}
return out;
}
}
@xhuriken
Copy link

xhuriken commented Apr 3, 2021

koulle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment