Anzeigen: Beitritt/Verlassen als Text und Signalton, Discord-Status, TS-Thema, Sprecher in der Actionbar (abschaltbar)
This commit is contained in:
1 parent
3c0e3ed17a
commit
b335933678
19 files changed
+583
-37
No files matched your search
@@ -10,7 +10,9 @@ import java.util.UUID;
|
||||
public sealed interface Message {
|
||||
|
||||
/** Plugin → Bridge, jede Sekunde: Herzschlag und verbundene Spieler pro Raum. */
|
||||
record Hello(int version, Map<String, Integer> members) implements Message {}
|
||||
record Hello(int version, Map<String, List<Member>> members) implements Message {}
|
||||
|
||||
record Member(UUID id, String name) {}
|
||||
|
||||
/** Bridge → Plugin, Antwort auf jedes Hello: die Räume und wer auf den anderen Seiten ist. */
|
||||
record Rooms(List<RoomInfo> rooms) implements Message {}
|
||||
@@ -22,4 +24,10 @@ public sealed interface Message {
|
||||
* die Spieler-UUID, beim Bridge → Plugin eine feste UUID pro externem Sprecher.
|
||||
*/
|
||||
record Audio(String room, UUID source, byte[] opus) implements Message {}
|
||||
|
||||
/** Bridge → Plugin: Chat-Hinweis an alle in der Gruppe, z. B. wer dazugekommen ist. */
|
||||
record Notice(String room, String text) implements Message {}
|
||||
|
||||
/** Bridge → Plugin: wer aus Discord/TeamSpeak gerade spricht (für die Actionbar). */
|
||||
record Speakers(String room, List<String> names) implements Message {}
|
||||
}
|
||||
@@ -14,13 +14,15 @@ import java.util.UUID;
|
||||
|
||||
public final class Protocol {
|
||||
/** Bei inkompatiblen Änderungen am Format hochzählen. */
|
||||
public static final int VERSION = 1;
|
||||
public static final int VERSION = 2;
|
||||
public static final int DEFAULT_PORT = 24470;
|
||||
public static final int MAX_DATAGRAM = 2048;
|
||||
|
||||
private static final byte HELLO = 1;
|
||||
private static final byte ROOMS = 2;
|
||||
private static final byte AUDIO = 3;
|
||||
private static final byte NOTICE = 4;
|
||||
private static final byte SPEAKERS = 5;
|
||||
|
||||
private Protocol() {}
|
||||
|
||||
@@ -32,9 +34,13 @@ public final class Protocol {
|
||||
out.writeByte(HELLO);
|
||||
out.writeInt(hello.version());
|
||||
out.writeShort(hello.members().size());
|
||||
for (Map.Entry<String, Integer> e : hello.members().entrySet()) {
|
||||
for (Map.Entry<String, List<Message.Member>> e : hello.members().entrySet()) {
|
||||
out.writeUTF(e.getKey());
|
||||
out.writeShort(e.getValue());
|
||||
out.writeShort(e.getValue().size());
|
||||
for (Message.Member member : e.getValue()) {
|
||||
writeUuid(out, member.id());
|
||||
out.writeUTF(member.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
case Message.Rooms rooms -> {
|
||||
@@ -55,6 +61,17 @@ public final class Protocol {
|
||||
writeUuid(out, audio.source());
|
||||
out.write(audio.opus());
|
||||
}
|
||||
case Message.Notice notice -> {
|
||||
out.writeByte(NOTICE);
|
||||
out.writeUTF(notice.room());
|
||||
out.writeUTF(notice.text());
|
||||
}
|
||||
case Message.Speakers speakers -> {
|
||||
out.writeByte(SPEAKERS);
|
||||
out.writeUTF(speakers.room());
|
||||
out.writeShort(speakers.names().size());
|
||||
for (String name : speakers.names()) out.writeUTF(name);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
@@ -69,8 +86,14 @@ public final class Protocol {
|
||||
case HELLO -> {
|
||||
int version = in.readInt();
|
||||
int count = in.readUnsignedShort();
|
||||
Map<String, Integer> members = new LinkedHashMap<>();
|
||||
for (int i = 0; i < count; i++) members.put(in.readUTF(), in.readUnsignedShort());
|
||||
Map<String, List<Message.Member>> members = new LinkedHashMap<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
String room = in.readUTF();
|
||||
int size = in.readUnsignedShort();
|
||||
List<Message.Member> list = new ArrayList<>(size);
|
||||
for (int j = 0; j < size; j++) list.add(new Message.Member(readUuid(in), in.readUTF()));
|
||||
members.put(room, list);
|
||||
}
|
||||
yield new Message.Hello(version, members);
|
||||
}
|
||||
case ROOMS -> {
|
||||
@@ -83,6 +106,14 @@ public final class Protocol {
|
||||
yield new Message.Rooms(rooms);
|
||||
}
|
||||
case AUDIO -> new Message.Audio(in.readUTF(), readUuid(in), in.readAllBytes());
|
||||
case NOTICE -> new Message.Notice(in.readUTF(), in.readUTF());
|
||||
case SPEAKERS -> {
|
||||
String room = in.readUTF();
|
||||
int size = in.readUnsignedShort();
|
||||
List<String> names = new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) names.add(in.readUTF());
|
||||
yield new Message.Speakers(room, names);
|
||||
}
|
||||
default -> throw new IOException("Unbekannter Nachrichtentyp " + type);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ class ProtocolTest {
|
||||
|
||||
@Test
|
||||
void hello() throws IOException {
|
||||
Message.Hello hello = new Message.Hello(Protocol.VERSION, Map.of("crosstalk-1", 3));
|
||||
Message.Hello hello = new Message.Hello(Protocol.VERSION,
|
||||
Map.of("crosstalk-1", List.of(new Message.Member(UUID.randomUUID(), "Steve"))));
|
||||
assertEquals(hello, roundTrip(hello));
|
||||
}
|
||||
|
||||
@@ -39,6 +40,14 @@ class ProtocolTest {
|
||||
assertArrayEquals(opus, audio.opus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void noticeAndSpeakers() throws IOException {
|
||||
Message.Notice notice = new Message.Notice("crosstalk-1", "Anna (Discord) ist dazugekommen.");
|
||||
assertEquals(notice, roundTrip(notice));
|
||||
Message.Speakers speakers = new Message.Speakers("crosstalk-1", List.of("Anna (Discord)", "Bob (TeamSpeak)"));
|
||||
assertEquals(speakers, roundTrip(speakers));
|
||||
}
|
||||
|
||||
@Test
|
||||
void unknownType() {
|
||||
assertThrows(IOException.class, () -> Protocol.decode(new byte[]{42}, 0, 1));
|
||||
|
||||
Reference in new issue
Block a user