From 6b897976e6f4e09556eab9adcadf4200fed89b01 Mon Sep 17 00:00:00 2001
From: SofianeLasri <alasri250@gmail.com>
Date: Sat, 5 Mar 2022 15:27:13 +0100
Subject: [PATCH] 1.4

---
 pom.xml                                       |   2 +-
 .../com/slprojects/slcraftplugin/Main.java    | 139 +++++++++++++++---
 .../commandes/linkCodeCommand.java            |  78 ++++++++++
 src/main/resources/plugin.yml                 |   8 +-
 .../com/slprojects/slcraftplugin/Main.class   | Bin 11996 -> 14946 bytes
 .../commandes/linkCodeCommand.class           | Bin 0 -> 5876 bytes
 target/classes/plugin.yml                     |  10 +-
 target/maven-archiver/pom.properties          |   4 +-
 .../compile/default-compile/createdFiles.lst  |   1 +
 .../compile/default-compile/inputFiles.lst    |   1 +
 10 files changed, 215 insertions(+), 28 deletions(-)
 create mode 100644 src/main/java/com/slprojects/slcraftplugin/commandes/linkCodeCommand.java
 create mode 100644 target/classes/com/slprojects/slcraftplugin/commandes/linkCodeCommand.class

diff --git a/pom.xml b/pom.xml
index 672242a..c886200 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 
     <groupId>com.slprojects</groupId>
     <artifactId>SLCraftPlugin</artifactId>
-    <version>1.3</version>
+    <version>1.4</version>
     <packaging>jar</packaging>
 
     <name>SLCraftPlugin</name>
diff --git a/src/main/java/com/slprojects/slcraftplugin/Main.java b/src/main/java/com/slprojects/slcraftplugin/Main.java
index e3b1b3f..45f9473 100644
--- a/src/main/java/com/slprojects/slcraftplugin/Main.java
+++ b/src/main/java/com/slprojects/slcraftplugin/Main.java
@@ -2,6 +2,7 @@
 
 package com.slprojects.slcraftplugin;
 
+import com.slprojects.slcraftplugin.commandes.linkCodeCommand;
 import com.slprojects.slcraftplugin.commandes.wildCommand;
 import org.bukkit.ChatColor;
 import org.bukkit.Sound;
@@ -15,14 +16,12 @@ import org.bukkit.event.player.PlayerJoinEvent;
 import org.bukkit.event.player.PlayerQuitEvent;
 import org.bukkit.plugin.java.JavaPlugin;
 import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
 import org.mariadb.jdbc.MariaDbPoolDataSource;
 
-import java.io.FileReader;
 import java.sql.*;
-import java.text.SimpleDateFormat;
 import java.time.Duration;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -60,12 +59,15 @@ public final class Main extends JavaPlugin implements Listener {
         // On initialise la base de donnée
         initDatabase();
 
-        wildCommandActiveUsers = new ArrayList<UUID>();
-        playTimeUsersIndexes = new ArrayList<UUID>();
-        playTimeUsersDate = new ArrayList<LocalDateTime>();
+        wildCommandActiveUsers = new ArrayList<>();
+        playTimeUsersIndexes = new ArrayList<>();
+        playTimeUsersDate = new ArrayList<>();
         wildCommand wildCommand = new wildCommand(this);
         getCommand("wild").setExecutor(wildCommand);
 
+        linkCodeCommand linkCodeCommand = new linkCodeCommand(this);
+        getCommand("getLinkCode").setExecutor(linkCodeCommand);
+
         getLogger().info(ChatColor.GREEN+"SL-Craft | Plugin démarré");
     }
 
@@ -82,9 +84,11 @@ public final class Main extends JavaPlugin implements Listener {
         playTimeUsersIndexes.add(e.getPlayer().getUniqueId());
         playTimeUsersDate.add(LocalDateTime.now());
 
+        // On affiche le message de bienvenue
         String welcomeMessage = PlaceholderAPI.setPlaceholders(e.getPlayer(), getConfig().getString("player-join-message"));
-        e.setJoinMessage(welcomeMessage);
+        // Et on joue un petit son chez tous les joueurs
         for(Player p : getServer().getOnlinePlayers()){
+            p.sendMessage(welcomeMessage);
             if(getConfig().getBoolean("player-join-playSound")){
                 p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 0);
             }
@@ -96,9 +100,8 @@ public final class Main extends JavaPlugin implements Listener {
     public void onPlayerQuit(PlayerQuitEvent e) {
         savePlayer(e.getPlayer());
         String quitMessage = PlaceholderAPI.setPlaceholders(e.getPlayer(), getConfig().getString("player-quit-message"));
-        e.setQuitMessage(quitMessage);
         for(Player p : getServer().getOnlinePlayers()){
-            //p.sendMessage(quitMessage);
+            p.sendMessage(quitMessage);
         }
     }
 
@@ -106,25 +109,30 @@ public final class Main extends JavaPlugin implements Listener {
     @SuppressWarnings("unchecked")
     public void savePlayer(Player player) {
         JSONObject target = new JSONObject();
+        // On ajoute l'uuid et son nom
         target.put("uuid", player.getUniqueId().toString());
+        target.put("name", player.getName());
+        
+        // La date de join (locale, au cas où CoreProtect ne l'a pas)
+        target.put("joinedDate", playTimeUsersDate.get(playTimeUsersIndexes.indexOf(player.getUniqueId())).toString());
 
+        // On calcule le temps de jeu
         LocalDateTime timeNow = LocalDateTime.now();
         Duration duration = Duration.between(timeNow, playTimeUsersDate.get(playTimeUsersIndexes.indexOf(player.getUniqueId())));
         long playedTimeInSeconds = Math.abs(duration.toSeconds());
 
-        target.put("time", playedTimeInSeconds);
+        // On ajoute le temps de jeu au joueur
+        target.put("playedTime", playedTimeInSeconds);
 
         playTimeUsersDate.remove(playTimeUsersIndexes.indexOf(player.getUniqueId()));
         playTimeUsersIndexes.remove(player.getUniqueId());
 
-        target.put("joins", Integer.valueOf(player.getStatistic(Statistic.LEAVE_GAME) + 1));
+        target.put("joins", player.getStatistic(Statistic.LEAVE_GAME) + 1);
+        target.put("hasPlayedBefore", player.hasPlayedBefore());
         writePlayer(target);
     }
 
-    @SuppressWarnings("unchecked")
     private void writePlayer(JSONObject target) {
-        JSONParser jsonParser = new JSONParser();
-
         // On ouvre la bdd
         Connection con = bddOpenConn();
         try {
@@ -139,29 +147,107 @@ public final class Main extends JavaPlugin implements Listener {
                     // On insère la dernière date de join
                     PreparedStatement insertionLastJoin = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'playedTime',?)");
                     insertionLastJoin.setString(1, target.get("uuid").toString());
-                    insertionLastJoin.setString(2, target.get("time").toString());
-                    resultat = insertionLastJoin.executeQuery();
+                    insertionLastJoin.setString(2, target.get("playedTime").toString());
+                    insertionLastJoin.executeQuery();
 
                     // On insère le nombre de connexions
                     PreparedStatement insertionNbJoins = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'joins',?)");
                     insertionNbJoins.setString(1, target.get("uuid").toString());
                     insertionNbJoins.setString(2, target.get("joins").toString());
-                    resultat = insertionNbJoins.executeQuery();
+                    insertionNbJoins.executeQuery();
+
+                    // On va regarder si l'utilisateur a déjà joué avant (vu qu'on avait pas de données sur ce joueur)
+                    if(target.get("hasPlayedBefore").toString().equals("true")){
+                        // On va piocher la date d'inscription chez CoreProtect (si elle existe)
+                        // On la prend chez CoreProtect car le plugin a été installé dans les premières semaines du serveur. Il a donc bcp plus de données que nous concernant les anciens joueurs.
+                        PreparedStatement rechercheDateInscription = con.prepareStatement("SELECT time FROM co_user WHERE uuid = ?");
+                        rechercheDateInscription.setString(1, target.get("uuid").toString());
+                        resultat = rechercheDateInscription.executeQuery();
+
+                        if(resultat.next()){
+                            // On insère la date d'inscription
+                            PreparedStatement insertionDateInscription = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'joinedDate',?)");
+                            insertionDateInscription.setString(1, target.get("uuid").toString());
+                            insertionDateInscription.setString(2, java.sql.Timestamp.valueOf(LocalDateTime.ofEpochSecond(Long.parseLong(resultat.getString("time")), 0, ZoneOffset.UTC)).toString()); // Il faut convertir le timestamp (epoch second) en date
+                            insertionDateInscription.executeQuery();
+
+                            // On va précisier que la date d'inscription a été trouvée chez CoreProtect
+                            getLogger().info("L'utilisateur "+ChatColor.GOLD+target.get("name").toString()+ChatColor.RESET+" n'avait pas de données sur sa date d'inscription dans dans la table des paramètres utilisateurs. On lui a donc attribué comme date de création du compte, celle que détenait CoreProtect.");
+                        } else {
+                            // On insère la date d'inscription (du coup on considère que l'utilisateur n'a pas joué avant, malgré la condition)
+                            PreparedStatement insertionDateInscription = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'joinedDate',?)");
+                            insertionDateInscription.setString(1, target.get("uuid").toString());
+                            insertionDateInscription.setString(2, java.sql.Timestamp.valueOf(target.get("joinedDate").toString()).toString());
+                            insertionDateInscription.executeQuery();
+                            
+                            // On va préciser que la date d'inscription n'a pas été trouvée chez CoreProtect
+                            PreparedStatement insertionInaccurrateJoinedDate = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'inaccurrateJoinedDate',?)");
+                            insertionInaccurrateJoinedDate.setString(1, target.get("uuid").toString());
+                            insertionInaccurrateJoinedDate.setString(2, "true");
+                            insertionInaccurrateJoinedDate.executeQuery();
+                            
+                            getLogger().info("L'utilisateur "+ChatColor.GOLD+target.get("name").toString()+ChatColor.RESET+" n'avait pas de données sur sa date d'inscription dans dans la table des paramètres utilisateurs, ni dans la table des utilisateurs de CoreProtect. On lui a donc attribué comme date de création du compte, la date du début de sa partie.");
+                        }
+                    }else{
+                        // C'est un nouvel utilisateur, on peut lui attribuer la date d'inscription précédement calculée
+                        PreparedStatement insertionDateInscription = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'joinedDate',?)");
+                        insertionDateInscription.setString(1, target.get("uuid").toString());
+                        insertionDateInscription.setString(2, java.sql.Timestamp.valueOf(target.get("joinedDate").toString()).toString());
+                        insertionDateInscription.executeQuery();
+                    }
                 }else{
                     PreparedStatement tempsJeuJoueur = con.prepareStatement("SELECT value FROM site_userSetting WHERE uuid = ? AND name = 'playedTime'");
                     tempsJeuJoueur.setString(1, target.get("uuid").toString());
                     resultat = tempsJeuJoueur.executeQuery();
                     if(resultat.next()) {
-                        int totalPlayedTime = parseInt(resultat.getString(1)) + parseInt(target.get("time").toString());
+                        int totalPlayedTime = parseInt(resultat.getString(1)) + parseInt(target.get("playedTime").toString());
                         PreparedStatement modifyPlayedTime = con.prepareStatement("UPDATE `site_userSetting` SET `value`=? WHERE  `uuid`=? AND `name`='playedTime'");
                         modifyPlayedTime.setInt(1, totalPlayedTime);
                         modifyPlayedTime.setString(2, target.get("uuid").toString());
-                        resultat = modifyPlayedTime.executeQuery();
+                        modifyPlayedTime.executeQuery();
 
                         PreparedStatement modifyNbJoins = con.prepareStatement("UPDATE `site_userSetting` SET `value`=? WHERE  `uuid`=? AND `name`='joins'");
                         modifyNbJoins.setString(1, target.get("joins").toString());
                         modifyNbJoins.setString(2, target.get("uuid").toString());
-                        resultat = modifyNbJoins.executeQuery();
+                        modifyNbJoins.executeQuery();
+
+                        // On va regarder s'il a sa date d'inscription de renseignée
+                        PreparedStatement rechercheDateInscription = con.prepareStatement("SELECT * FROM site_userSetting WHERE uuid = ? AND name = 'joinedDate'");
+                        rechercheDateInscription.setString(1, target.get("uuid").toString());
+                        resultat = rechercheDateInscription.executeQuery();
+
+                        if(!resultat.next()){
+                            // On va regarder si l'on dispose de sa date d'inscription chez CoreProtect
+                            rechercheDateInscription = con.prepareStatement("SELECT time FROM co_user WHERE uuid = ?");
+                            rechercheDateInscription.setString(1, target.get("uuid").toString());
+                            resultat = rechercheDateInscription.executeQuery();
+
+                            if(resultat.next()){
+                                // On insère la date d'inscription
+                                PreparedStatement insertionDateInscription = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'joinedDate',?)");
+                                insertionDateInscription.setString(1, target.get("uuid").toString());
+                                insertionDateInscription.setString(2, java.sql.Timestamp.valueOf(LocalDateTime.ofEpochSecond(Long.parseLong(resultat.getString("time")), 0, ZoneOffset.UTC)).toString()); // Il faut convertir le timestamp (epoch second) en date
+                                insertionDateInscription.executeQuery();
+
+                                // On va précisier que la date d'inscription a été trouvée chez CoreProtect
+                                getLogger().info("L'utilisateur "+ChatColor.GOLD+target.get("name").toString()+ChatColor.RESET+" n'avait pas de données sur sa date d'inscription dans dans la table des paramètres utilisateurs. On lui a donc attribué comme date de création du compte, celle que détenait CoreProtect.");
+                            } else {
+                                // On insère la date d'inscription (du coup, comme précédement, on prend la date d'inscription locale)
+                                PreparedStatement insertionDateInscription = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'joinedDate',?)");
+                                insertionDateInscription.setString(1, target.get("uuid").toString());
+                                insertionDateInscription.setString(2, java.sql.Timestamp.valueOf(target.get("joinedDate").toString()).toString());
+                                insertionDateInscription.executeQuery();
+
+                                // On va préciser que la date d'inscription n'a pas été trouvée chez CoreProtect
+                                PreparedStatement insertionInaccurrateJoinedDate = con.prepareStatement("INSERT INTO site_userSetting (`uuid`, `name`, `value`) VALUES (?,'inaccurrateJoinedDate',?)");
+                                insertionInaccurrateJoinedDate.setString(1, target.get("uuid").toString());
+                                insertionInaccurrateJoinedDate.setString(2, "true");
+                                insertionInaccurrateJoinedDate.executeQuery();
+
+                                getLogger().info("L'utilisateur "+ChatColor.GOLD+target.get("name").toString()+ChatColor.RESET+" n'avait pas de données sur sa date d'inscription dans dans la table des paramètres utilisateurs, ni dans la table des utilisateurs de CoreProtect. On lui a donc attribué comme date de création du compte, la date du début de sa partie.");
+                            }
+                        }
+
                     }else{
                         getLogger().warning(ChatColor.RED+"Erreur, nous n'avons pas de resultats pour la requête: SELECT value FROM site_userSetting WHERE uuid = '"+target.get("uuid")+"' AND name = playedTime");
                     }
@@ -206,7 +292,7 @@ public final class Main extends JavaPlugin implements Listener {
         try {
             MariaDbPoolDataSource dataSource = new MariaDbPoolDataSource("jdbc:mariadb://"+config.getString("database.host")+"/"+config.getString("database.database")+"?user="+config.getString("database.user")+"&password="+config.getString("database.password")+"&maxPoolSize=10");
             conn = dataSource.getConnection();
-            getLogger().info(ChatColor.GREEN+"Connexion à la base de données réussie!");
+            //getLogger().info(ChatColor.GREEN+"Connexion à la base de données réussie!");
         }// ou les saisir
         catch (SQLException e) {
             getLogger().warning(ChatColor.RED+"Erreur lors de la connexion à la base de données.");
@@ -224,7 +310,16 @@ public final class Main extends JavaPlugin implements Listener {
                     "  `value` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,\n" +
                     "  PRIMARY KEY (`uuid`,`name`) USING BTREE\n" +
                     ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
-            ResultSet rs=ps.executeQuery();
+            ps.executeQuery();
+            ps=con.prepareStatement("CREATE TABLE IF NOT EXISTS `site_linkCode` (\n" +
+                    " `uuid` VARCHAR(36) NOT NULL,\n" +
+                    " `code` VARCHAR(8) NOT NULL,\n" +
+                    " `time` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),\n" +
+                    " `used` BOOLEAN,\n" +
+                    " PRIMARY KEY (`uuid`),\n" +
+                    " UNIQUE INDEX `code` (`code`)\n" +
+                    ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
+            ps.executeQuery();
             con.close();
         }catch(Exception e){
             getLogger().warning(ChatColor.RED+"Erreur lors de l'exécution de initDatabase(): "+e);
diff --git a/src/main/java/com/slprojects/slcraftplugin/commandes/linkCodeCommand.java b/src/main/java/com/slprojects/slcraftplugin/commandes/linkCodeCommand.java
new file mode 100644
index 0000000..6618511
--- /dev/null
+++ b/src/main/java/com/slprojects/slcraftplugin/commandes/linkCodeCommand.java
@@ -0,0 +1,78 @@
+package com.slprojects.slcraftplugin.commandes;
+
+import com.slprojects.slcraftplugin.Main;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.time.LocalDateTime;
+import java.util.Random;
+
+public class linkCodeCommand implements CommandExecutor {
+
+    // Variables
+    private final Main plugin;
+
+    public linkCodeCommand(Main plugin){
+        // On récupère la classe parente pour les paramètres
+        this.plugin = plugin;
+    }
+
+    @Override
+    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args){
+        if (sender instanceof Player){
+            Player player = (Player) sender;
+
+            // On ouvre la bdd
+            Connection con = plugin.bddOpenConn();
+
+            try{
+                // On créé le code
+                int leftLimit = 48; // numeral '0'
+                int rightLimit = 122; // letter 'z'
+                int targetStringLength = 8;
+                Random random = new Random();
+
+                String generatedString = random.ints(leftLimit, rightLimit + 1)
+                        .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
+                        .limit(targetStringLength)
+                        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
+                        .toString();
+
+                // On va regarder si l'utilisateur a déjà généré un code auparavant
+                PreparedStatement rechercheLinkingCode = con.prepareStatement("SELECT * FROM site_linkCode WHERE uuid = ?");
+                rechercheLinkingCode.setString(1, player.getUniqueId().toString());
+                ResultSet resultat = rechercheLinkingCode.executeQuery();
+
+                if(resultat.next()){
+                    PreparedStatement modifyAccountLinkingCode = con.prepareStatement("UPDATE `site_linkCode` SET `code`=?, `time`=?, `used`='0' WHERE `uuid`=?");
+                    modifyAccountLinkingCode.setString(1, generatedString);
+                    modifyAccountLinkingCode.setString(2, java.sql.Timestamp.valueOf(LocalDateTime.now()).toString());
+                    modifyAccountLinkingCode.setString(3, player.getUniqueId().toString());
+                    modifyAccountLinkingCode.executeQuery();
+
+                }else{
+                    PreparedStatement insertionAccountLinkingCode = con.prepareStatement("INSERT INTO site_linkCode (`uuid`, `code`, `time`, `used`) VALUES (?, ?, ?, '0')");
+                    insertionAccountLinkingCode.setString(1, player.getUniqueId().toString());
+                    insertionAccountLinkingCode.setString(2, generatedString);
+                    insertionAccountLinkingCode.setString(3, java.sql.Timestamp.valueOf(LocalDateTime.now()).toString());
+                    insertionAccountLinkingCode.executeQuery();
+                }
+                player.sendMessage("Utilise ce code pour lier ton compte: "+ChatColor.GREEN+generatedString);
+                player.sendMessage(ChatColor.GRAY+"Ce code à usage unique expirera dans 5 minutes.");
+                plugin.getLogger().info("Le joueur "+ChatColor.GOLD+player.getName()+ChatColor.RESET+" a généré le code "+ChatColor.GREEN+generatedString+ChatColor.RESET+ChatColor.GRAY+" - Il expirera le "+java.sql.Timestamp.valueOf(LocalDateTime.now().plusMinutes(5)).toString());
+
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+
+        }
+        return true;
+    }
+}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 888b33e..59d20de 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -11,4 +11,10 @@ commands:
     description: Te permet de te téléporter à une coordonnée aléatoire
     aliases: [wild, tpr, tprandom]
     usage: /wild
-    permission: slcraft.wild
\ No newline at end of file
+    permission: slcraft.wild
+
+  getlinkcode:
+    description: Te permet d'obtenir un code pour associer ton compte Minecraft au site internet du serveur.'
+    aliases: [ getlinkcode ]
+    usage: /getlinkcode
+    permission: slcraft.getlinkcode
\ No newline at end of file
diff --git a/target/classes/com/slprojects/slcraftplugin/Main.class b/target/classes/com/slprojects/slcraftplugin/Main.class
index dede04c7759f58dd94d7996915db5017addd35b0..369cff01cfd21bed898d96352ea3e53d30472f15 100644
GIT binary patch
delta 7359
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
SFfed2Ffv6m#WKY+NCE&TnFFr?

delta 4742
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
bk`GJ@fJq@H5e5bZE(S&>Q6_OFNd`#(oV_&Z

diff --git a/target/classes/com/slprojects/slcraftplugin/commandes/linkCodeCommand.class b/target/classes/com/slprojects/slcraftplugin/commandes/linkCodeCommand.class
new file mode 100644
index 0000000000000000000000000000000000000000..d88f9a248516da416cd959a48ca284dcb4bdc4b4
GIT binary patch
literal 5876
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

literal 0
HcmV?d00001

diff --git a/target/classes/plugin.yml b/target/classes/plugin.yml
index b53f9a6..91a79f0 100644
--- a/target/classes/plugin.yml
+++ b/target/classes/plugin.yml
@@ -1,5 +1,5 @@
 name: SLCraftPlugin
-version: '1.3'
+version: '1.4'
 main: com.slprojects.slcraftplugin.Main
 depend: [PlaceholderAPI]
 api-version: 1.18
@@ -11,4 +11,10 @@ commands:
     description: Te permet de te téléporter à une coordonnée aléatoire
     aliases: [wild, tpr, tprandom]
     usage: /wild
-    permission: slcraft.wild
\ No newline at end of file
+    permission: slcraft.wild
+
+  getlinkcode:
+    description: Te permet d'obtenir un code pour associer ton compte Minecraft au site internet du serveur.'
+    aliases: [ getlinkcode ]
+    usage: /getlinkcode
+    permission: slcraft.getlinkcode
\ No newline at end of file
diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties
index 7e0909c..f16796f 100644
--- a/target/maven-archiver/pom.properties
+++ b/target/maven-archiver/pom.properties
@@ -1,5 +1,5 @@
 #Generated by Maven
-#Fri Jan 28 14:26:51 CET 2022
+#Sat Mar 05 15:11:15 CET 2022
 groupId=com.slprojects
 artifactId=SLCraftPlugin
-version=1.3
+version=1.4
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
index b075f29..06d0095 100644
--- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -1,3 +1,4 @@
 com\slprojects\slcraftplugin\commandes\wildCommand.class
 com\slprojects\slcraftplugin\Main.class
+com\slprojects\slcraftplugin\commandes\linkCodeCommand.class
 com\slprojects\slcraftplugin\commandes\wildCommand$1.class
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
index 73ca63b..2251861 100644
--- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -1,2 +1,3 @@
 C:\Users\sofia\Documents\Minecraft Plugin Workspace\SL-Craft Plugin\src\main\java\com\slprojects\slcraftplugin\commandes\wildCommand.java
 C:\Users\sofia\Documents\Minecraft Plugin Workspace\SL-Craft Plugin\src\main\java\com\slprojects\slcraftplugin\Main.java
+C:\Users\sofia\Documents\Minecraft Plugin Workspace\SL-Craft Plugin\src\main\java\com\slprojects\slcraftplugin\commandes\linkCodeCommand.java
-- 
GitLab