Whisper support
This commit is contained in:
+1
-1
@@ -31,7 +31,7 @@ out/
|
||||
.userlibraries
|
||||
|
||||
# Maven
|
||||
target/
|
||||
targetId/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.targetId>1.8</maven.compiler.targetId>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.github.manevolent.ts3j.enums;
|
||||
|
||||
public enum GroupWhisperTarget {
|
||||
ALL_CHANNELS(0),
|
||||
CURRENT_CHANNEL(1),
|
||||
PARENT_CHANNEL(2),
|
||||
ALL_PARENT_CHANNEL(3),
|
||||
CHANNEL_FAMILY(4),
|
||||
COMPLETE_CHANNEL_FAMILY(5),
|
||||
SUBCHANNELS(6)
|
||||
|
||||
;
|
||||
|
||||
private final int index;
|
||||
|
||||
GroupWhisperTarget(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public static GroupWhisperTarget fromId(int index) {
|
||||
for (GroupWhisperTarget value : values())
|
||||
if (value.getIndex() == index) return value;
|
||||
|
||||
throw new IllegalArgumentException("invalid index: " + index);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.github.manevolent.ts3j.enums;
|
||||
|
||||
public enum GroupWhisperType {
|
||||
SERVER_GROUP(0),
|
||||
CHANNEL_GROUP(1),
|
||||
CHANNEL_COMMANDER(2),
|
||||
ALL_CLIENTS(3)
|
||||
|
||||
;
|
||||
|
||||
private final int index;
|
||||
|
||||
GroupWhisperType(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public static GroupWhisperType fromId(int index) {
|
||||
for (GroupWhisperType value : values())
|
||||
if (value.getIndex() == index) return value;
|
||||
|
||||
throw new IllegalArgumentException("invalid index: " + index);
|
||||
}
|
||||
}
|
||||
+195
-24
@@ -1,63 +1,63 @@
|
||||
package com.github.manevolent.ts3j.protocol.packet;
|
||||
|
||||
import com.github.manevolent.ts3j.enums.CodecType;
|
||||
import com.github.manevolent.ts3j.enums.GroupWhisperTarget;
|
||||
import com.github.manevolent.ts3j.enums.GroupWhisperType;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
import com.github.manevolent.ts3j.protocol.header.HeaderFlag;
|
||||
import com.github.manevolent.ts3j.protocol.header.PacketHeader;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketBody1VoiceWhisper extends PacketBody {
|
||||
private int packetId;
|
||||
private int clientId;
|
||||
private CodecType codecType;
|
||||
private WhisperTarget target;
|
||||
private byte[] codecData;
|
||||
|
||||
public PacketBody1VoiceWhisper(ProtocolRole role) {
|
||||
super(PacketBodyType.VOICE_WHISPER, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeaderValues(PacketHeader header) {
|
||||
if (target instanceof WhisperTargetGroup)
|
||||
header.setPacketFlag(HeaderFlag.NEW_PROTOCOL, true);
|
||||
else
|
||||
header.setPacketFlag(HeaderFlag.NEW_PROTOCOL, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(PacketHeader header, ByteBuffer buffer) {
|
||||
packetId = buffer.getShort() & 0x0000FFFF;
|
||||
packetId = buffer.getShort() & 0xFFFF;
|
||||
|
||||
if (getRole() == ProtocolRole.SERVER)
|
||||
clientId = buffer.getShort() & 0x0000FFFF;
|
||||
clientId = buffer.getShort() & 0xFFFF;
|
||||
|
||||
codecType = CodecType.fromId((int) (buffer.get() & 0xFF));
|
||||
|
||||
|
||||
if (getRole() == ProtocolRole.CLIENT) {
|
||||
if (header.getPacketFlag(HeaderFlag.NEW_PROTOCOL)) {
|
||||
int groupWhisperType = buffer.get() & 0xFF;
|
||||
int groupWhisperTarget = buffer.get() & 0xFF;
|
||||
long targetChannelIdorGroupId = buffer.getLong();
|
||||
|
||||
// TODO
|
||||
setTarget(new WhisperTargetGroup());
|
||||
} else {
|
||||
int channelIdCount = buffer.get() & 0xFF;
|
||||
int clientIdCount = buffer.get() & 0xFF;
|
||||
|
||||
List<Long> channelIds = new ArrayList<>(channelIdCount);
|
||||
for (int i = 0; i < channelIdCount; i ++) channelIds.add(buffer.getLong());
|
||||
|
||||
List<Integer> clientIds = new ArrayList<>(clientIdCount);
|
||||
for (int i = 0; i < clientIdCount; i ++) clientIds.add(buffer.getShort() & 0xFFFF);
|
||||
|
||||
// TODO
|
||||
setTarget(new WhisperTargetMultiple());
|
||||
}
|
||||
} else {
|
||||
setTarget(new WhisperTargetServerToClient());
|
||||
}
|
||||
|
||||
codecData = new byte[buffer.remaining()];
|
||||
target.read(buffer);
|
||||
|
||||
buffer.get(codecData);
|
||||
read(buffer);
|
||||
}
|
||||
|
||||
// We implemented the above so this is unneccessary.
|
||||
@Override
|
||||
public void read(ByteBuffer buffer) {
|
||||
throw new UnsupportedOperationException();
|
||||
codecData = new byte[buffer.remaining()];
|
||||
buffer.get(codecData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,6 +69,9 @@ public class PacketBody1VoiceWhisper extends PacketBody {
|
||||
|
||||
buffer.put((byte)(codecType.getIndex() & 0xFF));
|
||||
|
||||
if (getRole() == ProtocolRole.CLIENT)
|
||||
target.write(buffer);
|
||||
|
||||
buffer.put(codecData);
|
||||
}
|
||||
|
||||
@@ -76,8 +79,7 @@ public class PacketBody1VoiceWhisper extends PacketBody {
|
||||
public int getSize() {
|
||||
switch (getRole()) {
|
||||
case CLIENT:
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
return 2 + 1 + target.getSize() + codecData.length;
|
||||
case SERVER:
|
||||
return 2 + 2 + 1 + codecData.length;
|
||||
default:
|
||||
@@ -119,4 +121,173 @@ public class PacketBody1VoiceWhisper extends PacketBody {
|
||||
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public WhisperTarget getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(WhisperTarget target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public static abstract class WhisperTarget {
|
||||
public abstract void write(ByteBuffer buffer);
|
||||
public abstract void read(ByteBuffer buffer);
|
||||
|
||||
public abstract int getSize();
|
||||
}
|
||||
|
||||
public static class WhisperTargetServerToClient extends WhisperTarget {
|
||||
@Override
|
||||
public void write(ByteBuffer buffer) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer buffer) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return 0; // Empty
|
||||
}
|
||||
}
|
||||
|
||||
public static class WhisperTargetMultiple extends WhisperTarget {
|
||||
private int[] channelIds;
|
||||
private int[] clientIds;
|
||||
|
||||
public int[] getChannelIds() {
|
||||
return channelIds;
|
||||
}
|
||||
|
||||
public void setChannelIds(int[] channelIds) {
|
||||
this.channelIds = channelIds;
|
||||
}
|
||||
|
||||
public int[] getClientIds() {
|
||||
return clientIds;
|
||||
}
|
||||
|
||||
public void setClientIds(int[] clientIds) {
|
||||
this.clientIds = clientIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buffer) {
|
||||
if (channelIds != null)
|
||||
buffer.put((byte) (channelIds.length & 0xFF));
|
||||
else
|
||||
buffer.put((byte) 0x00);
|
||||
|
||||
if (clientIds != null)
|
||||
buffer.put((byte) (clientIds.length & 0xFF));
|
||||
else
|
||||
buffer.put((byte) 0x00);
|
||||
|
||||
if (channelIds != null) {
|
||||
for (int channelId : channelIds) {
|
||||
buffer.putLong((long) channelId);
|
||||
}
|
||||
}
|
||||
|
||||
if (clientIds != null) {
|
||||
for (int clientId : clientIds) {
|
||||
buffer.putShort((short) (clientId & 0xFFFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer buffer) {
|
||||
int channelIdCount = buffer.get() & 0xFF;
|
||||
int clientIdCount = buffer.get() & 0xFF;
|
||||
|
||||
channelIds = new int[channelIdCount];
|
||||
for (int n = 0; n < channelIdCount; n ++)
|
||||
channelIds[n] = (int) (buffer.getLong());
|
||||
|
||||
clientIds = new int[clientIdCount];
|
||||
for (int n = 0; n < channelIdCount; n ++)
|
||||
clientIds[n] = (buffer.getShort() & 0xFFFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return 2 + 2 +
|
||||
(channelIds == null ? 0 : channelIds.length * 8) +
|
||||
(clientIds == null ? 0 : clientIds.length * 2);
|
||||
}
|
||||
}
|
||||
|
||||
public static class WhisperTargetGroup extends WhisperTarget {
|
||||
private GroupWhisperType whisperType;
|
||||
private GroupWhisperTarget whisperTarget;
|
||||
private long targetId;
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buffer) {
|
||||
buffer.put((byte) (whisperType.getIndex() & 0xFF));
|
||||
buffer.put((byte) (whisperTarget.getIndex() & 0xFF));
|
||||
buffer.putLong(targetId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer buffer) {
|
||||
whisperType = GroupWhisperType.fromId(buffer.get() & 0xFF);
|
||||
whisperTarget = GroupWhisperTarget.fromId(buffer.get() & 0xFF);
|
||||
targetId = buffer.getLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return 1 + 1 + 8;
|
||||
}
|
||||
|
||||
public GroupWhisperType getWhisperType() {
|
||||
return whisperType;
|
||||
}
|
||||
|
||||
public void setWhisperType(GroupWhisperType whisperType) {
|
||||
this.whisperType = whisperType;
|
||||
}
|
||||
|
||||
public GroupWhisperTarget getWhisperTarget() {
|
||||
return whisperTarget;
|
||||
}
|
||||
|
||||
public void setWhisperTarget(GroupWhisperTarget whisperTarget) {
|
||||
this.whisperTarget = whisperTarget;
|
||||
}
|
||||
|
||||
public long getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
public void setTargetId(long targetId) {
|
||||
this.targetId = targetId;
|
||||
}
|
||||
}
|
||||
|
||||
public static WhisperTarget createChannel(int channelId) {
|
||||
WhisperTargetMultiple multiple = new WhisperTargetMultiple();
|
||||
multiple.setChannelIds(new int[] { channelId });
|
||||
return multiple;
|
||||
}
|
||||
|
||||
public static WhisperTarget createClient(int clientId) {
|
||||
WhisperTargetMultiple multiple = new WhisperTargetMultiple();
|
||||
multiple.setClientIds(new int[] { clientId });
|
||||
return multiple;
|
||||
}
|
||||
|
||||
public static WhisperTarget createServer() {
|
||||
WhisperTargetGroup group = new WhisperTargetGroup();
|
||||
|
||||
group.setWhisperTarget(GroupWhisperTarget.ALL_CHANNELS);
|
||||
group.setWhisperType(GroupWhisperType.ALL_CLIENTS);
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -5,6 +5,7 @@ import com.github.manevolent.ts3j.command.CommandProcessor;
|
||||
import com.github.manevolent.ts3j.command.MultiCommand;
|
||||
import com.github.manevolent.ts3j.protocol.Packet;
|
||||
import com.github.manevolent.ts3j.protocol.packet.PacketBody0Voice;
|
||||
import com.github.manevolent.ts3j.protocol.packet.PacketBody1VoiceWhisper;
|
||||
import com.github.manevolent.ts3j.protocol.packet.PacketBody2Command;
|
||||
import com.github.manevolent.ts3j.protocol.packet.PacketBody3CommandLow;
|
||||
import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
|
||||
@@ -57,6 +58,10 @@ public abstract class LocalClientHandlerFull extends LocalClientHandler {
|
||||
Consumer<PacketBody0Voice> handler = getClient().getVoiceHandler();
|
||||
if (handler != null) handler.accept((PacketBody0Voice) packet.getBody());
|
||||
break;
|
||||
case VOICE_WHISPER:
|
||||
Consumer<PacketBody1VoiceWhisper> whisperConsumer = getClient().getWhisperHandler();
|
||||
if (whisperConsumer != null) whisperConsumer.accept((PacketBody1VoiceWhisper) packet.getBody());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -70,6 +70,8 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
private CommandProcessor commandProcessor;
|
||||
|
||||
private Consumer<PacketBody0Voice> voiceHandler;
|
||||
private Consumer<PacketBody1VoiceWhisper> whisperHandler;
|
||||
|
||||
private Consumer<Throwable> exceptionHandler = Throwable::printStackTrace;
|
||||
|
||||
private Identity identity = null;
|
||||
@@ -886,6 +888,14 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
this.voiceHandler = voiceHandler;
|
||||
}
|
||||
|
||||
public Consumer<PacketBody1VoiceWhisper> getWhisperHandler() {
|
||||
return whisperHandler;
|
||||
}
|
||||
|
||||
public void setWhisperHandler(Consumer<PacketBody1VoiceWhisper> whisperHandler) {
|
||||
this.whisperHandler = whisperHandler;
|
||||
}
|
||||
|
||||
private class NetworkHandler implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Reference in New Issue
Block a user