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 {
|
||||
// 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')
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
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é
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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.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");
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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");
|
||||
});
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user