Ajout de commandes pour l'accès aux parties.
This commit is contained in:
parent
149911f430
commit
668e472e71
16
build.gradle
16
build.gradle
@ -12,10 +12,22 @@ apply plugin: 'eclipse'
|
|||||||
repositories {
|
repositories {
|
||||||
// Use jcenter for resolving dependencies.
|
// Use jcenter for resolving dependencies.
|
||||||
// You can declare any Maven/Ivy/file repository here.
|
// You can declare any Maven/Ivy/file repository here.
|
||||||
jcenter()
|
|
||||||
mavenCentral()
|
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 {
|
jar {
|
||||||
manifest {
|
manifest {
|
||||||
attributes(
|
attributes(
|
||||||
@ -32,4 +44,6 @@ dependencies {
|
|||||||
implementation 'com.amihaiemil.web:eo-yaml:5.2.1'
|
implementation 'com.amihaiemil.web:eo-yaml:5.2.1'
|
||||||
implementation 'com.formdev:flatlaf:1.3'
|
implementation 'com.formdev:flatlaf:1.3'
|
||||||
|
|
||||||
|
implementation files('../../bernard/BernardLibs.git/build/libs/BernardLibs.jar')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import java.net.SocketException;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -13,6 +14,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@ -25,54 +27,24 @@ import com.amihaiemil.eoyaml.Yaml;
|
|||||||
import com.amihaiemil.eoyaml.YamlMapping;
|
import com.amihaiemil.eoyaml.YamlMapping;
|
||||||
import com.amihaiemil.eoyaml.YamlNode;
|
import com.amihaiemil.eoyaml.YamlNode;
|
||||||
import com.amihaiemil.eoyaml.YamlSequenceBuilder;
|
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.BytesUtils;
|
||||||
import com.bernard.util.ParseUtils;
|
import com.bernard.util.ParseUtils;
|
||||||
import com.bernard.util.YamlUtils;
|
import com.bernard.util.YamlUtils;
|
||||||
|
|
||||||
public class AudioServer {
|
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 AudioFormat formatAudio = new AudioFormat(8000f, 16, 1, true, true);
|
||||||
public static int packetMaxSize = 97282;
|
|
||||||
public static int communicationPort = 35295;
|
|
||||||
|
|
||||||
public Serveur serveur;
|
public Serveur serveur;
|
||||||
|
|
||||||
int micId = 0;
|
int micId = 0;
|
||||||
int speakerId = 0;
|
int speakerId = 0;
|
||||||
|
|
||||||
|
private GameNetworkInterface gameInterface;
|
||||||
|
|
||||||
Map<Integer,String> mics;
|
Map<Integer,String> mics;
|
||||||
Map<Integer,String> speakers;
|
Map<Integer,String> speakers;
|
||||||
Map<Integer,SocketAddress> micsAddr;
|
Map<Integer,SocketAddress> micsAddr;
|
||||||
@ -82,7 +54,7 @@ public class AudioServer {
|
|||||||
private Set<Runnable> changeListeners;
|
private Set<Runnable> changeListeners;
|
||||||
private Set<Consumer<Exception>> serverErrorException;
|
private Set<Consumer<Exception>> serverErrorException;
|
||||||
|
|
||||||
public AudioServer() throws SocketException, UnknownHostException {
|
public AudioServer(GameManager manager) throws SocketException, UnknownHostException {
|
||||||
mics = new HashMap<Integer, String>();
|
mics = new HashMap<Integer, String>();
|
||||||
micsAddr = new HashMap<Integer, SocketAddress>();
|
micsAddr = new HashMap<Integer, SocketAddress>();
|
||||||
speakers = new HashMap<Integer, String>();
|
speakers = new HashMap<Integer, String>();
|
||||||
@ -92,11 +64,13 @@ public class AudioServer {
|
|||||||
changeListeners = new HashSet<>();
|
changeListeners = new HashSet<>();
|
||||||
serverErrorException = new HashSet<>();
|
serverErrorException = new HashSet<>();
|
||||||
|
|
||||||
|
gameInterface = new GameNetworkInterface(manager, this);
|
||||||
|
|
||||||
initServer();
|
initServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AudioServer(YamlMapping data) throws SocketException, UnknownHostException {
|
public AudioServer(GameManager manager, YamlMapping data) throws SocketException, UnknownHostException {
|
||||||
this();
|
this(manager);
|
||||||
for(YamlNode spkn : data.yamlMapping("enceintes").values()) {
|
for(YamlNode spkn : data.yamlMapping("enceintes").values()) {
|
||||||
try {
|
try {
|
||||||
YamlMapping spk = spkn.asMapping();
|
YamlMapping spk = spkn.asMapping();
|
||||||
@ -143,7 +117,7 @@ public class AudioServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initServer() throws SocketException, UnknownHostException {
|
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) {
|
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));
|
System.out.println("Commande reçue : "+commande+" de "+senderAddress+" de taille "+(data.limit()+1));
|
||||||
switch (commande) {
|
switch (commande) {
|
||||||
|
|
||||||
case AudioServer.DECLARE_NUMBER:
|
case Codes.DECLARE_NUMBER:
|
||||||
|
|
||||||
UUID uuid = new UUID(data.getLong(), data.getLong());
|
UUID uuid = new UUID(data.getLong(), data.getLong());
|
||||||
byte deviceType = data.get();
|
byte deviceType = data.get();
|
||||||
String deviceName = BytesUtils.readString(data);
|
String deviceName = BytesUtils.readString(data);
|
||||||
int newId;
|
int newId;
|
||||||
switch (deviceType) {
|
switch (deviceType) {
|
||||||
case AudioServer.MIC_DEVICE:
|
case Codes.Device.MIC_DEVICE:
|
||||||
newId = micId++;
|
newId = micId++;
|
||||||
mics.put(newId, deviceName);
|
mics.put(newId, deviceName);
|
||||||
micsAddr.put(newId, senderAddress);
|
micsAddr.put(newId, senderAddress);
|
||||||
listening.put(newId, new ArrayList<>());
|
listening.put(newId, new ArrayList<>());
|
||||||
publishAudioList(speakersAddr.values());
|
publishAudioList(speakersAddr.values());
|
||||||
break;
|
break;
|
||||||
case AudioServer.SPEAKER_DEVICE:
|
case Codes.Device.SPEAKER_DEVICE:
|
||||||
newId = speakerId++;
|
newId = speakerId++;
|
||||||
speakers.put(newId, deviceName);
|
speakers.put(newId, deviceName);
|
||||||
speakersAddr.put(newId, senderAddress);
|
speakersAddr.put(newId, senderAddress);
|
||||||
break;
|
break;
|
||||||
default:return;
|
default:return;
|
||||||
}
|
}
|
||||||
ByteBuffer out = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out.put(AudioServer.OK_ID);
|
out.put(Codes.OK_ID);
|
||||||
out.putLong(uuid.getMostSignificantBits());
|
out.putLong(uuid.getMostSignificantBits());
|
||||||
out.putLong(uuid.getLeastSignificantBits());
|
out.putLong(uuid.getLeastSignificantBits());
|
||||||
out.put(deviceType);
|
out.put(deviceType);
|
||||||
@ -186,15 +160,15 @@ public class AudioServer {
|
|||||||
changeListeners.forEach(Runnable::run);
|
changeListeners.forEach(Runnable::run);
|
||||||
System.out.println("Accepting request from "+senderAddress);
|
System.out.println("Accepting request from "+senderAddress);
|
||||||
break;
|
break;
|
||||||
case AudioServer.ASK_STREAMING:
|
case Codes.ASK_STREAMING:
|
||||||
int listened = data.getInt();
|
int listened = data.getInt();
|
||||||
int listener = data.getInt();
|
int listener = data.getInt();
|
||||||
|
|
||||||
if(listening.get(listened).contains(listener))
|
if(listening.get(listened).contains(listener))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ByteBuffer out3 = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out3 = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out3.put(AudioServer.START_STREAMING);
|
out3.put(Codes.START_STREAMING);
|
||||||
out3.putInt(listened);
|
out3.putInt(listened);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(out3, micsAddr.get(listened));
|
serveur.sendData(out3, micsAddr.get(listened));
|
||||||
@ -206,7 +180,7 @@ public class AudioServer {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AudioServer.ASK_STOP_STREAMING:
|
case Codes.ASK_STOP_STREAMING:
|
||||||
int listened2 = data.getInt();
|
int listened2 = data.getInt();
|
||||||
int listener2 = data.getInt();
|
int listener2 = data.getInt();
|
||||||
if(listened2==-1)break;
|
if(listened2==-1)break;
|
||||||
@ -219,8 +193,8 @@ public class AudioServer {
|
|||||||
|
|
||||||
if(listening.get(listened2).isEmpty()) {
|
if(listening.get(listened2).isEmpty()) {
|
||||||
try {
|
try {
|
||||||
ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out4.put(AudioServer.STOP_STREAMING);
|
out4.put(Codes.STOP_STREAMING);
|
||||||
out4.putInt(listened2);
|
out4.putInt(listened2);
|
||||||
serveur.sendData(out4, micsAddr.get(listened2));
|
serveur.sendData(out4, micsAddr.get(listened2));
|
||||||
|
|
||||||
@ -230,7 +204,7 @@ public class AudioServer {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AudioServer.AUDIO_STREAM:
|
case Codes.AUDIO_STREAM:
|
||||||
int micId = data.getInt();
|
int micId = data.getInt();
|
||||||
data.position(data.limit());
|
data.position(data.limit());
|
||||||
|
|
||||||
@ -246,17 +220,17 @@ public class AudioServer {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case AudioServer.ASK_AUDIO_LIST:
|
case Codes.ASK_AUDIO_LIST:
|
||||||
|
|
||||||
System.out.println("Sending audio list to "+senderAddress+" : ");
|
System.out.println("Sending audio list to "+senderAddress+" : ");
|
||||||
publishAudioList(Collections.singleton(senderAddress));
|
publishAudioList(Collections.singleton(senderAddress));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AudioServer.DISCONNECTING:
|
case Codes.DISCONNECTING:
|
||||||
byte deviceType2 = data.get();
|
byte deviceType2 = data.get();
|
||||||
int deviceId = data.getInt();
|
int deviceId = data.getInt();
|
||||||
if(deviceType2==AudioServer.MIC_DEVICE) {
|
if(deviceType2==Codes.Device.MIC_DEVICE) {
|
||||||
// On le déréférence
|
// On le déréférence
|
||||||
if(!mics.containsKey(deviceId)) {
|
if(!mics.containsKey(deviceId)) {
|
||||||
System.out.println("Le micro d'id "+deviceId+" est déjà désinscrit");
|
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
|
// On enlève tous les liens d'écoute
|
||||||
for(int spkId : listening.get(deviceId)) {
|
for(int spkId : listening.get(deviceId)) {
|
||||||
// Annoncer à ce speaker que le micro est déconnécté et qu'il ne peut plus l'écouter.
|
// Annoncer à ce speaker que le micro est déconnécté et qu'il ne peut plus l'écouter.
|
||||||
ByteBuffer out5 = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out5 = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out5.put(AudioServer.DISCONNECTING);
|
out5.put(Codes.DISCONNECTING);
|
||||||
out5.put(AudioServer.MIC_DEVICE);
|
out5.put(Codes.Device.MIC_DEVICE);
|
||||||
out5.putInt(deviceId);
|
out5.putInt(deviceId);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(out5, speakersAddr.get(spkId));
|
serveur.sendData(out5, speakersAddr.get(spkId));
|
||||||
@ -283,7 +257,7 @@ public class AudioServer {
|
|||||||
listening.remove(deviceId);
|
listening.remove(deviceId);
|
||||||
publishAudioList(speakersAddr.values());
|
publishAudioList(speakersAddr.values());
|
||||||
|
|
||||||
}else if(deviceType2==AudioServer.SPEAKER_DEVICE) {
|
}else if(deviceType2==Codes.Device.SPEAKER_DEVICE) {
|
||||||
|
|
||||||
// On le déréférence
|
// On le déréférence
|
||||||
System.out.println("Déconnection de l'enceinte "+speakers.get(deviceId));
|
System.out.println("Déconnection de l'enceinte "+speakers.get(deviceId));
|
||||||
@ -299,8 +273,8 @@ public class AudioServer {
|
|||||||
if(listening.get(lstTo).isEmpty()) {
|
if(listening.get(lstTo).isEmpty()) {
|
||||||
// Si il n'y a plus rien à écouter.
|
// Si il n'y a plus rien à écouter.
|
||||||
try {
|
try {
|
||||||
ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out4.put(AudioServer.STOP_STREAMING);
|
out4.put(Codes.STOP_STREAMING);
|
||||||
out4.putInt(lstTo);
|
out4.putInt(lstTo);
|
||||||
serveur.sendData(out4, micsAddr.get(lstTo));
|
serveur.sendData(out4, micsAddr.get(lstTo));
|
||||||
} catch (IOException e1) {
|
} 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);
|
System.err.println("Je ne sais pas comment réagir à la déconnection d'un appareil de type "+deviceType2);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
System.out.println("Je ne devait pas recevoir cette commade !");
|
System.out.println("Je ne devait pas recevoir cette commade !");
|
||||||
}
|
}
|
||||||
@ -342,8 +328,8 @@ public class AudioServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void publishAudioList(Collection<SocketAddress> to) {
|
public void publishAudioList(Collection<SocketAddress> to) {
|
||||||
ByteBuffer out = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out.put(AudioServer.GIVE_AUDIO_LIST);
|
out.put(Codes.GIVE_AUDIO_LIST);
|
||||||
out.putInt(mics.size());
|
out.putInt(mics.size());
|
||||||
for(Entry<Integer, String> mic : mics.entrySet()) {
|
for(Entry<Integer, String> mic : mics.entrySet()) {
|
||||||
out.putInt(mic.getKey());
|
out.putInt(mic.getKey());
|
||||||
@ -377,8 +363,8 @@ public class AudioServer {
|
|||||||
listening.get(lstTo).remove(id);
|
listening.get(lstTo).remove(id);
|
||||||
|
|
||||||
// Si il n'y a plus rien à écouter.
|
// Si il n'y a plus rien à écouter.
|
||||||
ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out4.put(AudioServer.STOP_STREAMING);
|
out4.put(Codes.STOP_STREAMING);
|
||||||
out4.putInt(lstTo);
|
out4.putInt(lstTo);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(out4, speakersAddr.get(id));
|
serveur.sendData(out4, speakersAddr.get(id));
|
||||||
@ -394,9 +380,9 @@ public void disconnectEnceinte(int id) {
|
|||||||
if(!speakers.containsKey(id))
|
if(!speakers.containsKey(id))
|
||||||
return;
|
return;
|
||||||
// On lui annonce notre déconnection, puis on la supprime des données
|
// On lui annonce notre déconnection, puis on la supprime des données
|
||||||
ByteBuffer decoBuf = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer decoBuf = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
decoBuf.put(AudioServer.DISCONNECTING);
|
decoBuf.put(Codes.DISCONNECTING);
|
||||||
decoBuf.put(AudioServer.MASTER_DEVICE);
|
decoBuf.put(Codes.Device.MASTER_DEVICE);
|
||||||
decoBuf.putInt(0);
|
decoBuf.putInt(0);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(decoBuf, speakersAddr.get(id));
|
serveur.sendData(decoBuf, speakersAddr.get(id));
|
||||||
@ -415,8 +401,8 @@ public void disconnectEnceinte(int id) {
|
|||||||
|
|
||||||
if(listening.get(lstTo).isEmpty()) {
|
if(listening.get(lstTo).isEmpty()) {
|
||||||
// Si il n'y a plus rien à écouter.
|
// Si il n'y a plus rien à écouter.
|
||||||
ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out4.put(AudioServer.STOP_STREAMING);
|
out4.put(Codes.STOP_STREAMING);
|
||||||
out4.putInt(lstTo);
|
out4.putInt(lstTo);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(out4, micsAddr.get(lstTo));
|
serveur.sendData(out4, micsAddr.get(lstTo));
|
||||||
@ -433,9 +419,9 @@ public void disconnectEnceinte(int id) {
|
|||||||
if(!mics.containsKey(id))
|
if(!mics.containsKey(id))
|
||||||
return;
|
return;
|
||||||
// On lui annonce notre déconnection, puis on la supprime des données
|
// On lui annonce notre déconnection, puis on la supprime des données
|
||||||
ByteBuffer decoBuf = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer decoBuf = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
decoBuf.put(AudioServer.DISCONNECTING);
|
decoBuf.put(Codes.DISCONNECTING);
|
||||||
decoBuf.put(AudioServer.MASTER_DEVICE);
|
decoBuf.put(Codes.Device.MASTER_DEVICE);
|
||||||
decoBuf.putInt(0);
|
decoBuf.putInt(0);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(decoBuf, micsAddr.get(id));
|
serveur.sendData(decoBuf, micsAddr.get(id));
|
||||||
@ -448,8 +434,8 @@ public void disconnectEnceinte(int id) {
|
|||||||
changeListeners.forEach(Runnable::run);
|
changeListeners.forEach(Runnable::run);
|
||||||
|
|
||||||
for(int lster : listening.get(id)) {
|
for(int lster : listening.get(id)) {
|
||||||
ByteBuffer out4 = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer out4 = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
out4.put(AudioServer.STOP_STREAMING);
|
out4.put(Codes.STOP_STREAMING);
|
||||||
out4.putInt(id);
|
out4.putInt(id);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(out4, speakersAddr.get(lster));
|
serveur.sendData(out4, speakersAddr.get(lster));
|
||||||
@ -473,7 +459,7 @@ public void disconnectEnceinte(int id) {
|
|||||||
|
|
||||||
changeListeners.forEach(Runnable::run);
|
changeListeners.forEach(Runnable::run);
|
||||||
|
|
||||||
serveur.dispose();
|
serveur.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public YamlMapping saveToYaml() {
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
101
src/main/java/com/bernard/murder/audio/Codes.java
Normal file
101
src/main/java/com/bernard/murder/audio/Codes.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -60,19 +60,19 @@ public class MicServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initServer() throws SocketException, UnknownHostException {
|
public void initServer() throws SocketException, UnknownHostException {
|
||||||
serveur = new Serveur(this::receiveCommand, AudioServer.communicationPort);
|
serveur = new Serveur(this::receiveCommand, Codes.communicationPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializeAudioId() {
|
public void initializeAudioId() {
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
|
|
||||||
|
|
||||||
askedUUID = UUID.randomUUID();
|
askedUUID = UUID.randomUUID();
|
||||||
|
|
||||||
buffer.put(AudioServer.DECLARE_NUMBER);
|
buffer.put(Codes.DECLARE_NUMBER);
|
||||||
buffer.putLong(askedUUID.getMostSignificantBits());
|
buffer.putLong(askedUUID.getMostSignificantBits());
|
||||||
buffer.putLong(askedUUID.getLeastSignificantBits());
|
buffer.putLong(askedUUID.getLeastSignificantBits());
|
||||||
buffer.put(AudioServer.MIC_DEVICE);
|
buffer.put(Codes.Device.MIC_DEVICE);
|
||||||
|
|
||||||
BytesUtils.writeString(buffer, micName);
|
BytesUtils.writeString(buffer, micName);
|
||||||
|
|
||||||
@ -88,26 +88,26 @@ public class MicServer {
|
|||||||
System.out.println("Commande reçue : "+commande);
|
System.out.println("Commande reçue : "+commande);
|
||||||
switch (commande) {
|
switch (commande) {
|
||||||
|
|
||||||
case AudioServer.START_STREAMING:
|
case Codes.START_STREAMING:
|
||||||
int askedMicId = data.getInt();
|
int askedMicId = data.getInt();
|
||||||
if(askedMicId != this.micId)return;
|
if(askedMicId != this.micId)return;
|
||||||
shouldStream = true;
|
shouldStream = true;
|
||||||
micLine.start();
|
micLine.start();
|
||||||
launchDataStream();
|
launchDataStream();
|
||||||
break;
|
break;
|
||||||
case AudioServer.STOP_STREAMING:
|
case Codes.STOP_STREAMING:
|
||||||
int askedMicId2 = data.getInt();
|
int askedMicId2 = data.getInt();
|
||||||
if(askedMicId2 != this.micId)return;
|
if(askedMicId2 != this.micId)return;
|
||||||
shouldStream = false;
|
shouldStream = false;
|
||||||
micLine.stop();
|
micLine.stop();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AudioServer.OK_ID:
|
case Codes.OK_ID:
|
||||||
UUID uuid = new UUID(data.getLong(), data.getLong());
|
UUID uuid = new UUID(data.getLong(), data.getLong());
|
||||||
byte deviceType = data.get();
|
byte deviceType = data.get();
|
||||||
int deviceId = data.getInt();
|
int deviceId = data.getInt();
|
||||||
|
|
||||||
if(!askedUUID.equals(uuid) || deviceType!=AudioServer.MIC_DEVICE)
|
if(!askedUUID.equals(uuid) || deviceType!=Codes.Device.MIC_DEVICE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.micId = deviceId;
|
this.micId = deviceId;
|
||||||
@ -122,9 +122,9 @@ public class MicServer {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AudioServer.DISCONNECTING:
|
case Codes.DISCONNECTING:
|
||||||
byte deviceType2 = data.get();
|
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 !");
|
System.out.println("Le master s'est déconnécté, on fait de même !");
|
||||||
masterAddress=null;
|
masterAddress=null;
|
||||||
this.dispose();
|
this.dispose();
|
||||||
@ -143,7 +143,7 @@ public class MicServer {
|
|||||||
streamingThread = new Thread(()->{
|
streamingThread = new Thread(()->{
|
||||||
byte[] packetData = new byte[1+4+packetLength];
|
byte[] packetData = new byte[1+4+packetLength];
|
||||||
ByteBuffer audioPacket = ByteBuffer.wrap(packetData);
|
ByteBuffer audioPacket = ByteBuffer.wrap(packetData);
|
||||||
audioPacket.put(AudioServer.AUDIO_STREAM);
|
audioPacket.put(Codes.AUDIO_STREAM);
|
||||||
audioPacket.putInt(micId);
|
audioPacket.putInt(micId);
|
||||||
audioPacket.position(audioPacket.position()+packetLength);
|
audioPacket.position(audioPacket.position()+packetLength);
|
||||||
micLine.start();
|
micLine.start();
|
||||||
@ -163,9 +163,9 @@ public class MicServer {
|
|||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if(masterAddress!=null) {
|
if(masterAddress!=null) {
|
||||||
ByteBuffer decoPacket = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer decoPacket = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
decoPacket.put(AudioServer.DISCONNECTING);
|
decoPacket.put(Codes.DISCONNECTING);
|
||||||
decoPacket.put(AudioServer.MIC_DEVICE);
|
decoPacket.put(Codes.Device.MIC_DEVICE);
|
||||||
decoPacket.putInt(micId);
|
decoPacket.putInt(micId);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(decoPacket,masterAddress);
|
serveur.sendData(decoPacket,masterAddress);
|
||||||
@ -175,7 +175,7 @@ public class MicServer {
|
|||||||
}
|
}
|
||||||
shouldStream=false;
|
shouldStream=false;
|
||||||
micLine.close();
|
micLine.close();
|
||||||
serveur.dispose();
|
serveur.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setServerAnswered(Runnable serverAnswered) {
|
public void setServerAnswered(Runnable serverAnswered) {
|
||||||
|
|||||||
@ -29,6 +29,8 @@ public class Serveur {
|
|||||||
|
|
||||||
volatile boolean isReceiving = false;
|
volatile boolean isReceiving = false;
|
||||||
|
|
||||||
|
boolean networkOnSeparatedThread = false;
|
||||||
|
|
||||||
BiConsumer<ByteBuffer,SocketAddress> consumer;
|
BiConsumer<ByteBuffer,SocketAddress> consumer;
|
||||||
|
|
||||||
public Serveur(Consumer<ByteBuffer> dataEater, int port) throws UnknownHostException, SocketException {
|
public Serveur(Consumer<ByteBuffer> dataEater, int port) throws UnknownHostException, SocketException {
|
||||||
@ -116,6 +118,21 @@ public class Serveur {
|
|||||||
public void sendData(byte[] data, SocketAddress address) throws IOException {
|
public void sendData(byte[] data, SocketAddress address) throws IOException {
|
||||||
if(data.length < packetMaxLength) {
|
if(data.length < packetMaxLength) {
|
||||||
DatagramPacket packet = new DatagramPacket(data, data.length,address);
|
DatagramPacket packet = new DatagramPacket(data, data.length,address);
|
||||||
|
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);
|
socket.send(packet);
|
||||||
}else {
|
}else {
|
||||||
//XXX Ça, ca ne marche pas !
|
//XXX Ça, ca ne marche pas !
|
||||||
@ -154,10 +171,14 @@ public class Serveur {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void dispose() {
|
public void close() {
|
||||||
isReceiving = false;
|
isReceiving = false;
|
||||||
socket.close();
|
socket.close();
|
||||||
packetReceiver.interrupt();
|
packetReceiver.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNetworkOnSeparatedThread(boolean networkOnSeparatedThread) {
|
||||||
|
this.networkOnSeparatedThread = networkOnSeparatedThread;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,7 +62,7 @@ public class SpeakerServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initServer() throws SocketException, UnknownHostException {
|
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 {
|
public void initializeSpeakerDevice() throws LineUnavailableException {
|
||||||
@ -71,15 +71,15 @@ public class SpeakerServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initializeAudioId() {
|
public void initializeAudioId() {
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
|
|
||||||
|
|
||||||
askedUUID = UUID.randomUUID();
|
askedUUID = UUID.randomUUID();
|
||||||
|
|
||||||
buffer.put(AudioServer.DECLARE_NUMBER);
|
buffer.put(Codes.DECLARE_NUMBER);
|
||||||
buffer.putLong(askedUUID.getMostSignificantBits());
|
buffer.putLong(askedUUID.getMostSignificantBits());
|
||||||
buffer.putLong(askedUUID.getLeastSignificantBits());
|
buffer.putLong(askedUUID.getLeastSignificantBits());
|
||||||
buffer.put(AudioServer.SPEAKER_DEVICE);
|
buffer.put(Codes.Device.SPEAKER_DEVICE);
|
||||||
|
|
||||||
BytesUtils.writeString(buffer, speakerName);
|
BytesUtils.writeString(buffer, speakerName);
|
||||||
|
|
||||||
@ -97,10 +97,10 @@ public class SpeakerServer {
|
|||||||
return;
|
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(micId);
|
||||||
buffer.putInt(speakerId);
|
buffer.putInt(speakerId);
|
||||||
|
|
||||||
@ -117,10 +117,10 @@ public class SpeakerServer {
|
|||||||
System.out.println("J'arêtte d'écouter le vide");
|
System.out.println("J'arêtte d'écouter le vide");
|
||||||
return;
|
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(listeningTo);
|
||||||
buffer.putInt(speakerId);
|
buffer.putInt(speakerId);
|
||||||
|
|
||||||
@ -133,8 +133,8 @@ public class SpeakerServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void askAudioList() {
|
public void askAudioList() {
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer buffer = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
buffer.put(AudioServer.ASK_AUDIO_LIST);
|
buffer.put(Codes.ASK_AUDIO_LIST);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(buffer,masterAddress);
|
serveur.sendData(buffer,masterAddress);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -147,7 +147,7 @@ public class SpeakerServer {
|
|||||||
System.out.println("Commande recue : "+commande);
|
System.out.println("Commande recue : "+commande);
|
||||||
switch (commande) {
|
switch (commande) {
|
||||||
|
|
||||||
case AudioServer.AUDIO_STREAM:
|
case Codes.AUDIO_STREAM:
|
||||||
int micId = data.getInt();
|
int micId = data.getInt();
|
||||||
if(micId != listeningTo)break;
|
if(micId != listeningTo)break;
|
||||||
byte[] audioData=new byte[data.remaining()];
|
byte[] audioData=new byte[data.remaining()];
|
||||||
@ -155,12 +155,12 @@ public class SpeakerServer {
|
|||||||
speakerLine.write(audioData, 0, audioData.length);
|
speakerLine.write(audioData, 0, audioData.length);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AudioServer.OK_ID:
|
case Codes.OK_ID:
|
||||||
UUID uuid = new UUID(data.getLong(), data.getLong());
|
UUID uuid = new UUID(data.getLong(), data.getLong());
|
||||||
byte deviceType = data.get();
|
byte deviceType = data.get();
|
||||||
int deviceId = data.getInt();
|
int deviceId = data.getInt();
|
||||||
|
|
||||||
if(!askedUUID.equals(uuid) || deviceType!=AudioServer.SPEAKER_DEVICE)
|
if(!askedUUID.equals(uuid) || deviceType!=Codes.Device.SPEAKER_DEVICE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
speakerId = deviceId;
|
speakerId = deviceId;
|
||||||
@ -174,7 +174,7 @@ public class SpeakerServer {
|
|||||||
|
|
||||||
askAudioList();
|
askAudioList();
|
||||||
break;
|
break;
|
||||||
case AudioServer.GIVE_AUDIO_LIST:
|
case Codes.GIVE_AUDIO_LIST:
|
||||||
int micCount = data.getInt();
|
int micCount = data.getInt();
|
||||||
mics = new HashMap<Integer, String>(micCount);
|
mics = new HashMap<Integer, String>(micCount);
|
||||||
for(int i = 0; i<micCount;i++) {
|
for(int i = 0; i<micCount;i++) {
|
||||||
@ -185,16 +185,16 @@ public class SpeakerServer {
|
|||||||
micListUpdateListener.forEach(c -> c.accept(mics));
|
micListUpdateListener.forEach(c -> c.accept(mics));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AudioServer.DISCONNECTING:
|
case Codes.DISCONNECTING:
|
||||||
byte deviceType2 = data.get();
|
byte deviceType2 = data.get();
|
||||||
int deviceId2 = data.getInt();
|
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 !");
|
System.out.println("Le master s'est déconnécté, on fait de même !");
|
||||||
masterAddress=null;
|
masterAddress=null;
|
||||||
this.dispose();
|
this.dispose();
|
||||||
for(Runnable toRun : disconnectListener)
|
for(Runnable toRun : disconnectListener)
|
||||||
toRun.run();
|
toRun.run();
|
||||||
}else if(deviceType2==AudioServer.MIC_DEVICE){
|
}else if(deviceType2==Codes.Device.MIC_DEVICE){
|
||||||
if(listeningTo==deviceId2) {
|
if(listeningTo==deviceId2) {
|
||||||
System.out.println("Le micro que l'on écoutait s'est déconnécté.");
|
System.out.println("Le micro que l'on écoutait s'est déconnécté.");
|
||||||
listeningTo=-1;
|
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 ^^");
|
System.out.println("Un appareil de type "+deviceType2+" s'est déconécté, mais je m'en fout ^^");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AudioServer.STOP_STREAMING:
|
case Codes.STOP_STREAMING:
|
||||||
int deviceId3 = data.getInt();
|
int deviceId3 = data.getInt();
|
||||||
if(listeningTo==deviceId3) {
|
if(listeningTo==deviceId3) {
|
||||||
System.out.println("Le micro que l'on écoutait arêtte d'émmetre.");
|
System.out.println("Le micro que l'on écoutait arêtte d'émmetre.");
|
||||||
@ -220,9 +220,9 @@ public class SpeakerServer {
|
|||||||
}
|
}
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if(masterAddress!=null) {
|
if(masterAddress!=null) {
|
||||||
ByteBuffer decoPacket = ByteBuffer.allocate(AudioServer.packetMaxSize);
|
ByteBuffer decoPacket = ByteBuffer.allocate(Codes.packetMaxSize);
|
||||||
decoPacket.put(AudioServer.DISCONNECTING);
|
decoPacket.put(Codes.DISCONNECTING);
|
||||||
decoPacket.put(AudioServer.SPEAKER_DEVICE);
|
decoPacket.put(Codes.Device.SPEAKER_DEVICE);
|
||||||
decoPacket.putInt(speakerId);
|
decoPacket.putInt(speakerId);
|
||||||
try {
|
try {
|
||||||
serveur.sendData(decoPacket,masterAddress);
|
serveur.sendData(decoPacket,masterAddress);
|
||||||
@ -235,7 +235,7 @@ public class SpeakerServer {
|
|||||||
speakerLine.stop();
|
speakerLine.stop();
|
||||||
speakerLine.close();
|
speakerLine.close();
|
||||||
}
|
}
|
||||||
serveur.dispose();
|
serveur.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setServerAnswered(Runnable serverAnswered) {
|
public void setServerAnswered(Runnable serverAnswered) {
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import javax.swing.Timer;
|
|||||||
|
|
||||||
import com.amihaiemil.eoyaml.Yaml;
|
import com.amihaiemil.eoyaml.Yaml;
|
||||||
import com.amihaiemil.eoyaml.YamlMapping;
|
import com.amihaiemil.eoyaml.YamlMapping;
|
||||||
|
import com.bernard.murder.model.Action;
|
||||||
import com.bernard.murder.model.Inventaire;
|
import com.bernard.murder.model.Inventaire;
|
||||||
import com.bernard.murder.model.Objet;
|
import com.bernard.murder.model.Objet;
|
||||||
import com.bernard.murder.model.Partie;
|
import com.bernard.murder.model.Partie;
|
||||||
@ -26,6 +27,7 @@ public class GameManager {
|
|||||||
|
|
||||||
Partie partie;
|
Partie partie;
|
||||||
Map<Inventaire,Set<Runnable>> inventoryUpdateListeners;
|
Map<Inventaire,Set<Runnable>> inventoryUpdateListeners;
|
||||||
|
Map<Personnage,Set<Runnable>> actionsUpdateListeners;
|
||||||
|
|
||||||
long startTime;
|
long startTime;
|
||||||
|
|
||||||
@ -36,6 +38,7 @@ public class GameManager {
|
|||||||
public GameManager(Partie partie) {
|
public GameManager(Partie partie) {
|
||||||
this.partie = partie;
|
this.partie = partie;
|
||||||
this.inventoryUpdateListeners = new HashMap<Inventaire, Set<Runnable>>();
|
this.inventoryUpdateListeners = new HashMap<Inventaire, Set<Runnable>>();
|
||||||
|
this.actionsUpdateListeners = new HashMap<Personnage, Set<Runnable>>();
|
||||||
this.minelsQuicksaver = () -> Yaml.createYamlMappingBuilder().build();
|
this.minelsQuicksaver = () -> Yaml.createYamlMappingBuilder().build();
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
@ -57,6 +60,14 @@ public class GameManager {
|
|||||||
for(Runnable r : inventoryUpdateListeners.get(inv))
|
for(Runnable r : inventoryUpdateListeners.get(inv))
|
||||||
r.run();
|
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() {
|
public void dumpCurrentState() {
|
||||||
System.out.println(partie);
|
System.out.println(partie);
|
||||||
@ -67,6 +78,11 @@ public class GameManager {
|
|||||||
inventoryUpdateListeners.put(inv, new HashSet<Runnable>());
|
inventoryUpdateListeners.put(inv, new HashSet<Runnable>());
|
||||||
inventoryUpdateListeners.get(inv).add(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() {
|
public void quickSave() {
|
||||||
File toSave = new File(quickSaveFilename());
|
File toSave = new File(quickSaveFilename());
|
||||||
@ -114,6 +130,10 @@ public class GameManager {
|
|||||||
return partie.personnagesStream().filter(p -> key.equalsIgnoreCase(p.getNom())).findAny().orElse(null);
|
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) {
|
public void bindMinelQuicksaver(Supplier<YamlMapping> minelsQuicksaver) {
|
||||||
this.minelsQuicksaver = minelsQuicksaver;
|
this.minelsQuicksaver = minelsQuicksaver;
|
||||||
}
|
}
|
||||||
@ -148,5 +168,19 @@ public class GameManager {
|
|||||||
inventoryUpdate(inv);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
356
src/main/java/com/bernard/murder/game/GameNetworkInterface.java
Normal file
356
src/main/java/com/bernard/murder/game/GameNetworkInterface.java
Normal 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)) {
|
||||||
|
// 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<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)) {
|
||||||
|
// 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<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))) {
|
||||||
|
// 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<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é
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -40,14 +40,6 @@ public class Action implements Cloneable{
|
|||||||
return System.currentTimeMillis()-triggertime-basetime>0;
|
return System.currentTimeMillis()-triggertime-basetime>0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void launch() {
|
|
||||||
triggertime=System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
triggertime=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasFinished() {
|
public boolean hasFinished() {
|
||||||
return triggertime + basetime - System.currentTimeMillis()<0;
|
return triggertime + basetime - System.currentTimeMillis()<0;
|
||||||
}
|
}
|
||||||
@ -68,6 +60,10 @@ public class Action implements Cloneable{
|
|||||||
return triggertime;
|
return triggertime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTriggertime(long triggertime) {
|
||||||
|
this.triggertime = triggertime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package com.bernard.murder.model;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class Personnage implements Inventaire{
|
public class Personnage implements Inventaire {
|
||||||
|
|
||||||
String nom;
|
String nom;
|
||||||
Set<Objet> inventaire;
|
Set<Objet> inventaire;
|
||||||
@ -82,7 +82,11 @@ public class Personnage implements Inventaire{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInventoryName() {
|
public String getInventoryName() {
|
||||||
return "Inventaire de "+getNom();
|
return getInventoryNameFromPersoName(getNom());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String getInventoryNameFromPersoName(String persoName) {
|
||||||
|
return "Inventaire de "+persoName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
src/main/java/com/bernard/murder/model/messages/Message.java
Normal file
17
src/main/java/com/bernard/murder/model/messages/Message.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
24
src/main/java/com/bernard/murder/model/messages/Thread.java
Normal file
24
src/main/java/com/bernard/murder/model/messages/Thread.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -28,7 +28,7 @@ import javax.swing.border.EmptyBorder;
|
|||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
|
||||||
import com.bernard.murder.audio.AudioServer;
|
import com.bernard.murder.audio.Codes;
|
||||||
import com.bernard.murder.audio.SpeakerServer;
|
import com.bernard.murder.audio.SpeakerServer;
|
||||||
|
|
||||||
public class EnceinteServeurFrame extends JFrame{
|
public class EnceinteServeurFrame extends JFrame{
|
||||||
@ -76,7 +76,7 @@ public class EnceinteServeurFrame extends JFrame{
|
|||||||
mics.setModel(new DefaultListModel<>());
|
mics.setModel(new DefaultListModel<>());
|
||||||
serverControl.setText("Lancer");
|
serverControl.setText("Lancer");
|
||||||
}else {
|
}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);
|
masterIP.setEnabled(false);
|
||||||
serveur.setServerAnswered(()->{
|
serveur.setServerAnswered(()->{
|
||||||
serverControl.setText("Arrêter");
|
serverControl.setText("Arrêter");
|
||||||
|
|||||||
@ -81,13 +81,13 @@ public class LauncherFrame extends JFrame{
|
|||||||
else
|
else
|
||||||
switch(Parametres.instance.lookAndFeel) {
|
switch(Parametres.instance.lookAndFeel) {
|
||||||
case "flatlaf-light":
|
case "flatlaf-light":
|
||||||
FlatLightLaf.install();break;
|
FlatLightLaf.setup();break;
|
||||||
case "flatlaf-dark":
|
case "flatlaf-dark":
|
||||||
FlatDarkLaf.install();break;
|
FlatDarkLaf.setup();break;
|
||||||
case "flatlaf-intelliJ":
|
case "flatlaf-intelliJ":
|
||||||
FlatIntelliJLaf.install();break;
|
FlatIntelliJLaf.setup();break;
|
||||||
case "flatlaf-darcula":
|
case "flatlaf-darcula":
|
||||||
FlatDarculaLaf.install();break;
|
FlatDarculaLaf.setup();break;
|
||||||
default:
|
default:
|
||||||
UIManager.setLookAndFeel(Parametres.instance.lookAndFeel);
|
UIManager.setLookAndFeel(Parametres.instance.lookAndFeel);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import javax.swing.JScrollPane;
|
|||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
import com.bernard.murder.audio.AudioServer;
|
import com.bernard.murder.audio.Codes;
|
||||||
import com.bernard.murder.audio.MicServer;
|
import com.bernard.murder.audio.MicServer;
|
||||||
|
|
||||||
public class MicServeurFrame extends JFrame{
|
public class MicServeurFrame extends JFrame{
|
||||||
@ -70,7 +70,7 @@ public class MicServeurFrame extends JFrame{
|
|||||||
serverControl.setText("Lancer");
|
serverControl.setText("Lancer");
|
||||||
}else {
|
}else {
|
||||||
masterIP.setEnabled(false);
|
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(()->{
|
serveur.setServerAnswered(()->{
|
||||||
serverControl.setText("Arrêter");
|
serverControl.setText("Arrêter");
|
||||||
});
|
});
|
||||||
|
|||||||
@ -113,14 +113,14 @@ public class ActionsMinel extends Minel {
|
|||||||
|
|
||||||
private void launchAction(Action a) {
|
private void launchAction(Action a) {
|
||||||
if(!a.canBeLaunched())return;
|
if(!a.canBeLaunched())return;
|
||||||
a.launch();
|
manager.launchAction(a);
|
||||||
actionButtons.get(a).setEnabled(false);
|
actionButtons.get(a).setEnabled(false);
|
||||||
updateText(a);
|
updateText(a);
|
||||||
updatingActions.add(a);
|
updatingActions.add(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetAction(Action a) {
|
private void resetAction(Action a) {
|
||||||
a.reset();
|
manager.resetAction(a);
|
||||||
actionButtons.get(a).setEnabled(true);
|
actionButtons.get(a).setEnabled(true);
|
||||||
updateTexts();
|
updateTexts();
|
||||||
updatingActions.remove(a);
|
updatingActions.remove(a);
|
||||||
|
|||||||
@ -38,7 +38,8 @@ public class ServeurMinel extends Minel {
|
|||||||
public ServeurMinel(GameManager manager) {
|
public ServeurMinel(GameManager manager) {
|
||||||
super(manager);
|
super(manager);
|
||||||
try {
|
try {
|
||||||
serveur = new AudioServer();
|
serveur = new AudioServer(manager);
|
||||||
|
serveur.genPasswords();
|
||||||
}catch(SocketException | UnknownHostException ex) {
|
}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);
|
JOptionPane.showMessageDialog(null, "Lancement du serveur audio impossible !\n"+ex.getMessage(), "Impossible de lancer le serveur audio", JOptionPane.ERROR_MESSAGE, null);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user