Ajout de commandes pour l'accès aux parties.

This commit is contained in:
Mysaa 2021-08-20 15:47:11 +02:00
parent 149911f430
commit 668e472e71
17 changed files with 703 additions and 137 deletions

View File

@ -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')
}

View File

@ -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<Integer,String> mics;
Map<Integer,String> speakers;
Map<Integer,SocketAddress> micsAddr;
@ -82,7 +54,7 @@ public class AudioServer {
private Set<Runnable> changeListeners;
private Set<Consumer<Exception>> serverErrorException;
public AudioServer() throws SocketException, UnknownHostException {
public AudioServer(GameManager manager) throws SocketException, UnknownHostException {
mics = new HashMap<Integer, String>();
micsAddr = new HashMap<Integer, SocketAddress>();
speakers = new HashMap<Integer, String>();
@ -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<SocketAddress> 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<Integer, String> 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);
}
}
}

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -29,6 +29,8 @@ public class Serveur {
volatile boolean isReceiving = false;
boolean networkOnSeparatedThread = false;
BiConsumer<ByteBuffer,SocketAddress> consumer;
public Serveur(Consumer<ByteBuffer> 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;
}
}

View File

@ -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<Integer, String>(micCount);
for(int i = 0; i<micCount;i++) {
@ -185,16 +185,16 @@ public class SpeakerServer {
micListUpdateListener.forEach(c -> 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) {

View File

@ -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<Inventaire,Set<Runnable>> inventoryUpdateListeners;
Map<Personnage,Set<Runnable>> actionsUpdateListeners;
long startTime;
@ -36,6 +38,7 @@ public class GameManager {
public GameManager(Partie partie) {
this.partie = partie;
this.inventoryUpdateListeners = new HashMap<Inventaire, Set<Runnable>>();
this.actionsUpdateListeners = new HashMap<Personnage, Set<Runnable>>();
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<Runnable>());
inventoryUpdateListeners.get(inv).add(runnable);
}
public void addActionsUpdateListener(Personnage perso, Runnable runnable) {
if(!actionsUpdateListeners.containsKey(perso))
actionsUpdateListeners.put(perso, new HashSet<Runnable>());
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<YamlMapping> 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;
}
}

View File

@ -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<String, String> joueursTokens; // <token, joueur name>
Map<String, String> opTokens; // <token, op name>
Map<String, String> passwords; // <Nom du joueur/op, Mdp>
Map<String,List<Thread>> messages; // <Nom du joueur, tous les threads>
Map<String, Set<SocketAddress>> messageListeners; // <Nom du joueur/op, ensemble des adresses à notifier>
Set<String> 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<Personnage> 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)) {
// 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<SocketAddress> 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)) {
// 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<SocketAddress> 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))) {
// 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<SocketAddress> 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<Objet> 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<Action> 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<SocketAddress> 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é
;
}
}

View File

@ -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;
}
}

View File

@ -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<Objet> 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;
}

View File

@ -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;
}
}

View File

@ -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<Message> 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;
}
}

View File

@ -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");

View File

@ -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);
}

View File

@ -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");
});

View File

@ -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);

View File

@ -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);
}