From 668e472e712149913b6e4e785e586264ad739416 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Fri, 20 Aug 2021 15:47:11 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20commandes=20pour=20l'acc=C3=A8s=20?= =?UTF-8?q?aux=20parties.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 16 +- .../com/bernard/murder/audio/AudioServer.java | 150 ++++---- .../java/com/bernard/murder/audio/Codes.java | 101 +++++ .../com/bernard/murder/audio/MicServer.java | 30 +- .../com/bernard/murder/audio/Serveur.java | 25 +- .../bernard/murder/audio/SpeakerServer.java | 44 +-- .../com/bernard/murder/game/GameManager.java | 34 ++ .../murder/game/GameNetworkInterface.java | 356 ++++++++++++++++++ .../java/com/bernard/murder/model/Action.java | 12 +- .../com/bernard/murder/model/Personnage.java | 8 +- .../murder/model/messages/Message.java | 17 + .../bernard/murder/model/messages/Thread.java | 24 ++ .../murder/view/EnceinteServeurFrame.java | 4 +- .../bernard/murder/view/LauncherFrame.java | 8 +- .../bernard/murder/view/MicServeurFrame.java | 4 +- .../murder/view/minel/ActionsMinel.java | 4 +- .../murder/view/minel/ServeurMinel.java | 3 +- 17 files changed, 703 insertions(+), 137 deletions(-) create mode 100644 src/main/java/com/bernard/murder/audio/Codes.java create mode 100644 src/main/java/com/bernard/murder/game/GameNetworkInterface.java create mode 100644 src/main/java/com/bernard/murder/model/messages/Message.java create mode 100644 src/main/java/com/bernard/murder/model/messages/Thread.java diff --git a/build.gradle b/build.gradle index 5621793..21b1bcf 100644 --- a/build.gradle +++ b/build.gradle @@ -12,10 +12,22 @@ apply plugin: 'eclipse' repositories { // Use jcenter for resolving dependencies. // You can declare any Maven/Ivy/file repository here. - jcenter() mavenCentral() + } +task apiJar(type: Jar) { +archiveFileName = "MurderatorAPI.jar" + group 'build' + description "Fait un jar avec juste l'api" + from(sourceSets.main.output) { + include "com/bernard/murder/model/**" + include "com/bernard/murder/audio/Serveur*.class" + include "com/bernard/murder/audio/Codes*.class" + } +} + + jar { manifest { attributes( @@ -32,4 +44,6 @@ dependencies { implementation 'com.amihaiemil.web:eo-yaml:5.2.1' implementation 'com.formdev:flatlaf:1.3' + implementation files('../../bernard/BernardLibs.git/build/libs/BernardLibs.jar') + } diff --git a/src/main/java/com/bernard/murder/audio/AudioServer.java b/src/main/java/com/bernard/murder/audio/AudioServer.java index 8e2fd3f..75b7dff 100755 --- a/src/main/java/com/bernard/murder/audio/AudioServer.java +++ b/src/main/java/com/bernard/murder/audio/AudioServer.java @@ -6,6 +6,7 @@ import java.net.SocketException; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -13,6 +14,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ThreadLocalRandom; import java.util.Set; import java.util.UUID; import java.util.function.Consumer; @@ -25,54 +27,24 @@ import com.amihaiemil.eoyaml.Yaml; import com.amihaiemil.eoyaml.YamlMapping; import com.amihaiemil.eoyaml.YamlNode; import com.amihaiemil.eoyaml.YamlSequenceBuilder; +import com.bernard.murder.game.GameManager; +import com.bernard.murder.game.GameNetworkInterface; +import com.bernard.murder.model.Personnage; import com.bernard.util.BytesUtils; import com.bernard.util.ParseUtils; import com.bernard.util.YamlUtils; public class AudioServer { - // Format des paquets [commande 1, UUID identifier, byte deviceType, String name] - public static final byte DECLARE_NUMBER = 0x02; - // Format des paquets [commande 1, UUID identifier, byte deviceType, int id] - public static final byte OK_ID = 0x03; - // Format des paquets [commande 1] - public static final byte ASK_AUDIO_LIST= 0x04; - // Format des paquets [commande 1, int Count, {int id, String name}] - public static final byte GIVE_AUDIO_LIST = 0x05; - // Format des paquets: [commande 1, int listenId, int myId] - // -> Une enceinte demande à master le son d'un micro - public static final byte ASK_STREAMING = 0x06; - // Format des paquets: [commande 1, int id] - // -> Master demande à un micro d'envoyer du son - public static final byte START_STREAMING = 0x07; - // Format des paquets: [commande 1, int listenId, int myId] - // -> Une enceinte demande à master de ne plus recevoir le son d'un micro - public static final byte ASK_STOP_STREAMING = 0x09; - // Format des paquets: [commande 1, int id] - // -> Master demande à un micro de ne plus émettre. - // -> Master annonce à une enceinte qu'il n'emmet plus le micro demandé. - public static final byte STOP_STREAMING = 0x08; - // Format des paquets [commande 1, int id, ~ data] - public static final byte AUDIO_STREAM = 0x01; - // Format des paquets [commande 1, byte deviceType, int deviceId] - // Un terminal indique qu'il se ferme à la connection - public static final byte DISCONNECTING = 0x0A; - - - public static final byte MASTER_DEVICE = 0x42; - public static final byte SPEAKER_DEVICE = 0x01; - public static final byte MIC_DEVICE = 0x02; - - public static AudioFormat formatAudio = new AudioFormat(8000f, 16, 1, true, true); - public static int packetMaxSize = 97282; - public static int communicationPort = 35295; public Serveur serveur; int micId = 0; int speakerId = 0; + private GameNetworkInterface gameInterface; + Map mics; Map speakers; Map micsAddr; @@ -82,7 +54,7 @@ public class AudioServer { private Set changeListeners; private Set> serverErrorException; - public AudioServer() throws SocketException, UnknownHostException { + public AudioServer(GameManager manager) throws SocketException, UnknownHostException { mics = new HashMap(); micsAddr = new HashMap(); speakers = new HashMap(); @@ -92,11 +64,13 @@ public class AudioServer { changeListeners = new HashSet<>(); serverErrorException = new HashSet<>(); + gameInterface = new GameNetworkInterface(manager, this); + initServer(); } - public AudioServer(YamlMapping data) throws SocketException, UnknownHostException { - this(); + public AudioServer(GameManager manager, YamlMapping data) throws SocketException, UnknownHostException { + this(manager); for(YamlNode spkn : data.yamlMapping("enceintes").values()) { try { YamlMapping spk = spkn.asMapping(); @@ -143,7 +117,7 @@ public class AudioServer { } public void initServer() throws SocketException, UnknownHostException { - serveur = new Serveur(this::receiveCommand, AudioServer.communicationPort); + serveur = new Serveur(this::receiveCommand, Codes.communicationPort); } public void receiveCommand(ByteBuffer data,SocketAddress senderAddress) { @@ -151,29 +125,29 @@ public class AudioServer { System.out.println("Commande reçue : "+commande+" de "+senderAddress+" de taille "+(data.limit()+1)); switch (commande) { - case AudioServer.DECLARE_NUMBER: + case Codes.DECLARE_NUMBER: UUID uuid = new UUID(data.getLong(), data.getLong()); byte deviceType = data.get(); String deviceName = BytesUtils.readString(data); int newId; switch (deviceType) { - case AudioServer.MIC_DEVICE: + case Codes.Device.MIC_DEVICE: newId = micId++; mics.put(newId, deviceName); micsAddr.put(newId, senderAddress); listening.put(newId, new ArrayList<>()); publishAudioList(speakersAddr.values()); break; - case AudioServer.SPEAKER_DEVICE: + case Codes.Device.SPEAKER_DEVICE: newId = speakerId++; speakers.put(newId, deviceName); speakersAddr.put(newId, senderAddress); break; default:return; } - ByteBuffer out = ByteBuffer.allocate(AudioServer.packetMaxSize); - out.put(AudioServer.OK_ID); + ByteBuffer out = ByteBuffer.allocate(Codes.packetMaxSize); + out.put(Codes.OK_ID); out.putLong(uuid.getMostSignificantBits()); out.putLong(uuid.getLeastSignificantBits()); out.put(deviceType); @@ -186,15 +160,15 @@ public class AudioServer { changeListeners.forEach(Runnable::run); System.out.println("Accepting request from "+senderAddress); break; - case AudioServer.ASK_STREAMING: + case Codes.ASK_STREAMING: int listened = data.getInt(); int listener = data.getInt(); if(listening.get(listened).contains(listener)) break; - ByteBuffer out3 = ByteBuffer.allocate(AudioServer.packetMaxSize); - out3.put(AudioServer.START_STREAMING); + ByteBuffer out3 = ByteBuffer.allocate(Codes.packetMaxSize); + out3.put(Codes.START_STREAMING); out3.putInt(listened); try { serveur.sendData(out3, micsAddr.get(listened)); @@ -206,7 +180,7 @@ public class AudioServer { } break; - case AudioServer.ASK_STOP_STREAMING: + case Codes.ASK_STOP_STREAMING: int listened2 = data.getInt(); int listener2 = data.getInt(); if(listened2==-1)break; @@ -219,8 +193,8 @@ public class AudioServer { if(listening.get(listened2).isEmpty()) { try { - ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize); - out4.put(AudioServer.STOP_STREAMING); + ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize); + out4.put(Codes.STOP_STREAMING); out4.putInt(listened2); serveur.sendData(out4, micsAddr.get(listened2)); @@ -230,7 +204,7 @@ public class AudioServer { } break; - case AudioServer.AUDIO_STREAM: + case Codes.AUDIO_STREAM: int micId = data.getInt(); data.position(data.limit()); @@ -246,17 +220,17 @@ public class AudioServer { break; - case AudioServer.ASK_AUDIO_LIST: + case Codes.ASK_AUDIO_LIST: System.out.println("Sending audio list to "+senderAddress+" : "); publishAudioList(Collections.singleton(senderAddress)); break; - case AudioServer.DISCONNECTING: + case Codes.DISCONNECTING: byte deviceType2 = data.get(); int deviceId = data.getInt(); - if(deviceType2==AudioServer.MIC_DEVICE) { + if(deviceType2==Codes.Device.MIC_DEVICE) { // On le déréférence if(!mics.containsKey(deviceId)) { System.out.println("Le micro d'id "+deviceId+" est déjà désinscrit"); @@ -270,9 +244,9 @@ public class AudioServer { // On enlève tous les liens d'écoute for(int spkId : listening.get(deviceId)) { // Annoncer à ce speaker que le micro est déconnécté et qu'il ne peut plus l'écouter. - ByteBuffer out5 = ByteBuffer.allocate(AudioServer.packetMaxSize); - out5.put(AudioServer.DISCONNECTING); - out5.put(AudioServer.MIC_DEVICE); + ByteBuffer out5 = ByteBuffer.allocate(Codes.packetMaxSize); + out5.put(Codes.DISCONNECTING); + out5.put(Codes.Device.MIC_DEVICE); out5.putInt(deviceId); try { serveur.sendData(out5, speakersAddr.get(spkId)); @@ -283,7 +257,7 @@ public class AudioServer { listening.remove(deviceId); publishAudioList(speakersAddr.values()); - }else if(deviceType2==AudioServer.SPEAKER_DEVICE) { + }else if(deviceType2==Codes.Device.SPEAKER_DEVICE) { // On le déréférence System.out.println("Déconnection de l'enceinte "+speakers.get(deviceId)); @@ -299,8 +273,8 @@ public class AudioServer { if(listening.get(lstTo).isEmpty()) { // Si il n'y a plus rien à écouter. try { - ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize); - out4.put(AudioServer.STOP_STREAMING); + ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize); + out4.put(Codes.STOP_STREAMING); out4.putInt(lstTo); serveur.sendData(out4, micsAddr.get(lstTo)); } catch (IOException e1) { @@ -313,7 +287,19 @@ public class AudioServer { System.err.println("Je ne sais pas comment réagir à la déconnection d'un appareil de type "+deviceType2); } break; - + case Codes.PING: + ByteBuffer outPong = ByteBuffer.allocate(Codes.packetMaxSize); + outPong.put(Codes.PONG); + try { + serveur.sendData(outPong, senderAddress); + } catch (IOException e) { + e.printStackTrace(); + } + break; + case Codes.ACCES_PARTIE: + // On délègue + gameInterface.receiveCommand(data, senderAddress); + break; default: System.out.println("Je ne devait pas recevoir cette commade !"); } @@ -342,8 +328,8 @@ public class AudioServer { } public void publishAudioList(Collection to) { - ByteBuffer out = ByteBuffer.allocate(AudioServer.packetMaxSize); - out.put(AudioServer.GIVE_AUDIO_LIST); + ByteBuffer out = ByteBuffer.allocate(Codes.packetMaxSize); + out.put(Codes.GIVE_AUDIO_LIST); out.putInt(mics.size()); for(Entry mic : mics.entrySet()) { out.putInt(mic.getKey()); @@ -377,8 +363,8 @@ public class AudioServer { listening.get(lstTo).remove(id); // Si il n'y a plus rien à écouter. - ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize); - out4.put(AudioServer.STOP_STREAMING); + ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize); + out4.put(Codes.STOP_STREAMING); out4.putInt(lstTo); try { serveur.sendData(out4, speakersAddr.get(id)); @@ -394,9 +380,9 @@ public void disconnectEnceinte(int id) { if(!speakers.containsKey(id)) return; // On lui annonce notre déconnection, puis on la supprime des données - ByteBuffer decoBuf = ByteBuffer.allocate(AudioServer.packetMaxSize); - decoBuf.put(AudioServer.DISCONNECTING); - decoBuf.put(AudioServer.MASTER_DEVICE); + ByteBuffer decoBuf = ByteBuffer.allocate(Codes.packetMaxSize); + decoBuf.put(Codes.DISCONNECTING); + decoBuf.put(Codes.Device.MASTER_DEVICE); decoBuf.putInt(0); try { serveur.sendData(decoBuf, speakersAddr.get(id)); @@ -415,8 +401,8 @@ public void disconnectEnceinte(int id) { if(listening.get(lstTo).isEmpty()) { // Si il n'y a plus rien à écouter. - ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize); - out4.put(AudioServer.STOP_STREAMING); + ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize); + out4.put(Codes.STOP_STREAMING); out4.putInt(lstTo); try { serveur.sendData(out4, micsAddr.get(lstTo)); @@ -433,9 +419,9 @@ public void disconnectEnceinte(int id) { if(!mics.containsKey(id)) return; // On lui annonce notre déconnection, puis on la supprime des données - ByteBuffer decoBuf = ByteBuffer.allocate(AudioServer.packetMaxSize); - decoBuf.put(AudioServer.DISCONNECTING); - decoBuf.put(AudioServer.MASTER_DEVICE); + ByteBuffer decoBuf = ByteBuffer.allocate(Codes.packetMaxSize); + decoBuf.put(Codes.DISCONNECTING); + decoBuf.put(Codes.Device.MASTER_DEVICE); decoBuf.putInt(0); try { serveur.sendData(decoBuf, micsAddr.get(id)); @@ -448,8 +434,8 @@ public void disconnectEnceinte(int id) { changeListeners.forEach(Runnable::run); for(int lster : listening.get(id)) { - ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize); - out4.put(AudioServer.STOP_STREAMING); + ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize); + out4.put(Codes.STOP_STREAMING); out4.putInt(id); try { serveur.sendData(out4, speakersAddr.get(lster)); @@ -473,7 +459,7 @@ public void disconnectEnceinte(int id) { changeListeners.forEach(Runnable::run); - serveur.dispose(); + serveur.close(); } public YamlMapping saveToYaml() { @@ -508,4 +494,16 @@ public void disconnectEnceinte(int id) { } + + public void genPasswords() { //XXX : Refaire ce système avec considération pour les OPés aussi ^^ + for(Personnage perso : gameInterface.theManager.partie().personnages()) { + byte[] tokenBytes = new byte[6]; + ThreadLocalRandom.current().nextBytes(tokenBytes); + String pass = Base64.getUrlEncoder().encodeToString(tokenBytes); + pass = "bb"; + gameInterface.addPass(perso.getNom(),pass); + System.out.println("Mdp de "+perso.getNom()+": "+pass); + + } + } } diff --git a/src/main/java/com/bernard/murder/audio/Codes.java b/src/main/java/com/bernard/murder/audio/Codes.java new file mode 100644 index 0000000..2a5df10 --- /dev/null +++ b/src/main/java/com/bernard/murder/audio/Codes.java @@ -0,0 +1,101 @@ +package com.bernard.murder.audio; + +public class Codes { + + public static class Device{ + public static final byte MASTER_DEVICE = 0x42; + public static final byte SPEAKER_DEVICE = 0x01; + public static final byte MIC_DEVICE = 0x02; + } + + public static int packetMaxSize = 97282; + public static int communicationPort = 35295; + + + + // Format des paquets [commande 1, UUID identifier, byte deviceType, String name] + public static final byte DECLARE_NUMBER = 0x02; + // Format des paquets [commande 1, UUID identifier, byte deviceType, int id] + public static final byte OK_ID = 0x03; + // Format des paquets [commande 1] + public static final byte ASK_AUDIO_LIST= 0x04; + // Format des paquets [commande 1, int Count, {int id, String name}] + public static final byte GIVE_AUDIO_LIST = 0x05; + // Format des paquets: [commande 1, int listenId, int myId] + // -> Une enceinte demande à master le son d'un micro + public static final byte ASK_STREAMING = 0x06; + // Format des paquets: [commande 1, int id] + // -> Master demande à un micro d'envoyer du son + public static final byte START_STREAMING = 0x07; + // Format des paquets: [commande 1, int listenId, int myId]e.printStackTrace(); + // -> Une enceinte demande à master de ne plus recevoir le son d'un micro + public static final byte ASK_STOP_STREAMING = 0x09; + // Format des paquets: [commande 1, int id] + // -> Master demande à un micro de ne plus émettre. + // -> Master annonce à une enceinte qu'il n'emmet plus le micro demandé. + public static final byte STOP_STREAMING = 0x08; + // Format des paquets [commande 1, int id, ~ data] + public static final byte AUDIO_STREAM = 0x01; + // Format des paquets [commande 1, byte deviceType, int deviceId] + // Un terminal indique qu'il se ferme à la connection + public static final byte DISCONNECTING = 0x0A; + + // Envoie la commande au gamemanager afin que la commande accède à la partie. + public static final byte ACCES_PARTIE = 0x2A; + + public static final byte PING = 0x3A; + public static final byte PONG = 0x3B; + + + public static class Partie { + // [ACCÈS_PARTIE, commandePartie 1, String opName, String mdp] + public static final byte ASK_OP_TOKEN = 0x71; + // [ACCÈS_PARTIE, commandePartie 1, String joueurName, String mdp] + public static final byte ASK_JOUEUR_TOKEN = 0x72; + // [ACCÈS_PARTIE, commandePartie 1, String token] + public static final byte GIVING_TOKEN = 0x73; + // [ACCÈS_PARTIE, commandePartie 1, String token] + public static final byte AUTH_ERROR = 0x75; + + + + //Entête de tous le paquets: [ACCÈS_PARTIE, commandePartie 1] + + // [] (pas besoin du token) + public static final byte ASK_PLAYER_LIST = 0x01; + // [int nombreDeJoueurs, nombreDeJoueurs*String joueursNames] + public static final byte GIVE_PLAYER_LIST = 0x02; + + // [String token, String inventoryName] + public static final byte ASK_INVENTORY = 0x03; + // [String token, String inventoryName] + public static final byte ASK_INVENTORY_WATCH = 0x04; + // [String inventoryName, int objCount, objCount*String objNames] + public static final byte INVENTORY_CONTENT = 0x05; + + // [String token, String persoName] + public static final byte ASK_ACTIONS = 0x06; + // [String token, String persoName] + public static final byte ASK_ACTIONS_WATCH = 0x07; + // [String persoName, int actionCount, (String actionName, long basetime, long triggertime)*actionCount] + public static final byte ACTIONS_STATUS = 0x08; + + // [String token, UUID askCode, long startTimestamp] + public static final byte ASK_NEW_THREAD = 0x09; + // [UUID askCode, String persoName, long uid, long startTimestamp] + public static final byte CREATED_NEW_THREAD = 0x0A; + /// [String token, long uid, long closeTimestamp] + public static final byte CLOSE_NEW_THREAD = 0x0B; + // [long uid, long closeTimestamp] + public static final byte CLOSED_THREAD = 0x0C; + // [String token, long sendTimestamp, @Nullable long threadUid, String emmeteur, String texte] + public static final byte SEND_MESSAGE = 0x0D; + // [long sendTimestamp, @Nullable long threadUid, @Nullable int threadPosition, String emmeteur, String texte] + public static final byte NEW_MESSAGE = 0x0D; + + // [String token, long threadUid, @Nullable String op] + public static final byte ASK_ASSIGNATION = 0x10; + // [String token, long threadUid, @Nulalble String newOp] + public static final byte CREATED_ASSIGNATION = 0x11; + } +} diff --git a/src/main/java/com/bernard/murder/audio/MicServer.java b/src/main/java/com/bernard/murder/audio/MicServer.java index 2442ab2..185a594 100755 --- a/src/main/java/com/bernard/murder/audio/MicServer.java +++ b/src/main/java/com/bernard/murder/audio/MicServer.java @@ -60,19 +60,19 @@ public class MicServer { } public void initServer() throws SocketException, UnknownHostException { - serveur = new Serveur(this::receiveCommand, AudioServer.communicationPort); + serveur = new Serveur(this::receiveCommand, Codes.communicationPort); } public void initializeAudioId() { - ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize); + ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize); askedUUID = UUID.randomUUID(); - buffer.put(AudioServer.DECLARE_NUMBER); + buffer.put(Codes.DECLARE_NUMBER); buffer.putLong(askedUUID.getMostSignificantBits()); buffer.putLong(askedUUID.getLeastSignificantBits()); - buffer.put(AudioServer.MIC_DEVICE); + buffer.put(Codes.Device.MIC_DEVICE); BytesUtils.writeString(buffer, micName); @@ -88,26 +88,26 @@ public class MicServer { System.out.println("Commande reçue : "+commande); switch (commande) { - case AudioServer.START_STREAMING: + case Codes.START_STREAMING: int askedMicId = data.getInt(); if(askedMicId != this.micId)return; shouldStream = true; micLine.start(); launchDataStream(); break; - case AudioServer.STOP_STREAMING: + case Codes.STOP_STREAMING: int askedMicId2 = data.getInt(); if(askedMicId2 != this.micId)return; shouldStream = false; micLine.stop(); break; - case AudioServer.OK_ID: + case Codes.OK_ID: UUID uuid = new UUID(data.getLong(), data.getLong()); byte deviceType = data.get(); int deviceId = data.getInt(); - if(!askedUUID.equals(uuid) || deviceType!=AudioServer.MIC_DEVICE) + if(!askedUUID.equals(uuid) || deviceType!=Codes.Device.MIC_DEVICE) return; this.micId = deviceId; @@ -122,9 +122,9 @@ public class MicServer { } break; - case AudioServer.DISCONNECTING: + case Codes.DISCONNECTING: byte deviceType2 = data.get(); - if(deviceType2==AudioServer.MASTER_DEVICE) { + if(deviceType2==Codes.Device.MASTER_DEVICE) { System.out.println("Le master s'est déconnécté, on fait de même !"); masterAddress=null; this.dispose(); @@ -143,7 +143,7 @@ public class MicServer { streamingThread = new Thread(()->{ byte[] packetData = new byte[1+4+packetLength]; ByteBuffer audioPacket = ByteBuffer.wrap(packetData); - audioPacket.put(AudioServer.AUDIO_STREAM); + audioPacket.put(Codes.AUDIO_STREAM); audioPacket.putInt(micId); audioPacket.position(audioPacket.position()+packetLength); micLine.start(); @@ -163,9 +163,9 @@ public class MicServer { public void dispose() { if(masterAddress!=null) { - ByteBuffer decoPacket = ByteBuffer.allocate(AudioServer.packetMaxSize); - decoPacket.put(AudioServer.DISCONNECTING); - decoPacket.put(AudioServer.MIC_DEVICE); + ByteBuffer decoPacket = ByteBuffer.allocate(Codes.packetMaxSize); + decoPacket.put(Codes.DISCONNECTING); + decoPacket.put(Codes.Device.MIC_DEVICE); decoPacket.putInt(micId); try { serveur.sendData(decoPacket,masterAddress); @@ -175,7 +175,7 @@ public class MicServer { } shouldStream=false; micLine.close(); - serveur.dispose(); + serveur.close(); } public void setServerAnswered(Runnable serverAnswered) { diff --git a/src/main/java/com/bernard/murder/audio/Serveur.java b/src/main/java/com/bernard/murder/audio/Serveur.java index a455e43..8913b57 100755 --- a/src/main/java/com/bernard/murder/audio/Serveur.java +++ b/src/main/java/com/bernard/murder/audio/Serveur.java @@ -29,6 +29,8 @@ public class Serveur { volatile boolean isReceiving = false; + boolean networkOnSeparatedThread = false; + BiConsumer consumer; public Serveur(Consumer dataEater, int port) throws UnknownHostException, SocketException { @@ -116,7 +118,22 @@ public class Serveur { public void sendData(byte[] data, SocketAddress address) throws IOException { if(data.length < packetMaxLength) { DatagramPacket packet = new DatagramPacket(data, data.length,address); - socket.send(packet); + if(networkOnSeparatedThread) { + Thread subLauncher = new Thread(() -> { + try { + socket.send(packet); + } catch (IOException e) { + Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e); + } + }); + subLauncher.start(); + try { + subLauncher.join(); + } catch (InterruptedException e) {} + + } + else + socket.send(packet); }else { //XXX Ça, ca ne marche pas ! short packetCount = (short) (data.length / (packetMaxLength-42)); @@ -154,10 +171,14 @@ public class Serveur { } } - public void dispose() { + public void close() { isReceiving = false; socket.close(); packetReceiver.interrupt(); } + public void setNetworkOnSeparatedThread(boolean networkOnSeparatedThread) { + this.networkOnSeparatedThread = networkOnSeparatedThread; + } + } diff --git a/src/main/java/com/bernard/murder/audio/SpeakerServer.java b/src/main/java/com/bernard/murder/audio/SpeakerServer.java index 9e57cf2..ebf414a 100755 --- a/src/main/java/com/bernard/murder/audio/SpeakerServer.java +++ b/src/main/java/com/bernard/murder/audio/SpeakerServer.java @@ -62,7 +62,7 @@ public class SpeakerServer { } public void initServer() throws SocketException, UnknownHostException { - serveur = new Serveur(this::receiveCommand,AudioServer.communicationPort); + serveur = new Serveur(this::receiveCommand,Codes.communicationPort); } public void initializeSpeakerDevice() throws LineUnavailableException { @@ -71,15 +71,15 @@ public class SpeakerServer { } public void initializeAudioId() { - ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize); + ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize); askedUUID = UUID.randomUUID(); - buffer.put(AudioServer.DECLARE_NUMBER); + buffer.put(Codes.DECLARE_NUMBER); buffer.putLong(askedUUID.getMostSignificantBits()); buffer.putLong(askedUUID.getLeastSignificantBits()); - buffer.put(AudioServer.SPEAKER_DEVICE); + buffer.put(Codes.Device.SPEAKER_DEVICE); BytesUtils.writeString(buffer, speakerName); @@ -97,10 +97,10 @@ public class SpeakerServer { return; - ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize); + ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize); - buffer.put(AudioServer.ASK_STREAMING); + buffer.put(Codes.ASK_STREAMING); buffer.putInt(micId); buffer.putInt(speakerId); @@ -117,10 +117,10 @@ public class SpeakerServer { System.out.println("J'arêtte d'écouter le vide"); return; } - ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize); + ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize); - buffer.put(AudioServer.ASK_STOP_STREAMING); + buffer.put(Codes.ASK_STOP_STREAMING); buffer.putInt(listeningTo); buffer.putInt(speakerId); @@ -133,8 +133,8 @@ public class SpeakerServer { } public void askAudioList() { - ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize); - buffer.put(AudioServer.ASK_AUDIO_LIST); + ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize); + buffer.put(Codes.ASK_AUDIO_LIST); try { serveur.sendData(buffer,masterAddress); } catch (IOException e) { @@ -147,7 +147,7 @@ public class SpeakerServer { System.out.println("Commande recue : "+commande); switch (commande) { - case AudioServer.AUDIO_STREAM: + case Codes.AUDIO_STREAM: int micId = data.getInt(); if(micId != listeningTo)break; byte[] audioData=new byte[data.remaining()]; @@ -155,12 +155,12 @@ public class SpeakerServer { speakerLine.write(audioData, 0, audioData.length); break; - case AudioServer.OK_ID: + case Codes.OK_ID: UUID uuid = new UUID(data.getLong(), data.getLong()); byte deviceType = data.get(); int deviceId = data.getInt(); - if(!askedUUID.equals(uuid) || deviceType!=AudioServer.SPEAKER_DEVICE) + if(!askedUUID.equals(uuid) || deviceType!=Codes.Device.SPEAKER_DEVICE) return; speakerId = deviceId; @@ -174,7 +174,7 @@ public class SpeakerServer { askAudioList(); break; - case AudioServer.GIVE_AUDIO_LIST: + case Codes.GIVE_AUDIO_LIST: int micCount = data.getInt(); mics = new HashMap(micCount); for(int i = 0; i c.accept(mics)); break; - case AudioServer.DISCONNECTING: + case Codes.DISCONNECTING: byte deviceType2 = data.get(); int deviceId2 = data.getInt(); - if(deviceType2==AudioServer.MASTER_DEVICE) { + if(deviceType2==Codes.Device.MASTER_DEVICE) { System.out.println("Le master s'est déconnécté, on fait de même !"); masterAddress=null; this.dispose(); for(Runnable toRun : disconnectListener) toRun.run(); - }else if(deviceType2==AudioServer.MIC_DEVICE){ + }else if(deviceType2==Codes.Device.MIC_DEVICE){ if(listeningTo==deviceId2) { System.out.println("Le micro que l'on écoutait s'est déconnécté."); listeningTo=-1; @@ -205,7 +205,7 @@ public class SpeakerServer { System.out.println("Un appareil de type "+deviceType2+" s'est déconécté, mais je m'en fout ^^"); } break; - case AudioServer.STOP_STREAMING: + case Codes.STOP_STREAMING: int deviceId3 = data.getInt(); if(listeningTo==deviceId3) { System.out.println("Le micro que l'on écoutait arêtte d'émmetre."); @@ -220,9 +220,9 @@ public class SpeakerServer { } public void dispose() { if(masterAddress!=null) { - ByteBuffer decoPacket = ByteBuffer.allocate(AudioServer.packetMaxSize); - decoPacket.put(AudioServer.DISCONNECTING); - decoPacket.put(AudioServer.SPEAKER_DEVICE); + ByteBuffer decoPacket = ByteBuffer.allocate(Codes.packetMaxSize); + decoPacket.put(Codes.DISCONNECTING); + decoPacket.put(Codes.Device.SPEAKER_DEVICE); decoPacket.putInt(speakerId); try { serveur.sendData(decoPacket,masterAddress); @@ -235,7 +235,7 @@ public class SpeakerServer { speakerLine.stop(); speakerLine.close(); } - serveur.dispose(); + serveur.close(); } public void setServerAnswered(Runnable serverAnswered) { diff --git a/src/main/java/com/bernard/murder/game/GameManager.java b/src/main/java/com/bernard/murder/game/GameManager.java index 3f33e20..905497d 100644 --- a/src/main/java/com/bernard/murder/game/GameManager.java +++ b/src/main/java/com/bernard/murder/game/GameManager.java @@ -17,6 +17,7 @@ import javax.swing.Timer; import com.amihaiemil.eoyaml.Yaml; import com.amihaiemil.eoyaml.YamlMapping; +import com.bernard.murder.model.Action; import com.bernard.murder.model.Inventaire; import com.bernard.murder.model.Objet; import com.bernard.murder.model.Partie; @@ -26,6 +27,7 @@ public class GameManager { Partie partie; Map> inventoryUpdateListeners; + Map> actionsUpdateListeners; long startTime; @@ -36,6 +38,7 @@ public class GameManager { public GameManager(Partie partie) { this.partie = partie; this.inventoryUpdateListeners = new HashMap>(); + this.actionsUpdateListeners = new HashMap>(); this.minelsQuicksaver = () -> Yaml.createYamlMappingBuilder().build(); startTime = System.currentTimeMillis(); @@ -57,6 +60,14 @@ public class GameManager { for(Runnable r : inventoryUpdateListeners.get(inv)) r.run(); } + public void actionsUpdate(Action act) { + actionsUpdate(partie.personnagesStream().filter(p->p.getActions().contains(act)).findAny().get()); + } + public void actionsUpdate(Personnage inv) { + if(!actionsUpdateListeners.containsKey(inv))return; + for(Runnable r : actionsUpdateListeners.get(inv)) + r.run(); + } public void dumpCurrentState() { System.out.println(partie); @@ -67,6 +78,11 @@ public class GameManager { inventoryUpdateListeners.put(inv, new HashSet()); inventoryUpdateListeners.get(inv).add(runnable); } + public void addActionsUpdateListener(Personnage perso, Runnable runnable) { + if(!actionsUpdateListeners.containsKey(perso)) + actionsUpdateListeners.put(perso, new HashSet()); + actionsUpdateListeners.get(perso).add(runnable); + } public void quickSave() { File toSave = new File(quickSaveFilename()); @@ -114,6 +130,10 @@ public class GameManager { return partie.personnagesStream().filter(p -> key.equalsIgnoreCase(p.getNom())).findAny().orElse(null); } + public Personnage getPersoHavingAction(Action act) { + return partie.personnagesStream().filter(p -> p.getActions().contains(act)).findAny().orElse(null); + } + public void bindMinelQuicksaver(Supplier minelsQuicksaver) { this.minelsQuicksaver = minelsQuicksaver; } @@ -148,5 +168,19 @@ public class GameManager { inventoryUpdate(inv); } + public void launchAction(Action a) { + a.setTriggertime(System.currentTimeMillis()); + actionsUpdate(a); + } + + public void resetAction(Action a) { + a.setTriggertime(0); + actionsUpdate(a); + } + + public Partie partie() { + return partie; + } + } diff --git a/src/main/java/com/bernard/murder/game/GameNetworkInterface.java b/src/main/java/com/bernard/murder/game/GameNetworkInterface.java new file mode 100644 index 0000000..6448e0c --- /dev/null +++ b/src/main/java/com/bernard/murder/game/GameNetworkInterface.java @@ -0,0 +1,356 @@ +package com.bernard.murder.game; + +import java.io.IOException; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +import com.bernard.murder.audio.AudioServer; +import com.bernard.murder.audio.Codes; +import com.bernard.murder.model.Action; +import com.bernard.murder.model.Inventaire; +import com.bernard.murder.model.Objet; +import com.bernard.murder.model.Personnage; +import com.bernard.murder.model.messages.Message; +import com.bernard.murder.model.messages.Thread; +import com.bernard.util.BytesUtils; + +public class GameNetworkInterface { + + public GameManager theManager; + AudioServer theServer; + + + Map joueursTokens; // + Map opTokens; // + + Map passwords; // + + Map> messages; // + Map> messageListeners; // + + Set opNames; + + long globalThreadUid = 0L; + + public GameNetworkInterface(GameManager theManager, AudioServer theServer) { + this.theManager = theManager; + this.theServer = theServer; + + joueursTokens = new HashMap<>(); + opTokens = new HashMap<>(); + passwords = new HashMap<>(); + } + + + + + public synchronized void receiveCommand(ByteBuffer cmd,SocketAddress senderAddress) { + byte commandePartie = cmd.get(); + System.out.println("Sous-commande: "+commandePartie); + + String token; + switch(commandePartie) { + case Codes.Partie.ASK_OP_TOKEN: + case Codes.Partie.ASK_JOUEUR_TOKEN: + String name = BytesUtils.readString(cmd); + String mdp = BytesUtils.readString(cmd); + if(!passwords.get(name).equals(mdp)) { + // Pas autorisé !!! + authError(senderAddress, null); + return; + } + byte[] tokenBytes = new byte[72]; + ThreadLocalRandom.current().nextBytes(tokenBytes); + String newToken = Base64.getUrlEncoder().encodeToString(tokenBytes); + if(commandePartie == Codes.Partie.ASK_OP_TOKEN) { + opTokens.put(newToken, name); + opNames.add(name); + } + if(commandePartie == Codes.Partie.ASK_JOUEUR_TOKEN) + joueursTokens.put(newToken, name); + System.out.println("Ajout d'un joli token !"+opTokens+";"+joueursTokens); + + //XXX: On enregistre aussi la jolie adresse pour recevoir les messages, c'est cencé bouger + messageListeners.putIfAbsent(name, new HashSet<>()); + messageListeners.get(name).add(senderAddress); + + ByteBuffer outToken = ByteBuffer.allocate(Codes.packetMaxSize); + outToken.put(Codes.ACCES_PARTIE); + outToken.put(Codes.Partie.GIVING_TOKEN); + BytesUtils.writeString(outToken, newToken); + try { + theServer.serveur.sendData(outToken, senderAddress); + } catch (IOException e) { + e.printStackTrace(); + } + break; + + case Codes.Partie.ASK_PLAYER_LIST: + //Pas besoin du token pour cette requête + ByteBuffer outList = ByteBuffer.allocate(Codes.packetMaxSize); + outList.put(Codes.ACCES_PARTIE); + outList.put(Codes.Partie.GIVE_PLAYER_LIST); + Set persos = theManager.partie.personnages(); + outList.putInt(persos.size()); + for(Personnage perso:persos) + BytesUtils.writeString(outList, perso.getNom()); + try { + theServer.serveur.sendData(outList, senderAddress); + } catch (IOException e) { + e.printStackTrace(); + } + break; + + case Codes.Partie.ASK_INVENTORY: + case Codes.Partie.ASK_INVENTORY_WATCH: + + token = BytesUtils.readString(cmd); + String invName = BytesUtils.readString(cmd); + if(!opTokens.containsKey(token)) { + // Alors on teste le joueur. + String toktoktoken = token; + Personnage perso = theManager.partie.personnagesStream() + .filter(p -> p.getNom().equals(joueursTokens.get(toktoktoken))) + .findAny().orElse(null); + if(!(perso!=null && perso.getInventoryName().equals(invName))) { + authError(senderAddress, token); + return; + } + } + // Autorisééééé + sendInventoryContent(senderAddress,invName); + if(commandePartie==Codes.Partie.ASK_INVENTORY_WATCH) { + theManager.addInventoryUpdateListener(theManager.getInventoryByName(invName), () -> sendInventoryContent(senderAddress,invName)); + } + break; + + case Codes.Partie.ASK_ACTIONS: + case Codes.Partie.ASK_ACTIONS_WATCH: + + token = BytesUtils.readString(cmd); + String persoName = BytesUtils.readString(cmd); + if(!opTokens.containsKey(token)) { + // Alors on teste le joueur. + String toktoken = token; + Personnage perso = theManager.partie.personnagesStream() + .filter(p -> p.getNom().equals(joueursTokens.get(toktoken))) + .findAny().orElse(null); + if(!(perso!=null && perso.getNom().equals(persoName))) { + authError(senderAddress, token); + return; + } + } + // Autorisééééé + sendActionsStatus(senderAddress,persoName); + if(commandePartie==Codes.Partie.ASK_INVENTORY_WATCH) { + theManager.addActionsUpdateListener(theManager.getPersoByName(persoName), () -> sendActionsStatus(senderAddress,persoName)); + } + break; + + case Codes.Partie.ASK_NEW_THREAD: + token = BytesUtils.readString(cmd); + UUID requestId = new UUID(cmd.getLong(), cmd.getLong()); + long startTimestamp = cmd.getLong(); + + if(!joueursTokens.containsKey(token)) { + // Mé t ki en fét ? + authError(senderAddress, token); + return; + }else + persoName = joueursTokens.get(token); + + long newUid = globalThreadUid++; + Thread t = new Thread(persoName, startTimestamp, newUid); + messages.putIfAbsent(persoName, new ArrayList<>()); + messages.get(persoName).add(t); + + ByteBuffer outThr = ByteBuffer.allocate(Codes.packetMaxSize); + outThr.put(Codes.ACCES_PARTIE); + outThr.put(Codes.Partie.CREATED_NEW_THREAD); + outThr.putLong(requestId.getMostSignificantBits()); + outThr.putLong(requestId.getLeastSignificantBits()); + BytesUtils.writeString(outThr,persoName); + outThr.putLong(newUid); + outThr.putLong(startTimestamp); + + Set dests = new HashSet<>(); + dests.addAll(messageListeners.getOrDefault(persoName,Set.of())); // Tous les comptes du joueur + dests.add(senderAddress); // Celui qui a envoyé + dests.addAll(opAddresses()); // Et tous les opés + for(SocketAddress dest : dests){ + try { + theServer.serveur.sendData(outThr, dest); + } catch (IOException e) { + e.printStackTrace(); + } + } + break; + + case Codes.Partie.CLOSE_NEW_THREAD: + token = BytesUtils.readString(cmd); + long uidToClose = cmd.getLong(); + long closeTimestamp = cmd.getLong(); + + if(!joueursTokens.containsKey(token) && !opTokens.containsKey(token)) { + // Mé t ki en fét ? + authError(senderAddress, token); + return; + } + + + Thread ttc = threadFromUid(uidToClose); + persoName = ttc.joueur; + ttc.closeTime = closeTimestamp; + + ByteBuffer outThrC = ByteBuffer.allocate(Codes.packetMaxSize); + outThrC.put(Codes.ACCES_PARTIE); + outThrC.put(Codes.Partie.CLOSED_THREAD); + outThrC.putLong(uidToClose); + outThrC.putLong(closeTimestamp); + Set destsC = new HashSet<>(); + destsC.addAll(messageListeners.getOrDefault(persoName,Set.of())); // Tous les comptes du joueur + destsC.add(senderAddress); // Celui qui a envoyé + destsC.addAll(opAddresses()); // Et tous les opés + for(SocketAddress dest : destsC){ + try { + theServer.serveur.sendData(outThrC, dest); + } catch (IOException e) { + e.printStackTrace(); + } + } + break; + + case Codes.Partie.SEND_MESSAGE: + token = BytesUtils.readString(cmd); + long sendTimestamp = cmd.getLong(); + long threadUid = cmd.getLong(); + String emmeteur = BytesUtils.readString(cmd); + String message = BytesUtils.readString(cmd); + + + if(!(joueursTokens.containsKey(token) && joueursTokens.get(token).equals(emmeteur)) && + !(opTokens.containsKey(token) && opTokens.get(token).equals(emmeteur))) { + // Mé t ki en fét ? + authError(senderAddress, token); + return; + } + + if(threadUid<0) { + System.err.println("Je ne sais pas encore traiter les messages hors thread, revenez plus tard"); + return; + } + Thread tt = threadFromUid(threadUid); + Message mess = new Message(emmeteur, message, sendTimestamp); + int newPos = tt.messages.size(); + tt.messages.add(mess); + + ByteBuffer outMess = ByteBuffer.allocate(Codes.packetMaxSize); + outMess.put(Codes.ACCES_PARTIE); + outMess.put(Codes.Partie.NEW_MESSAGE); + outMess.putLong(sendTimestamp); + outMess.putLong(threadUid); + outMess.putInt(newPos); + BytesUtils.writeString(outMess,emmeteur); + BytesUtils.writeString(outMess,message); + + Set destsM = new HashSet<>(); + destsM.addAll(messageListeners.getOrDefault(tt.joueur,Set.of())); // Tous les comptes du joueur + destsM.add(senderAddress); // Celui qui a envoyé + destsM.addAll(opAddresses()); // Et tous les opés + for(SocketAddress dest : destsM){ + try { + theServer.serveur.sendData(outMess, dest); + } catch (IOException e) { + e.printStackTrace(); + } + } + break; + } + } + + public void sendInventoryContent(SocketAddress destinataire, String inventoryName) { + Inventaire inv = theManager.getInventoryByName(inventoryName); + ByteBuffer outInv = ByteBuffer.allocate(Codes.packetMaxSize); + outInv.put(Codes.ACCES_PARTIE); + outInv.put(Codes.Partie.INVENTORY_CONTENT); + Set objs = inv.getObjects(); + outInv.putInt(objs.size()); + for(Objet obj:objs) + BytesUtils.writeString(outInv, obj.getNom()); + try { + theServer.serveur.sendData(outInv, destinataire); + } catch (IOException e) { + e.printStackTrace(); + } + } + public void sendActionsStatus(SocketAddress destinataire, String persoName) { + System.out.println("Sending actions of "+persoName+ " to "+destinataire); + Personnage perso = theManager.getPersoByName(persoName); + ByteBuffer outPerso = ByteBuffer.allocate(Codes.packetMaxSize); + outPerso.put(Codes.ACCES_PARTIE); + outPerso.put(Codes.Partie.ACTIONS_STATUS); + BytesUtils.writeString(outPerso, persoName); + Set actions = perso.getActions(); + outPerso.putInt(actions.size()); + for(Action act:actions) { + BytesUtils.writeString(outPerso, act.getName()); + outPerso.putLong(act.getBasetime()); + outPerso.putLong(act.getTriggertime()); + } + try { + theServer.serveur.sendData(outPerso, destinataire); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void authError(SocketAddress responce, String token) { + System.out.println("Refus du token "+token); + ByteBuffer out = ByteBuffer.allocate(Codes.packetMaxSize); + out.put(Codes.ACCES_PARTIE); + out.put(Codes.Partie.AUTH_ERROR); + if(token!=null) + BytesUtils.writeString(out, token); + else + BytesUtils.writeString(out, ""); + try { + theServer.serveur.sendData(out, responce); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Set opAddresses(){ + return opNames.stream() + .map(messageListeners::get) + .reduce(new HashSet<>(), (a,b) -> {a.addAll(b);return a;}); + } + + + + public void addPass(String nom, String pass) { + passwords.put(nom, pass); + } + + public Thread threadFromUid(long theUid) { + return messages.values().stream() + .map(l -> l.stream().filter(t -> t.uid==theUid).findAny()) + .filter(Optional::isPresent) + .findAny() + .get() + .get()// Vérifié + ; + } + +} diff --git a/src/main/java/com/bernard/murder/model/Action.java b/src/main/java/com/bernard/murder/model/Action.java index a9844d5..1c12c84 100644 --- a/src/main/java/com/bernard/murder/model/Action.java +++ b/src/main/java/com/bernard/murder/model/Action.java @@ -39,14 +39,6 @@ public class Action implements Cloneable{ public boolean canBeLaunched() { return System.currentTimeMillis()-triggertime-basetime>0; } - - public void launch() { - triggertime=System.currentTimeMillis(); - } - - public void reset() { - triggertime=0; - } public boolean hasFinished() { return triggertime + basetime - System.currentTimeMillis()<0; @@ -68,6 +60,10 @@ public class Action implements Cloneable{ return triggertime; } + public void setTriggertime(long triggertime) { + this.triggertime = triggertime; + } + } diff --git a/src/main/java/com/bernard/murder/model/Personnage.java b/src/main/java/com/bernard/murder/model/Personnage.java index 6c8ddf0..15d7d87 100644 --- a/src/main/java/com/bernard/murder/model/Personnage.java +++ b/src/main/java/com/bernard/murder/model/Personnage.java @@ -3,7 +3,7 @@ package com.bernard.murder.model; import java.util.Set; import java.util.stream.Stream; -public class Personnage implements Inventaire{ +public class Personnage implements Inventaire { String nom; Set inventaire; @@ -82,7 +82,11 @@ public class Personnage implements Inventaire{ @Override public String getInventoryName() { - return "Inventaire de "+getNom(); + return getInventoryNameFromPersoName(getNom()); + } + + public static final String getInventoryNameFromPersoName(String persoName) { + return "Inventaire de "+persoName; } diff --git a/src/main/java/com/bernard/murder/model/messages/Message.java b/src/main/java/com/bernard/murder/model/messages/Message.java new file mode 100644 index 0000000..a532543 --- /dev/null +++ b/src/main/java/com/bernard/murder/model/messages/Message.java @@ -0,0 +1,17 @@ +package com.bernard.murder.model.messages; + +public class Message { + + public String emmeteur; + public String texte; + public long sendTimestamp; + + public Message(String emmeteur, String texte, long sendTimestamp) { + this.emmeteur = emmeteur; + this.texte = texte; + this.sendTimestamp = sendTimestamp; + } + + + +} diff --git a/src/main/java/com/bernard/murder/model/messages/Thread.java b/src/main/java/com/bernard/murder/model/messages/Thread.java new file mode 100644 index 0000000..7a6a483 --- /dev/null +++ b/src/main/java/com/bernard/murder/model/messages/Thread.java @@ -0,0 +1,24 @@ +package com.bernard.murder.model.messages; + +import java.util.ArrayList; +import java.util.List; + +public class Thread { + + public String joueur; + public long openTimestamp; + public String opAssigne; + public List messages; + public long closeTime = -1; + public long uid; + + public Thread(String joueur, long openTimestamp, long uid) { + this.joueur = joueur; + this.openTimestamp = openTimestamp; + this.messages = new ArrayList<>(); + this.uid = uid; + } + + + +} diff --git a/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java b/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java index f7b4ac9..4db67f3 100755 --- a/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java +++ b/src/main/java/com/bernard/murder/view/EnceinteServeurFrame.java @@ -28,7 +28,7 @@ import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import com.bernard.murder.audio.AudioServer; +import com.bernard.murder.audio.Codes; import com.bernard.murder.audio.SpeakerServer; public class EnceinteServeurFrame extends JFrame{ @@ -76,7 +76,7 @@ public class EnceinteServeurFrame extends JFrame{ mics.setModel(new DefaultListModel<>()); serverControl.setText("Lancer"); }else { - serveur = new SpeakerServer(new InetSocketAddress(masterIP.getText(), AudioServer.communicationPort), deviceName,enceinteListe.getSelectedValue().tdl); + serveur = new SpeakerServer(new InetSocketAddress(masterIP.getText(), Codes.communicationPort), deviceName,enceinteListe.getSelectedValue().tdl); masterIP.setEnabled(false); serveur.setServerAnswered(()->{ serverControl.setText("Arrêter"); diff --git a/src/main/java/com/bernard/murder/view/LauncherFrame.java b/src/main/java/com/bernard/murder/view/LauncherFrame.java index 5f52b5d..fb042b7 100755 --- a/src/main/java/com/bernard/murder/view/LauncherFrame.java +++ b/src/main/java/com/bernard/murder/view/LauncherFrame.java @@ -81,13 +81,13 @@ public class LauncherFrame extends JFrame{ else switch(Parametres.instance.lookAndFeel) { case "flatlaf-light": - FlatLightLaf.install();break; + FlatLightLaf.setup();break; case "flatlaf-dark": - FlatDarkLaf.install();break; + FlatDarkLaf.setup();break; case "flatlaf-intelliJ": - FlatIntelliJLaf.install();break; + FlatIntelliJLaf.setup();break; case "flatlaf-darcula": - FlatDarculaLaf.install();break; + FlatDarculaLaf.setup();break; default: UIManager.setLookAndFeel(Parametres.instance.lookAndFeel); } diff --git a/src/main/java/com/bernard/murder/view/MicServeurFrame.java b/src/main/java/com/bernard/murder/view/MicServeurFrame.java index 82987bc..d431624 100755 --- a/src/main/java/com/bernard/murder/view/MicServeurFrame.java +++ b/src/main/java/com/bernard/murder/view/MicServeurFrame.java @@ -21,7 +21,7 @@ import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; -import com.bernard.murder.audio.AudioServer; +import com.bernard.murder.audio.Codes; import com.bernard.murder.audio.MicServer; public class MicServeurFrame extends JFrame{ @@ -70,7 +70,7 @@ public class MicServeurFrame extends JFrame{ serverControl.setText("Lancer"); }else { masterIP.setEnabled(false); - serveur = new MicServer(new InetSocketAddress(masterIP.getText(), AudioServer.communicationPort), deviceName,micListe.getSelectedValue().tdl); + serveur = new MicServer(new InetSocketAddress(masterIP.getText(), Codes.communicationPort), deviceName,micListe.getSelectedValue().tdl); serveur.setServerAnswered(()->{ serverControl.setText("Arrêter"); }); diff --git a/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java b/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java index c5ed4b7..8e5821d 100755 --- a/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java +++ b/src/main/java/com/bernard/murder/view/minel/ActionsMinel.java @@ -113,14 +113,14 @@ public class ActionsMinel extends Minel { private void launchAction(Action a) { if(!a.canBeLaunched())return; - a.launch(); + manager.launchAction(a); actionButtons.get(a).setEnabled(false); updateText(a); updatingActions.add(a); } private void resetAction(Action a) { - a.reset(); + manager.resetAction(a); actionButtons.get(a).setEnabled(true); updateTexts(); updatingActions.remove(a); diff --git a/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java b/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java index e4d8682..f5737be 100755 --- a/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java +++ b/src/main/java/com/bernard/murder/view/minel/ServeurMinel.java @@ -38,7 +38,8 @@ public class ServeurMinel extends Minel { public ServeurMinel(GameManager manager) { super(manager); try { - serveur = new AudioServer(); + serveur = new AudioServer(manager); + serveur.genPasswords(); }catch(SocketException | UnknownHostException ex) { JOptionPane.showMessageDialog(null, "Lancement du serveur audio impossible !\n"+ex.getMessage(), "Impossible de lancer le serveur audio", JOptionPane.ERROR_MESSAGE, null); }