diff --git a/src/connexion/Channel.java b/src/connexion/Channel.java new file mode 100644 index 0000000..8f39ebf --- /dev/null +++ b/src/connexion/Channel.java @@ -0,0 +1,69 @@ +package connexion; + +import environnements.*; +import types.Mouvement; +import personnages.Personnage; + +public class Channel extends Personnage { + private Reseau reseau; + + public Channel(Object[][] map, String channel) { + super(new int [] {19,19}); + reseau=new Reseau(channel); + } + + + /** + * Méthode permettant l'envoi de message, grâce à celle de Réseau + * @param String contenant la direction voulue + **/ + public void envoyerMessage(String s) { + reseau.sendContent(s); + } + + /** + * Méthode permettant la réception du dernier message envoyé, grâce à celle de Réseau + **/ + public String recupererMessage() { + return reseau.getLastedContent(); + } + + /** + * Méthode permettant de convertir un String en Mouvement + * (Le String est celui récupéré dans le channel) + * @param String s + * @return Mouvement + */ + public Mouvement conversion(String s){ + if (s.equals("U") || s.equals("u")){ + return Mouvement.HAUT; + }else if (s.equals("D") || s.equals("d")){ + return Mouvement.BAS; + }else if (s.equals("L") || s.equals("l")){ + return Mouvement.GAUCHE; + }else if (s.equals("R") || s.equals("r")){ + return Mouvement.DROITE; + } + return null; + } + + + /** + * Cette méthode est commune à toutes les sous-classes de personnages + * Elle permet de jouer. Ici, on bouge le personnage en fonction du String + * reçu dans le Channel, converti en Mouvement. + * @param map + * @return boolean qui indique si le Personnage est vivant ou pas. + */ + // @Override + public boolean round(Map map){ + int [] coordinate=this.getHeadCoordinate(); + this.moveSnake(conversion(recupererMessage())); + if (map.isGameOver(coordinate) || this.applyEffects(map.getEffect(coordinate))){ + return true; + } + map.deleteItems(coordinate); + this.increaseRound(); + return false; + } +} \ No newline at end of file diff --git a/src/connexion/Reseau.java b/src/connexion/Reseau.java new file mode 100644 index 0000000..8b30758 --- /dev/null +++ b/src/connexion/Reseau.java @@ -0,0 +1,281 @@ +package connexion; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import javax.net.ssl.HttpsURLConnection; + +import static java.util.Arrays.copyOfRange; + +/** + *

Cette classe est destiné un projet de fin d'année de L1, ne pas l'utiliser dans + * d'autre circonstance que dans ce projet. Elle contient plusieurs fonctions qui est + * utile pour la communication entre la machine et le site Padifac. + * + * @author Loïc GUEZO + * @version 1.0.0 + * @since 2024 + * @see Padiflac + */ +@SuppressWarnings("deprecation") + public class Reseau { + private static final String ADDRESS = "https://prog-reseau-m1.lacl.fr/padiflac/"; + private String CHANNEL; + private URL url; + + private ArrayList wordArrayList; + private ArrayList newerWordArrayList; + + private int index; + + /** + *

Le constructeur defini quelque information cruciale puis appelle directement la + * fonction {@code #searchContent()}. + * + * @param channel Ce string est utilisé pour se connecter à un channel dans le serveur web + */ + public Reseau(String channel) { + this.CHANNEL = channel; + this.wordArrayList = new ArrayList(); + this.newerWordArrayList = new ArrayList(); + + this.connexion(); + } + + /** + *

cette fonction redefini quelque information cruciale puis appelle directement la + * fonction {@code #searchContentSorted()}. + * + * @param channel Ce string est utilisé pour se reconnecter à un channel dans le serveur web + */ + public void reconnexion(String channel) { + this.CHANNEL = channel; + this.wordArrayList.clear(); + this.newerWordArrayList.clear(); + + this.connexion(); + } + + /** + * @return cette fonction renvoie tout ce qui est disponible sur le site quand on appelle la + * fonction searchContent et qui mets tout le texte dans le {@link ArrayList} + */ + public ArrayList getArrayContent() { + return this.wordArrayList; + } + + /** + * @return cette fonction renvoie uniquement les nouveauté de qui est disponible sur le site + * quand on appelle la fonction searchContent et qui mets tout le texte dans le {@link ArrayList} + */ + public ArrayList getNewArrayListContent() { + return this.newerWordArrayList; + } + + /** + *

cette fonction est en parallèle avec {@code #getLastedContent()} qui récupère le dernier indice + * utilisé lors de l'appelle de {@code #getLastedContent()}. + * @return renvoie le dernier indice + */ + public int getIndex() { + return this.index; + } + + /** + *

cette fonction est en parallèle avec {@code #getLastedContent()} et {@code #getIndex()}. Elle va + * reset l'indice. + */ + public void resetIndex() { + this.index = 0; + } + + /** + * @return cette fonction renvoie le String de l'indice puis l'incrémenter. Si c'est la fin de la liste, + * il renvoie null sans incrémenter + */ + public String getLastedContent() { + return (this.getArrayContent().size() > this.index) ? getArrayContent().get(this.index++) : null; + } + + /** + *

cherche les informations et trie seulement les nouvelles entre eux : + *


+     * Reseau reseau = new Reseau("ChatTest"); // dans le serveur : {"arbre", "pomme", "chocolat", "arbre"}
+     *System.out.println(reseau.searchContentSorted().toString()); // {"arbre", "arbre", "pomme", "chocolat"}
+     * 
+ * @return il renvoie le {@link ArrayList} de la liste + */ + public ArrayList searchContentSorted() { + ArrayList localNewerArrayList = this.searchContent(); + if (this.getArrayContent().isEmpty()) this.addContentToContent(localNewerArrayList); + else this.searchDuplicates(localNewerArrayList); + return this.wordArrayList; + } + + /** + *

cherche les informations mais ne trie pas les nouvelles entre eux : + *


+     * Reseau reseau = new Reseau("ChatTest"); // dans le serveur : {"arbre", "pomme", "chocolat", "arbre"}
+     *System.out.println(reseau.searchContentSorted().toString()); // {"arbre", "arbre", "pomme", "chocolat"}
+     * 
+ *

attention, il peut y avoir des erreurs en rajoutant par exemple {"arbre", "pomme", "chocolat", "pomme"} + * @return + */ + public ArrayList searchArrayListNotSorted() { + ArrayList localNewerArrayList = this.searchContent(); + this.addContentToContent(localNewerArrayList); + return this.wordArrayList; + } + + /** + *

ce programme essaye d'envoyer le String en parametre. Attention, la communication entre le serveur et la machine + * peut prendre du temps ! + * @param content Le contenu de texte que vous voulez renvoyer + */ + public void sendContent(String content) { + try { + this.url = new URL(ADDRESS + CHANNEL + "?nonce=" + this.generateNonce()); + HttpsURLConnection connection = (HttpsURLConnection)this.url.openConnection(); + + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + + OutputStream outputStream = connection.getOutputStream(); + outputStream.write(serializeToString(content)); + outputStream.close(); + + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + InputStream inputStream = connection.getInputStream(); + inputStream.close(); + } else { + System.out.println("Erreur lors de l'envoi de la requête. Code de réponse : " + responseCode); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private ArrayList searchContent() { + try { + byte[] bytes = this.url.openConnection().getInputStream().readAllBytes(); + ArrayList localNewerArrayList = new ArrayList(); + + StringBuffer textContent = new StringBuffer(); + + for(int i = 0; i < bytes.length; i++) { + byte charByte = bytes[i]; + + if(charByte == '|' && textContent.length() > 0) { + int size = Integer.parseInt(textContent.toString()); + byte[] buffer = copyOfRange(bytes, i + 1, i + 1 + size); + + localNewerArrayList.add(new String(buffer)); + + i += size; + textContent.setLength(0); + + } else { + textContent.append((char)charByte); + } + } + return localNewerArrayList; + + } catch (Exception e) { + return null; + } + } + + private void addContentToContent(ArrayList localArrayList) { + int arrayListLength = this.getArrayContent().size(); + + this.newerWordArrayList.clear(); + + for(int i = arrayListLength; i < localArrayList.size(); i++) { + String arrayListValue = localArrayList.get(i); + this.wordArrayList.add(arrayListValue); + this.newerWordArrayList.add(arrayListValue); + } + } + + private void searchDuplicates(ArrayList localArrayList) { + HashMap counterHashMap = this.compareHashMap( + arrayListToHashmapCounter(this.wordArrayList), + arrayListToHashmapCounter(localArrayList) + ); + + this.newerWordArrayList.clear(); + + for(Map.Entry value : counterHashMap.entrySet()) { + String arrayListValue = value.getKey(); + + for(int i =0; i arrayListToHashmapCounter(ArrayList list) { + HashMap hashmapListCounter = new HashMap(); + + for(int i = 0; i compareHashMap(HashMap olderHashMap, HashMap newerHashMap) { + HashMap hashMapCompared = new HashMap(); + + for (Map.Entry entry : newerHashMap.entrySet()) { + String key = entry.getKey(); + Integer newValue = entry.getValue(); + Integer oldValue = olderHashMap.get(key); + + if (oldValue == null) { + hashMapCompared.put(key, newValue); + } else if (newValue > oldValue) { + hashMapCompared.put(key, newValue - oldValue); + } + } + + return hashMapCompared; + } + + private String generateNonce() { + return UUID.randomUUID().toString().replace("-", "")+ + UUID.randomUUID().toString().replace("-", ""); + } + + private byte[] serializeToString(String text) throws IOException { + return text.getBytes(); + } + + private void connexion() { + try { + this.url = new URL(ADDRESS + CHANNEL); + + this.searchContentSorted(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file